xref: /aosp_15_r20/external/clang/include/clang/AST/DeclarationName.h (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file declares the DeclarationName and DeclarationNameTable classes.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li #ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
14*67e74705SXin Li #define LLVM_CLANG_AST_DECLARATIONNAME_H
15*67e74705SXin Li 
16*67e74705SXin Li #include "clang/Basic/IdentifierTable.h"
17*67e74705SXin Li #include "clang/Basic/PartialDiagnostic.h"
18*67e74705SXin Li #include "llvm/Support/Compiler.h"
19*67e74705SXin Li 
20*67e74705SXin Li namespace llvm {
21*67e74705SXin Li   template <typename T> struct DenseMapInfo;
22*67e74705SXin Li }
23*67e74705SXin Li 
24*67e74705SXin Li namespace clang {
25*67e74705SXin Li   class ASTContext;
26*67e74705SXin Li   class CXXLiteralOperatorIdName;
27*67e74705SXin Li   class CXXOperatorIdName;
28*67e74705SXin Li   class CXXSpecialName;
29*67e74705SXin Li   class DeclarationNameExtra;
30*67e74705SXin Li   class IdentifierInfo;
31*67e74705SXin Li   class MultiKeywordSelector;
32*67e74705SXin Li   enum OverloadedOperatorKind : int;
33*67e74705SXin Li   struct PrintingPolicy;
34*67e74705SXin Li   class QualType;
35*67e74705SXin Li   class Type;
36*67e74705SXin Li   class TypeSourceInfo;
37*67e74705SXin Li   class UsingDirectiveDecl;
38*67e74705SXin Li 
39*67e74705SXin Li   template <typename> class CanQual;
40*67e74705SXin Li   typedef CanQual<Type> CanQualType;
41*67e74705SXin Li 
42*67e74705SXin Li /// DeclarationName - The name of a declaration. In the common case,
43*67e74705SXin Li /// this just stores an IdentifierInfo pointer to a normal
44*67e74705SXin Li /// name. However, it also provides encodings for Objective-C
45*67e74705SXin Li /// selectors (optimizing zero- and one-argument selectors, which make
46*67e74705SXin Li /// up 78% percent of all selectors in Cocoa.h) and special C++ names
47*67e74705SXin Li /// for constructors, destructors, and conversion functions.
48*67e74705SXin Li class DeclarationName {
49*67e74705SXin Li public:
50*67e74705SXin Li   /// NameKind - The kind of name this object contains.
51*67e74705SXin Li   enum NameKind {
52*67e74705SXin Li     Identifier,
53*67e74705SXin Li     ObjCZeroArgSelector,
54*67e74705SXin Li     ObjCOneArgSelector,
55*67e74705SXin Li     ObjCMultiArgSelector,
56*67e74705SXin Li     CXXConstructorName,
57*67e74705SXin Li     CXXDestructorName,
58*67e74705SXin Li     CXXConversionFunctionName,
59*67e74705SXin Li     CXXOperatorName,
60*67e74705SXin Li     CXXLiteralOperatorName,
61*67e74705SXin Li     CXXUsingDirective
62*67e74705SXin Li   };
63*67e74705SXin Li   static const unsigned NumNameKinds = CXXUsingDirective + 1;
64*67e74705SXin Li 
65*67e74705SXin Li private:
66*67e74705SXin Li   /// StoredNameKind - The kind of name that is actually stored in the
67*67e74705SXin Li   /// upper bits of the Ptr field. This is only used internally.
68*67e74705SXin Li   ///
69*67e74705SXin Li   /// Note: The entries here are synchronized with the entries in Selector,
70*67e74705SXin Li   /// for efficient translation between the two.
71*67e74705SXin Li   enum StoredNameKind {
72*67e74705SXin Li     StoredIdentifier = 0,
73*67e74705SXin Li     StoredObjCZeroArgSelector = 0x01,
74*67e74705SXin Li     StoredObjCOneArgSelector = 0x02,
75*67e74705SXin Li     StoredDeclarationNameExtra = 0x03,
76*67e74705SXin Li     PtrMask = 0x03
77*67e74705SXin Li   };
78*67e74705SXin Li 
79*67e74705SXin Li   /// Ptr - The lowest two bits are used to express what kind of name
80*67e74705SXin Li   /// we're actually storing, using the values of NameKind. Depending
81*67e74705SXin Li   /// on the kind of name this is, the upper bits of Ptr may have one
82*67e74705SXin Li   /// of several different meanings:
83*67e74705SXin Li   ///
84*67e74705SXin Li   ///   StoredIdentifier - The name is a normal identifier, and Ptr is
85*67e74705SXin Li   ///   a normal IdentifierInfo pointer.
86*67e74705SXin Li   ///
87*67e74705SXin Li   ///   StoredObjCZeroArgSelector - The name is an Objective-C
88*67e74705SXin Li   ///   selector with zero arguments, and Ptr is an IdentifierInfo
89*67e74705SXin Li   ///   pointer pointing to the selector name.
90*67e74705SXin Li   ///
91*67e74705SXin Li   ///   StoredObjCOneArgSelector - The name is an Objective-C selector
92*67e74705SXin Li   ///   with one argument, and Ptr is an IdentifierInfo pointer
93*67e74705SXin Li   ///   pointing to the selector name.
94*67e74705SXin Li   ///
95*67e74705SXin Li   ///   StoredDeclarationNameExtra - Ptr is actually a pointer to a
96*67e74705SXin Li   ///   DeclarationNameExtra structure, whose first value will tell us
97*67e74705SXin Li   ///   whether this is an Objective-C selector, C++ operator-id name,
98*67e74705SXin Li   ///   or special C++ name.
99*67e74705SXin Li   uintptr_t Ptr;
100*67e74705SXin Li 
101*67e74705SXin Li   /// getStoredNameKind - Return the kind of object that is stored in
102*67e74705SXin Li   /// Ptr.
getStoredNameKind()103*67e74705SXin Li   StoredNameKind getStoredNameKind() const {
104*67e74705SXin Li     return static_cast<StoredNameKind>(Ptr & PtrMask);
105*67e74705SXin Li   }
106*67e74705SXin Li 
107*67e74705SXin Li   /// getExtra - Get the "extra" information associated with this
108*67e74705SXin Li   /// multi-argument selector or C++ special name.
getExtra()109*67e74705SXin Li   DeclarationNameExtra *getExtra() const {
110*67e74705SXin Li     assert(getStoredNameKind() == StoredDeclarationNameExtra &&
111*67e74705SXin Li            "Declaration name does not store an Extra structure");
112*67e74705SXin Li     return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
113*67e74705SXin Li   }
114*67e74705SXin Li 
115*67e74705SXin Li   /// getAsCXXSpecialName - If the stored pointer is actually a
116*67e74705SXin Li   /// CXXSpecialName, returns a pointer to it. Otherwise, returns
117*67e74705SXin Li   /// a NULL pointer.
getAsCXXSpecialName()118*67e74705SXin Li   CXXSpecialName *getAsCXXSpecialName() const {
119*67e74705SXin Li     NameKind Kind = getNameKind();
120*67e74705SXin Li     if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
121*67e74705SXin Li       return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
122*67e74705SXin Li     return nullptr;
123*67e74705SXin Li   }
124*67e74705SXin Li 
125*67e74705SXin Li   /// getAsCXXOperatorIdName
getAsCXXOperatorIdName()126*67e74705SXin Li   CXXOperatorIdName *getAsCXXOperatorIdName() const {
127*67e74705SXin Li     if (getNameKind() == CXXOperatorName)
128*67e74705SXin Li       return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
129*67e74705SXin Li     return nullptr;
130*67e74705SXin Li   }
131*67e74705SXin Li 
getAsCXXLiteralOperatorIdName()132*67e74705SXin Li   CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
133*67e74705SXin Li     if (getNameKind() == CXXLiteralOperatorName)
134*67e74705SXin Li       return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
135*67e74705SXin Li     return nullptr;
136*67e74705SXin Li   }
137*67e74705SXin Li 
138*67e74705SXin Li   // Construct a declaration name from the name of a C++ constructor,
139*67e74705SXin Li   // destructor, or conversion function.
DeclarationName(CXXSpecialName * Name)140*67e74705SXin Li   DeclarationName(CXXSpecialName *Name)
141*67e74705SXin Li     : Ptr(reinterpret_cast<uintptr_t>(Name)) {
142*67e74705SXin Li     assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
143*67e74705SXin Li     Ptr |= StoredDeclarationNameExtra;
144*67e74705SXin Li   }
145*67e74705SXin Li 
146*67e74705SXin Li   // Construct a declaration name from the name of a C++ overloaded
147*67e74705SXin Li   // operator.
DeclarationName(CXXOperatorIdName * Name)148*67e74705SXin Li   DeclarationName(CXXOperatorIdName *Name)
149*67e74705SXin Li     : Ptr(reinterpret_cast<uintptr_t>(Name)) {
150*67e74705SXin Li     assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
151*67e74705SXin Li     Ptr |= StoredDeclarationNameExtra;
152*67e74705SXin Li   }
153*67e74705SXin Li 
DeclarationName(CXXLiteralOperatorIdName * Name)154*67e74705SXin Li   DeclarationName(CXXLiteralOperatorIdName *Name)
155*67e74705SXin Li     : Ptr(reinterpret_cast<uintptr_t>(Name)) {
156*67e74705SXin Li     assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
157*67e74705SXin Li     Ptr |= StoredDeclarationNameExtra;
158*67e74705SXin Li   }
159*67e74705SXin Li 
160*67e74705SXin Li   /// Construct a declaration name from a raw pointer.
DeclarationName(uintptr_t Ptr)161*67e74705SXin Li   DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
162*67e74705SXin Li 
163*67e74705SXin Li   friend class DeclarationNameTable;
164*67e74705SXin Li   friend class NamedDecl;
165*67e74705SXin Li 
166*67e74705SXin Li   /// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
167*67e74705SXin Li   /// for this name as a void pointer if it's not an identifier.
168*67e74705SXin Li   void *getFETokenInfoAsVoidSlow() const;
169*67e74705SXin Li 
170*67e74705SXin Li public:
171*67e74705SXin Li   /// DeclarationName - Used to create an empty selector.
DeclarationName()172*67e74705SXin Li   DeclarationName() : Ptr(0) { }
173*67e74705SXin Li 
174*67e74705SXin Li   // Construct a declaration name from an IdentifierInfo *.
DeclarationName(const IdentifierInfo * II)175*67e74705SXin Li   DeclarationName(const IdentifierInfo *II)
176*67e74705SXin Li     : Ptr(reinterpret_cast<uintptr_t>(II)) {
177*67e74705SXin Li     assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
178*67e74705SXin Li   }
179*67e74705SXin Li 
180*67e74705SXin Li   // Construct a declaration name from an Objective-C selector.
DeclarationName(Selector Sel)181*67e74705SXin Li   DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { }
182*67e74705SXin Li 
183*67e74705SXin Li   /// getUsingDirectiveName - Return name for all using-directives.
184*67e74705SXin Li   static DeclarationName getUsingDirectiveName();
185*67e74705SXin Li 
186*67e74705SXin Li   // operator bool() - Evaluates true when this declaration name is
187*67e74705SXin Li   // non-empty.
188*67e74705SXin Li   explicit operator bool() const {
189*67e74705SXin Li     return ((Ptr & PtrMask) != 0) ||
190*67e74705SXin Li            (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
191*67e74705SXin Li   }
192*67e74705SXin Li 
193*67e74705SXin Li   /// \brief Evaluates true when this declaration name is empty.
isEmpty()194*67e74705SXin Li   bool isEmpty() const {
195*67e74705SXin Li     return !*this;
196*67e74705SXin Li   }
197*67e74705SXin Li 
198*67e74705SXin Li   /// Predicate functions for querying what type of name this is.
isIdentifier()199*67e74705SXin Li   bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
isObjCZeroArgSelector()200*67e74705SXin Li   bool isObjCZeroArgSelector() const {
201*67e74705SXin Li     return getStoredNameKind() == StoredObjCZeroArgSelector;
202*67e74705SXin Li   }
isObjCOneArgSelector()203*67e74705SXin Li   bool isObjCOneArgSelector() const {
204*67e74705SXin Li     return getStoredNameKind() == StoredObjCOneArgSelector;
205*67e74705SXin Li   }
206*67e74705SXin Li 
207*67e74705SXin Li   /// getNameKind - Determine what kind of name this is.
208*67e74705SXin Li   NameKind getNameKind() const;
209*67e74705SXin Li 
210*67e74705SXin Li   /// \brief Determines whether the name itself is dependent, e.g., because it
211*67e74705SXin Li   /// involves a C++ type that is itself dependent.
212*67e74705SXin Li   ///
213*67e74705SXin Li   /// Note that this does not capture all of the notions of "dependent name",
214*67e74705SXin Li   /// because an identifier can be a dependent name if it is used as the
215*67e74705SXin Li   /// callee in a call expression with dependent arguments.
216*67e74705SXin Li   bool isDependentName() const;
217*67e74705SXin Li 
218*67e74705SXin Li   /// getNameAsString - Retrieve the human-readable string for this name.
219*67e74705SXin Li   std::string getAsString() const;
220*67e74705SXin Li 
221*67e74705SXin Li   /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
222*67e74705SXin Li   /// this declaration name, or NULL if this declaration name isn't a
223*67e74705SXin Li   /// simple identifier.
getAsIdentifierInfo()224*67e74705SXin Li   IdentifierInfo *getAsIdentifierInfo() const {
225*67e74705SXin Li     if (isIdentifier())
226*67e74705SXin Li       return reinterpret_cast<IdentifierInfo *>(Ptr);
227*67e74705SXin Li     return nullptr;
228*67e74705SXin Li   }
229*67e74705SXin Li 
230*67e74705SXin Li   /// getAsOpaqueInteger - Get the representation of this declaration
231*67e74705SXin Li   /// name as an opaque integer.
getAsOpaqueInteger()232*67e74705SXin Li   uintptr_t getAsOpaqueInteger() const { return Ptr; }
233*67e74705SXin Li 
234*67e74705SXin Li   /// getAsOpaquePtr - Get the representation of this declaration name as
235*67e74705SXin Li   /// an opaque pointer.
getAsOpaquePtr()236*67e74705SXin Li   void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
237*67e74705SXin Li 
getFromOpaquePtr(void * P)238*67e74705SXin Li   static DeclarationName getFromOpaquePtr(void *P) {
239*67e74705SXin Li     DeclarationName N;
240*67e74705SXin Li     N.Ptr = reinterpret_cast<uintptr_t> (P);
241*67e74705SXin Li     return N;
242*67e74705SXin Li   }
243*67e74705SXin Li 
getFromOpaqueInteger(uintptr_t P)244*67e74705SXin Li   static DeclarationName getFromOpaqueInteger(uintptr_t P) {
245*67e74705SXin Li     DeclarationName N;
246*67e74705SXin Li     N.Ptr = P;
247*67e74705SXin Li     return N;
248*67e74705SXin Li   }
249*67e74705SXin Li 
250*67e74705SXin Li   /// getCXXNameType - If this name is one of the C++ names (of a
251*67e74705SXin Li   /// constructor, destructor, or conversion function), return the
252*67e74705SXin Li   /// type associated with that name.
253*67e74705SXin Li   QualType getCXXNameType() const;
254*67e74705SXin Li 
255*67e74705SXin Li   /// getCXXOverloadedOperator - If this name is the name of an
256*67e74705SXin Li   /// overloadable operator in C++ (e.g., @c operator+), retrieve the
257*67e74705SXin Li   /// kind of overloaded operator.
258*67e74705SXin Li   OverloadedOperatorKind getCXXOverloadedOperator() const;
259*67e74705SXin Li 
260*67e74705SXin Li   /// getCXXLiteralIdentifier - If this name is the name of a literal
261*67e74705SXin Li   /// operator, retrieve the identifier associated with it.
262*67e74705SXin Li   IdentifierInfo *getCXXLiteralIdentifier() const;
263*67e74705SXin Li 
264*67e74705SXin Li   /// getObjCSelector - Get the Objective-C selector stored in this
265*67e74705SXin Li   /// declaration name.
getObjCSelector()266*67e74705SXin Li   Selector getObjCSelector() const {
267*67e74705SXin Li     assert((getNameKind() == ObjCZeroArgSelector ||
268*67e74705SXin Li             getNameKind() == ObjCOneArgSelector ||
269*67e74705SXin Li             getNameKind() == ObjCMultiArgSelector ||
270*67e74705SXin Li             Ptr == 0) && "Not a selector!");
271*67e74705SXin Li     return Selector(Ptr);
272*67e74705SXin Li   }
273*67e74705SXin Li 
274*67e74705SXin Li   /// getFETokenInfo/setFETokenInfo - The language front-end is
275*67e74705SXin Li   /// allowed to associate arbitrary metadata with some kinds of
276*67e74705SXin Li   /// declaration names, including normal identifiers and C++
277*67e74705SXin Li   /// constructors, destructors, and conversion functions.
278*67e74705SXin Li   template<typename T>
getFETokenInfo()279*67e74705SXin Li   T *getFETokenInfo() const {
280*67e74705SXin Li     if (const IdentifierInfo *Info = getAsIdentifierInfo())
281*67e74705SXin Li       return Info->getFETokenInfo<T>();
282*67e74705SXin Li     return static_cast<T*>(getFETokenInfoAsVoidSlow());
283*67e74705SXin Li   }
284*67e74705SXin Li 
285*67e74705SXin Li   void setFETokenInfo(void *T);
286*67e74705SXin Li 
287*67e74705SXin Li   /// operator== - Determine whether the specified names are identical..
288*67e74705SXin Li   friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
289*67e74705SXin Li     return LHS.Ptr == RHS.Ptr;
290*67e74705SXin Li   }
291*67e74705SXin Li 
292*67e74705SXin Li   /// operator!= - Determine whether the specified names are different.
293*67e74705SXin Li   friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
294*67e74705SXin Li     return LHS.Ptr != RHS.Ptr;
295*67e74705SXin Li   }
296*67e74705SXin Li 
getEmptyMarker()297*67e74705SXin Li   static DeclarationName getEmptyMarker() {
298*67e74705SXin Li     return DeclarationName(uintptr_t(-1));
299*67e74705SXin Li   }
300*67e74705SXin Li 
getTombstoneMarker()301*67e74705SXin Li   static DeclarationName getTombstoneMarker() {
302*67e74705SXin Li     return DeclarationName(uintptr_t(-2));
303*67e74705SXin Li   }
304*67e74705SXin Li 
305*67e74705SXin Li   static int compare(DeclarationName LHS, DeclarationName RHS);
306*67e74705SXin Li 
307*67e74705SXin Li   void print(raw_ostream &OS, const PrintingPolicy &Policy);
308*67e74705SXin Li 
309*67e74705SXin Li   void dump() const;
310*67e74705SXin Li };
311*67e74705SXin Li 
312*67e74705SXin Li raw_ostream &operator<<(raw_ostream &OS, DeclarationName N);
313*67e74705SXin Li 
314*67e74705SXin Li /// Ordering on two declaration names. If both names are identifiers,
315*67e74705SXin Li /// this provides a lexicographical ordering.
316*67e74705SXin Li inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
317*67e74705SXin Li   return DeclarationName::compare(LHS, RHS) < 0;
318*67e74705SXin Li }
319*67e74705SXin Li 
320*67e74705SXin Li /// Ordering on two declaration names. If both names are identifiers,
321*67e74705SXin Li /// this provides a lexicographical ordering.
322*67e74705SXin Li inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
323*67e74705SXin Li   return DeclarationName::compare(LHS, RHS) > 0;
324*67e74705SXin Li }
325*67e74705SXin Li 
326*67e74705SXin Li /// Ordering on two declaration names. If both names are identifiers,
327*67e74705SXin Li /// this provides a lexicographical ordering.
328*67e74705SXin Li inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
329*67e74705SXin Li   return DeclarationName::compare(LHS, RHS) <= 0;
330*67e74705SXin Li }
331*67e74705SXin Li 
332*67e74705SXin Li /// Ordering on two declaration names. If both names are identifiers,
333*67e74705SXin Li /// this provides a lexicographical ordering.
334*67e74705SXin Li inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
335*67e74705SXin Li   return DeclarationName::compare(LHS, RHS) >= 0;
336*67e74705SXin Li }
337*67e74705SXin Li 
338*67e74705SXin Li /// DeclarationNameTable - Used to store and retrieve DeclarationName
339*67e74705SXin Li /// instances for the various kinds of declaration names, e.g., normal
340*67e74705SXin Li /// identifiers, C++ constructor names, etc. This class contains
341*67e74705SXin Li /// uniqued versions of each of the C++ special names, which can be
342*67e74705SXin Li /// retrieved using its member functions (e.g.,
343*67e74705SXin Li /// getCXXConstructorName).
344*67e74705SXin Li class DeclarationNameTable {
345*67e74705SXin Li   const ASTContext &Ctx;
346*67e74705SXin Li   void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
347*67e74705SXin Li   CXXOperatorIdName *CXXOperatorNames; // Operator names
348*67e74705SXin Li   void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
349*67e74705SXin Li 
350*67e74705SXin Li   DeclarationNameTable(const DeclarationNameTable&) = delete;
351*67e74705SXin Li   void operator=(const DeclarationNameTable&) = delete;
352*67e74705SXin Li 
353*67e74705SXin Li public:
354*67e74705SXin Li   DeclarationNameTable(const ASTContext &C);
355*67e74705SXin Li   ~DeclarationNameTable();
356*67e74705SXin Li 
357*67e74705SXin Li   /// getIdentifier - Create a declaration name that is a simple
358*67e74705SXin Li   /// identifier.
getIdentifier(const IdentifierInfo * ID)359*67e74705SXin Li   DeclarationName getIdentifier(const IdentifierInfo *ID) {
360*67e74705SXin Li     return DeclarationName(ID);
361*67e74705SXin Li   }
362*67e74705SXin Li 
363*67e74705SXin Li   /// getCXXConstructorName - Returns the name of a C++ constructor
364*67e74705SXin Li   /// for the given Type.
365*67e74705SXin Li   DeclarationName getCXXConstructorName(CanQualType Ty);
366*67e74705SXin Li 
367*67e74705SXin Li   /// getCXXDestructorName - Returns the name of a C++ destructor
368*67e74705SXin Li   /// for the given Type.
369*67e74705SXin Li   DeclarationName getCXXDestructorName(CanQualType Ty);
370*67e74705SXin Li 
371*67e74705SXin Li   /// getCXXConversionFunctionName - Returns the name of a C++
372*67e74705SXin Li   /// conversion function for the given Type.
373*67e74705SXin Li   DeclarationName getCXXConversionFunctionName(CanQualType Ty);
374*67e74705SXin Li 
375*67e74705SXin Li   /// getCXXSpecialName - Returns a declaration name for special kind
376*67e74705SXin Li   /// of C++ name, e.g., for a constructor, destructor, or conversion
377*67e74705SXin Li   /// function.
378*67e74705SXin Li   DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
379*67e74705SXin Li                                     CanQualType Ty);
380*67e74705SXin Li 
381*67e74705SXin Li   /// getCXXOperatorName - Get the name of the overloadable C++
382*67e74705SXin Li   /// operator corresponding to Op.
383*67e74705SXin Li   DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
384*67e74705SXin Li 
385*67e74705SXin Li   /// getCXXLiteralOperatorName - Get the name of the literal operator function
386*67e74705SXin Li   /// with II as the identifier.
387*67e74705SXin Li   DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
388*67e74705SXin Li };
389*67e74705SXin Li 
390*67e74705SXin Li /// DeclarationNameLoc - Additional source/type location info
391*67e74705SXin Li /// for a declaration name. Needs a DeclarationName in order
392*67e74705SXin Li /// to be interpreted correctly.
393*67e74705SXin Li struct DeclarationNameLoc {
394*67e74705SXin Li   // The source location for identifier stored elsewhere.
395*67e74705SXin Li   // struct {} Identifier;
396*67e74705SXin Li 
397*67e74705SXin Li   // Type info for constructors, destructors and conversion functions.
398*67e74705SXin Li   // Locations (if any) for the tilde (destructor) or operator keyword
399*67e74705SXin Li   // (conversion) are stored elsewhere.
400*67e74705SXin Li   struct NT {
401*67e74705SXin Li     TypeSourceInfo *TInfo;
402*67e74705SXin Li   };
403*67e74705SXin Li 
404*67e74705SXin Li   // The location (if any) of the operator keyword is stored elsewhere.
405*67e74705SXin Li   struct CXXOpName {
406*67e74705SXin Li     unsigned BeginOpNameLoc;
407*67e74705SXin Li     unsigned EndOpNameLoc;
408*67e74705SXin Li   };
409*67e74705SXin Li 
410*67e74705SXin Li   // The location (if any) of the operator keyword is stored elsewhere.
411*67e74705SXin Li   struct CXXLitOpName {
412*67e74705SXin Li     unsigned OpNameLoc;
413*67e74705SXin Li   };
414*67e74705SXin Li 
415*67e74705SXin Li   // struct {} CXXUsingDirective;
416*67e74705SXin Li   // struct {} ObjCZeroArgSelector;
417*67e74705SXin Li   // struct {} ObjCOneArgSelector;
418*67e74705SXin Li   // struct {} ObjCMultiArgSelector;
419*67e74705SXin Li   union {
420*67e74705SXin Li     struct NT NamedType;
421*67e74705SXin Li     struct CXXOpName CXXOperatorName;
422*67e74705SXin Li     struct CXXLitOpName CXXLiteralOperatorName;
423*67e74705SXin Li   };
424*67e74705SXin Li 
425*67e74705SXin Li   DeclarationNameLoc(DeclarationName Name);
426*67e74705SXin Li   // FIXME: this should go away once all DNLocs are properly initialized.
DeclarationNameLocDeclarationNameLoc427*67e74705SXin Li   DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
428*67e74705SXin Li }; // struct DeclarationNameLoc
429*67e74705SXin Li 
430*67e74705SXin Li 
431*67e74705SXin Li /// DeclarationNameInfo - A collector data type for bundling together
432*67e74705SXin Li /// a DeclarationName and the correspnding source/type location info.
433*67e74705SXin Li struct DeclarationNameInfo {
434*67e74705SXin Li private:
435*67e74705SXin Li   /// Name - The declaration name, also encoding name kind.
436*67e74705SXin Li   DeclarationName Name;
437*67e74705SXin Li   /// Loc - The main source location for the declaration name.
438*67e74705SXin Li   SourceLocation NameLoc;
439*67e74705SXin Li   /// Info - Further source/type location info for special kinds of names.
440*67e74705SXin Li   DeclarationNameLoc LocInfo;
441*67e74705SXin Li 
442*67e74705SXin Li public:
443*67e74705SXin Li   // FIXME: remove it.
DeclarationNameInfoDeclarationNameInfo444*67e74705SXin Li   DeclarationNameInfo() {}
445*67e74705SXin Li 
DeclarationNameInfoDeclarationNameInfo446*67e74705SXin Li   DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
447*67e74705SXin Li     : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
448*67e74705SXin Li 
DeclarationNameInfoDeclarationNameInfo449*67e74705SXin Li   DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
450*67e74705SXin Li                       DeclarationNameLoc LocInfo)
451*67e74705SXin Li     : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
452*67e74705SXin Li 
453*67e74705SXin Li   /// getName - Returns the embedded declaration name.
getNameDeclarationNameInfo454*67e74705SXin Li   DeclarationName getName() const { return Name; }
455*67e74705SXin Li   /// setName - Sets the embedded declaration name.
setNameDeclarationNameInfo456*67e74705SXin Li   void setName(DeclarationName N) { Name = N; }
457*67e74705SXin Li 
458*67e74705SXin Li   /// getLoc - Returns the main location of the declaration name.
getLocDeclarationNameInfo459*67e74705SXin Li   SourceLocation getLoc() const { return NameLoc; }
460*67e74705SXin Li   /// setLoc - Sets the main location of the declaration name.
setLocDeclarationNameInfo461*67e74705SXin Li   void setLoc(SourceLocation L) { NameLoc = L; }
462*67e74705SXin Li 
getInfoDeclarationNameInfo463*67e74705SXin Li   const DeclarationNameLoc &getInfo() const { return LocInfo; }
getInfoDeclarationNameInfo464*67e74705SXin Li   DeclarationNameLoc &getInfo() { return LocInfo; }
setInfoDeclarationNameInfo465*67e74705SXin Li   void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
466*67e74705SXin Li 
467*67e74705SXin Li   /// getNamedTypeInfo - Returns the source type info associated to
468*67e74705SXin Li   /// the name. Assumes it is a constructor, destructor or conversion.
getNamedTypeInfoDeclarationNameInfo469*67e74705SXin Li   TypeSourceInfo *getNamedTypeInfo() const {
470*67e74705SXin Li     assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
471*67e74705SXin Li            Name.getNameKind() == DeclarationName::CXXDestructorName ||
472*67e74705SXin Li            Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
473*67e74705SXin Li     return LocInfo.NamedType.TInfo;
474*67e74705SXin Li   }
475*67e74705SXin Li   /// setNamedTypeInfo - Sets the source type info associated to
476*67e74705SXin Li   /// the name. Assumes it is a constructor, destructor or conversion.
setNamedTypeInfoDeclarationNameInfo477*67e74705SXin Li   void setNamedTypeInfo(TypeSourceInfo *TInfo) {
478*67e74705SXin Li     assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
479*67e74705SXin Li            Name.getNameKind() == DeclarationName::CXXDestructorName ||
480*67e74705SXin Li            Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
481*67e74705SXin Li     LocInfo.NamedType.TInfo = TInfo;
482*67e74705SXin Li   }
483*67e74705SXin Li 
484*67e74705SXin Li   /// getCXXOperatorNameRange - Gets the range of the operator name
485*67e74705SXin Li   /// (without the operator keyword). Assumes it is a (non-literal) operator.
getCXXOperatorNameRangeDeclarationNameInfo486*67e74705SXin Li   SourceRange getCXXOperatorNameRange() const {
487*67e74705SXin Li     assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
488*67e74705SXin Li     return SourceRange(
489*67e74705SXin Li      SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
490*67e74705SXin Li      SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
491*67e74705SXin Li                        );
492*67e74705SXin Li   }
493*67e74705SXin Li   /// setCXXOperatorNameRange - Sets the range of the operator name
494*67e74705SXin Li   /// (without the operator keyword). Assumes it is a C++ operator.
setCXXOperatorNameRangeDeclarationNameInfo495*67e74705SXin Li   void setCXXOperatorNameRange(SourceRange R) {
496*67e74705SXin Li     assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
497*67e74705SXin Li     LocInfo.CXXOperatorName.BeginOpNameLoc = R.getBegin().getRawEncoding();
498*67e74705SXin Li     LocInfo.CXXOperatorName.EndOpNameLoc = R.getEnd().getRawEncoding();
499*67e74705SXin Li   }
500*67e74705SXin Li 
501*67e74705SXin Li   /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
502*67e74705SXin Li   /// operator name (not the operator keyword).
503*67e74705SXin Li   /// Assumes it is a literal operator.
getCXXLiteralOperatorNameLocDeclarationNameInfo504*67e74705SXin Li   SourceLocation getCXXLiteralOperatorNameLoc() const {
505*67e74705SXin Li     assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
506*67e74705SXin Li     return SourceLocation::
507*67e74705SXin Li       getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
508*67e74705SXin Li   }
509*67e74705SXin Li   /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
510*67e74705SXin Li   /// operator name (not the operator keyword).
511*67e74705SXin Li   /// Assumes it is a literal operator.
setCXXLiteralOperatorNameLocDeclarationNameInfo512*67e74705SXin Li   void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
513*67e74705SXin Li     assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
514*67e74705SXin Li     LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
515*67e74705SXin Li   }
516*67e74705SXin Li 
517*67e74705SXin Li   /// \brief Determine whether this name involves a template parameter.
518*67e74705SXin Li   bool isInstantiationDependent() const;
519*67e74705SXin Li 
520*67e74705SXin Li   /// \brief Determine whether this name contains an unexpanded
521*67e74705SXin Li   /// parameter pack.
522*67e74705SXin Li   bool containsUnexpandedParameterPack() const;
523*67e74705SXin Li 
524*67e74705SXin Li   /// getAsString - Retrieve the human-readable string for this name.
525*67e74705SXin Li   std::string getAsString() const;
526*67e74705SXin Li 
527*67e74705SXin Li   /// printName - Print the human-readable name to a stream.
528*67e74705SXin Li   void printName(raw_ostream &OS) const;
529*67e74705SXin Li 
530*67e74705SXin Li   /// getBeginLoc - Retrieve the location of the first token.
getBeginLocDeclarationNameInfo531*67e74705SXin Li   SourceLocation getBeginLoc() const { return NameLoc; }
532*67e74705SXin Li   /// getEndLoc - Retrieve the location of the last token.
533*67e74705SXin Li   SourceLocation getEndLoc() const;
534*67e74705SXin Li   /// getSourceRange - The range of the declaration name.
getSourceRangeDeclarationNameInfo535*67e74705SXin Li   SourceRange getSourceRange() const LLVM_READONLY {
536*67e74705SXin Li     return SourceRange(getLocStart(), getLocEnd());
537*67e74705SXin Li   }
getLocStartDeclarationNameInfo538*67e74705SXin Li   SourceLocation getLocStart() const LLVM_READONLY {
539*67e74705SXin Li     return getBeginLoc();
540*67e74705SXin Li   }
getLocEndDeclarationNameInfo541*67e74705SXin Li   SourceLocation getLocEnd() const LLVM_READONLY {
542*67e74705SXin Li     SourceLocation EndLoc = getEndLoc();
543*67e74705SXin Li     return EndLoc.isValid() ? EndLoc : getLocStart();
544*67e74705SXin Li   }
545*67e74705SXin Li };
546*67e74705SXin Li 
547*67e74705SXin Li /// Insertion operator for diagnostics.  This allows sending DeclarationName's
548*67e74705SXin Li /// into a diagnostic with <<.
549*67e74705SXin Li inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
550*67e74705SXin Li                                            DeclarationName N) {
551*67e74705SXin Li   DB.AddTaggedVal(N.getAsOpaqueInteger(),
552*67e74705SXin Li                   DiagnosticsEngine::ak_declarationname);
553*67e74705SXin Li   return DB;
554*67e74705SXin Li }
555*67e74705SXin Li 
556*67e74705SXin Li /// Insertion operator for partial diagnostics.  This allows binding
557*67e74705SXin Li /// DeclarationName's into a partial diagnostic with <<.
558*67e74705SXin Li inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
559*67e74705SXin Li                                            DeclarationName N) {
560*67e74705SXin Li   PD.AddTaggedVal(N.getAsOpaqueInteger(),
561*67e74705SXin Li                   DiagnosticsEngine::ak_declarationname);
562*67e74705SXin Li   return PD;
563*67e74705SXin Li }
564*67e74705SXin Li 
565*67e74705SXin Li inline raw_ostream &operator<<(raw_ostream &OS,
566*67e74705SXin Li                                      DeclarationNameInfo DNInfo) {
567*67e74705SXin Li   DNInfo.printName(OS);
568*67e74705SXin Li   return OS;
569*67e74705SXin Li }
570*67e74705SXin Li 
571*67e74705SXin Li }  // end namespace clang
572*67e74705SXin Li 
573*67e74705SXin Li namespace llvm {
574*67e74705SXin Li /// Define DenseMapInfo so that DeclarationNames can be used as keys
575*67e74705SXin Li /// in DenseMap and DenseSets.
576*67e74705SXin Li template<>
577*67e74705SXin Li struct DenseMapInfo<clang::DeclarationName> {
578*67e74705SXin Li   static inline clang::DeclarationName getEmptyKey() {
579*67e74705SXin Li     return clang::DeclarationName::getEmptyMarker();
580*67e74705SXin Li   }
581*67e74705SXin Li 
582*67e74705SXin Li   static inline clang::DeclarationName getTombstoneKey() {
583*67e74705SXin Li     return clang::DeclarationName::getTombstoneMarker();
584*67e74705SXin Li   }
585*67e74705SXin Li 
586*67e74705SXin Li   static unsigned getHashValue(clang::DeclarationName Name) {
587*67e74705SXin Li     return DenseMapInfo<void*>::getHashValue(Name.getAsOpaquePtr());
588*67e74705SXin Li   }
589*67e74705SXin Li 
590*67e74705SXin Li   static inline bool
591*67e74705SXin Li   isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
592*67e74705SXin Li     return LHS == RHS;
593*67e74705SXin Li   }
594*67e74705SXin Li };
595*67e74705SXin Li 
596*67e74705SXin Li template <>
597*67e74705SXin Li struct isPodLike<clang::DeclarationName> { static const bool value = true; };
598*67e74705SXin Li 
599*67e74705SXin Li }  // end namespace llvm
600*67e74705SXin Li 
601*67e74705SXin Li #endif
602