summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/clang/AST/DeclarationName.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983e/include/clang/AST/DeclarationName.h')
-rw-r--r--clang-r353983e/include/clang/AST/DeclarationName.h866
1 files changed, 866 insertions, 0 deletions
diff --git a/clang-r353983e/include/clang/AST/DeclarationName.h b/clang-r353983e/include/clang/AST/DeclarationName.h
new file mode 100644
index 00000000..e5d34399
--- /dev/null
+++ b/clang-r353983e/include/clang/AST/DeclarationName.h
@@ -0,0 +1,866 @@
+//===- DeclarationName.h - Representation of declaration names --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the DeclarationName and DeclarationNameTable classes.
+//
+//===----------------------------------------------------------------------===//
+
+#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>
+#include <cstdint>
+#include <cstring>
+#include <string>
+
+namespace clang {
+
+class ASTContext;
+template <typename> class CanQual;
+class DeclarationName;
+class DeclarationNameTable;
+class MultiKeywordSelector;
+struct PrintingPolicy;
+class TemplateDecl;
+class TypeSourceInfo;
+class UsingDirectiveDecl;
+
+using CanQualType = CanQual<Type>;
+
+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:
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ ID.AddPointer(Type.getAsOpaquePtr());
+ }
+};
+
+/// 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;
+
+ /// 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 represent the kind of name that is actually stored in the
+ /// upper bits of the Ptr field. This is only used internally.
+ ///
+ /// 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 = 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
+ };
+
+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:
+ ///
+ /// StoredIdentifier - The name is a normal identifier, and Ptr is
+ /// a normal IdentifierInfo pointer.
+ ///
+ /// StoredObjCZeroArgSelector - The name is an Objective-C
+ /// selector with zero arguments, and Ptr is an IdentifierInfo
+ /// pointer pointing to the selector name.
+ ///
+ /// StoredObjCOneArgSelector - The name is an Objective-C selector
+ /// 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++ deduction guide,
+ /// C++ literal operator, or C++ using directive.
+ uintptr_t Ptr = 0;
+
+ StoredNameKind getStoredNameKind() const {
+ return static_cast<StoredNameKind>(Ptr & PtrMask);
+ }
+
+ void *getPtr() const { return reinterpret_cast<void *>(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;
+ }
+
+ /// Construct a declaration name from a DeclarationNameExtra.
+ DeclarationName(detail::DeclarationNameExtra *Name) {
+ setPtrAndKind(Name, StoredDeclarationNameExtra);
+ }
+
+ /// 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);
+ }
+
+ /// Construct a DeclarationName from a CXXOperatorIdName.
+ DeclarationName(detail::CXXOperatorIdName *Name) {
+ setPtrAndKind(Name, StoredCXXOperatorName);
+ }
+
+ /// 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());
+ }
+
+ /// 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());
+ }
+
+ /// 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:
+ /// Construct an empty declaration name.
+ DeclarationName() { setPtrAndKind(nullptr, StoredIdentifier); }
+
+ /// Construct a declaration name from an IdentifierInfo *.
+ DeclarationName(const IdentifierInfo *II) {
+ setPtrAndKind(II, StoredIdentifier);
+ }
+
+ /// Construct a declaration name from an Objective-C selector.
+ DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
+
+ /// 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);
+ }
+
+ /// Evaluates true when this declaration name is non-empty.
+ explicit operator bool() const {
+ return getPtr() || (getStoredNameKind() != StoredIdentifier);
+ }
+
+ /// Evaluates true when this declaration name is empty.
+ bool isEmpty() const { return !*this; }
+
+ /// Predicate functions for querying what type of name this is.
+ bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
+ bool isObjCZeroArgSelector() const {
+ return getStoredNameKind() == StoredObjCZeroArgSelector;
+ }
+ bool isObjCOneArgSelector() const {
+ return getStoredNameKind() == StoredObjCOneArgSelector;
+ }
+
+ /// 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.
+ ///
+ /// Note that this does not capture all of the notions of "dependent name",
+ /// because an identifier can be a dependent name if it is used as the
+ /// callee in a call expression with dependent arguments.
+ bool isDependentName() const;
+
+ /// Retrieve the human-readable string for this name.
+ std::string getAsString() const;
+
+ /// 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 castAsIdentifierInfo();
+ return nullptr;
+ }
+
+ /// Get the representation of this declaration name as an opaque integer.
+ uintptr_t getAsOpaqueInteger() const { return 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);
+ 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;
+ }
+
+ /// 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 {
+ if (getNameKind() == CXXDeductionGuideName) {
+ assert(getPtr() &&
+ "getCXXDeductionGuideTemplate on a null DeclarationName!");
+ return castAsCXXDeductionGuideNameExtra()->Template;
+ }
+ return nullptr;
+ }
+
+ /// 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;
+ }
+
+ /// 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;
+ }
+
+ /// Get the Objective-C selector stored in this declaration name.
+ Selector getObjCSelector() const {
+ assert((getNameKind() == ObjCZeroArgSelector ||
+ getNameKind() == ObjCOneArgSelector ||
+ getNameKind() == ObjCMultiArgSelector || !getPtr()) &&
+ "Not a selector!");
+ return Selector(Ptr);
+ }
+
+ /// 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) {
+ assert(getPtr() && "setFETokenInfo on an empty DeclarationName!");
+ if (getStoredNameKind() == StoredIdentifier)
+ castAsIdentifierInfo()->setFETokenInfo(T);
+ else
+ setFETokenInfoSlow(T);
+ }
+
+ /// Determine whether the specified names are identical.
+ friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
+ return LHS.Ptr == RHS.Ptr;
+ }
+
+ /// Determine whether the specified names are different.
+ friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
+ return LHS.Ptr != RHS.Ptr;
+ }
+
+ static DeclarationName getEmptyMarker() {
+ DeclarationName Name;
+ Name.Ptr = uintptr_t(-1);
+ return Name;
+ }
+
+ static DeclarationName getTombstoneMarker() {
+ DeclarationName Name;
+ Name.Ptr = uintptr_t(-2);
+ return Name;
+ }
+
+ static int compare(DeclarationName LHS, DeclarationName RHS);
+
+ void print(raw_ostream &OS, const PrintingPolicy &Policy);
+
+ void dump() const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, DeclarationName N);
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
+ return DeclarationName::compare(LHS, RHS) < 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
+ return DeclarationName::compare(LHS, RHS) > 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
+ return DeclarationName::compare(LHS, RHS) <= 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
+ return DeclarationName::compare(LHS, RHS) >= 0;
+}
+
+/// 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).
+class DeclarationNameTable {
+ /// Used to allocate elements in the FoldingSets below.
+ const ASTContext &Ctx;
+
+ /// 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;
+
+ /// Create a declaration name that is a simple identifier.
+ DeclarationName getIdentifier(const IdentifierInfo *ID) {
+ return DeclarationName(ID);
+ }
+
+ /// Returns the name of a C++ constructor for the given Type.
+ DeclarationName getCXXConstructorName(CanQualType Ty);
+
+ /// 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);
+
+ /// Returns the name of a C++ conversion function for the given Type.
+ DeclarationName getCXXConversionFunctionName(CanQualType Ty);
+
+ /// 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);
+
+ /// Get the name of the overloadable C++ operator corresponding to Op.
+ DeclarationName getCXXOperatorName(OverloadedOperatorKind Op) {
+ return DeclarationName(&CXXOperatorNames[Op]);
+ }
+
+ /// Get the name of the literal operator function with II as the identifier.
+ DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
+};
+
+/// DeclarationNameLoc - Additional source/type location info
+/// for a declaration name. Needs a DeclarationName in order
+/// to be interpreted correctly.
+struct DeclarationNameLoc {
+ // The source location for identifier stored elsewhere.
+ // struct {} Identifier;
+
+ // Type info for constructors, destructors and conversion functions.
+ // Locations (if any) for the tilde (destructor) or operator keyword
+ // (conversion) are stored elsewhere.
+ struct NT {
+ TypeSourceInfo *TInfo;
+ };
+
+ // The location (if any) of the operator keyword is stored elsewhere.
+ struct CXXOpName {
+ unsigned BeginOpNameLoc;
+ unsigned EndOpNameLoc;
+ };
+
+ // The location (if any) of the operator keyword is stored elsewhere.
+ struct CXXLitOpName {
+ unsigned OpNameLoc;
+ };
+
+ // struct {} CXXUsingDirective;
+ // struct {} ObjCZeroArgSelector;
+ // struct {} ObjCOneArgSelector;
+ // struct {} ObjCMultiArgSelector;
+ union {
+ struct NT NamedType;
+ struct CXXOpName CXXOperatorName;
+ struct CXXLitOpName CXXLiteralOperatorName;
+ };
+
+ DeclarationNameLoc(DeclarationName Name);
+
+ // FIXME: this should go away once all DNLocs are properly initialized.
+ DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
+};
+
+/// DeclarationNameInfo - A collector data type for bundling together
+/// a DeclarationName and the correspnding source/type location info.
+struct DeclarationNameInfo {
+private:
+ /// Name - The declaration name, also encoding name kind.
+ DeclarationName Name;
+
+ /// Loc - The main source location for the declaration name.
+ SourceLocation NameLoc;
+
+ /// Info - Further source/type location info for special kinds of names.
+ DeclarationNameLoc LocInfo;
+
+public:
+ // FIXME: remove it.
+ DeclarationNameInfo() = default;
+
+ DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
+ : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
+
+ DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
+ DeclarationNameLoc LocInfo)
+ : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
+
+ /// getName - Returns the embedded declaration name.
+ DeclarationName getName() const { return Name; }
+
+ /// setName - Sets the embedded declaration name.
+ void setName(DeclarationName N) { Name = N; }
+
+ /// getLoc - Returns the main location of the declaration name.
+ SourceLocation getLoc() const { return NameLoc; }
+
+ /// setLoc - Sets the main location of the declaration name.
+ void setLoc(SourceLocation L) { NameLoc = L; }
+
+ const DeclarationNameLoc &getInfo() const { return LocInfo; }
+ DeclarationNameLoc &getInfo() { return LocInfo; }
+ void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
+
+ /// getNamedTypeInfo - Returns the source type info associated to
+ /// the name. Assumes it is a constructor, destructor or conversion.
+ TypeSourceInfo *getNamedTypeInfo() const {
+ if (Name.getNameKind() != DeclarationName::CXXConstructorName &&
+ Name.getNameKind() != DeclarationName::CXXDestructorName &&
+ Name.getNameKind() != DeclarationName::CXXConversionFunctionName)
+ return nullptr;
+ return LocInfo.NamedType.TInfo;
+ }
+
+ /// setNamedTypeInfo - Sets the source type info associated to
+ /// the name. Assumes it is a constructor, destructor or conversion.
+ void setNamedTypeInfo(TypeSourceInfo *TInfo) {
+ assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
+ Name.getNameKind() == DeclarationName::CXXDestructorName ||
+ Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+ LocInfo.NamedType.TInfo = TInfo;
+ }
+
+ /// getCXXOperatorNameRange - Gets the range of the operator name
+ /// (without the operator keyword). Assumes it is a (non-literal) operator.
+ SourceRange getCXXOperatorNameRange() const {
+ if (Name.getNameKind() != DeclarationName::CXXOperatorName)
+ return SourceRange();
+ return SourceRange(
+ SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
+ SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
+ );
+ }
+
+ /// setCXXOperatorNameRange - Sets the range of the operator name
+ /// (without the operator keyword). Assumes it is a C++ operator.
+ void setCXXOperatorNameRange(SourceRange R) {
+ assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+ LocInfo.CXXOperatorName.BeginOpNameLoc = R.getBegin().getRawEncoding();
+ LocInfo.CXXOperatorName.EndOpNameLoc = R.getEnd().getRawEncoding();
+ }
+
+ /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
+ /// operator name (not the operator keyword).
+ /// Assumes it is a literal operator.
+ SourceLocation getCXXLiteralOperatorNameLoc() const {
+ if (Name.getNameKind() != DeclarationName::CXXLiteralOperatorName)
+ return SourceLocation();
+ return SourceLocation::
+ getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
+ }
+
+ /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
+ /// operator name (not the operator keyword).
+ /// Assumes it is a literal operator.
+ void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
+ assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+ LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
+ }
+
+ /// Determine whether this name involves a template parameter.
+ bool isInstantiationDependent() const;
+
+ /// Determine whether this name contains an unexpanded
+ /// parameter pack.
+ bool containsUnexpandedParameterPack() const;
+
+ /// getAsString - Retrieve the human-readable string for this name.
+ std::string getAsString() const;
+
+ /// printName - Print the human-readable name to a stream.
+ void printName(raw_ostream &OS) const;
+
+ /// getBeginLoc - Retrieve the location of the first token.
+ SourceLocation getBeginLoc() const { return NameLoc; }
+
+ /// getSourceRange - The range of the declaration name.
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(getBeginLoc(), getEndLoc());
+ }
+
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ SourceLocation EndLoc = getEndLocPrivate();
+ return EndLoc.isValid() ? EndLoc : getBeginLoc();
+ }
+
+private:
+ SourceLocation getEndLocPrivate() const;
+};
+
+/// Insertion operator for diagnostics. This allows sending DeclarationName's
+/// into a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ DeclarationName N) {
+ DB.AddTaggedVal(N.getAsOpaqueInteger(),
+ DiagnosticsEngine::ak_declarationname);
+ return DB;
+}
+
+/// Insertion operator for partial diagnostics. This allows binding
+/// DeclarationName's into a partial diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ DeclarationName N) {
+ PD.AddTaggedVal(N.getAsOpaqueInteger(),
+ DiagnosticsEngine::ak_declarationname);
+ return PD;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ DeclarationNameInfo DNInfo) {
+ DNInfo.printName(OS);
+ return OS;
+}
+
+} // namespace clang
+
+namespace llvm {
+
+/// Define DenseMapInfo so that DeclarationNames can be used as keys
+/// in DenseMap and DenseSets.
+template<>
+struct DenseMapInfo<clang::DeclarationName> {
+ static inline clang::DeclarationName getEmptyKey() {
+ return clang::DeclarationName::getEmptyMarker();
+ }
+
+ static inline clang::DeclarationName getTombstoneKey() {
+ return clang::DeclarationName::getTombstoneMarker();
+ }
+
+ static unsigned getHashValue(clang::DeclarationName Name) {
+ return DenseMapInfo<void*>::getHashValue(Name.getAsOpaquePtr());
+ }
+
+ static inline bool
+ isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
+ return LHS == RHS;
+ }
+};
+
+} // namespace llvm
+
+#endif // LLVM_CLANG_AST_DECLARATIONNAME_H