1515// ===----------------------------------------------------------------------===//
1616
1717#include " TypeCheckMacros.h"
18+ #include " TypeChecker.h"
1819#include " swift/AST/ASTContext.h"
1920#include " swift/AST/Expr.h"
2021#include " swift/AST/SourceFile.h"
2122#include " swift/Basic/SourceManager.h"
2223#include " swift/Parse/Lexer.h"
24+ #include " swift/Parse/Parser.h"
2325
2426using namespace swift ;
2527
@@ -74,7 +76,7 @@ Expr *swift::expandMacroExpr(
7476 std::tie (endLine, endColumn) =
7577 sourceMgr.getLineAndColumnInBuffer (endLoc, *bufferID);
7678
77- out << sourceMgr.getIdentifierForBuffer (*bufferID) << " :"
79+ out << " in " << sourceMgr.getIdentifierForBuffer (*bufferID) << " :"
7880 << startLine << " :" << startColumn
7981 << " -" << endLine << " :" << endColumn;
8082 }
@@ -86,13 +88,39 @@ Expr *swift::expandMacroExpr(
8688 StringRef (evaluatedSource, evaluatedSourceLength), bufferName);
8789 unsigned macroBufferID = sourceMgr.addNewSourceBuffer (std::move (macroBuffer));
8890
89- // FIXME: Debug output.
90- llvm::outs () << " Macro rewrite: "
91- << " #" << macroName
92- << " --> " << sourceMgr.getEntireTextForBuffer (macroBufferID)
93- << " \n " ;
91+ // Create a source file to hold the macro buffer.
92+ // FIXME: Seems like we should record this somewhere?
93+ auto macroSourceFile = new (ctx) SourceFile (
94+ *dc->getParentModule (), SourceFileKind::Library, macroBufferID);
95+
96+ // Parse the expression.
97+ Parser parser (macroBufferID, *macroSourceFile, &ctx.Diags , nullptr , nullptr );
98+ parser.consumeTokenWithoutFeedingReceiver ();
99+ auto parsedResult = parser.parseExpr (diag::expected_macro_expansion_expr);
100+ if (parsedResult.isParseError () || parsedResult.isNull ()) {
101+ // Tack on a note to say where we expanded the macro from?
102+ return nullptr ;
103+ }
104+
105+ // Type-check the expanded expression.
106+ // FIXME: Would like to pass through type checking options like "discarded"
107+ // that are captured by TypeCheckExprOptions.
108+ Expr *expandedExpr = parsedResult.get ();
109+ constraints::ContextualTypeInfo contextualType {
110+ TypeLoc::withoutLoc (expandedType),
111+ // FIXME: Add a contextual type purpose for macro expansion.
112+ ContextualTypePurpose::CTP_CoerceOperand
113+ };
114+
115+ Type realExpandedType = TypeChecker::typeCheckExpression (
116+ expandedExpr, dc, contextualType);
117+ if (!realExpandedType)
118+ return nullptr ;
94119
95- return nullptr ;
120+ assert ((expandedType->isEqual (realExpandedType) ||
121+ realExpandedType->hasError ()) &&
122+ " Type checking changed the result type?" );
123+ return expandedExpr;
96124}
97125
98126#endif // SWIFT_SWIFT_PARSER
0 commit comments