123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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;
- struct PrintingPolicy;
- class TemplateDecl;
- class TypeSourceInfo;
- 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) const;
- 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.
- class 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 {
- SourceLocation::UIntTy BeginOpNameLoc;
- SourceLocation::UIntTy EndOpNameLoc;
- };
- // The location (if any) of the operator keyword is stored elsewhere.
- struct CXXLitOpName {
- SourceLocation::UIntTy OpNameLoc;
- };
- // struct {} CXXUsingDirective;
- // struct {} ObjCZeroArgSelector;
- // struct {} ObjCOneArgSelector;
- // struct {} ObjCMultiArgSelector;
- union {
- struct NT NamedType;
- struct CXXOpName CXXOperatorName;
- struct CXXLitOpName CXXLiteralOperatorName;
- };
- void setNamedTypeLoc(TypeSourceInfo *TInfo) { NamedType.TInfo = TInfo; }
- void setCXXOperatorNameRange(SourceRange Range) {
- CXXOperatorName.BeginOpNameLoc = Range.getBegin().getRawEncoding();
- CXXOperatorName.EndOpNameLoc = Range.getEnd().getRawEncoding();
- }
- void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
- CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
- }
- public:
- DeclarationNameLoc(DeclarationName Name);
- // FIXME: this should go away once all DNLocs are properly initialized.
- DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
- /// Returns the source type info. Assumes that the object stores location
- /// information of a constructor, destructor or conversion operator.
- TypeSourceInfo *getNamedTypeInfo() const { return NamedType.TInfo; }
- /// Return the beginning location of the getCXXOperatorNameRange() range.
- SourceLocation getCXXOperatorNameBeginLoc() const {
- return SourceLocation::getFromRawEncoding(CXXOperatorName.BeginOpNameLoc);
- }
- /// Return the end location of the getCXXOperatorNameRange() range.
- SourceLocation getCXXOperatorNameEndLoc() const {
- return SourceLocation::getFromRawEncoding(CXXOperatorName.EndOpNameLoc);
- }
- /// Return the range of the operator name (without the operator keyword).
- /// Assumes that the object stores location information of a (non-literal)
- /// operator.
- SourceRange getCXXOperatorNameRange() const {
- return SourceRange(getCXXOperatorNameBeginLoc(),
- getCXXOperatorNameEndLoc());
- }
- /// Return the location of the literal operator name (without the operator
- /// keyword). Assumes that the object stores location information of a literal
- /// operator.
- SourceLocation getCXXLiteralOperatorNameLoc() const {
- return SourceLocation::getFromRawEncoding(CXXLiteralOperatorName.OpNameLoc);
- }
- /// Construct location information for a constructor, destructor or conversion
- /// operator.
- static DeclarationNameLoc makeNamedTypeLoc(TypeSourceInfo *TInfo) {
- DeclarationNameLoc DNL;
- DNL.setNamedTypeLoc(TInfo);
- return DNL;
- }
- /// Construct location information for a non-literal C++ operator.
- static DeclarationNameLoc makeCXXOperatorNameLoc(SourceLocation BeginLoc,
- SourceLocation EndLoc) {
- return makeCXXOperatorNameLoc(SourceRange(BeginLoc, EndLoc));
- }
- /// Construct location information for a non-literal C++ operator.
- static DeclarationNameLoc makeCXXOperatorNameLoc(SourceRange Range) {
- DeclarationNameLoc DNL;
- DNL.setCXXOperatorNameRange(Range);
- return DNL;
- }
- /// Construct location information for a literal C++ operator.
- static DeclarationNameLoc makeCXXLiteralOperatorNameLoc(SourceLocation Loc) {
- DeclarationNameLoc DNL;
- DNL.setCXXLiteralOperatorNameLoc(Loc);
- return DNL;
- }
- };
- /// 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; }
- 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.getNamedTypeInfo();
- }
- /// 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 = DeclarationNameLoc::makeNamedTypeLoc(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 LocInfo.getCXXOperatorNameRange();
- }
- /// 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 = DeclarationNameLoc::makeCXXOperatorNameLoc(R);
- }
- /// 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 LocInfo.getCXXLiteralOperatorNameLoc();
- }
- /// 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 = DeclarationNameLoc::makeCXXLiteralOperatorNameLoc(Loc);
- }
- /// 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, PrintingPolicy Policy) 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 partial diagnostics. This allows binding
- /// DeclarationName's into a partial diagnostic with <<.
- inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
- DeclarationName N) {
- PD.AddTaggedVal(N.getAsOpaqueInteger(),
- DiagnosticsEngine::ak_declarationname);
- return PD;
- }
- raw_ostream &operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo);
- } // 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;
- }
- };
- template <> struct PointerLikeTypeTraits<clang::DeclarationName> {
- static inline void *getAsVoidPointer(clang::DeclarationName P) {
- return P.getAsOpaquePtr();
- }
- static inline clang::DeclarationName getFromVoidPointer(void *P) {
- return clang::DeclarationName::getFromOpaquePtr(P);
- }
- static constexpr int NumLowBitsAvailable = 0;
- };
- } // namespace llvm
- // The definition of AssumedTemplateStorage is factored out of TemplateName to
- // resolve a cyclic dependency between it and DeclarationName (via Type).
- namespace clang {
- /// A structure for storing the information associated with a name that has
- /// been assumed to be a template name (despite finding no TemplateDecls).
- class AssumedTemplateStorage : public UncommonTemplateNameStorage {
- friend class ASTContext;
- AssumedTemplateStorage(DeclarationName Name)
- : UncommonTemplateNameStorage(Assumed, 0), Name(Name) {}
- DeclarationName Name;
- public:
- /// Get the name of the template.
- DeclarationName getDeclName() const { return Name; }
- };
- } // namespace clang
- #endif // LLVM_CLANG_AST_DECLARATIONNAME_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|