[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
Fri Sep 6 14:07:23 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/3] [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/3] 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,
>From a8b3384128ba9b4cb340c80fb7c59b1dceefa31b Mon Sep 17 00:00:00 2001
From: Bill Wendling <morbo at google.com>
Date: Fri, 6 Sep 2024 14:07:08 -0700
Subject: [PATCH 3/3] Use better name and add short comment.
---
clang/include/clang/Parse/Parser.h | 2 +-
clang/lib/Parse/ParseDecl.cpp | 18 ++++++++++++++++--
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index bffe9919fd6bbc..47f72135c97cff 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2943,7 +2943,7 @@ class Parser : public CodeCompletionHandler {
return false;
}
- bool ParseGNUSingleAttribute(ParsedAttributes &Attrs, SourceLocation &EndLoc,
+ bool ParseSingleGNUAttribute(ParsedAttributes &Attrs, SourceLocation &EndLoc,
LateParsedAttrList *LateAttrs = nullptr,
Declarator *D = nullptr);
void ParseGNUAttributes(ParsedAttributes &Attrs,
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 3ddc37db3a1bd1..61a1ca3da6bca0 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -146,7 +146,21 @@ void Parser::ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
} while (MoreToParse);
}
-bool Parser::ParseGNUSingleAttribute(ParsedAttributes &Attrs,
+/// 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) {
@@ -290,7 +304,7 @@ void Parser::ParseGNUAttributes(ParsedAttributes &Attrs,
break;
}
- if (ParseGNUSingleAttribute(Attrs, EndLoc, LateAttrs, D))
+ if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))
break;
} while (Tok.is(tok::comma));
More information about the cfe-commits
mailing list