@@ -4786,7 +4786,8 @@ static void skipAttribute(Parser &P) {
4786
4786
}
4787
4787
}
4788
4788
4789
- bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4789
+ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes,
4790
+ bool hadAttrsOrModifiers) {
4790
4791
if (Tok.is(tok::at_sign) && peekToken().is(tok::kw_rethrows)) {
4791
4792
// @rethrows does not follow the general rule of @<identifier> so
4792
4793
// it is needed to short circuit this else there will be an infinite
@@ -4835,22 +4836,40 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4835
4836
(Tok.is(tok::pound_endif) && !allowPoundIfAttributes))
4836
4837
return true;
4837
4838
4838
- return isStartOfSwiftDecl(allowPoundIfAttributes);
4839
+ return isStartOfSwiftDecl(allowPoundIfAttributes,
4840
+ /*hadAttrsOrModifiers=*/true);
4839
4841
}
4840
4842
4841
- if (Tok.is(tok::pound) && peekToken().is(tok::identifier)) {
4842
- // Macro expansions at the top level are declarations.
4843
- return !isInSILMode() && SF.Kind != SourceFileKind::Interface &&
4844
- CurDeclContext->isModuleScopeContext() && !allowTopLevelCode();
4843
+ if (Tok.is(tok::pound)) {
4844
+ if (isStartOfFreestandingMacroExpansion()) {
4845
+ if (isInSILMode() || SF.Kind == SourceFileKind::Interface)
4846
+ return false;
4847
+
4848
+ // Parse '#<identifier>' after attrs/modifiers as a macro expansion decl.
4849
+ if (hadAttrsOrModifiers)
4850
+ return true;
4851
+
4852
+ // Macro expansions at the top level of non-script file are declarations.
4853
+ return CurDeclContext->isModuleScopeContext() && !allowTopLevelCode();
4854
+ }
4855
+
4856
+ // Otherwise, prefer parsing it as an expression.
4857
+ return false;
4845
4858
}
4846
4859
4847
4860
// Skip a #if that contains only attributes in all branches. These will be
4848
4861
// parsed as attributes of a declaration, not as separate declarations.
4849
4862
if (Tok.is(tok::pound_if) && allowPoundIfAttributes) {
4850
4863
BacktrackingScope backtrack(*this);
4851
4864
bool sawAnyAttributes = false;
4852
- return skipIfConfigOfAttributes(sawAnyAttributes) &&
4853
- (Tok.is(tok::eof) || (sawAnyAttributes && isStartOfSwiftDecl()));
4865
+ if (!skipIfConfigOfAttributes(sawAnyAttributes))
4866
+ return false;
4867
+ if (Tok.is(tok::eof))
4868
+ return true;
4869
+ if (!sawAnyAttributes)
4870
+ return false;
4871
+ return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/true,
4872
+ /*hadAttrsOrModifiers=*/true);
4854
4873
}
4855
4874
4856
4875
// If we have a decl modifying keyword, check if the next token is a valid
@@ -4872,13 +4891,15 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4872
4891
// If we found the start of a decl while trying to skip over the
4873
4892
// paren, then we have something incomplete like 'private('. Return
4874
4893
// true for better recovery.
4875
- if (isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false))
4894
+ if (isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false,
4895
+ /*hadAttrsOrModifiers=*/true))
4876
4896
return true;
4877
4897
4878
4898
skipSingle();
4879
4899
}
4880
4900
}
4881
- return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false);
4901
+ return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false,
4902
+ /*hadAttrsOrModifiers=*/true);
4882
4903
}
4883
4904
}
4884
4905
@@ -4905,7 +4926,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4905
4926
consumeToken(tok::l_paren);
4906
4927
consumeToken(tok::identifier);
4907
4928
consumeToken(tok::r_paren);
4908
- return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false);
4929
+ return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false,
4930
+ /*hadAttrsOrModifiers=*/true);
4909
4931
}
4910
4932
4911
4933
if (Tok.isContextualKeyword("actor")) {
@@ -4917,7 +4939,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4917
4939
// it's an actor declaration, otherwise, it isn't.
4918
4940
do {
4919
4941
consumeToken();
4920
- } while (isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false));
4942
+ } while (isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false,
4943
+ /*hadAttrsOrModifiers=*/true));
4921
4944
return Tok.is(tok::identifier);
4922
4945
}
4923
4946
@@ -4960,12 +4983,14 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4960
4983
// If we found the start of a decl while trying to skip over the
4961
4984
// paren, then we have something incomplete like 'package('. Return
4962
4985
// true for better recovery.
4963
- if (isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false))
4986
+ if (isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false,
4987
+ /*hadAttrsOrModifiers=*/true))
4964
4988
return true;
4965
4989
skipSingle();
4966
4990
}
4967
4991
}
4968
- return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false);
4992
+ return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false,
4993
+ /*hadAttrsOrModifiers=*/true);
4969
4994
}
4970
4995
}
4971
4996
@@ -4976,7 +5001,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4976
5001
// Otherwise, do a recursive parse.
4977
5002
Parser::BacktrackingScope Backtrack(*this);
4978
5003
consumeToken(tok::identifier);
4979
- return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false);
5004
+ return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false,
5005
+ /*hadAttrsOrModifiers=*/true);
4980
5006
}
4981
5007
4982
5008
bool Parser::isStartOfSILDecl() {
@@ -5004,6 +5030,19 @@ bool Parser::isStartOfSILDecl() {
5004
5030
llvm_unreachable("Unhandled case in switch");
5005
5031
}
5006
5032
5033
+ bool Parser::isStartOfFreestandingMacroExpansion() {
5034
+ // Check if "'#' <identifier>" without any whitespace between them.
5035
+ if (!Tok.is(tok::pound))
5036
+ return false;
5037
+ if (Tok.getRange().getEnd() != peekToken().getLoc())
5038
+ return false;
5039
+ if (!peekToken().isAny(tok::identifier, tok::code_complete) &&
5040
+ // allow keywords right after '#' so we can diagnose it when parsing.
5041
+ !peekToken().isKeyword())
5042
+ return false;
5043
+ return true;
5044
+ }
5045
+
5007
5046
void Parser::consumeDecl(ParserPosition BeginParserPosition,
5008
5047
ParseDeclOptions Flags,
5009
5048
bool IsTopLevel) {
@@ -5256,9 +5295,15 @@ Parser::parseDecl(ParseDeclOptions Flags,
5256
5295
// Handled below.
5257
5296
break;
5258
5297
case tok::pound:
5259
- if (Tok.isAtStartOfLine() &&
5260
- peekToken().is(tok::code_complete) &&
5261
- Tok.getLoc().getAdvancedLoc(1) == peekToken().getLoc()) {
5298
+ if (!isStartOfFreestandingMacroExpansion()) {
5299
+ consumeToken(tok::pound);
5300
+ diagnose(Tok.getLoc(),
5301
+ diag::macro_expansion_decl_expected_macro_identifier);
5302
+ DeclResult = makeParserError();
5303
+ break;
5304
+ }
5305
+
5306
+ if (peekToken().is(tok::code_complete)) {
5262
5307
consumeToken();
5263
5308
if (CodeCompletionCallbacks) {
5264
5309
CodeCompletionCallbacks->completeAfterPoundDirective();
@@ -5270,6 +5315,7 @@ Parser::parseDecl(ParseDeclOptions Flags,
5270
5315
5271
5316
// Parse as a macro expansion.
5272
5317
DeclResult = parseDeclMacroExpansion(Flags, Attributes);
5318
+ StaticLoc = SourceLoc(); // Ignore 'static' on macro expansion
5273
5319
break;
5274
5320
5275
5321
case tok::pound_if:
@@ -9803,10 +9849,10 @@ Parser::parseDeclMacroExpansion(ParseDeclOptions flags,
9803
9849
}
9804
9850
}
9805
9851
9806
- return makeParserResult (
9807
- status ,
9808
- new ( Context) MacroExpansionDecl(
9809
- CurDeclContext, poundLoc, macroNameRef, macroNameLoc,
9810
- leftAngleLoc, Context.AllocateCopy(genericArgs), rightAngleLoc,
9811
- argList) );
9852
+ auto *med = new (Context) MacroExpansionDecl (
9853
+ CurDeclContext, poundLoc, macroNameRef, macroNameLoc, leftAngleLoc ,
9854
+ Context.AllocateCopy(genericArgs), rightAngleLoc, argList);
9855
+ med->getAttrs() = attributes;
9856
+
9857
+ return makeParserResult(status, med );
9812
9858
}
0 commit comments