@@ -4786,7 +4786,8 @@ static void skipAttribute(Parser &P) {
47864786 }
47874787}
47884788
4789- bool Parser::isStartOfSwiftDecl (bool allowPoundIfAttributes) {
4789+ bool Parser::isStartOfSwiftDecl (bool allowPoundIfAttributes,
4790+ bool hadAttrsOrModifiers) {
47904791 if (Tok.is (tok::at_sign) && peekToken ().is (tok::kw_rethrows)) {
47914792 // @rethrows does not follow the general rule of @<identifier> so
47924793 // it is needed to short circuit this else there will be an infinite
@@ -4835,22 +4836,40 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
48354836 (Tok.is (tok::pound_endif) && !allowPoundIfAttributes))
48364837 return true ;
48374838
4838- return isStartOfSwiftDecl (allowPoundIfAttributes);
4839+ return isStartOfSwiftDecl (allowPoundIfAttributes,
4840+ /* hadAttrsOrModifiers=*/ true );
48394841 }
48404842
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 ;
48454858 }
48464859
48474860 // Skip a #if that contains only attributes in all branches. These will be
48484861 // parsed as attributes of a declaration, not as separate declarations.
48494862 if (Tok.is (tok::pound_if) && allowPoundIfAttributes) {
48504863 BacktrackingScope backtrack (*this );
48514864 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 );
48544873 }
48554874
48564875 // If we have a decl modifying keyword, check if the next token is a valid
@@ -4872,13 +4891,15 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
48724891 // If we found the start of a decl while trying to skip over the
48734892 // paren, then we have something incomplete like 'private('. Return
48744893 // true for better recovery.
4875- if (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ))
4894+ if (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4895+ /* hadAttrsOrModifiers=*/ true ))
48764896 return true ;
48774897
48784898 skipSingle ();
48794899 }
48804900 }
4881- return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false );
4901+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4902+ /* hadAttrsOrModifiers=*/ true );
48824903 }
48834904 }
48844905
@@ -4905,7 +4926,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
49054926 consumeToken (tok::l_paren);
49064927 consumeToken (tok::identifier);
49074928 consumeToken (tok::r_paren);
4908- return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false );
4929+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4930+ /* hadAttrsOrModifiers=*/ true );
49094931 }
49104932
49114933 if (Tok.isContextualKeyword (" actor" )) {
@@ -4917,7 +4939,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
49174939 // it's an actor declaration, otherwise, it isn't.
49184940 do {
49194941 consumeToken ();
4920- } while (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ));
4942+ } while (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4943+ /* hadAttrsOrModifiers=*/ true ));
49214944 return Tok.is (tok::identifier);
49224945 }
49234946
@@ -4960,12 +4983,14 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
49604983 // If we found the start of a decl while trying to skip over the
49614984 // paren, then we have something incomplete like 'package('. Return
49624985 // true for better recovery.
4963- if (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ))
4986+ if (isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4987+ /* hadAttrsOrModifiers=*/ true ))
49644988 return true ;
49654989 skipSingle ();
49664990 }
49674991 }
4968- return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false );
4992+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
4993+ /* hadAttrsOrModifiers=*/ true );
49694994 }
49704995 }
49714996
@@ -4976,7 +5001,8 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
49765001 // Otherwise, do a recursive parse.
49775002 Parser::BacktrackingScope Backtrack (*this );
49785003 consumeToken (tok::identifier);
4979- return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false );
5004+ return isStartOfSwiftDecl (/* allowPoundIfAttributes=*/ false ,
5005+ /* hadAttrsOrModifiers=*/ true );
49805006}
49815007
49825008bool Parser::isStartOfSILDecl () {
@@ -5004,6 +5030,19 @@ bool Parser::isStartOfSILDecl() {
50045030 llvm_unreachable (" Unhandled case in switch" );
50055031}
50065032
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+
50075046void Parser::consumeDecl (ParserPosition BeginParserPosition,
50085047 ParseDeclOptions Flags,
50095048 bool IsTopLevel) {
@@ -5256,9 +5295,15 @@ Parser::parseDecl(ParseDeclOptions Flags,
52565295 // Handled below.
52575296 break ;
52585297 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)) {
52625307 consumeToken ();
52635308 if (CodeCompletionCallbacks) {
52645309 CodeCompletionCallbacks->completeAfterPoundDirective ();
@@ -5270,6 +5315,7 @@ Parser::parseDecl(ParseDeclOptions Flags,
52705315
52715316 // Parse as a macro expansion.
52725317 DeclResult = parseDeclMacroExpansion (Flags, Attributes);
5318+ StaticLoc = SourceLoc (); // Ignore 'static' on macro expansion
52735319 break ;
52745320
52755321 case tok::pound_if:
@@ -9810,10 +9856,10 @@ Parser::parseDeclMacroExpansion(ParseDeclOptions flags,
98109856 }
98119857 }
98129858
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 );
98199865}
0 commit comments