106f32e7eSjoerg //===- DeclarationName.h - Representation of declaration names --*- C++ -*-===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file declares the DeclarationName and DeclarationNameTable classes.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg
1306f32e7eSjoerg #ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
1406f32e7eSjoerg #define LLVM_CLANG_AST_DECLARATIONNAME_H
1506f32e7eSjoerg
1606f32e7eSjoerg #include "clang/AST/Type.h"
1706f32e7eSjoerg #include "clang/Basic/Diagnostic.h"
1806f32e7eSjoerg #include "clang/Basic/IdentifierTable.h"
1906f32e7eSjoerg #include "clang/Basic/OperatorKinds.h"
2006f32e7eSjoerg #include "clang/Basic/PartialDiagnostic.h"
2106f32e7eSjoerg #include "clang/Basic/SourceLocation.h"
2206f32e7eSjoerg #include "llvm/ADT/DenseMapInfo.h"
2306f32e7eSjoerg #include "llvm/ADT/FoldingSet.h"
2406f32e7eSjoerg #include "llvm/Support/Compiler.h"
2506f32e7eSjoerg #include "llvm/Support/type_traits.h"
2606f32e7eSjoerg #include <cassert>
2706f32e7eSjoerg #include <cstdint>
2806f32e7eSjoerg #include <cstring>
2906f32e7eSjoerg #include <string>
3006f32e7eSjoerg
3106f32e7eSjoerg namespace clang {
3206f32e7eSjoerg
3306f32e7eSjoerg class ASTContext;
3406f32e7eSjoerg template <typename> class CanQual;
3506f32e7eSjoerg class DeclarationName;
3606f32e7eSjoerg class DeclarationNameTable;
3706f32e7eSjoerg class MultiKeywordSelector;
3806f32e7eSjoerg struct PrintingPolicy;
3906f32e7eSjoerg class TemplateDecl;
4006f32e7eSjoerg class TypeSourceInfo;
4106f32e7eSjoerg class UsingDirectiveDecl;
4206f32e7eSjoerg
4306f32e7eSjoerg using CanQualType = CanQual<Type>;
4406f32e7eSjoerg
4506f32e7eSjoerg namespace detail {
4606f32e7eSjoerg
4706f32e7eSjoerg /// CXXSpecialNameExtra records the type associated with one of the "special"
4806f32e7eSjoerg /// kinds of declaration names in C++, e.g., constructors, destructors, and
4906f32e7eSjoerg /// conversion functions. Note that CXXSpecialName is used for C++ constructor,
5006f32e7eSjoerg /// destructor and conversion functions, but the actual kind is not stored in
5106f32e7eSjoerg /// CXXSpecialName. Instead we use three different FoldingSet<CXXSpecialName>
5206f32e7eSjoerg /// in DeclarationNameTable.
alignas(IdentifierInfoAlignment)5306f32e7eSjoerg class alignas(IdentifierInfoAlignment) CXXSpecialNameExtra
5406f32e7eSjoerg : public llvm::FoldingSetNode {
5506f32e7eSjoerg friend class clang::DeclarationName;
5606f32e7eSjoerg friend class clang::DeclarationNameTable;
5706f32e7eSjoerg
5806f32e7eSjoerg /// The type associated with this declaration name.
5906f32e7eSjoerg QualType Type;
6006f32e7eSjoerg
6106f32e7eSjoerg /// Extra information associated with this declaration name that
6206f32e7eSjoerg /// can be used by the front end. All bits are really needed
6306f32e7eSjoerg /// so it is not possible to stash something in the low order bits.
6406f32e7eSjoerg void *FETokenInfo;
6506f32e7eSjoerg
6606f32e7eSjoerg CXXSpecialNameExtra(QualType QT) : Type(QT), FETokenInfo(nullptr) {}
6706f32e7eSjoerg
6806f32e7eSjoerg public:
6906f32e7eSjoerg void Profile(llvm::FoldingSetNodeID &ID) {
7006f32e7eSjoerg ID.AddPointer(Type.getAsOpaquePtr());
7106f32e7eSjoerg }
7206f32e7eSjoerg };
7306f32e7eSjoerg
7406f32e7eSjoerg /// Contains extra information for the name of a C++ deduction guide.
alignas(IdentifierInfoAlignment)7506f32e7eSjoerg class alignas(IdentifierInfoAlignment) CXXDeductionGuideNameExtra
7606f32e7eSjoerg : public detail::DeclarationNameExtra,
7706f32e7eSjoerg public llvm::FoldingSetNode {
7806f32e7eSjoerg friend class clang::DeclarationName;
7906f32e7eSjoerg friend class clang::DeclarationNameTable;
8006f32e7eSjoerg
8106f32e7eSjoerg /// The template named by the deduction guide.
8206f32e7eSjoerg TemplateDecl *Template;
8306f32e7eSjoerg
8406f32e7eSjoerg /// Extra information associated with this operator name that
8506f32e7eSjoerg /// can be used by the front end. All bits are really needed
8606f32e7eSjoerg /// so it is not possible to stash something in the low order bits.
8706f32e7eSjoerg void *FETokenInfo;
8806f32e7eSjoerg
8906f32e7eSjoerg CXXDeductionGuideNameExtra(TemplateDecl *TD)
9006f32e7eSjoerg : DeclarationNameExtra(CXXDeductionGuideName), Template(TD),
9106f32e7eSjoerg FETokenInfo(nullptr) {}
9206f32e7eSjoerg
9306f32e7eSjoerg public:
9406f32e7eSjoerg void Profile(llvm::FoldingSetNodeID &ID) { ID.AddPointer(Template); }
9506f32e7eSjoerg };
9606f32e7eSjoerg
9706f32e7eSjoerg /// Contains extra information for the name of an overloaded operator
9806f32e7eSjoerg /// in C++, such as "operator+. This do not includes literal or conversion
9906f32e7eSjoerg /// operators. For literal operators see CXXLiteralOperatorIdName and for
10006f32e7eSjoerg /// conversion operators see CXXSpecialNameExtra.
alignas(IdentifierInfoAlignment)10106f32e7eSjoerg class alignas(IdentifierInfoAlignment) CXXOperatorIdName {
10206f32e7eSjoerg friend class clang::DeclarationName;
10306f32e7eSjoerg friend class clang::DeclarationNameTable;
10406f32e7eSjoerg
10506f32e7eSjoerg /// The kind of this operator.
10606f32e7eSjoerg OverloadedOperatorKind Kind = OO_None;
10706f32e7eSjoerg
10806f32e7eSjoerg /// Extra information associated with this operator name that
10906f32e7eSjoerg /// can be used by the front end. All bits are really needed
11006f32e7eSjoerg /// so it is not possible to stash something in the low order bits.
11106f32e7eSjoerg void *FETokenInfo = nullptr;
11206f32e7eSjoerg };
11306f32e7eSjoerg
11406f32e7eSjoerg /// Contains the actual identifier that makes up the
11506f32e7eSjoerg /// name of a C++ literal operator.
alignas(IdentifierInfoAlignment)11606f32e7eSjoerg class alignas(IdentifierInfoAlignment) CXXLiteralOperatorIdName
11706f32e7eSjoerg : public detail::DeclarationNameExtra,
11806f32e7eSjoerg public llvm::FoldingSetNode {
11906f32e7eSjoerg friend class clang::DeclarationName;
12006f32e7eSjoerg friend class clang::DeclarationNameTable;
12106f32e7eSjoerg
12206f32e7eSjoerg IdentifierInfo *ID;
12306f32e7eSjoerg
12406f32e7eSjoerg /// Extra information associated with this operator name that
12506f32e7eSjoerg /// can be used by the front end. All bits are really needed
12606f32e7eSjoerg /// so it is not possible to stash something in the low order bits.
12706f32e7eSjoerg void *FETokenInfo;
12806f32e7eSjoerg
12906f32e7eSjoerg CXXLiteralOperatorIdName(IdentifierInfo *II)
13006f32e7eSjoerg : DeclarationNameExtra(CXXLiteralOperatorName), ID(II),
13106f32e7eSjoerg FETokenInfo(nullptr) {}
13206f32e7eSjoerg
13306f32e7eSjoerg public:
13406f32e7eSjoerg void Profile(llvm::FoldingSetNodeID &FSID) { FSID.AddPointer(ID); }
13506f32e7eSjoerg };
13606f32e7eSjoerg
13706f32e7eSjoerg } // namespace detail
13806f32e7eSjoerg
13906f32e7eSjoerg /// The name of a declaration. In the common case, this just stores
14006f32e7eSjoerg /// an IdentifierInfo pointer to a normal name. However, it also provides
14106f32e7eSjoerg /// encodings for Objective-C selectors (optimizing zero- and one-argument
14206f32e7eSjoerg /// selectors, which make up 78% percent of all selectors in Cocoa.h),
14306f32e7eSjoerg /// special C++ names for constructors, destructors, and conversion functions,
14406f32e7eSjoerg /// and C++ overloaded operators.
14506f32e7eSjoerg class DeclarationName {
14606f32e7eSjoerg friend class DeclarationNameTable;
14706f32e7eSjoerg friend class NamedDecl;
14806f32e7eSjoerg
14906f32e7eSjoerg /// StoredNameKind represent the kind of name that is actually stored in the
15006f32e7eSjoerg /// upper bits of the Ptr field. This is only used internally.
15106f32e7eSjoerg ///
15206f32e7eSjoerg /// NameKind, StoredNameKind, and DeclarationNameExtra::ExtraKind
15306f32e7eSjoerg /// must satisfy the following properties. These properties enable
15406f32e7eSjoerg /// efficient conversion between the various kinds.
15506f32e7eSjoerg ///
15606f32e7eSjoerg /// * The first seven enumerators of StoredNameKind must have the same
15706f32e7eSjoerg /// numerical value as the first seven enumerators of NameKind.
15806f32e7eSjoerg /// This enable efficient conversion between the two enumerations
15906f32e7eSjoerg /// in the usual case.
16006f32e7eSjoerg ///
16106f32e7eSjoerg /// * The enumerations values of DeclarationNameExtra::ExtraKind must start
16206f32e7eSjoerg /// at zero, and correspond to the numerical value of the first non-inline
16306f32e7eSjoerg /// enumeration values of NameKind minus an offset. This makes conversion
16406f32e7eSjoerg /// between DeclarationNameExtra::ExtraKind and NameKind possible with
16506f32e7eSjoerg /// a single addition/substraction.
16606f32e7eSjoerg ///
16706f32e7eSjoerg /// * The enumeration values of Selector::IdentifierInfoFlag must correspond
16806f32e7eSjoerg /// to the relevant enumeration values of StoredNameKind.
16906f32e7eSjoerg /// More specifically:
17006f32e7eSjoerg /// * ZeroArg == StoredObjCZeroArgSelector,
17106f32e7eSjoerg /// * OneArg == StoredObjCOneArgSelector,
17206f32e7eSjoerg /// * MultiArg == StoredDeclarationNameExtra
17306f32e7eSjoerg ///
17406f32e7eSjoerg /// * PtrMask must mask the low 3 bits of Ptr.
17506f32e7eSjoerg enum StoredNameKind {
17606f32e7eSjoerg StoredIdentifier = 0,
17706f32e7eSjoerg StoredObjCZeroArgSelector = Selector::ZeroArg,
17806f32e7eSjoerg StoredObjCOneArgSelector = Selector::OneArg,
17906f32e7eSjoerg StoredCXXConstructorName = 3,
18006f32e7eSjoerg StoredCXXDestructorName = 4,
18106f32e7eSjoerg StoredCXXConversionFunctionName = 5,
18206f32e7eSjoerg StoredCXXOperatorName = 6,
18306f32e7eSjoerg StoredDeclarationNameExtra = Selector::MultiArg,
18406f32e7eSjoerg PtrMask = 7,
18506f32e7eSjoerg UncommonNameKindOffset = 8
18606f32e7eSjoerg };
18706f32e7eSjoerg
18806f32e7eSjoerg static_assert(alignof(IdentifierInfo) >= 8 &&
18906f32e7eSjoerg alignof(detail::DeclarationNameExtra) >= 8 &&
19006f32e7eSjoerg alignof(detail::CXXSpecialNameExtra) >= 8 &&
19106f32e7eSjoerg alignof(detail::CXXOperatorIdName) >= 8 &&
19206f32e7eSjoerg alignof(detail::CXXDeductionGuideNameExtra) >= 8 &&
19306f32e7eSjoerg alignof(detail::CXXLiteralOperatorIdName) >= 8,
19406f32e7eSjoerg "The various classes that DeclarationName::Ptr can point to"
19506f32e7eSjoerg " must be at least aligned to 8 bytes!");
19606f32e7eSjoerg
19706f32e7eSjoerg public:
19806f32e7eSjoerg /// The kind of the name stored in this DeclarationName.
19906f32e7eSjoerg /// The first 7 enumeration values are stored inline and correspond
20006f32e7eSjoerg /// to frequently used kinds. The rest is stored in DeclarationNameExtra
20106f32e7eSjoerg /// and correspond to infrequently used kinds.
20206f32e7eSjoerg enum NameKind {
20306f32e7eSjoerg Identifier = StoredIdentifier,
20406f32e7eSjoerg ObjCZeroArgSelector = StoredObjCZeroArgSelector,
20506f32e7eSjoerg ObjCOneArgSelector = StoredObjCOneArgSelector,
20606f32e7eSjoerg CXXConstructorName = StoredCXXConstructorName,
20706f32e7eSjoerg CXXDestructorName = StoredCXXDestructorName,
20806f32e7eSjoerg CXXConversionFunctionName = StoredCXXConversionFunctionName,
20906f32e7eSjoerg CXXOperatorName = StoredCXXOperatorName,
21006f32e7eSjoerg CXXDeductionGuideName = UncommonNameKindOffset +
21106f32e7eSjoerg detail::DeclarationNameExtra::CXXDeductionGuideName,
21206f32e7eSjoerg CXXLiteralOperatorName =
21306f32e7eSjoerg UncommonNameKindOffset +
21406f32e7eSjoerg detail::DeclarationNameExtra::CXXLiteralOperatorName,
21506f32e7eSjoerg CXXUsingDirective = UncommonNameKindOffset +
21606f32e7eSjoerg detail::DeclarationNameExtra::CXXUsingDirective,
21706f32e7eSjoerg ObjCMultiArgSelector = UncommonNameKindOffset +
21806f32e7eSjoerg detail::DeclarationNameExtra::ObjCMultiArgSelector
21906f32e7eSjoerg };
22006f32e7eSjoerg
22106f32e7eSjoerg private:
22206f32e7eSjoerg /// The lowest three bits of Ptr are used to express what kind of name
22306f32e7eSjoerg /// we're actually storing, using the values of StoredNameKind. Depending
22406f32e7eSjoerg /// on the kind of name this is, the upper bits of Ptr may have one
22506f32e7eSjoerg /// of several different meanings:
22606f32e7eSjoerg ///
22706f32e7eSjoerg /// StoredIdentifier - The name is a normal identifier, and Ptr is
22806f32e7eSjoerg /// a normal IdentifierInfo pointer.
22906f32e7eSjoerg ///
23006f32e7eSjoerg /// StoredObjCZeroArgSelector - The name is an Objective-C
23106f32e7eSjoerg /// selector with zero arguments, and Ptr is an IdentifierInfo
23206f32e7eSjoerg /// pointer pointing to the selector name.
23306f32e7eSjoerg ///
23406f32e7eSjoerg /// StoredObjCOneArgSelector - The name is an Objective-C selector
23506f32e7eSjoerg /// with one argument, and Ptr is an IdentifierInfo pointer
23606f32e7eSjoerg /// pointing to the selector name.
23706f32e7eSjoerg ///
23806f32e7eSjoerg /// StoredCXXConstructorName - The name of a C++ constructor,
23906f32e7eSjoerg /// Ptr points to a CXXSpecialNameExtra.
24006f32e7eSjoerg ///
24106f32e7eSjoerg /// StoredCXXDestructorName - The name of a C++ destructor,
24206f32e7eSjoerg /// Ptr points to a CXXSpecialNameExtra.
24306f32e7eSjoerg ///
24406f32e7eSjoerg /// StoredCXXConversionFunctionName - The name of a C++ conversion function,
24506f32e7eSjoerg /// Ptr points to a CXXSpecialNameExtra.
24606f32e7eSjoerg ///
24706f32e7eSjoerg /// StoredCXXOperatorName - The name of an overloaded C++ operator,
24806f32e7eSjoerg /// Ptr points to a CXXOperatorIdName.
24906f32e7eSjoerg ///
25006f32e7eSjoerg /// StoredDeclarationNameExtra - Ptr is actually a pointer to a
25106f32e7eSjoerg /// DeclarationNameExtra structure, whose first value will tell us
25206f32e7eSjoerg /// whether this is an Objective-C selector, C++ deduction guide,
25306f32e7eSjoerg /// C++ literal operator, or C++ using directive.
25406f32e7eSjoerg uintptr_t Ptr = 0;
25506f32e7eSjoerg
getStoredNameKind()25606f32e7eSjoerg StoredNameKind getStoredNameKind() const {
25706f32e7eSjoerg return static_cast<StoredNameKind>(Ptr & PtrMask);
25806f32e7eSjoerg }
25906f32e7eSjoerg
getPtr()26006f32e7eSjoerg void *getPtr() const { return reinterpret_cast<void *>(Ptr & ~PtrMask); }
26106f32e7eSjoerg
setPtrAndKind(const void * P,StoredNameKind Kind)26206f32e7eSjoerg void setPtrAndKind(const void *P, StoredNameKind Kind) {
26306f32e7eSjoerg uintptr_t PAsInteger = reinterpret_cast<uintptr_t>(P);
26406f32e7eSjoerg assert((Kind & ~PtrMask) == 0 &&
26506f32e7eSjoerg "Invalid StoredNameKind in setPtrAndKind!");
26606f32e7eSjoerg assert((PAsInteger & PtrMask) == 0 &&
26706f32e7eSjoerg "Improperly aligned pointer in setPtrAndKind!");
26806f32e7eSjoerg Ptr = PAsInteger | Kind;
26906f32e7eSjoerg }
27006f32e7eSjoerg
27106f32e7eSjoerg /// Construct a declaration name from a DeclarationNameExtra.
DeclarationName(detail::DeclarationNameExtra * Name)27206f32e7eSjoerg DeclarationName(detail::DeclarationNameExtra *Name) {
27306f32e7eSjoerg setPtrAndKind(Name, StoredDeclarationNameExtra);
27406f32e7eSjoerg }
27506f32e7eSjoerg
27606f32e7eSjoerg /// Construct a declaration name from a CXXSpecialNameExtra.
DeclarationName(detail::CXXSpecialNameExtra * Name,StoredNameKind StoredKind)27706f32e7eSjoerg DeclarationName(detail::CXXSpecialNameExtra *Name,
27806f32e7eSjoerg StoredNameKind StoredKind) {
27906f32e7eSjoerg assert((StoredKind == StoredCXXConstructorName ||
28006f32e7eSjoerg StoredKind == StoredCXXDestructorName ||
28106f32e7eSjoerg StoredKind == StoredCXXConversionFunctionName) &&
28206f32e7eSjoerg "Invalid StoredNameKind when constructing a DeclarationName"
28306f32e7eSjoerg " from a CXXSpecialNameExtra!");
28406f32e7eSjoerg setPtrAndKind(Name, StoredKind);
28506f32e7eSjoerg }
28606f32e7eSjoerg
28706f32e7eSjoerg /// Construct a DeclarationName from a CXXOperatorIdName.
DeclarationName(detail::CXXOperatorIdName * Name)28806f32e7eSjoerg DeclarationName(detail::CXXOperatorIdName *Name) {
28906f32e7eSjoerg setPtrAndKind(Name, StoredCXXOperatorName);
29006f32e7eSjoerg }
29106f32e7eSjoerg
29206f32e7eSjoerg /// Assert that the stored pointer points to an IdentifierInfo and return it.
castAsIdentifierInfo()29306f32e7eSjoerg IdentifierInfo *castAsIdentifierInfo() const {
29406f32e7eSjoerg assert((getStoredNameKind() == StoredIdentifier) &&
29506f32e7eSjoerg "DeclarationName does not store an IdentifierInfo!");
29606f32e7eSjoerg return static_cast<IdentifierInfo *>(getPtr());
29706f32e7eSjoerg }
29806f32e7eSjoerg
29906f32e7eSjoerg /// Assert that the stored pointer points to a DeclarationNameExtra
30006f32e7eSjoerg /// and return it.
castAsExtra()30106f32e7eSjoerg detail::DeclarationNameExtra *castAsExtra() const {
30206f32e7eSjoerg assert((getStoredNameKind() == StoredDeclarationNameExtra) &&
30306f32e7eSjoerg "DeclarationName does not store an Extra structure!");
30406f32e7eSjoerg return static_cast<detail::DeclarationNameExtra *>(getPtr());
30506f32e7eSjoerg }
30606f32e7eSjoerg
30706f32e7eSjoerg /// Assert that the stored pointer points to a CXXSpecialNameExtra
30806f32e7eSjoerg /// and return it.
castAsCXXSpecialNameExtra()30906f32e7eSjoerg detail::CXXSpecialNameExtra *castAsCXXSpecialNameExtra() const {
31006f32e7eSjoerg assert((getStoredNameKind() == StoredCXXConstructorName ||
31106f32e7eSjoerg getStoredNameKind() == StoredCXXDestructorName ||
31206f32e7eSjoerg getStoredNameKind() == StoredCXXConversionFunctionName) &&
31306f32e7eSjoerg "DeclarationName does not store a CXXSpecialNameExtra!");
31406f32e7eSjoerg return static_cast<detail::CXXSpecialNameExtra *>(getPtr());
31506f32e7eSjoerg }
31606f32e7eSjoerg
31706f32e7eSjoerg /// Assert that the stored pointer points to a CXXOperatorIdName
31806f32e7eSjoerg /// and return it.
castAsCXXOperatorIdName()31906f32e7eSjoerg detail::CXXOperatorIdName *castAsCXXOperatorIdName() const {
32006f32e7eSjoerg assert((getStoredNameKind() == StoredCXXOperatorName) &&
32106f32e7eSjoerg "DeclarationName does not store a CXXOperatorIdName!");
32206f32e7eSjoerg return static_cast<detail::CXXOperatorIdName *>(getPtr());
32306f32e7eSjoerg }
32406f32e7eSjoerg
32506f32e7eSjoerg /// Assert that the stored pointer points to a CXXDeductionGuideNameExtra
32606f32e7eSjoerg /// and return it.
castAsCXXDeductionGuideNameExtra()32706f32e7eSjoerg detail::CXXDeductionGuideNameExtra *castAsCXXDeductionGuideNameExtra() const {
32806f32e7eSjoerg assert(getNameKind() == CXXDeductionGuideName &&
32906f32e7eSjoerg "DeclarationName does not store a CXXDeductionGuideNameExtra!");
33006f32e7eSjoerg return static_cast<detail::CXXDeductionGuideNameExtra *>(getPtr());
33106f32e7eSjoerg }
33206f32e7eSjoerg
33306f32e7eSjoerg /// Assert that the stored pointer points to a CXXLiteralOperatorIdName
33406f32e7eSjoerg /// and return it.
castAsCXXLiteralOperatorIdName()33506f32e7eSjoerg detail::CXXLiteralOperatorIdName *castAsCXXLiteralOperatorIdName() const {
33606f32e7eSjoerg assert(getNameKind() == CXXLiteralOperatorName &&
33706f32e7eSjoerg "DeclarationName does not store a CXXLiteralOperatorIdName!");
33806f32e7eSjoerg return static_cast<detail::CXXLiteralOperatorIdName *>(getPtr());
33906f32e7eSjoerg }
34006f32e7eSjoerg
34106f32e7eSjoerg /// Get and set the FETokenInfo in the less common cases where the
34206f32e7eSjoerg /// declaration name do not point to an identifier.
34306f32e7eSjoerg void *getFETokenInfoSlow() const;
34406f32e7eSjoerg void setFETokenInfoSlow(void *T);
34506f32e7eSjoerg
34606f32e7eSjoerg public:
34706f32e7eSjoerg /// Construct an empty declaration name.
DeclarationName()34806f32e7eSjoerg DeclarationName() { setPtrAndKind(nullptr, StoredIdentifier); }
34906f32e7eSjoerg
35006f32e7eSjoerg /// Construct a declaration name from an IdentifierInfo *.
DeclarationName(const IdentifierInfo * II)35106f32e7eSjoerg DeclarationName(const IdentifierInfo *II) {
35206f32e7eSjoerg setPtrAndKind(II, StoredIdentifier);
35306f32e7eSjoerg }
35406f32e7eSjoerg
35506f32e7eSjoerg /// Construct a declaration name from an Objective-C selector.
DeclarationName(Selector Sel)35606f32e7eSjoerg DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
35706f32e7eSjoerg
35806f32e7eSjoerg /// Returns the name for all C++ using-directives.
getUsingDirectiveName()35906f32e7eSjoerg static DeclarationName getUsingDirectiveName() {
36006f32e7eSjoerg // Single instance of DeclarationNameExtra for using-directive
36106f32e7eSjoerg static detail::DeclarationNameExtra UDirExtra(
36206f32e7eSjoerg detail::DeclarationNameExtra::CXXUsingDirective);
36306f32e7eSjoerg return DeclarationName(&UDirExtra);
36406f32e7eSjoerg }
36506f32e7eSjoerg
36606f32e7eSjoerg /// Evaluates true when this declaration name is non-empty.
36706f32e7eSjoerg explicit operator bool() const {
36806f32e7eSjoerg return getPtr() || (getStoredNameKind() != StoredIdentifier);
36906f32e7eSjoerg }
37006f32e7eSjoerg
37106f32e7eSjoerg /// Evaluates true when this declaration name is empty.
isEmpty()37206f32e7eSjoerg bool isEmpty() const { return !*this; }
37306f32e7eSjoerg
37406f32e7eSjoerg /// Predicate functions for querying what type of name this is.
isIdentifier()37506f32e7eSjoerg bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
isObjCZeroArgSelector()37606f32e7eSjoerg bool isObjCZeroArgSelector() const {
37706f32e7eSjoerg return getStoredNameKind() == StoredObjCZeroArgSelector;
37806f32e7eSjoerg }
isObjCOneArgSelector()37906f32e7eSjoerg bool isObjCOneArgSelector() const {
38006f32e7eSjoerg return getStoredNameKind() == StoredObjCOneArgSelector;
38106f32e7eSjoerg }
38206f32e7eSjoerg
38306f32e7eSjoerg /// Determine what kind of name this is.
getNameKind()38406f32e7eSjoerg NameKind getNameKind() const {
38506f32e7eSjoerg // We rely on the fact that the first 7 NameKind and StoredNameKind
38606f32e7eSjoerg // have the same numerical value. This makes the usual case efficient.
38706f32e7eSjoerg StoredNameKind StoredKind = getStoredNameKind();
38806f32e7eSjoerg if (StoredKind != StoredDeclarationNameExtra)
38906f32e7eSjoerg return static_cast<NameKind>(StoredKind);
39006f32e7eSjoerg // We have to consult DeclarationNameExtra. We rely on the fact that the
39106f32e7eSjoerg // enumeration values of ExtraKind correspond to the enumeration values of
39206f32e7eSjoerg // NameKind minus an offset of UncommonNameKindOffset.
39306f32e7eSjoerg unsigned ExtraKind = castAsExtra()->getKind();
39406f32e7eSjoerg return static_cast<NameKind>(UncommonNameKindOffset + ExtraKind);
39506f32e7eSjoerg }
39606f32e7eSjoerg
39706f32e7eSjoerg /// Determines whether the name itself is dependent, e.g., because it
39806f32e7eSjoerg /// involves a C++ type that is itself dependent.
39906f32e7eSjoerg ///
40006f32e7eSjoerg /// Note that this does not capture all of the notions of "dependent name",
40106f32e7eSjoerg /// because an identifier can be a dependent name if it is used as the
40206f32e7eSjoerg /// callee in a call expression with dependent arguments.
40306f32e7eSjoerg bool isDependentName() const;
40406f32e7eSjoerg
40506f32e7eSjoerg /// Retrieve the human-readable string for this name.
40606f32e7eSjoerg std::string getAsString() const;
40706f32e7eSjoerg
40806f32e7eSjoerg /// Retrieve the IdentifierInfo * stored in this declaration name,
40906f32e7eSjoerg /// or null if this declaration name isn't a simple identifier.
getAsIdentifierInfo()41006f32e7eSjoerg IdentifierInfo *getAsIdentifierInfo() const {
41106f32e7eSjoerg if (isIdentifier())
41206f32e7eSjoerg return castAsIdentifierInfo();
41306f32e7eSjoerg return nullptr;
41406f32e7eSjoerg }
41506f32e7eSjoerg
41606f32e7eSjoerg /// Get the representation of this declaration name as an opaque integer.
getAsOpaqueInteger()41706f32e7eSjoerg uintptr_t getAsOpaqueInteger() const { return Ptr; }
41806f32e7eSjoerg
41906f32e7eSjoerg /// Get the representation of this declaration name as an opaque pointer.
getAsOpaquePtr()42006f32e7eSjoerg void *getAsOpaquePtr() const { return reinterpret_cast<void *>(Ptr); }
42106f32e7eSjoerg
42206f32e7eSjoerg /// Get a declaration name from an opaque pointer returned by getAsOpaquePtr.
getFromOpaquePtr(void * P)42306f32e7eSjoerg static DeclarationName getFromOpaquePtr(void *P) {
42406f32e7eSjoerg DeclarationName N;
42506f32e7eSjoerg N.Ptr = reinterpret_cast<uintptr_t>(P);
42606f32e7eSjoerg return N;
42706f32e7eSjoerg }
42806f32e7eSjoerg
42906f32e7eSjoerg /// Get a declaration name from an opaque integer
43006f32e7eSjoerg /// returned by getAsOpaqueInteger.
getFromOpaqueInteger(uintptr_t P)43106f32e7eSjoerg static DeclarationName getFromOpaqueInteger(uintptr_t P) {
43206f32e7eSjoerg DeclarationName N;
43306f32e7eSjoerg N.Ptr = P;
43406f32e7eSjoerg return N;
43506f32e7eSjoerg }
43606f32e7eSjoerg
43706f32e7eSjoerg /// If this name is one of the C++ names (of a constructor, destructor,
43806f32e7eSjoerg /// or conversion function), return the type associated with that name.
getCXXNameType()43906f32e7eSjoerg QualType getCXXNameType() const {
44006f32e7eSjoerg if (getStoredNameKind() == StoredCXXConstructorName ||
44106f32e7eSjoerg getStoredNameKind() == StoredCXXDestructorName ||
44206f32e7eSjoerg getStoredNameKind() == StoredCXXConversionFunctionName) {
44306f32e7eSjoerg assert(getPtr() && "getCXXNameType on a null DeclarationName!");
44406f32e7eSjoerg return castAsCXXSpecialNameExtra()->Type;
44506f32e7eSjoerg }
44606f32e7eSjoerg return QualType();
44706f32e7eSjoerg }
44806f32e7eSjoerg
44906f32e7eSjoerg /// If this name is the name of a C++ deduction guide, return the
45006f32e7eSjoerg /// template associated with that name.
getCXXDeductionGuideTemplate()45106f32e7eSjoerg TemplateDecl *getCXXDeductionGuideTemplate() const {
45206f32e7eSjoerg if (getNameKind() == CXXDeductionGuideName) {
45306f32e7eSjoerg assert(getPtr() &&
45406f32e7eSjoerg "getCXXDeductionGuideTemplate on a null DeclarationName!");
45506f32e7eSjoerg return castAsCXXDeductionGuideNameExtra()->Template;
45606f32e7eSjoerg }
45706f32e7eSjoerg return nullptr;
45806f32e7eSjoerg }
45906f32e7eSjoerg
46006f32e7eSjoerg /// If this name is the name of an overloadable operator in C++
46106f32e7eSjoerg /// (e.g., @c operator+), retrieve the kind of overloaded operator.
getCXXOverloadedOperator()46206f32e7eSjoerg OverloadedOperatorKind getCXXOverloadedOperator() const {
46306f32e7eSjoerg if (getStoredNameKind() == StoredCXXOperatorName) {
46406f32e7eSjoerg assert(getPtr() && "getCXXOverloadedOperator on a null DeclarationName!");
46506f32e7eSjoerg return castAsCXXOperatorIdName()->Kind;
46606f32e7eSjoerg }
46706f32e7eSjoerg return OO_None;
46806f32e7eSjoerg }
46906f32e7eSjoerg
47006f32e7eSjoerg /// If this name is the name of a literal operator,
47106f32e7eSjoerg /// retrieve the identifier associated with it.
getCXXLiteralIdentifier()47206f32e7eSjoerg IdentifierInfo *getCXXLiteralIdentifier() const {
47306f32e7eSjoerg if (getNameKind() == CXXLiteralOperatorName) {
47406f32e7eSjoerg assert(getPtr() && "getCXXLiteralIdentifier on a null DeclarationName!");
47506f32e7eSjoerg return castAsCXXLiteralOperatorIdName()->ID;
47606f32e7eSjoerg }
47706f32e7eSjoerg return nullptr;
47806f32e7eSjoerg }
47906f32e7eSjoerg
48006f32e7eSjoerg /// Get the Objective-C selector stored in this declaration name.
getObjCSelector()48106f32e7eSjoerg Selector getObjCSelector() const {
48206f32e7eSjoerg assert((getNameKind() == ObjCZeroArgSelector ||
48306f32e7eSjoerg getNameKind() == ObjCOneArgSelector ||
48406f32e7eSjoerg getNameKind() == ObjCMultiArgSelector || !getPtr()) &&
48506f32e7eSjoerg "Not a selector!");
48606f32e7eSjoerg return Selector(Ptr);
48706f32e7eSjoerg }
48806f32e7eSjoerg
48906f32e7eSjoerg /// Get and set FETokenInfo. The language front-end is allowed to associate
49006f32e7eSjoerg /// arbitrary metadata with some kinds of declaration names, including normal
49106f32e7eSjoerg /// identifiers and C++ constructors, destructors, and conversion functions.
getFETokenInfo()49206f32e7eSjoerg void *getFETokenInfo() const {
49306f32e7eSjoerg assert(getPtr() && "getFETokenInfo on an empty DeclarationName!");
49406f32e7eSjoerg if (getStoredNameKind() == StoredIdentifier)
49506f32e7eSjoerg return castAsIdentifierInfo()->getFETokenInfo();
49606f32e7eSjoerg return getFETokenInfoSlow();
49706f32e7eSjoerg }
49806f32e7eSjoerg
setFETokenInfo(void * T)49906f32e7eSjoerg void setFETokenInfo(void *T) {
50006f32e7eSjoerg assert(getPtr() && "setFETokenInfo on an empty DeclarationName!");
50106f32e7eSjoerg if (getStoredNameKind() == StoredIdentifier)
50206f32e7eSjoerg castAsIdentifierInfo()->setFETokenInfo(T);
50306f32e7eSjoerg else
50406f32e7eSjoerg setFETokenInfoSlow(T);
50506f32e7eSjoerg }
50606f32e7eSjoerg
50706f32e7eSjoerg /// Determine whether the specified names are identical.
50806f32e7eSjoerg friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
50906f32e7eSjoerg return LHS.Ptr == RHS.Ptr;
51006f32e7eSjoerg }
51106f32e7eSjoerg
51206f32e7eSjoerg /// Determine whether the specified names are different.
51306f32e7eSjoerg friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
51406f32e7eSjoerg return LHS.Ptr != RHS.Ptr;
51506f32e7eSjoerg }
51606f32e7eSjoerg
getEmptyMarker()51706f32e7eSjoerg static DeclarationName getEmptyMarker() {
51806f32e7eSjoerg DeclarationName Name;
51906f32e7eSjoerg Name.Ptr = uintptr_t(-1);
52006f32e7eSjoerg return Name;
52106f32e7eSjoerg }
52206f32e7eSjoerg
getTombstoneMarker()52306f32e7eSjoerg static DeclarationName getTombstoneMarker() {
52406f32e7eSjoerg DeclarationName Name;
52506f32e7eSjoerg Name.Ptr = uintptr_t(-2);
52606f32e7eSjoerg return Name;
52706f32e7eSjoerg }
52806f32e7eSjoerg
52906f32e7eSjoerg static int compare(DeclarationName LHS, DeclarationName RHS);
53006f32e7eSjoerg
531*13fbcb42Sjoerg void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
53206f32e7eSjoerg
53306f32e7eSjoerg void dump() const;
53406f32e7eSjoerg };
53506f32e7eSjoerg
53606f32e7eSjoerg raw_ostream &operator<<(raw_ostream &OS, DeclarationName N);
53706f32e7eSjoerg
53806f32e7eSjoerg /// Ordering on two declaration names. If both names are identifiers,
53906f32e7eSjoerg /// this provides a lexicographical ordering.
54006f32e7eSjoerg inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
54106f32e7eSjoerg return DeclarationName::compare(LHS, RHS) < 0;
54206f32e7eSjoerg }
54306f32e7eSjoerg
54406f32e7eSjoerg /// Ordering on two declaration names. If both names are identifiers,
54506f32e7eSjoerg /// this provides a lexicographical ordering.
54606f32e7eSjoerg inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
54706f32e7eSjoerg return DeclarationName::compare(LHS, RHS) > 0;
54806f32e7eSjoerg }
54906f32e7eSjoerg
55006f32e7eSjoerg /// Ordering on two declaration names. If both names are identifiers,
55106f32e7eSjoerg /// this provides a lexicographical ordering.
55206f32e7eSjoerg inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
55306f32e7eSjoerg return DeclarationName::compare(LHS, RHS) <= 0;
55406f32e7eSjoerg }
55506f32e7eSjoerg
55606f32e7eSjoerg /// Ordering on two declaration names. If both names are identifiers,
55706f32e7eSjoerg /// this provides a lexicographical ordering.
55806f32e7eSjoerg inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
55906f32e7eSjoerg return DeclarationName::compare(LHS, RHS) >= 0;
56006f32e7eSjoerg }
56106f32e7eSjoerg
56206f32e7eSjoerg /// DeclarationNameTable is used to store and retrieve DeclarationName
56306f32e7eSjoerg /// instances for the various kinds of declaration names, e.g., normal
56406f32e7eSjoerg /// identifiers, C++ constructor names, etc. This class contains
56506f32e7eSjoerg /// uniqued versions of each of the C++ special names, which can be
56606f32e7eSjoerg /// retrieved using its member functions (e.g., getCXXConstructorName).
56706f32e7eSjoerg class DeclarationNameTable {
56806f32e7eSjoerg /// Used to allocate elements in the FoldingSets below.
56906f32e7eSjoerg const ASTContext &Ctx;
57006f32e7eSjoerg
57106f32e7eSjoerg /// Manage the uniqued CXXSpecialNameExtra representing C++ constructors.
57206f32e7eSjoerg /// getCXXConstructorName and getCXXSpecialName can be used to obtain
57306f32e7eSjoerg /// a DeclarationName from the corresponding type of the constructor.
57406f32e7eSjoerg llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXConstructorNames;
57506f32e7eSjoerg
57606f32e7eSjoerg /// Manage the uniqued CXXSpecialNameExtra representing C++ destructors.
57706f32e7eSjoerg /// getCXXDestructorName and getCXXSpecialName can be used to obtain
57806f32e7eSjoerg /// a DeclarationName from the corresponding type of the destructor.
57906f32e7eSjoerg llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXDestructorNames;
58006f32e7eSjoerg
58106f32e7eSjoerg /// Manage the uniqued CXXSpecialNameExtra representing C++ conversion
58206f32e7eSjoerg /// functions. getCXXConversionFunctionName and getCXXSpecialName can be
58306f32e7eSjoerg /// used to obtain a DeclarationName from the corresponding type of the
58406f32e7eSjoerg /// conversion function.
58506f32e7eSjoerg llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXConversionFunctionNames;
58606f32e7eSjoerg
58706f32e7eSjoerg /// Manage the uniqued CXXOperatorIdName, which contain extra information
58806f32e7eSjoerg /// for the name of overloaded C++ operators. getCXXOperatorName
58906f32e7eSjoerg /// can be used to obtain a DeclarationName from the operator kind.
59006f32e7eSjoerg detail::CXXOperatorIdName CXXOperatorNames[NUM_OVERLOADED_OPERATORS];
59106f32e7eSjoerg
59206f32e7eSjoerg /// Manage the uniqued CXXLiteralOperatorIdName, which contain extra
59306f32e7eSjoerg /// information for the name of C++ literal operators.
59406f32e7eSjoerg /// getCXXLiteralOperatorName can be used to obtain a DeclarationName
59506f32e7eSjoerg /// from the corresponding IdentifierInfo.
59606f32e7eSjoerg llvm::FoldingSet<detail::CXXLiteralOperatorIdName> CXXLiteralOperatorNames;
59706f32e7eSjoerg
59806f32e7eSjoerg /// Manage the uniqued CXXDeductionGuideNameExtra, which contain
59906f32e7eSjoerg /// extra information for the name of a C++ deduction guide.
60006f32e7eSjoerg /// getCXXDeductionGuideName can be used to obtain a DeclarationName
60106f32e7eSjoerg /// from the corresponding template declaration.
60206f32e7eSjoerg llvm::FoldingSet<detail::CXXDeductionGuideNameExtra> CXXDeductionGuideNames;
60306f32e7eSjoerg
60406f32e7eSjoerg public:
60506f32e7eSjoerg DeclarationNameTable(const ASTContext &C);
60606f32e7eSjoerg DeclarationNameTable(const DeclarationNameTable &) = delete;
60706f32e7eSjoerg DeclarationNameTable &operator=(const DeclarationNameTable &) = delete;
60806f32e7eSjoerg DeclarationNameTable(DeclarationNameTable &&) = delete;
60906f32e7eSjoerg DeclarationNameTable &operator=(DeclarationNameTable &&) = delete;
61006f32e7eSjoerg ~DeclarationNameTable() = default;
61106f32e7eSjoerg
61206f32e7eSjoerg /// Create a declaration name that is a simple identifier.
getIdentifier(const IdentifierInfo * ID)61306f32e7eSjoerg DeclarationName getIdentifier(const IdentifierInfo *ID) {
61406f32e7eSjoerg return DeclarationName(ID);
61506f32e7eSjoerg }
61606f32e7eSjoerg
61706f32e7eSjoerg /// Returns the name of a C++ constructor for the given Type.
61806f32e7eSjoerg DeclarationName getCXXConstructorName(CanQualType Ty);
61906f32e7eSjoerg
62006f32e7eSjoerg /// Returns the name of a C++ destructor for the given Type.
62106f32e7eSjoerg DeclarationName getCXXDestructorName(CanQualType Ty);
62206f32e7eSjoerg
62306f32e7eSjoerg /// Returns the name of a C++ deduction guide for the given template.
62406f32e7eSjoerg DeclarationName getCXXDeductionGuideName(TemplateDecl *TD);
62506f32e7eSjoerg
62606f32e7eSjoerg /// Returns the name of a C++ conversion function for the given Type.
62706f32e7eSjoerg DeclarationName getCXXConversionFunctionName(CanQualType Ty);
62806f32e7eSjoerg
62906f32e7eSjoerg /// Returns a declaration name for special kind of C++ name,
63006f32e7eSjoerg /// e.g., for a constructor, destructor, or conversion function.
63106f32e7eSjoerg /// Kind must be one of:
63206f32e7eSjoerg /// * DeclarationName::CXXConstructorName,
63306f32e7eSjoerg /// * DeclarationName::CXXDestructorName or
63406f32e7eSjoerg /// * DeclarationName::CXXConversionFunctionName
63506f32e7eSjoerg DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
63606f32e7eSjoerg CanQualType Ty);
63706f32e7eSjoerg
63806f32e7eSjoerg /// Get the name of the overloadable C++ operator corresponding to Op.
getCXXOperatorName(OverloadedOperatorKind Op)63906f32e7eSjoerg DeclarationName getCXXOperatorName(OverloadedOperatorKind Op) {
64006f32e7eSjoerg return DeclarationName(&CXXOperatorNames[Op]);
64106f32e7eSjoerg }
64206f32e7eSjoerg
64306f32e7eSjoerg /// Get the name of the literal operator function with II as the identifier.
64406f32e7eSjoerg DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
64506f32e7eSjoerg };
64606f32e7eSjoerg
64706f32e7eSjoerg /// DeclarationNameLoc - Additional source/type location info
64806f32e7eSjoerg /// for a declaration name. Needs a DeclarationName in order
64906f32e7eSjoerg /// to be interpreted correctly.
650*13fbcb42Sjoerg class DeclarationNameLoc {
65106f32e7eSjoerg // The source location for identifier stored elsewhere.
65206f32e7eSjoerg // struct {} Identifier;
65306f32e7eSjoerg
65406f32e7eSjoerg // Type info for constructors, destructors and conversion functions.
65506f32e7eSjoerg // Locations (if any) for the tilde (destructor) or operator keyword
65606f32e7eSjoerg // (conversion) are stored elsewhere.
65706f32e7eSjoerg struct NT {
65806f32e7eSjoerg TypeSourceInfo *TInfo;
65906f32e7eSjoerg };
66006f32e7eSjoerg
66106f32e7eSjoerg // The location (if any) of the operator keyword is stored elsewhere.
66206f32e7eSjoerg struct CXXOpName {
66306f32e7eSjoerg unsigned BeginOpNameLoc;
66406f32e7eSjoerg unsigned EndOpNameLoc;
66506f32e7eSjoerg };
66606f32e7eSjoerg
66706f32e7eSjoerg // The location (if any) of the operator keyword is stored elsewhere.
66806f32e7eSjoerg struct CXXLitOpName {
66906f32e7eSjoerg unsigned OpNameLoc;
67006f32e7eSjoerg };
67106f32e7eSjoerg
67206f32e7eSjoerg // struct {} CXXUsingDirective;
67306f32e7eSjoerg // struct {} ObjCZeroArgSelector;
67406f32e7eSjoerg // struct {} ObjCOneArgSelector;
67506f32e7eSjoerg // struct {} ObjCMultiArgSelector;
67606f32e7eSjoerg union {
67706f32e7eSjoerg struct NT NamedType;
67806f32e7eSjoerg struct CXXOpName CXXOperatorName;
67906f32e7eSjoerg struct CXXLitOpName CXXLiteralOperatorName;
68006f32e7eSjoerg };
68106f32e7eSjoerg
setNamedTypeLoc(TypeSourceInfo * TInfo)682*13fbcb42Sjoerg void setNamedTypeLoc(TypeSourceInfo *TInfo) { NamedType.TInfo = TInfo; }
68306f32e7eSjoerg
setCXXOperatorNameRange(SourceRange Range)684*13fbcb42Sjoerg void setCXXOperatorNameRange(SourceRange Range) {
685*13fbcb42Sjoerg CXXOperatorName.BeginOpNameLoc = Range.getBegin().getRawEncoding();
686*13fbcb42Sjoerg CXXOperatorName.EndOpNameLoc = Range.getEnd().getRawEncoding();
687*13fbcb42Sjoerg }
688*13fbcb42Sjoerg
setCXXLiteralOperatorNameLoc(SourceLocation Loc)689*13fbcb42Sjoerg void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
690*13fbcb42Sjoerg CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
691*13fbcb42Sjoerg }
692*13fbcb42Sjoerg
693*13fbcb42Sjoerg public:
694*13fbcb42Sjoerg DeclarationNameLoc(DeclarationName Name);
69506f32e7eSjoerg // FIXME: this should go away once all DNLocs are properly initialized.
DeclarationNameLoc()69606f32e7eSjoerg DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
697*13fbcb42Sjoerg
698*13fbcb42Sjoerg /// Returns the source type info. Assumes that the object stores location
699*13fbcb42Sjoerg /// information of a constructor, destructor or conversion operator.
getNamedTypeInfo()700*13fbcb42Sjoerg TypeSourceInfo *getNamedTypeInfo() const { return NamedType.TInfo; }
701*13fbcb42Sjoerg
702*13fbcb42Sjoerg /// Return the beginning location of the getCXXOperatorNameRange() range.
getCXXOperatorNameBeginLoc()703*13fbcb42Sjoerg SourceLocation getCXXOperatorNameBeginLoc() const {
704*13fbcb42Sjoerg return SourceLocation::getFromRawEncoding(CXXOperatorName.BeginOpNameLoc);
705*13fbcb42Sjoerg }
706*13fbcb42Sjoerg
707*13fbcb42Sjoerg /// Return the end location of the getCXXOperatorNameRange() range.
getCXXOperatorNameEndLoc()708*13fbcb42Sjoerg SourceLocation getCXXOperatorNameEndLoc() const {
709*13fbcb42Sjoerg return SourceLocation::getFromRawEncoding(CXXOperatorName.EndOpNameLoc);
710*13fbcb42Sjoerg }
711*13fbcb42Sjoerg
712*13fbcb42Sjoerg /// Return the range of the operator name (without the operator keyword).
713*13fbcb42Sjoerg /// Assumes that the object stores location information of a (non-literal)
714*13fbcb42Sjoerg /// operator.
getCXXOperatorNameRange()715*13fbcb42Sjoerg SourceRange getCXXOperatorNameRange() const {
716*13fbcb42Sjoerg return SourceRange(getCXXOperatorNameBeginLoc(),
717*13fbcb42Sjoerg getCXXOperatorNameEndLoc());
718*13fbcb42Sjoerg }
719*13fbcb42Sjoerg
720*13fbcb42Sjoerg /// Return the location of the literal operator name (without the operator
721*13fbcb42Sjoerg /// keyword). Assumes that the object stores location information of a literal
722*13fbcb42Sjoerg /// operator.
getCXXLiteralOperatorNameLoc()723*13fbcb42Sjoerg SourceLocation getCXXLiteralOperatorNameLoc() const {
724*13fbcb42Sjoerg return SourceLocation::getFromRawEncoding(CXXLiteralOperatorName.OpNameLoc);
725*13fbcb42Sjoerg }
726*13fbcb42Sjoerg
727*13fbcb42Sjoerg /// Construct location information for a constructor, destructor or conversion
728*13fbcb42Sjoerg /// operator.
makeNamedTypeLoc(TypeSourceInfo * TInfo)729*13fbcb42Sjoerg static DeclarationNameLoc makeNamedTypeLoc(TypeSourceInfo *TInfo) {
730*13fbcb42Sjoerg DeclarationNameLoc DNL;
731*13fbcb42Sjoerg DNL.setNamedTypeLoc(TInfo);
732*13fbcb42Sjoerg return DNL;
733*13fbcb42Sjoerg }
734*13fbcb42Sjoerg
735*13fbcb42Sjoerg /// Construct location information for a non-literal C++ operator.
makeCXXOperatorNameLoc(SourceLocation BeginLoc,SourceLocation EndLoc)736*13fbcb42Sjoerg static DeclarationNameLoc makeCXXOperatorNameLoc(SourceLocation BeginLoc,
737*13fbcb42Sjoerg SourceLocation EndLoc) {
738*13fbcb42Sjoerg return makeCXXOperatorNameLoc(SourceRange(BeginLoc, EndLoc));
739*13fbcb42Sjoerg }
740*13fbcb42Sjoerg
741*13fbcb42Sjoerg /// Construct location information for a non-literal C++ operator.
makeCXXOperatorNameLoc(SourceRange Range)742*13fbcb42Sjoerg static DeclarationNameLoc makeCXXOperatorNameLoc(SourceRange Range) {
743*13fbcb42Sjoerg DeclarationNameLoc DNL;
744*13fbcb42Sjoerg DNL.setCXXOperatorNameRange(Range);
745*13fbcb42Sjoerg return DNL;
746*13fbcb42Sjoerg }
747*13fbcb42Sjoerg
748*13fbcb42Sjoerg /// Construct location information for a literal C++ operator.
makeCXXLiteralOperatorNameLoc(SourceLocation Loc)749*13fbcb42Sjoerg static DeclarationNameLoc makeCXXLiteralOperatorNameLoc(SourceLocation Loc) {
750*13fbcb42Sjoerg DeclarationNameLoc DNL;
751*13fbcb42Sjoerg DNL.setCXXLiteralOperatorNameLoc(Loc);
752*13fbcb42Sjoerg return DNL;
753*13fbcb42Sjoerg }
75406f32e7eSjoerg };
75506f32e7eSjoerg
75606f32e7eSjoerg /// DeclarationNameInfo - A collector data type for bundling together
75706f32e7eSjoerg /// a DeclarationName and the correspnding source/type location info.
75806f32e7eSjoerg struct DeclarationNameInfo {
75906f32e7eSjoerg private:
76006f32e7eSjoerg /// Name - The declaration name, also encoding name kind.
76106f32e7eSjoerg DeclarationName Name;
76206f32e7eSjoerg
76306f32e7eSjoerg /// Loc - The main source location for the declaration name.
76406f32e7eSjoerg SourceLocation NameLoc;
76506f32e7eSjoerg
76606f32e7eSjoerg /// Info - Further source/type location info for special kinds of names.
76706f32e7eSjoerg DeclarationNameLoc LocInfo;
76806f32e7eSjoerg
76906f32e7eSjoerg public:
77006f32e7eSjoerg // FIXME: remove it.
77106f32e7eSjoerg DeclarationNameInfo() = default;
77206f32e7eSjoerg
DeclarationNameInfoDeclarationNameInfo77306f32e7eSjoerg DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
77406f32e7eSjoerg : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
77506f32e7eSjoerg
DeclarationNameInfoDeclarationNameInfo77606f32e7eSjoerg DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
77706f32e7eSjoerg DeclarationNameLoc LocInfo)
77806f32e7eSjoerg : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
77906f32e7eSjoerg
78006f32e7eSjoerg /// getName - Returns the embedded declaration name.
getNameDeclarationNameInfo78106f32e7eSjoerg DeclarationName getName() const { return Name; }
78206f32e7eSjoerg
78306f32e7eSjoerg /// setName - Sets the embedded declaration name.
setNameDeclarationNameInfo78406f32e7eSjoerg void setName(DeclarationName N) { Name = N; }
78506f32e7eSjoerg
78606f32e7eSjoerg /// getLoc - Returns the main location of the declaration name.
getLocDeclarationNameInfo78706f32e7eSjoerg SourceLocation getLoc() const { return NameLoc; }
78806f32e7eSjoerg
78906f32e7eSjoerg /// setLoc - Sets the main location of the declaration name.
setLocDeclarationNameInfo79006f32e7eSjoerg void setLoc(SourceLocation L) { NameLoc = L; }
79106f32e7eSjoerg
getInfoDeclarationNameInfo79206f32e7eSjoerg const DeclarationNameLoc &getInfo() const { return LocInfo; }
setInfoDeclarationNameInfo79306f32e7eSjoerg void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
79406f32e7eSjoerg
79506f32e7eSjoerg /// getNamedTypeInfo - Returns the source type info associated to
79606f32e7eSjoerg /// the name. Assumes it is a constructor, destructor or conversion.
getNamedTypeInfoDeclarationNameInfo79706f32e7eSjoerg TypeSourceInfo *getNamedTypeInfo() const {
79806f32e7eSjoerg if (Name.getNameKind() != DeclarationName::CXXConstructorName &&
79906f32e7eSjoerg Name.getNameKind() != DeclarationName::CXXDestructorName &&
80006f32e7eSjoerg Name.getNameKind() != DeclarationName::CXXConversionFunctionName)
80106f32e7eSjoerg return nullptr;
802*13fbcb42Sjoerg return LocInfo.getNamedTypeInfo();
80306f32e7eSjoerg }
80406f32e7eSjoerg
80506f32e7eSjoerg /// setNamedTypeInfo - Sets the source type info associated to
80606f32e7eSjoerg /// the name. Assumes it is a constructor, destructor or conversion.
setNamedTypeInfoDeclarationNameInfo80706f32e7eSjoerg void setNamedTypeInfo(TypeSourceInfo *TInfo) {
80806f32e7eSjoerg assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
80906f32e7eSjoerg Name.getNameKind() == DeclarationName::CXXDestructorName ||
81006f32e7eSjoerg Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
811*13fbcb42Sjoerg LocInfo = DeclarationNameLoc::makeNamedTypeLoc(TInfo);
81206f32e7eSjoerg }
81306f32e7eSjoerg
81406f32e7eSjoerg /// getCXXOperatorNameRange - Gets the range of the operator name
81506f32e7eSjoerg /// (without the operator keyword). Assumes it is a (non-literal) operator.
getCXXOperatorNameRangeDeclarationNameInfo81606f32e7eSjoerg SourceRange getCXXOperatorNameRange() const {
81706f32e7eSjoerg if (Name.getNameKind() != DeclarationName::CXXOperatorName)
81806f32e7eSjoerg return SourceRange();
819*13fbcb42Sjoerg return LocInfo.getCXXOperatorNameRange();
82006f32e7eSjoerg }
82106f32e7eSjoerg
82206f32e7eSjoerg /// setCXXOperatorNameRange - Sets the range of the operator name
82306f32e7eSjoerg /// (without the operator keyword). Assumes it is a C++ operator.
setCXXOperatorNameRangeDeclarationNameInfo82406f32e7eSjoerg void setCXXOperatorNameRange(SourceRange R) {
82506f32e7eSjoerg assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
826*13fbcb42Sjoerg LocInfo = DeclarationNameLoc::makeCXXOperatorNameLoc(R);
82706f32e7eSjoerg }
82806f32e7eSjoerg
82906f32e7eSjoerg /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
83006f32e7eSjoerg /// operator name (not the operator keyword).
83106f32e7eSjoerg /// Assumes it is a literal operator.
getCXXLiteralOperatorNameLocDeclarationNameInfo83206f32e7eSjoerg SourceLocation getCXXLiteralOperatorNameLoc() const {
83306f32e7eSjoerg if (Name.getNameKind() != DeclarationName::CXXLiteralOperatorName)
83406f32e7eSjoerg return SourceLocation();
835*13fbcb42Sjoerg return LocInfo.getCXXLiteralOperatorNameLoc();
83606f32e7eSjoerg }
83706f32e7eSjoerg
83806f32e7eSjoerg /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
83906f32e7eSjoerg /// operator name (not the operator keyword).
84006f32e7eSjoerg /// Assumes it is a literal operator.
setCXXLiteralOperatorNameLocDeclarationNameInfo84106f32e7eSjoerg void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
84206f32e7eSjoerg assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
843*13fbcb42Sjoerg LocInfo = DeclarationNameLoc::makeCXXLiteralOperatorNameLoc(Loc);
84406f32e7eSjoerg }
84506f32e7eSjoerg
84606f32e7eSjoerg /// Determine whether this name involves a template parameter.
84706f32e7eSjoerg bool isInstantiationDependent() const;
84806f32e7eSjoerg
84906f32e7eSjoerg /// Determine whether this name contains an unexpanded
85006f32e7eSjoerg /// parameter pack.
85106f32e7eSjoerg bool containsUnexpandedParameterPack() const;
85206f32e7eSjoerg
85306f32e7eSjoerg /// getAsString - Retrieve the human-readable string for this name.
85406f32e7eSjoerg std::string getAsString() const;
85506f32e7eSjoerg
85606f32e7eSjoerg /// printName - Print the human-readable name to a stream.
857*13fbcb42Sjoerg void printName(raw_ostream &OS, PrintingPolicy Policy) const;
85806f32e7eSjoerg
85906f32e7eSjoerg /// getBeginLoc - Retrieve the location of the first token.
getBeginLocDeclarationNameInfo86006f32e7eSjoerg SourceLocation getBeginLoc() const { return NameLoc; }
86106f32e7eSjoerg
86206f32e7eSjoerg /// getSourceRange - The range of the declaration name.
getSourceRangeDeclarationNameInfo86306f32e7eSjoerg SourceRange getSourceRange() const LLVM_READONLY {
86406f32e7eSjoerg return SourceRange(getBeginLoc(), getEndLoc());
86506f32e7eSjoerg }
86606f32e7eSjoerg
getEndLocDeclarationNameInfo86706f32e7eSjoerg SourceLocation getEndLoc() const LLVM_READONLY {
86806f32e7eSjoerg SourceLocation EndLoc = getEndLocPrivate();
86906f32e7eSjoerg return EndLoc.isValid() ? EndLoc : getBeginLoc();
87006f32e7eSjoerg }
87106f32e7eSjoerg
87206f32e7eSjoerg private:
87306f32e7eSjoerg SourceLocation getEndLocPrivate() const;
87406f32e7eSjoerg };
87506f32e7eSjoerg
87606f32e7eSjoerg /// Insertion operator for partial diagnostics. This allows binding
87706f32e7eSjoerg /// DeclarationName's into a partial diagnostic with <<.
878*13fbcb42Sjoerg inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
87906f32e7eSjoerg DeclarationName N) {
88006f32e7eSjoerg PD.AddTaggedVal(N.getAsOpaqueInteger(),
88106f32e7eSjoerg DiagnosticsEngine::ak_declarationname);
88206f32e7eSjoerg return PD;
88306f32e7eSjoerg }
88406f32e7eSjoerg
885*13fbcb42Sjoerg raw_ostream &operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo);
88606f32e7eSjoerg
88706f32e7eSjoerg } // namespace clang
88806f32e7eSjoerg
88906f32e7eSjoerg namespace llvm {
89006f32e7eSjoerg
89106f32e7eSjoerg /// Define DenseMapInfo so that DeclarationNames can be used as keys
89206f32e7eSjoerg /// in DenseMap and DenseSets.
89306f32e7eSjoerg template<>
89406f32e7eSjoerg struct DenseMapInfo<clang::DeclarationName> {
89506f32e7eSjoerg static inline clang::DeclarationName getEmptyKey() {
89606f32e7eSjoerg return clang::DeclarationName::getEmptyMarker();
89706f32e7eSjoerg }
89806f32e7eSjoerg
89906f32e7eSjoerg static inline clang::DeclarationName getTombstoneKey() {
90006f32e7eSjoerg return clang::DeclarationName::getTombstoneMarker();
90106f32e7eSjoerg }
90206f32e7eSjoerg
90306f32e7eSjoerg static unsigned getHashValue(clang::DeclarationName Name) {
90406f32e7eSjoerg return DenseMapInfo<void*>::getHashValue(Name.getAsOpaquePtr());
90506f32e7eSjoerg }
90606f32e7eSjoerg
90706f32e7eSjoerg static inline bool
90806f32e7eSjoerg isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
90906f32e7eSjoerg return LHS == RHS;
91006f32e7eSjoerg }
91106f32e7eSjoerg };
91206f32e7eSjoerg
913*13fbcb42Sjoerg template <> struct PointerLikeTypeTraits<clang::DeclarationName> {
914*13fbcb42Sjoerg static inline void *getAsVoidPointer(clang::DeclarationName P) {
915*13fbcb42Sjoerg return P.getAsOpaquePtr();
916*13fbcb42Sjoerg }
917*13fbcb42Sjoerg static inline clang::DeclarationName getFromVoidPointer(void *P) {
918*13fbcb42Sjoerg return clang::DeclarationName::getFromOpaquePtr(P);
919*13fbcb42Sjoerg }
920*13fbcb42Sjoerg static constexpr int NumLowBitsAvailable = 0;
921*13fbcb42Sjoerg };
922*13fbcb42Sjoerg
92306f32e7eSjoerg } // namespace llvm
92406f32e7eSjoerg
92506f32e7eSjoerg // The definition of AssumedTemplateStorage is factored out of TemplateName to
92606f32e7eSjoerg // resolve a cyclic dependency between it and DeclarationName (via Type).
92706f32e7eSjoerg namespace clang {
92806f32e7eSjoerg
92906f32e7eSjoerg /// A structure for storing the information associated with a name that has
93006f32e7eSjoerg /// been assumed to be a template name (despite finding no TemplateDecls).
93106f32e7eSjoerg class AssumedTemplateStorage : public UncommonTemplateNameStorage {
93206f32e7eSjoerg friend class ASTContext;
93306f32e7eSjoerg
93406f32e7eSjoerg AssumedTemplateStorage(DeclarationName Name)
93506f32e7eSjoerg : UncommonTemplateNameStorage(Assumed, 0), Name(Name) {}
93606f32e7eSjoerg DeclarationName Name;
93706f32e7eSjoerg
93806f32e7eSjoerg public:
93906f32e7eSjoerg /// Get the name of the template.
94006f32e7eSjoerg DeclarationName getDeclName() const { return Name; }
94106f32e7eSjoerg };
94206f32e7eSjoerg
94306f32e7eSjoerg } // namespace clang
94406f32e7eSjoerg
94506f32e7eSjoerg #endif // LLVM_CLANG_AST_DECLARATIONNAME_H
946