[clang] [BoundsSafety][NFC] Move LateParsedAttribute outside Parser class; move LateParsedAttrList to DeclSpec.h (PR #192145)
Yeoul Na via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 14 14:54:14 PDT 2026
https://github.com/rapidsna created https://github.com/llvm/llvm-project/pull/192145
Preparatory refactoring for llvm/llvm-project#179612, which introduces late parsing of bounds-safety attributes as type attributes. The new approach needs LateParsedAttribute accessible from DeclSpec.h (to store late attr pointers in DeclaratorChunk, Declarator, and DeclSpec), which cannot depend on Parser.h.
- Move LateParsedDeclaration and LateParsedAttribute to namespace level in Parser.h
- Move LateParsedAttrList to DeclSpec.h with a forward declaration of LateParsedAttribute
Other LateParsedDeclaration subclasses (LateParsedClass, LateParsedPragma, LateParsedMemberInitializer, etc.) remain inside Parser as they are only created and consumed within Parser and don't need to cross the Parser/Sema boundary.
>From 844fc9b65126aa307d679e76a876368a15d65cb9 Mon Sep 17 00:00:00 2001
From: Yeoul Na <yeoul_na at apple.com>
Date: Tue, 14 Apr 2026 12:26:18 -0700
Subject: [PATCH] [BoundsSafety][NFC] Move LateParsedAttribute outside Parser
class; move LateParsedAttrList to DeclSpec.h
Preparatory refactoring for llvm/llvm-project#179612, which introduces
late parsing of bounds-safety attributes as type attributes. The new
approach needs LateParsedAttribute accessible from DeclSpec.h (to store
late attr pointers in DeclaratorChunk, Declarator, and DeclSpec), which
cannot depend on Parser.h.
- Move LateParsedDeclaration and LateParsedAttribute to namespace level in Parser.h
- Move LateParsedAttrList to DeclSpec.h with a forward declaration of LateParsedAttribute
Other LateParsedDeclaration subclasses (LateParsedClass, LateParsedPragma,
LateParsedMemberInitializer, etc.) remain inside Parser as they are only
created and consumed within Parser and don't need to cross the Parser/Sema
boundary.
---
clang/include/clang/Parse/Parser.h | 107 +++++++++-------------
clang/include/clang/Sema/DeclSpec.h | 21 +++++
clang/lib/Parse/ParseCXXInlineMethods.cpp | 14 +--
3 files changed, 72 insertions(+), 70 deletions(-)
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index c077671cb2407..412fe5f13d844 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -164,6 +164,48 @@ enum class CXX11AttributeKind {
InvalidAttributeSpecifier
};
+/// [class.mem]p1: "... the class is regarded as complete within
+/// - function bodies
+/// - default arguments
+/// - exception-specifications (TODO: C++0x)
+/// - and brace-or-equal-initializers for non-static data members
+/// (including such things in nested classes)."
+/// LateParsedDeclarations build the tree of those elements so they can
+/// be parsed after parsing the top-level class.
+class LateParsedDeclaration {
+public:
+ virtual ~LateParsedDeclaration();
+
+ virtual void ParseLexedMethodDeclarations();
+ virtual void ParseLexedMemberInitializers();
+ virtual void ParseLexedMethodDefs();
+ virtual void ParseLexedAttributes();
+ virtual void ParseLexedPragmas();
+};
+
+/// Contains the lexed tokens of an attribute with arguments that
+/// may reference member variables and so need to be parsed at the
+/// end of the class declaration after parsing all other member
+/// member declarations.
+/// FIXME: Perhaps we should change the name of LateParsedDeclaration to
+/// LateParsedTokens.
+struct LateParsedAttribute : public LateParsedDeclaration {
+ Parser *Self;
+ CachedTokens Toks;
+ IdentifierInfo &AttrName;
+ IdentifierInfo *MacroII = nullptr;
+ SourceLocation AttrNameLoc;
+ SmallVector<Decl *, 2> Decls;
+
+ explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
+ SourceLocation Loc)
+ : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
+
+ void ParseLexedAttributes() override;
+
+ void addDecl(Decl *D) { Decls.push_back(D); }
+};
+
/// Parser - This implements a parser for the C family of languages. After
/// parsing units of the grammar, productions are invoked to handle whatever has
/// been read.
@@ -950,7 +992,6 @@ class Parser : public CodeCompletionHandler {
void SkipFunctionBody();
struct ParsedTemplateInfo;
- class LateParsedAttrList;
/// ParseFunctionDefinition - We parsed and verified that the specified
/// Declarator is well formed. If this is a K&R-style function, read the
@@ -1118,26 +1159,9 @@ class Parser : public CodeCompletionHandler {
///@{
private:
- struct ParsingClass;
+ friend struct LateParsedAttribute;
- /// [class.mem]p1: "... the class is regarded as complete within
- /// - function bodies
- /// - default arguments
- /// - exception-specifications (TODO: C++0x)
- /// - and brace-or-equal-initializers for non-static data members
- /// (including such things in nested classes)."
- /// LateParsedDeclarations build the tree of those elements so they can
- /// be parsed after parsing the top-level class.
- class LateParsedDeclaration {
- public:
- virtual ~LateParsedDeclaration();
-
- virtual void ParseLexedMethodDeclarations();
- virtual void ParseLexedMemberInitializers();
- virtual void ParseLexedMethodDefs();
- virtual void ParseLexedAttributes();
- virtual void ParseLexedPragmas();
- };
+ struct ParsingClass;
/// Inner node of the LateParsedDeclaration tree that parses
/// all its members recursively.
@@ -1161,29 +1185,6 @@ class Parser : public CodeCompletionHandler {
ParsingClass *Class;
};
- /// Contains the lexed tokens of an attribute with arguments that
- /// may reference member variables and so need to be parsed at the
- /// end of the class declaration after parsing all other member
- /// member declarations.
- /// FIXME: Perhaps we should change the name of LateParsedDeclaration to
- /// LateParsedTokens.
- struct LateParsedAttribute : public LateParsedDeclaration {
- Parser *Self;
- CachedTokens Toks;
- IdentifierInfo &AttrName;
- IdentifierInfo *MacroII = nullptr;
- SourceLocation AttrNameLoc;
- SmallVector<Decl *, 2> Decls;
-
- explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
- SourceLocation Loc)
- : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
-
- void ParseLexedAttributes() override;
-
- void addDecl(Decl *D) { Decls.push_back(D); }
- };
-
/// Contains the lexed tokens of a pragma with arguments that
/// may reference member variables and so need to be parsed at the
/// end of the class declaration after parsing all other member
@@ -1204,26 +1205,6 @@ class Parser : public CodeCompletionHandler {
void ParseLexedPragmas() override;
};
- // A list of late-parsed attributes. Used by ParseGNUAttributes.
- class LateParsedAttrList : public SmallVector<LateParsedAttribute *, 2> {
- public:
- LateParsedAttrList(bool PSoon = false,
- bool LateAttrParseExperimentalExtOnly = false)
- : ParseSoon(PSoon),
- LateAttrParseExperimentalExtOnly(LateAttrParseExperimentalExtOnly) {}
-
- bool parseSoon() { return ParseSoon; }
- /// returns true iff the attribute to be parsed should only be late parsed
- /// if it is annotated with `LateAttrParseExperimentalExt`
- bool lateAttrParseExperimentalExtOnly() {
- return LateAttrParseExperimentalExtOnly;
- }
-
- private:
- bool ParseSoon; // Are we planning to parse these shortly after creation?
- bool LateAttrParseExperimentalExtOnly;
- };
-
/// Contains the lexed tokens of a member function definition
/// which needs to be parsed at the end of the class declaration
/// after parsing all other member declarations.
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 6e5421c7072c7..aff63ec56ddb2 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -50,6 +50,7 @@ namespace clang {
class Declarator;
class OverflowBehaviorType;
struct TemplateIdAnnotation;
+ struct LateParsedAttribute;
/// Represents a C++ nested-name-specifier or a global scope specifier.
///
@@ -1249,6 +1250,26 @@ class UnqualifiedId {
/// A set of tokens that has been cached for later parsing.
typedef SmallVector<Token, 4> CachedTokens;
+// A list of late-parsed attributes. Used by ParseGNUAttributes.
+class LateParsedAttrList : public SmallVector<LateParsedAttribute *, 2> {
+public:
+ LateParsedAttrList(bool PSoon = false,
+ bool LateAttrParseExperimentalExtOnly = false)
+ : ParseSoon(PSoon),
+ LateAttrParseExperimentalExtOnly(LateAttrParseExperimentalExtOnly) {}
+
+ bool parseSoon() { return ParseSoon; }
+ /// returns true iff the attribute to be parsed should only be late parsed
+ /// if it is annotated with `LateAttrParseExperimentalExt`
+ bool lateAttrParseExperimentalExtOnly() {
+ return LateAttrParseExperimentalExtOnly;
+ }
+
+private:
+ bool ParseSoon; // Are we planning to parse these shortly after creation?
+ bool LateAttrParseExperimentalExtOnly;
+};
+
/// One instance of this struct is used for each type in a
/// declarator that is parsed.
///
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index bc18881e89110..bea7d9e55a77d 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -268,12 +268,12 @@ void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) {
Toks.push_back(Eof);
}
-Parser::LateParsedDeclaration::~LateParsedDeclaration() {}
-void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}
-void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {}
-void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}
-void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
-void Parser::LateParsedDeclaration::ParseLexedPragmas() {}
+LateParsedDeclaration::~LateParsedDeclaration() {}
+void LateParsedDeclaration::ParseLexedMethodDeclarations() {}
+void LateParsedDeclaration::ParseLexedMemberInitializers() {}
+void LateParsedDeclaration::ParseLexedMethodDefs() {}
+void LateParsedDeclaration::ParseLexedAttributes() {}
+void LateParsedDeclaration::ParseLexedPragmas() {}
Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)
: Self(P), Class(C) {}
@@ -314,7 +314,7 @@ void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {
Self->ParseLexedMemberInitializer(*this);
}
-void Parser::LateParsedAttribute::ParseLexedAttributes() {
+void LateParsedAttribute::ParseLexedAttributes() {
Self->ParseLexedAttribute(*this, true, false);
}
More information about the cfe-commits
mailing list