@@ -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:
@@ -9810,10 +9856,10 @@ Parser::parseDeclMacroExpansion(ParseDeclOptions flags,
9810
9856
}
9811
9857
}
9812
9858
9813
- return makeParserResult (
9814
- status ,
9815
- new ( Context) MacroExpansionDecl (
9816
- CurDeclContext, poundLoc, macroNameRef, macroNameLoc,
9817
- leftAngleLoc, Context. AllocateCopy (genericArgs), rightAngleLoc,
9818
- argList) );
9859
+ auto *med = new (Context) MacroExpansionDecl (
9860
+ CurDeclContext, poundLoc, macroNameRef, macroNameLoc, leftAngleLoc ,
9861
+ Context. AllocateCopy (genericArgs), rightAngleLoc, argList);
9862
+ med-> getAttrs () = attributes;
9863
+
9864
+ return makeParserResult (status, med );
9819
9865
}
0 commit comments