https://github.com/bwendling created https://github.com/llvm/llvm-project/pull/107300
Refactor attribute parsing so that the main code parsing an attribute can be called by a separate code path that doesn't start with the '__attribute' keyword. >From c30c6c11686cc95ba20eb7000d210b17757fbfe3 Mon Sep 17 00:00:00 2001 From: Bill Wendling <isanb...@gmail.com> Date: Wed, 4 Sep 2024 12:49:04 -0700 Subject: [PATCH] [Parser][NFC] Move the core parsing of an attribute into a separate method Refactor attribute parsing so that the main code parsing an attribute can be called by a separate code path that doesn't start with the '__attribute' keyword. --- clang/include/clang/Parse/Parser.h | 4 + clang/lib/Parse/ParseDecl.cpp | 125 ++++++++++++++++------------- 2 files changed, 72 insertions(+), 57 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index a7513069ff5da0..895f0436075356 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -2943,6 +2943,10 @@ class Parser : public CodeCompletionHandler { return false; } + bool ParseGNUSingleAttribute(ParsedAttributes &Attrs, + SourceLocation &EndLoc, + LateParsedAttrList *LateAttrs = nullptr, + Declarator *D = nullptr); void ParseGNUAttributes(ParsedAttributes &Attrs, LateParsedAttrList *LateAttrs = nullptr, Declarator *D = nullptr); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 78d729c5ef7d8a..3ddc37db3a1bd1 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -146,6 +146,72 @@ void Parser::ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs, } while (MoreToParse); } +bool Parser::ParseGNUSingleAttribute(ParsedAttributes &Attrs, + SourceLocation &EndLoc, + LateParsedAttrList *LateAttrs, + Declarator *D) { + IdentifierInfo *AttrName = Tok.getIdentifierInfo(); + if (!AttrName) + return true; + + SourceLocation AttrNameLoc = ConsumeToken(); + + if (Tok.isNot(tok::l_paren)) { + Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, + ParsedAttr::Form::GNU()); + return false; + } + + bool LateParse = false; + if (!LateAttrs) + LateParse = false; + else if (LateAttrs->lateAttrParseExperimentalExtOnly()) { + // The caller requested that this attribute **only** be late + // parsed for `LateAttrParseExperimentalExt` attributes. This will + // only be late parsed if the experimental language option is enabled. + LateParse = getLangOpts().ExperimentalLateParseAttributes && + IsAttributeLateParsedExperimentalExt(*AttrName); + } else { + // The caller did not restrict late parsing to only + // `LateAttrParseExperimentalExt` attributes so late parse + // both `LateAttrParseStandard` and `LateAttrParseExperimentalExt` + // attributes. + LateParse = IsAttributeLateParsedExperimentalExt(*AttrName) || + IsAttributeLateParsedStandard(*AttrName); + } + + // Handle "parameterized" attributes + if (!LateParse) { + ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc, nullptr, + SourceLocation(), ParsedAttr::Form::GNU(), D); + return false; + } + + // Handle attributes with arguments that require late parsing. + LateParsedAttribute *LA = + new LateParsedAttribute(this, *AttrName, AttrNameLoc); + LateAttrs->push_back(LA); + + // Attributes in a class are parsed at the end of the class, along + // with other late-parsed declarations. + if (!ClassStack.empty() && !LateAttrs->parseSoon()) + getCurrentClass().LateParsedDeclarations.push_back(LA); + + // Be sure ConsumeAndStoreUntil doesn't see the start l_paren, since it + // recursively consumes balanced parens. + LA->Toks.push_back(Tok); + ConsumeParen(); + // Consume everything up to and including the matching right parens. + ConsumeAndStoreUntil(tok::r_paren, LA->Toks, /*StopAtSemi=*/true); + + Token Eof; + Eof.startToken(); + Eof.setLocation(Tok.getLocation()); + LA->Toks.push_back(Eof); + + return false; +} + /// ParseGNUAttributes - Parse a non-empty attributes list. /// /// [GNU] attributes: @@ -223,64 +289,9 @@ void Parser::ParseGNUAttributes(ParsedAttributes &Attrs, AttributeCommonInfo::Syntax::AS_GNU); break; } - IdentifierInfo *AttrName = Tok.getIdentifierInfo(); - if (!AttrName) - break; - - SourceLocation AttrNameLoc = ConsumeToken(); - - if (Tok.isNot(tok::l_paren)) { - Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, - ParsedAttr::Form::GNU()); - continue; - } - - bool LateParse = false; - if (!LateAttrs) - LateParse = false; - else if (LateAttrs->lateAttrParseExperimentalExtOnly()) { - // The caller requested that this attribute **only** be late - // parsed for `LateAttrParseExperimentalExt` attributes. This will - // only be late parsed if the experimental language option is enabled. - LateParse = getLangOpts().ExperimentalLateParseAttributes && - IsAttributeLateParsedExperimentalExt(*AttrName); - } else { - // The caller did not restrict late parsing to only - // `LateAttrParseExperimentalExt` attributes so late parse - // both `LateAttrParseStandard` and `LateAttrParseExperimentalExt` - // attributes. - LateParse = IsAttributeLateParsedExperimentalExt(*AttrName) || - IsAttributeLateParsedStandard(*AttrName); - } - - // Handle "parameterized" attributes - if (!LateParse) { - ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc, nullptr, - SourceLocation(), ParsedAttr::Form::GNU(), D); - continue; - } - // Handle attributes with arguments that require late parsing. - LateParsedAttribute *LA = - new LateParsedAttribute(this, *AttrName, AttrNameLoc); - LateAttrs->push_back(LA); - - // Attributes in a class are parsed at the end of the class, along - // with other late-parsed declarations. - if (!ClassStack.empty() && !LateAttrs->parseSoon()) - getCurrentClass().LateParsedDeclarations.push_back(LA); - - // Be sure ConsumeAndStoreUntil doesn't see the start l_paren, since it - // recursively consumes balanced parens. - LA->Toks.push_back(Tok); - ConsumeParen(); - // Consume everything up to and including the matching right parens. - ConsumeAndStoreUntil(tok::r_paren, LA->Toks, /*StopAtSemi=*/true); - - Token Eof; - Eof.startToken(); - Eof.setLocation(Tok.getLocation()); - LA->Toks.push_back(Eof); + if (ParseGNUSingleAttribute(Attrs, EndLoc, LateAttrs, D)) + break; } while (Tok.is(tok::comma)); if (ExpectAndConsume(tok::r_paren)) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits