Author: Bill Wendling Date: 2024-09-06T21:08:33Z New Revision: 7815abec165114da29e191022c2816f857b1984f
URL: https://github.com/llvm/llvm-project/commit/7815abec165114da29e191022c2816f857b1984f DIFF: https://github.com/llvm/llvm-project/commit/7815abec165114da29e191022c2816f857b1984f.diff LOG: [Parser][NFC] Move the core parsing of an attribute into a separate method (#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. Added: Modified: clang/include/clang/Parse/Parser.h clang/lib/Parse/ParseDecl.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index a7513069ff5da0..47f72135c97cff 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -2943,6 +2943,9 @@ class Parser : public CodeCompletionHandler { return false; } + bool ParseSingleGNUAttribute(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..61a1ca3da6bca0 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -146,6 +146,86 @@ void Parser::ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs, } while (MoreToParse); } +/// ParseSingleGNUAttribute - Parse a single GNU attribute. +/// +/// [GNU] attrib: +/// empty +/// attrib-name +/// attrib-name '(' identifier ')' +/// attrib-name '(' identifier ',' nonempty-expr-list ')' +/// attrib-name '(' argument-expression-list [C99 6.5.2] ')' +/// +/// [GNU] attrib-name: +/// identifier +/// typespec +/// typequal +/// storageclass +bool Parser::ParseSingleGNUAttribute(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 +303,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 (ParseSingleGNUAttribute(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