[clang] [PATCH 1/4] [clang] Improve nested name specifier AST representation (PR #147835)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 11 07:23:27 PDT 2025
================
@@ -6,534 +6,266 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the NestedNameSpecifier class, which represents
-// a C++ nested-name-specifier.
+// This file completes the definition of the NestedNameSpecifier class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
-#include "clang/AST/DependenceFlags.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/NestedNameSpecifierBase.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Compiler.h"
-#include <cstdint>
-#include <cstdlib>
-#include <utility>
namespace clang {
-class ASTContext;
-class CXXRecordDecl;
-class IdentifierInfo;
-class LangOptions;
-class NamespaceAliasDecl;
-class NamespaceDecl;
-struct PrintingPolicy;
-class Type;
-class TypeLoc;
-
-/// Represents a C++ nested name specifier, such as
-/// "\::std::vector<int>::".
-///
-/// C++ nested name specifiers are the prefixes to qualified
-/// names. For example, "foo::" in "foo::x" is a nested name
-/// specifier. Nested name specifiers are made up of a sequence of
-/// specifiers, each of which can be a namespace, type, identifier
-/// (for dependent names), decltype specifier, or the global specifier ('::').
-/// The last two specifiers can only appear at the start of a
-/// nested-namespace-specifier.
-class NestedNameSpecifier : public llvm::FoldingSetNode {
- /// Enumeration describing
- enum StoredSpecifierKind {
- StoredIdentifier = 0,
- StoredDecl = 1,
- StoredTypeSpec = 2
- };
-
- /// The nested name specifier that precedes this nested name
- /// specifier.
- ///
- /// The pointer is the nested-name-specifier that precedes this
- /// one. The integer stores one of the first four values of type
- /// SpecifierKind.
- llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
-
- /// The last component in the nested name specifier, which
- /// can be an identifier, a declaration, or a type.
- ///
- /// When the pointer is NULL, this specifier represents the global
- /// specifier '::'. Otherwise, the pointer is one of
- /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
- /// specifier as encoded within the prefix.
- void* Specifier = nullptr;
-
-public:
- /// The kind of specifier that completes this nested name
- /// specifier.
- enum SpecifierKind {
- /// An identifier, stored as an IdentifierInfo*.
- Identifier,
-
- /// A namespace, stored as a NamespaceDecl*.
- Namespace,
-
- /// A namespace alias, stored as a NamespaceAliasDecl*.
- NamespaceAlias,
-
- /// A type, stored as a Type*.
- TypeSpec,
-
- /// The global specifier '::'. There is no stored value.
- Global,
-
- /// Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
- /// the class it appeared in.
- Super
- };
-
-private:
- /// Builds the global specifier.
- NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {}
-
- /// Copy constructor used internally to clone nested name
- /// specifiers.
- NestedNameSpecifier(const NestedNameSpecifier &Other) = default;
-
- /// Either find or insert the given nested name specifier
- /// mockup in the given context.
- static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
- const NestedNameSpecifier &Mockup);
-
-public:
- NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete;
-
- /// Builds a specifier combining a prefix and an identifier.
- ///
- /// The prefix must be dependent, since nested name specifiers
- /// referencing an identifier are only permitted when the identifier
- /// cannot be resolved.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const IdentifierInfo *II);
-
- /// Builds a nested name specifier that names a namespace.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceDecl *NS);
-
- /// Builds a nested name specifier that names a namespace alias.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceAliasDecl *Alias);
-
- /// Builds a nested name specifier that names a type.
- static NestedNameSpecifier *
- Create(const ASTContext &Context, NestedNameSpecifier *Prefix, const Type *T);
-
- /// Builds a specifier that consists of just an identifier.
- ///
- /// The nested-name-specifier is assumed to be dependent, but has no
- /// prefix because the prefix is implied by something outside of the
- /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
- /// type.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- const IdentifierInfo *II);
-
- /// Returns the nested name specifier representing the global
- /// scope.
- static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
-
- /// Returns the nested name specifier representing the __super scope
- /// for the given CXXRecordDecl.
- static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
- CXXRecordDecl *RD);
-
- /// Return the prefix of this nested name specifier.
- ///
- /// The prefix contains all of the parts of the nested name
- /// specifier that precede this current specifier. For example, for a
- /// nested name specifier that represents "foo::bar::", the current
- /// specifier will contain "bar::" and the prefix will contain
- /// "foo::".
- NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
-
- /// Determine what kind of nested name specifier is stored.
- SpecifierKind getKind() const;
-
- /// Retrieve the identifier stored in this nested name
- /// specifier.
- IdentifierInfo *getAsIdentifier() const {
- if (Prefix.getInt() == StoredIdentifier)
- return (IdentifierInfo *)Specifier;
-
- return nullptr;
+auto NestedNameSpecifier::getKind() const -> Kind {
----------------
Sirraide wrote:
Is there a reason all of these functions are defined in a header rather than a .cpp file? Does inlining them actually have that big of a performance impact?
https://github.com/llvm/llvm-project/pull/147835
More information about the cfe-commits
mailing list