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