[clang] 7815abe - [Parser][NFC] Move the core parsing of an attribute into a separate method (#107300)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 6 14:08:37 PDT 2024
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))
More information about the cfe-commits
mailing list