Skip to content

Commit 64e08d7

Browse files
authored
Merge pull request swiftlang#77436 from DougGregor/parse-expression-macro-buffer-as-expression
2 parents c623812 + 78b89b2 commit 64e08d7

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,6 +2095,8 @@ ERROR(unexpected_attribute_expansion,PointsToFirstBadToken,
20952095
ERROR(unexpected_member_expansion,PointsToFirstBadToken,
20962096
"unexpected token '%0' in expanded member list",
20972097
(StringRef))
2098+
ERROR(extra_tokens_after_expression,PointsToFirstBadToken,
2099+
"extra tokens after expression in macro expansion", ())
20982100

20992101
ERROR(parser_round_trip_error,none,
21002102
"source file did not round-trip through the new Swift parser", ())

lib/Parse/ParseRequests.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,27 @@ SourceFileParsingResult parseSourceFile(SourceFile &SF) {
310310
break;
311311

312312
case GeneratedSourceInfo::ExpressionMacroExpansion:
313+
case GeneratedSourceInfo::DefaultArgument: {
314+
// Prime the lexer.
315+
if (parser.Tok.is(tok::NUM_TOKENS))
316+
parser.consumeTokenWithoutFeedingReceiver();
317+
318+
ParserResult<Expr> resultExpr = parser.parseExpr(diag::expected_expr);
319+
if (auto expr = resultExpr.getPtrOrNull())
320+
items.push_back(expr);
321+
322+
if (!parser.Tok.is(tok::eof)) {
323+
parser.diagnose(parser.Tok, diag::extra_tokens_after_expression);
324+
while (!parser.Tok.is(tok::eof))
325+
parser.consumeToken();
326+
}
327+
328+
break;
329+
}
330+
313331
case GeneratedSourceInfo::PreambleMacroExpansion:
314332
case GeneratedSourceInfo::ReplacedFunctionBody:
315-
case GeneratedSourceInfo::PrettyPrinted:
316-
case GeneratedSourceInfo::DefaultArgument: {
333+
case GeneratedSourceInfo::PrettyPrinted:{
317334
parser.parseTopLevelItems(items);
318335
break;
319336
}

lib/Sema/TypeCheckMacros.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ MacroDefinition MacroDefinitionRequest::evaluate(
199199
if (!typeCheckedType)
200200
return MacroDefinition::forInvalid();
201201

202+
// If the expanded macro was one of the the magic literal expressions
203+
// (like #file), there's nothing to expand.
204+
if (auto magicLiteral =
205+
dyn_cast<MagicIdentifierLiteralExpr>(definition)) {
206+
StringRef expansionText = externalMacroName.unbridged();
207+
return MacroDefinition::forExpanded(ctx, expansionText, { }, { });
208+
}
209+
202210
// Dig out the macro that was expanded.
203211
auto expansion = cast<MacroExpansionExpr>(definition);
204212
auto expandedMacro =
@@ -1105,9 +1113,10 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion,
11051113
return nullptr;
11061114

11071115
case BuiltinMacroKind::IsolationMacro:
1108-
// Create a buffer full of scratch space; this will be populated
1109-
// much later.
1110-
std::string scratchSpace(128, ' ');
1116+
// Create a buffer with "nil" plus a bunch of scratch space. This
1117+
// will be populated much later.
1118+
std::string scratchSpace = "nil";
1119+
scratchSpace.append(125, ' ');
11111120
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
11121121
scratchSpace,
11131122
adjustMacroExpansionBufferName(*discriminator));

test/Macros/macro_expand_other.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,9 @@ func testFreestandingExpansionOfOther() {
3636
#endif
3737
}
3838

39+
@freestanding(expression)
40+
macro myLineMacro() -> Int = #line
41+
42+
var thisLine = #myLineMacro
43+
3944
testFreestandingExpansionOfOther()

0 commit comments

Comments
 (0)