[clang] [Parser][NFC] Move the core parsing of an attribute into a separate method (PR #107300)
Bill Wendling via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 4 13:48:11 PDT 2024
https://github.com/bwendling updated https://github.com/llvm/llvm-project/pull/107300
>From c30c6c11686cc95ba20eb7000d210b17757fbfe3 Mon Sep 17 00:00:00 2001
From: Bill Wendling <isanbard at gmail.com>
Date: Wed, 4 Sep 2024 12:49:04 -0700
Subject: [PATCH 1/2] [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))
>From c2c5c0e8fdca84c02119b8c22b1acc276eace325 Mon Sep 17 00:00:00 2001
From: Bill Wendling <morbo at google.com>
Date: Wed, 4 Sep 2024 13:48:01 -0700
Subject: [PATCH 2/2] Reformatting
---
clang/include/clang/Parse/Parser.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 895f0436075356..bffe9919fd6bbc 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2943,8 +2943,7 @@ class Parser : public CodeCompletionHandler {
return false;
}
- bool ParseGNUSingleAttribute(ParsedAttributes &Attrs,
- SourceLocation &EndLoc,
+ bool ParseGNUSingleAttribute(ParsedAttributes &Attrs, SourceLocation &EndLoc,
LateParsedAttrList *LateAttrs = nullptr,
Declarator *D = nullptr);
void ParseGNUAttributes(ParsedAttributes &Attrs,
More information about the cfe-commits
mailing list