summaryrefslogtreecommitdiff
path: root/include/clang/AST/DeclarationName.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/DeclarationName.h')
-rw-r--r--include/clang/AST/DeclarationName.h621
1 files changed, 428 insertions, 193 deletions
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 856f3ab5720e3..62afae23ec79a 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -14,11 +14,14 @@
#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
#define LLVM_CLANG_AST_DECLARATIONNAME_H
+#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
@@ -30,67 +33,195 @@ namespace clang {
class ASTContext;
template <typename> class CanQual;
-class CXXDeductionGuideNameExtra;
-class CXXLiteralOperatorIdName;
-class CXXOperatorIdName;
-class CXXSpecialName;
-class DeclarationNameExtra;
-class IdentifierInfo;
+class DeclarationName;
+class DeclarationNameTable;
class MultiKeywordSelector;
-enum OverloadedOperatorKind : int;
struct PrintingPolicy;
-class QualType;
class TemplateDecl;
-class Type;
class TypeSourceInfo;
class UsingDirectiveDecl;
using CanQualType = CanQual<Type>;
-/// DeclarationName - The name of a declaration. In the common case,
-/// this just stores an IdentifierInfo pointer to a normal
-/// name. However, it also provides encodings for Objective-C
-/// selectors (optimizing zero- and one-argument selectors, which make
-/// up 78% percent of all selectors in Cocoa.h) and special C++ names
-/// for constructors, destructors, and conversion functions.
-class DeclarationName {
+namespace detail {
+
+/// CXXSpecialNameExtra records the type associated with one of the "special"
+/// kinds of declaration names in C++, e.g., constructors, destructors, and
+/// conversion functions. Note that CXXSpecialName is used for C++ constructor,
+/// destructor and conversion functions, but the actual kind is not stored in
+/// CXXSpecialName. Instead we use three different FoldingSet<CXXSpecialName>
+/// in DeclarationNameTable.
+class alignas(IdentifierInfoAlignment) CXXSpecialNameExtra
+ : public llvm::FoldingSetNode {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
+
+ /// The type associated with this declaration name.
+ QualType Type;
+
+ /// Extra information associated with this declaration name that
+ /// can be used by the front end. All bits are really needed
+ /// so it is not possible to stash something in the low order bits.
+ void *FETokenInfo;
+
+ CXXSpecialNameExtra(QualType QT) : Type(QT), FETokenInfo(nullptr) {}
+
public:
- /// NameKind - The kind of name this object contains.
- enum NameKind {
- Identifier,
- ObjCZeroArgSelector,
- ObjCOneArgSelector,
- ObjCMultiArgSelector,
- CXXConstructorName,
- CXXDestructorName,
- CXXConversionFunctionName,
- CXXDeductionGuideName,
- CXXOperatorName,
- CXXLiteralOperatorName,
- CXXUsingDirective
- };
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ ID.AddPointer(Type.getAsOpaquePtr());
+ }
+};
- static const unsigned NumNameKinds = CXXUsingDirective + 1;
+/// Contains extra information for the name of a C++ deduction guide.
+class alignas(IdentifierInfoAlignment) CXXDeductionGuideNameExtra
+ : public detail::DeclarationNameExtra,
+ public llvm::FoldingSetNode {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
-private:
+ /// The template named by the deduction guide.
+ TemplateDecl *Template;
+
+ /// Extra information associated with this operator name that
+ /// can be used by the front end. All bits are really needed
+ /// so it is not possible to stash something in the low order bits.
+ void *FETokenInfo;
+
+ CXXDeductionGuideNameExtra(TemplateDecl *TD)
+ : DeclarationNameExtra(CXXDeductionGuideName), Template(TD),
+ FETokenInfo(nullptr) {}
+
+public:
+ void Profile(llvm::FoldingSetNodeID &ID) { ID.AddPointer(Template); }
+};
+
+/// Contains extra information for the name of an overloaded operator
+/// in C++, such as "operator+. This do not includes literal or conversion
+/// operators. For literal operators see CXXLiteralOperatorIdName and for
+/// conversion operators see CXXSpecialNameExtra.
+class alignas(IdentifierInfoAlignment) CXXOperatorIdName {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
+
+ /// The kind of this operator.
+ OverloadedOperatorKind Kind = OO_None;
+
+ /// Extra information associated with this operator name that
+ /// can be used by the front end. All bits are really needed
+ /// so it is not possible to stash something in the low order bits.
+ void *FETokenInfo = nullptr;
+};
+
+/// Contains the actual identifier that makes up the
+/// name of a C++ literal operator.
+class alignas(IdentifierInfoAlignment) CXXLiteralOperatorIdName
+ : public detail::DeclarationNameExtra,
+ public llvm::FoldingSetNode {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
+
+ IdentifierInfo *ID;
+
+ /// Extra information associated with this operator name that
+ /// can be used by the front end. All bits are really needed
+ /// so it is not possible to stash something in the low order bits.
+ void *FETokenInfo;
+
+ CXXLiteralOperatorIdName(IdentifierInfo *II)
+ : DeclarationNameExtra(CXXLiteralOperatorName), ID(II),
+ FETokenInfo(nullptr) {}
+
+public:
+ void Profile(llvm::FoldingSetNodeID &FSID) { FSID.AddPointer(ID); }
+};
+
+} // namespace detail
+
+/// The name of a declaration. In the common case, this just stores
+/// an IdentifierInfo pointer to a normal name. However, it also provides
+/// encodings for Objective-C selectors (optimizing zero- and one-argument
+/// selectors, which make up 78% percent of all selectors in Cocoa.h),
+/// special C++ names for constructors, destructors, and conversion functions,
+/// and C++ overloaded operators.
+class DeclarationName {
friend class DeclarationNameTable;
friend class NamedDecl;
- /// StoredNameKind - The kind of name that is actually stored in the
+ /// StoredNameKind represent the kind of name that is actually stored in the
/// upper bits of the Ptr field. This is only used internally.
///
- /// Note: The entries here are synchronized with the entries in Selector,
- /// for efficient translation between the two.
+ /// NameKind, StoredNameKind, and DeclarationNameExtra::ExtraKind
+ /// must satisfy the following properties. These properties enable
+ /// efficient conversion between the various kinds.
+ ///
+ /// * The first seven enumerators of StoredNameKind must have the same
+ /// numerical value as the first seven enumerators of NameKind.
+ /// This enable efficient conversion between the two enumerations
+ /// in the usual case.
+ ///
+ /// * The enumerations values of DeclarationNameExtra::ExtraKind must start
+ /// at zero, and correspond to the numerical value of the first non-inline
+ /// enumeration values of NameKind minus an offset. This makes conversion
+ /// between DeclarationNameExtra::ExtraKind and NameKind possible with
+ /// a single addition/substraction.
+ ///
+ /// * The enumeration values of Selector::IdentifierInfoFlag must correspond
+ /// to the relevant enumeration values of StoredNameKind.
+ /// More specifically:
+ /// * ZeroArg == StoredObjCZeroArgSelector,
+ /// * OneArg == StoredObjCOneArgSelector,
+ /// * MultiArg == StoredDeclarationNameExtra
+ ///
+ /// * PtrMask must mask the low 3 bits of Ptr.
enum StoredNameKind {
StoredIdentifier = 0,
- StoredObjCZeroArgSelector = 0x01,
- StoredObjCOneArgSelector = 0x02,
- StoredDeclarationNameExtra = 0x03,
- PtrMask = 0x03
+ StoredObjCZeroArgSelector = Selector::ZeroArg,
+ StoredObjCOneArgSelector = Selector::OneArg,
+ StoredCXXConstructorName = 3,
+ StoredCXXDestructorName = 4,
+ StoredCXXConversionFunctionName = 5,
+ StoredCXXOperatorName = 6,
+ StoredDeclarationNameExtra = Selector::MultiArg,
+ PtrMask = 7,
+ UncommonNameKindOffset = 8
+ };
+
+ static_assert(alignof(IdentifierInfo) >= 8 &&
+ alignof(detail::DeclarationNameExtra) >= 8 &&
+ alignof(detail::CXXSpecialNameExtra) >= 8 &&
+ alignof(detail::CXXOperatorIdName) >= 8 &&
+ alignof(detail::CXXDeductionGuideNameExtra) >= 8 &&
+ alignof(detail::CXXLiteralOperatorIdName) >= 8,
+ "The various classes that DeclarationName::Ptr can point to"
+ " must be at least aligned to 8 bytes!");
+
+public:
+ /// The kind of the name stored in this DeclarationName.
+ /// The first 7 enumeration values are stored inline and correspond
+ /// to frequently used kinds. The rest is stored in DeclarationNameExtra
+ /// and correspond to infrequently used kinds.
+ enum NameKind {
+ Identifier = StoredIdentifier,
+ ObjCZeroArgSelector = StoredObjCZeroArgSelector,
+ ObjCOneArgSelector = StoredObjCOneArgSelector,
+ CXXConstructorName = StoredCXXConstructorName,
+ CXXDestructorName = StoredCXXDestructorName,
+ CXXConversionFunctionName = StoredCXXConversionFunctionName,
+ CXXOperatorName = StoredCXXOperatorName,
+ CXXDeductionGuideName = UncommonNameKindOffset +
+ detail::DeclarationNameExtra::CXXDeductionGuideName,
+ CXXLiteralOperatorName =
+ UncommonNameKindOffset +
+ detail::DeclarationNameExtra::CXXLiteralOperatorName,
+ CXXUsingDirective = UncommonNameKindOffset +
+ detail::DeclarationNameExtra::CXXUsingDirective,
+ ObjCMultiArgSelector = UncommonNameKindOffset +
+ detail::DeclarationNameExtra::ObjCMultiArgSelector
};
- /// Ptr - The lowest two bits are used to express what kind of name
- /// we're actually storing, using the values of NameKind. Depending
+private:
+ /// The lowest three bits of Ptr are used to express what kind of name
+ /// we're actually storing, using the values of StoredNameKind. Depending
/// on the kind of name this is, the upper bits of Ptr may have one
/// of several different meanings:
///
@@ -105,99 +236,141 @@ private:
/// with one argument, and Ptr is an IdentifierInfo pointer
/// pointing to the selector name.
///
+ /// StoredCXXConstructorName - The name of a C++ constructor,
+ /// Ptr points to a CXXSpecialNameExtra.
+ ///
+ /// StoredCXXDestructorName - The name of a C++ destructor,
+ /// Ptr points to a CXXSpecialNameExtra.
+ ///
+ /// StoredCXXConversionFunctionName - The name of a C++ conversion function,
+ /// Ptr points to a CXXSpecialNameExtra.
+ ///
+ /// StoredCXXOperatorName - The name of an overloaded C++ operator,
+ /// Ptr points to a CXXOperatorIdName.
+ ///
/// StoredDeclarationNameExtra - Ptr is actually a pointer to a
/// DeclarationNameExtra structure, whose first value will tell us
- /// whether this is an Objective-C selector, C++ operator-id name,
- /// or special C++ name.
+ /// whether this is an Objective-C selector, C++ deduction guide,
+ /// C++ literal operator, or C++ using directive.
uintptr_t Ptr = 0;
- // Construct a declaration name from the name of a C++ constructor,
- // destructor, or conversion function.
- DeclarationName(DeclarationNameExtra *Name)
- : Ptr(reinterpret_cast<uintptr_t>(Name)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra");
- Ptr |= StoredDeclarationNameExtra;
+ StoredNameKind getStoredNameKind() const {
+ return static_cast<StoredNameKind>(Ptr & PtrMask);
}
- /// Construct a declaration name from a raw pointer.
- DeclarationName(uintptr_t Ptr) : Ptr(Ptr) {}
+ void *getPtr() const { return reinterpret_cast<void *>(Ptr & ~PtrMask); }
- /// getStoredNameKind - Return the kind of object that is stored in
- /// Ptr.
- StoredNameKind getStoredNameKind() const {
- return static_cast<StoredNameKind>(Ptr & PtrMask);
+ void setPtrAndKind(const void *P, StoredNameKind Kind) {
+ uintptr_t PAsInteger = reinterpret_cast<uintptr_t>(P);
+ assert((Kind & ~PtrMask) == 0 &&
+ "Invalid StoredNameKind in setPtrAndKind!");
+ assert((PAsInteger & PtrMask) == 0 &&
+ "Improperly aligned pointer in setPtrAndKind!");
+ Ptr = PAsInteger | Kind;
}
- /// getExtra - Get the "extra" information associated with this
- /// multi-argument selector or C++ special name.
- DeclarationNameExtra *getExtra() const {
- assert(getStoredNameKind() == StoredDeclarationNameExtra &&
- "Declaration name does not store an Extra structure");
- return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
+ /// Construct a declaration name from a DeclarationNameExtra.
+ DeclarationName(detail::DeclarationNameExtra *Name) {
+ setPtrAndKind(Name, StoredDeclarationNameExtra);
}
- /// getAsCXXSpecialName - If the stored pointer is actually a
- /// CXXSpecialName, returns a pointer to it. Otherwise, returns
- /// a NULL pointer.
- CXXSpecialName *getAsCXXSpecialName() const {
- NameKind Kind = getNameKind();
- if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
- return reinterpret_cast<CXXSpecialName *>(getExtra());
- return nullptr;
+ /// Construct a declaration name from a CXXSpecialNameExtra.
+ DeclarationName(detail::CXXSpecialNameExtra *Name,
+ StoredNameKind StoredKind) {
+ assert((StoredKind == StoredCXXConstructorName ||
+ StoredKind == StoredCXXDestructorName ||
+ StoredKind == StoredCXXConversionFunctionName) &&
+ "Invalid StoredNameKind when constructing a DeclarationName"
+ " from a CXXSpecialNameExtra!");
+ setPtrAndKind(Name, StoredKind);
}
- /// If the stored pointer is actually a CXXDeductionGuideNameExtra, returns a
- /// pointer to it. Otherwise, returns a NULL pointer.
- CXXDeductionGuideNameExtra *getAsCXXDeductionGuideNameExtra() const {
- if (getNameKind() == CXXDeductionGuideName)
- return reinterpret_cast<CXXDeductionGuideNameExtra *>(getExtra());
- return nullptr;
+ /// Construct a DeclarationName from a CXXOperatorIdName.
+ DeclarationName(detail::CXXOperatorIdName *Name) {
+ setPtrAndKind(Name, StoredCXXOperatorName);
}
- /// getAsCXXOperatorIdName
- CXXOperatorIdName *getAsCXXOperatorIdName() const {
- if (getNameKind() == CXXOperatorName)
- return reinterpret_cast<CXXOperatorIdName *>(getExtra());
- return nullptr;
+ /// Assert that the stored pointer points to an IdentifierInfo and return it.
+ IdentifierInfo *castAsIdentifierInfo() const {
+ assert((getStoredNameKind() == StoredIdentifier) &&
+ "DeclarationName does not store an IdentifierInfo!");
+ return static_cast<IdentifierInfo *>(getPtr());
}
- CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
- if (getNameKind() == CXXLiteralOperatorName)
- return reinterpret_cast<CXXLiteralOperatorIdName *>(getExtra());
- return nullptr;
+ /// Assert that the stored pointer points to a DeclarationNameExtra
+ /// and return it.
+ detail::DeclarationNameExtra *castAsExtra() const {
+ assert((getStoredNameKind() == StoredDeclarationNameExtra) &&
+ "DeclarationName does not store an Extra structure!");
+ return static_cast<detail::DeclarationNameExtra *>(getPtr());
}
- /// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
- /// for this name as a void pointer if it's not an identifier.
- void *getFETokenInfoAsVoidSlow() const;
+ /// Assert that the stored pointer points to a CXXSpecialNameExtra
+ /// and return it.
+ detail::CXXSpecialNameExtra *castAsCXXSpecialNameExtra() const {
+ assert((getStoredNameKind() == StoredCXXConstructorName ||
+ getStoredNameKind() == StoredCXXDestructorName ||
+ getStoredNameKind() == StoredCXXConversionFunctionName) &&
+ "DeclarationName does not store a CXXSpecialNameExtra!");
+ return static_cast<detail::CXXSpecialNameExtra *>(getPtr());
+ }
+
+ /// Assert that the stored pointer points to a CXXOperatorIdName
+ /// and return it.
+ detail::CXXOperatorIdName *castAsCXXOperatorIdName() const {
+ assert((getStoredNameKind() == StoredCXXOperatorName) &&
+ "DeclarationName does not store a CXXOperatorIdName!");
+ return static_cast<detail::CXXOperatorIdName *>(getPtr());
+ }
+
+ /// Assert that the stored pointer points to a CXXDeductionGuideNameExtra
+ /// and return it.
+ detail::CXXDeductionGuideNameExtra *castAsCXXDeductionGuideNameExtra() const {
+ assert(getNameKind() == CXXDeductionGuideName &&
+ "DeclarationName does not store a CXXDeductionGuideNameExtra!");
+ return static_cast<detail::CXXDeductionGuideNameExtra *>(getPtr());
+ }
+
+ /// Assert that the stored pointer points to a CXXLiteralOperatorIdName
+ /// and return it.
+ detail::CXXLiteralOperatorIdName *castAsCXXLiteralOperatorIdName() const {
+ assert(getNameKind() == CXXLiteralOperatorName &&
+ "DeclarationName does not store a CXXLiteralOperatorIdName!");
+ return static_cast<detail::CXXLiteralOperatorIdName *>(getPtr());
+ }
+
+ /// Get and set the FETokenInfo in the less common cases where the
+ /// declaration name do not point to an identifier.
+ void *getFETokenInfoSlow() const;
+ void setFETokenInfoSlow(void *T);
public:
- /// DeclarationName - Used to create an empty selector.
- DeclarationName() = default;
+ /// Construct an empty declaration name.
+ DeclarationName() { setPtrAndKind(nullptr, StoredIdentifier); }
- // Construct a declaration name from an IdentifierInfo *.
- DeclarationName(const IdentifierInfo *II)
- : Ptr(reinterpret_cast<uintptr_t>(II)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
+ /// Construct a declaration name from an IdentifierInfo *.
+ DeclarationName(const IdentifierInfo *II) {
+ setPtrAndKind(II, StoredIdentifier);
}
- // Construct a declaration name from an Objective-C selector.
+ /// Construct a declaration name from an Objective-C selector.
DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
- /// getUsingDirectiveName - Return name for all using-directives.
- static DeclarationName getUsingDirectiveName();
+ /// Returns the name for all C++ using-directives.
+ static DeclarationName getUsingDirectiveName() {
+ // Single instance of DeclarationNameExtra for using-directive
+ static detail::DeclarationNameExtra UDirExtra(
+ detail::DeclarationNameExtra::CXXUsingDirective);
+ return DeclarationName(&UDirExtra);
+ }
- // operator bool() - Evaluates true when this declaration name is
- // non-empty.
+ /// Evaluates true when this declaration name is non-empty.
explicit operator bool() const {
- return ((Ptr & PtrMask) != 0) ||
- (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
+ return getPtr() || (getStoredNameKind() != StoredIdentifier);
}
/// Evaluates true when this declaration name is empty.
- bool isEmpty() const {
- return !*this;
- }
+ bool isEmpty() const { return !*this; }
/// Predicate functions for querying what type of name this is.
bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
@@ -208,8 +381,19 @@ public:
return getStoredNameKind() == StoredObjCOneArgSelector;
}
- /// getNameKind - Determine what kind of name this is.
- NameKind getNameKind() const;
+ /// Determine what kind of name this is.
+ NameKind getNameKind() const {
+ // We rely on the fact that the first 7 NameKind and StoredNameKind
+ // have the same numerical value. This makes the usual case efficient.
+ StoredNameKind StoredKind = getStoredNameKind();
+ if (StoredKind != StoredDeclarationNameExtra)
+ return static_cast<NameKind>(StoredKind);
+ // We have to consult DeclarationNameExtra. We rely on the fact that the
+ // enumeration values of ExtraKind correspond to the enumeration values of
+ // NameKind minus an offset of UncommonNameKindOffset.
+ unsigned ExtraKind = castAsExtra()->getKind();
+ return static_cast<NameKind>(UncommonNameKindOffset + ExtraKind);
+ }
/// Determines whether the name itself is dependent, e.g., because it
/// involves a C++ type that is itself dependent.
@@ -219,95 +403,128 @@ public:
/// callee in a call expression with dependent arguments.
bool isDependentName() const;
- /// getNameAsString - Retrieve the human-readable string for this name.
+ /// Retrieve the human-readable string for this name.
std::string getAsString() const;
- /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
- /// this declaration name, or NULL if this declaration name isn't a
- /// simple identifier.
+ /// Retrieve the IdentifierInfo * stored in this declaration name,
+ /// or null if this declaration name isn't a simple identifier.
IdentifierInfo *getAsIdentifierInfo() const {
if (isIdentifier())
- return reinterpret_cast<IdentifierInfo *>(Ptr);
+ return castAsIdentifierInfo();
return nullptr;
}
- /// getAsOpaqueInteger - Get the representation of this declaration
- /// name as an opaque integer.
+ /// Get the representation of this declaration name as an opaque integer.
uintptr_t getAsOpaqueInteger() const { return Ptr; }
- /// getAsOpaquePtr - Get the representation of this declaration name as
- /// an opaque pointer.
- void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
+ /// Get the representation of this declaration name as an opaque pointer.
+ void *getAsOpaquePtr() const { return reinterpret_cast<void *>(Ptr); }
+ /// Get a declaration name from an opaque pointer returned by getAsOpaquePtr.
static DeclarationName getFromOpaquePtr(void *P) {
DeclarationName N;
- N.Ptr = reinterpret_cast<uintptr_t> (P);
+ N.Ptr = reinterpret_cast<uintptr_t>(P);
return N;
}
+ /// Get a declaration name from an opaque integer
+ /// returned by getAsOpaqueInteger.
static DeclarationName getFromOpaqueInteger(uintptr_t P) {
DeclarationName N;
N.Ptr = P;
return N;
}
- /// getCXXNameType - If this name is one of the C++ names (of a
- /// constructor, destructor, or conversion function), return the
- /// type associated with that name.
- QualType getCXXNameType() const;
+ /// If this name is one of the C++ names (of a constructor, destructor,
+ /// or conversion function), return the type associated with that name.
+ QualType getCXXNameType() const {
+ if (getStoredNameKind() == StoredCXXConstructorName ||
+ getStoredNameKind() == StoredCXXDestructorName ||
+ getStoredNameKind() == StoredCXXConversionFunctionName) {
+ assert(getPtr() && "getCXXNameType on a null DeclarationName!");
+ return castAsCXXSpecialNameExtra()->Type;
+ }
+ return QualType();
+ }
/// If this name is the name of a C++ deduction guide, return the
/// template associated with that name.
- TemplateDecl *getCXXDeductionGuideTemplate() const;
+ TemplateDecl *getCXXDeductionGuideTemplate() const {
+ if (getNameKind() == CXXDeductionGuideName) {
+ assert(getPtr() &&
+ "getCXXDeductionGuideTemplate on a null DeclarationName!");
+ return castAsCXXDeductionGuideNameExtra()->Template;
+ }
+ return nullptr;
+ }
- /// getCXXOverloadedOperator - If this name is the name of an
- /// overloadable operator in C++ (e.g., @c operator+), retrieve the
- /// kind of overloaded operator.
- OverloadedOperatorKind getCXXOverloadedOperator() const;
+ /// If this name is the name of an overloadable operator in C++
+ /// (e.g., @c operator+), retrieve the kind of overloaded operator.
+ OverloadedOperatorKind getCXXOverloadedOperator() const {
+ if (getStoredNameKind() == StoredCXXOperatorName) {
+ assert(getPtr() && "getCXXOverloadedOperator on a null DeclarationName!");
+ return castAsCXXOperatorIdName()->Kind;
+ }
+ return OO_None;
+ }
- /// getCXXLiteralIdentifier - If this name is the name of a literal
- /// operator, retrieve the identifier associated with it.
- IdentifierInfo *getCXXLiteralIdentifier() const;
+ /// If this name is the name of a literal operator,
+ /// retrieve the identifier associated with it.
+ IdentifierInfo *getCXXLiteralIdentifier() const {
+ if (getNameKind() == CXXLiteralOperatorName) {
+ assert(getPtr() && "getCXXLiteralIdentifier on a null DeclarationName!");
+ return castAsCXXLiteralOperatorIdName()->ID;
+ }
+ return nullptr;
+ }
- /// getObjCSelector - Get the Objective-C selector stored in this
- /// declaration name.
+ /// Get the Objective-C selector stored in this declaration name.
Selector getObjCSelector() const {
assert((getNameKind() == ObjCZeroArgSelector ||
getNameKind() == ObjCOneArgSelector ||
- getNameKind() == ObjCMultiArgSelector ||
- Ptr == 0) && "Not a selector!");
+ getNameKind() == ObjCMultiArgSelector || !getPtr()) &&
+ "Not a selector!");
return Selector(Ptr);
}
- /// getFETokenInfo/setFETokenInfo - The language front-end is
- /// allowed to associate arbitrary metadata with some kinds of
- /// declaration names, including normal identifiers and C++
- /// constructors, destructors, and conversion functions.
- template<typename T>
- T *getFETokenInfo() const {
- if (const IdentifierInfo *Info = getAsIdentifierInfo())
- return Info->getFETokenInfo<T>();
- return static_cast<T*>(getFETokenInfoAsVoidSlow());
+ /// Get and set FETokenInfo. The language front-end is allowed to associate
+ /// arbitrary metadata with some kinds of declaration names, including normal
+ /// identifiers and C++ constructors, destructors, and conversion functions.
+ void *getFETokenInfo() const {
+ assert(getPtr() && "getFETokenInfo on an empty DeclarationName!");
+ if (getStoredNameKind() == StoredIdentifier)
+ return castAsIdentifierInfo()->getFETokenInfo();
+ return getFETokenInfoSlow();
}
- void setFETokenInfo(void *T);
+ void setFETokenInfo(void *T) {
+ assert(getPtr() && "setFETokenInfo on an empty DeclarationName!");
+ if (getStoredNameKind() == StoredIdentifier)
+ castAsIdentifierInfo()->setFETokenInfo(T);
+ else
+ setFETokenInfoSlow(T);
+ }
- /// operator== - Determine whether the specified names are identical..
+ /// Determine whether the specified names are identical.
friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
return LHS.Ptr == RHS.Ptr;
}
- /// operator!= - Determine whether the specified names are different.
+ /// Determine whether the specified names are different.
friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
return LHS.Ptr != RHS.Ptr;
}
static DeclarationName getEmptyMarker() {
- return DeclarationName(uintptr_t(-1));
+ DeclarationName Name;
+ Name.Ptr = uintptr_t(-1);
+ return Name;
}
static DeclarationName getTombstoneMarker() {
- return DeclarationName(uintptr_t(-2));
+ DeclarationName Name;
+ Name.Ptr = uintptr_t(-2);
+ return Name;
}
static int compare(DeclarationName LHS, DeclarationName RHS);
@@ -343,67 +560,88 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
return DeclarationName::compare(LHS, RHS) >= 0;
}
-/// DeclarationNameTable - Used to store and retrieve DeclarationName
+/// DeclarationNameTable is used to store and retrieve DeclarationName
/// instances for the various kinds of declaration names, e.g., normal
/// identifiers, C++ constructor names, etc. This class contains
/// uniqued versions of each of the C++ special names, which can be
-/// retrieved using its member functions (e.g.,
-/// getCXXConstructorName).
+/// retrieved using its member functions (e.g., getCXXConstructorName).
class DeclarationNameTable {
+ /// Used to allocate elements in the FoldingSets below.
const ASTContext &Ctx;
- // Actually a FoldingSet<CXXSpecialName> *
- void *CXXSpecialNamesImpl;
-
- // Operator names
- CXXOperatorIdName *CXXOperatorNames;
-
- // Actually a CXXOperatorIdName*
- void *CXXLiteralOperatorNames;
-
- // FoldingSet<CXXDeductionGuideNameExtra> *
- void *CXXDeductionGuideNames;
+ /// Manage the uniqued CXXSpecialNameExtra representing C++ constructors.
+ /// getCXXConstructorName and getCXXSpecialName can be used to obtain
+ /// a DeclarationName from the corresponding type of the constructor.
+ llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXConstructorNames;
+
+ /// Manage the uniqued CXXSpecialNameExtra representing C++ destructors.
+ /// getCXXDestructorName and getCXXSpecialName can be used to obtain
+ /// a DeclarationName from the corresponding type of the destructor.
+ llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXDestructorNames;
+
+ /// Manage the uniqued CXXSpecialNameExtra representing C++ conversion
+ /// functions. getCXXConversionFunctionName and getCXXSpecialName can be
+ /// used to obtain a DeclarationName from the corresponding type of the
+ /// conversion function.
+ llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXConversionFunctionNames;
+
+ /// Manage the uniqued CXXOperatorIdName, which contain extra information
+ /// for the name of overloaded C++ operators. getCXXOperatorName
+ /// can be used to obtain a DeclarationName from the operator kind.
+ detail::CXXOperatorIdName CXXOperatorNames[NUM_OVERLOADED_OPERATORS];
+
+ /// Manage the uniqued CXXLiteralOperatorIdName, which contain extra
+ /// information for the name of C++ literal operators.
+ /// getCXXLiteralOperatorName can be used to obtain a DeclarationName
+ /// from the corresponding IdentifierInfo.
+ llvm::FoldingSet<detail::CXXLiteralOperatorIdName> CXXLiteralOperatorNames;
+
+ /// Manage the uniqued CXXDeductionGuideNameExtra, which contain
+ /// extra information for the name of a C++ deduction guide.
+ /// getCXXDeductionGuideName can be used to obtain a DeclarationName
+ /// from the corresponding template declaration.
+ llvm::FoldingSet<detail::CXXDeductionGuideNameExtra> CXXDeductionGuideNames;
public:
DeclarationNameTable(const ASTContext &C);
DeclarationNameTable(const DeclarationNameTable &) = delete;
DeclarationNameTable &operator=(const DeclarationNameTable &) = delete;
+ DeclarationNameTable(DeclarationNameTable &&) = delete;
+ DeclarationNameTable &operator=(DeclarationNameTable &&) = delete;
+ ~DeclarationNameTable() = default;
- ~DeclarationNameTable();
-
- /// getIdentifier - Create a declaration name that is a simple
- /// identifier.
+ /// Create a declaration name that is a simple identifier.
DeclarationName getIdentifier(const IdentifierInfo *ID) {
return DeclarationName(ID);
}
- /// getCXXConstructorName - Returns the name of a C++ constructor
- /// for the given Type.
+ /// Returns the name of a C++ constructor for the given Type.
DeclarationName getCXXConstructorName(CanQualType Ty);
- /// getCXXDestructorName - Returns the name of a C++ destructor
- /// for the given Type.
+ /// Returns the name of a C++ destructor for the given Type.
DeclarationName getCXXDestructorName(CanQualType Ty);
/// Returns the name of a C++ deduction guide for the given template.
DeclarationName getCXXDeductionGuideName(TemplateDecl *TD);
- /// getCXXConversionFunctionName - Returns the name of a C++
- /// conversion function for the given Type.
+ /// Returns the name of a C++ conversion function for the given Type.
DeclarationName getCXXConversionFunctionName(CanQualType Ty);
- /// getCXXSpecialName - Returns a declaration name for special kind
- /// of C++ name, e.g., for a constructor, destructor, or conversion
- /// function.
+ /// Returns a declaration name for special kind of C++ name,
+ /// e.g., for a constructor, destructor, or conversion function.
+ /// Kind must be one of:
+ /// * DeclarationName::CXXConstructorName,
+ /// * DeclarationName::CXXDestructorName or
+ /// * DeclarationName::CXXConversionFunctionName
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
CanQualType Ty);
- /// getCXXOperatorName - Get the name of the overloadable C++
- /// operator corresponding to Op.
- DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
+ /// Get the name of the overloadable C++ operator corresponding to Op.
+ DeclarationName getCXXOperatorName(OverloadedOperatorKind Op) {
+ return DeclarationName(&CXXOperatorNames[Op]);
+ }
- /// getCXXLiteralOperatorName - Get the name of the literal operator function
- /// with II as the identifier.
+ /// Get the name of the literal operator function with II as the identifier.
DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
};
@@ -491,9 +729,10 @@ public:
/// getNamedTypeInfo - Returns the source type info associated to
/// the name. Assumes it is a constructor, destructor or conversion.
TypeSourceInfo *getNamedTypeInfo() const {
- assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXDestructorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+ if (Name.getNameKind() != DeclarationName::CXXConstructorName &&
+ Name.getNameKind() != DeclarationName::CXXDestructorName &&
+ Name.getNameKind() != DeclarationName::CXXConversionFunctionName)
+ return nullptr;
return LocInfo.NamedType.TInfo;
}
@@ -509,7 +748,8 @@ public:
/// getCXXOperatorNameRange - Gets the range of the operator name
/// (without the operator keyword). Assumes it is a (non-literal) operator.
SourceRange getCXXOperatorNameRange() const {
- assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+ if (Name.getNameKind() != DeclarationName::CXXOperatorName)
+ return SourceRange();
return SourceRange(
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
@@ -528,7 +768,8 @@ public:
/// operator name (not the operator keyword).
/// Assumes it is a literal operator.
SourceLocation getCXXLiteralOperatorNameLoc() const {
- assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+ if (Name.getNameKind() != DeclarationName::CXXLiteralOperatorName)
+ return SourceLocation();
return SourceLocation::
getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
}
@@ -557,22 +798,16 @@ public:
/// getBeginLoc - Retrieve the location of the first token.
SourceLocation getBeginLoc() const { return NameLoc; }
- /// getEndLoc - Retrieve the location of the last token.
- SourceLocation getEndLoc() const { return getLocEnd(); }
-
/// getSourceRange - The range of the declaration name.
SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
+ return SourceRange(getBeginLoc(), getEndLoc());
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBeginLoc();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
SourceLocation EndLoc = getEndLocPrivate();
- return EndLoc.isValid() ? EndLoc : getLocStart();
+ return EndLoc.isValid() ? EndLoc : getBeginLoc();
}
+
private:
SourceLocation getEndLocPrivate() const;
};