@@ -4768,7 +4768,8 @@ static void skipAttribute(Parser &P) {
4768
4768
}
4769
4769
}
4770
4770
4771
- bool Parser::isStartOfSwiftDecl (bool allowPoundIfAttributes) {
4771
+ bool Parser::isStartOfSwiftDecl (bool allowPoundIfAttributes,
4772
+ bool hadAttrsOrModifiers) {
4772
4773
if (Tok.is (tok::at_sign) && peekToken ().is (tok::kw_rethrows)) {
4773
4774
// @rethrows does not follow the general rule of @<identifier> so
4774
4775
// it is needed to short circuit this else there will be an infinite
@@ -4817,22 +4818,40 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4817
4818
(Tok.is (tok::pound_endif) && !allowPoundIfAttributes))
4818
4819
return true ;
4819
4820
4820
- return isStartOfSwiftDecl (allowPoundIfAttributes);
4821
+ return isStartOfSwiftDecl (allowPoundIfAttributes,
4822
+ /* hadAttrsOrModifiers=*/ true );
4821
4823
}
4822
4824
4823
- if (Tok.is (tok::pound) && peekToken ().is (tok::identifier)) {
4824
- // Macro expansions at the top level are declarations.
4825
- return !isInSILMode () && SF.Kind != SourceFileKind::Interface &&
4826
- CurDeclContext->isModuleScopeContext () && !allowTopLevelCode ();
4825
+ if (Tok.is (tok::pound)) {
4826
+ if (isStartOfFreestandingMacroExpansion ()) {
4827
+ if (isInSILMode () || SF.Kind == SourceFileKind::Interface)
4828
+ return false ;
4829
+
4830
+ // Parse '#<identifier>' after attrs/modifiers as a macro expansion decl.
4831
+ if (hadAttrsOrModifiers)
4832
+ return true ;
4833
+
4834
+ // Macro expansions at the top level of non-script file are declarations.
4835
+ return CurDeclContext->isModuleScopeContext () && !allowTopLevelCode ();
4836
+ }
4837
+
4838
+ // Otherwise, prefer parsing it as an expression.
4839
+ return false ;
4827
4840
}
4828
4841
4829
4842
// Skip a #if that contains only attributes in all branches. These will be
4830
4843
// parsed as attributes of a declaration, not as separate declarations.
4831
4844
if (Tok.is (tok::pound_if) && allowPoundIfAttributes) {
4832
4845
BacktrackingScope backtrack (*this );
4833
4846
bool sawAnyAttributes = false ;
4834
- return skipIfConfigOfAttributes (sawAnyAttributes) &&
4835
- (Tok.is (tok::eof) || (sawAnyAttributes && isStartOfSwiftDecl ()));
4847
+ if (!skipIfConfigOfAttributes (sawAnyAttributes))
4848
+ return false ;
4849
+ if (Tok.is (tok::eof))
4850
+ return true ;
4851
+ if (!sawAnyAttributes)
4852
+ return false ;
4853
+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ true ,
4854
+ /* hadAttrsOrModifiers=*/ true );
4836
4855
}
4837
4856
4838
4857
// If we have a decl modifying keyword, check if the next token is a valid
@@ -4854,13 +4873,15 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4854
4873
// If we found the start of a decl while trying to skip over the
4855
4874
// paren, then we have something incomplete like 'private('. Return
4856
4875
// true for better recovery.
4857
- if (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ))
4876
+ if (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4877
+ /* hadAttrsOrModifiers=*/ true ))
4858
4878
return true ;
4859
4879
4860
4880
skipSingle ();
4861
4881
}
4862
4882
}
4863
- return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false );
4883
+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4884
+ /* hadAttrsOrModifiers=*/ true );
4864
4885
}
4865
4886
}
4866
4887
@@ -4887,7 +4908,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4887
4908
consumeToken (tok::l_paren);
4888
4909
consumeToken (tok::identifier);
4889
4910
consumeToken (tok::r_paren);
4890
- return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false );
4911
+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4912
+ /* hadAttrsOrModifiers=*/ true );
4891
4913
}
4892
4914
4893
4915
if (Tok.isContextualKeyword (" actor" )) {
@@ -4899,7 +4921,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4899
4921
// it's an actor declaration, otherwise, it isn't.
4900
4922
do {
4901
4923
consumeToken ();
4902
- } while (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ));
4924
+ } while (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4925
+ /* hadAttrsOrModifiers=*/ true ));
4903
4926
return Tok.is (tok::identifier);
4904
4927
}
4905
4928
@@ -4942,12 +4965,14 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4942
4965
// If we found the start of a decl while trying to skip over the
4943
4966
// paren, then we have something incomplete like 'package('. Return
4944
4967
// true for better recovery.
4945
- if (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ))
4968
+ if (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4969
+ /* hadAttrsOrModifiers=*/ true ))
4946
4970
return true ;
4947
4971
skipSingle ();
4948
4972
}
4949
4973
}
4950
- return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false );
4974
+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4975
+ /* hadAttrsOrModifiers=*/ true );
4951
4976
}
4952
4977
}
4953
4978
@@ -4958,7 +4983,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
4958
4983
// Otherwise, do a recursive parse.
4959
4984
Parser::BacktrackingScope Backtrack (*this );
4960
4985
consumeToken (tok::identifier);
4961
- return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false );
4986
+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4987
+ /* hadAttrsOrModifiers=*/ true );
4962
4988
}
4963
4989
4964
4990
bool Parser::isStartOfSILDecl () {
@@ -4986,6 +5012,19 @@ bool Parser::isStartOfSILDecl() {
4986
5012
llvm_unreachable (" Unhandled case in switch" );
4987
5013
}
4988
5014
5015
+ bool Parser::isStartOfFreestandingMacroExpansion () {
5016
+ // Check if "'#' <identifier>" without any whitespace between them.
5017
+ if (!Tok.is (tok::pound))
5018
+ return false ;
5019
+ if (Tok.getRange ().getEnd () != peekToken ().getLoc ())
5020
+ return false ;
5021
+ if (!peekToken ().isAny (tok::identifier, tok::code_complete) &&
5022
+ // allow keywords right after '#' so we can diagnose it when parsing.
5023
+ !peekToken ().isKeyword ())
5024
+ return false ;
5025
+ return true ;
5026
+ }
5027
+
4989
5028
void Parser::consumeDecl (ParserPosition BeginParserPosition,
4990
5029
ParseDeclOptions Flags,
4991
5030
bool IsTopLevel) {
@@ -5238,9 +5277,15 @@ Parser::parseDecl(ParseDeclOptions Flags,
5238
5277
// Handled below.
5239
5278
break ;
5240
5279
case tok::pound:
5241
- if (Tok.isAtStartOfLine () &&
5242
- peekToken ().is (tok::code_complete) &&
5243
- Tok.getLoc ().getAdvancedLoc (1 ) == peekToken ().getLoc ()) {
5280
+ if (!isStartOfFreestandingMacroExpansion ()) {
5281
+ consumeToken (tok::pound);
5282
+ diagnose (Tok.getLoc (),
5283
+ diag::macro_expansion_decl_expected_macro_identifier);
5284
+ DeclResult = makeParserError ();
5285
+ break ;
5286
+ }
5287
+
5288
+ if (peekToken ().is (tok::code_complete)) {
5244
5289
consumeToken ();
5245
5290
if (CodeCompletionCallbacks) {
5246
5291
CodeCompletionCallbacks->completeAfterPoundDirective ();
@@ -5252,6 +5297,7 @@ Parser::parseDecl(ParseDeclOptions Flags,
5252
5297
5253
5298
// Parse as a macro expansion.
5254
5299
DeclResult = parseDeclMacroExpansion (Flags, Attributes);
5300
+ StaticLoc = SourceLoc (); // Ignore 'static' on macro expansion
5255
5301
break ;
5256
5302
5257
5303
case tok::pound_if:
@@ -9785,10 +9831,10 @@ Parser::parseDeclMacroExpansion(ParseDeclOptions flags,
9785
9831
}
9786
9832
}
9787
9833
9788
- return makeParserResult (
9789
- status ,
9790
- new ( Context) MacroExpansionDecl (
9791
- CurDeclContext, poundLoc, macroNameRef, macroNameLoc,
9792
- leftAngleLoc, Context. AllocateCopy (genericArgs), rightAngleLoc,
9793
- argList) );
9834
+ auto *med = new (Context) MacroExpansionDecl (
9835
+ CurDeclContext, poundLoc, macroNameRef, macroNameLoc, leftAngleLoc ,
9836
+ Context. AllocateCopy (genericArgs), rightAngleLoc, argList);
9837
+ med-> getAttrs () = attributes;
9838
+
9839
+ return makeParserResult (status, med );
9794
9840
}
0 commit comments