xref: /minix3/external/bsd/llvm/dist/clang/lib/AST/DeclarationName.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc //
10*f4a2713aSLionel Sambuc // This file implements the DeclarationName and DeclarationNameTable
11*f4a2713aSLionel Sambuc // classes.
12*f4a2713aSLionel Sambuc //
13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
15*f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
16*f4a2713aSLionel Sambuc #include "clang/AST/DeclarationName.h"
17*f4a2713aSLionel Sambuc #include "clang/AST/Type.h"
18*f4a2713aSLionel Sambuc #include "clang/AST/TypeLoc.h"
19*f4a2713aSLionel Sambuc #include "clang/AST/TypeOrdering.h"
20*f4a2713aSLionel Sambuc #include "clang/Basic/IdentifierTable.h"
21*f4a2713aSLionel Sambuc #include "llvm/ADT/DenseMap.h"
22*f4a2713aSLionel Sambuc #include "llvm/ADT/FoldingSet.h"
23*f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
24*f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
25*f4a2713aSLionel Sambuc using namespace clang;
26*f4a2713aSLionel Sambuc 
27*f4a2713aSLionel Sambuc namespace clang {
28*f4a2713aSLionel Sambuc /// CXXSpecialName - Records the type associated with one of the
29*f4a2713aSLionel Sambuc /// "special" kinds of declaration names in C++, e.g., constructors,
30*f4a2713aSLionel Sambuc /// destructors, and conversion functions.
31*f4a2713aSLionel Sambuc class CXXSpecialName
32*f4a2713aSLionel Sambuc   : public DeclarationNameExtra, public llvm::FoldingSetNode {
33*f4a2713aSLionel Sambuc public:
34*f4a2713aSLionel Sambuc   /// Type - The type associated with this declaration name.
35*f4a2713aSLionel Sambuc   QualType Type;
36*f4a2713aSLionel Sambuc 
37*f4a2713aSLionel Sambuc   /// FETokenInfo - Extra information associated with this declaration
38*f4a2713aSLionel Sambuc   /// name that can be used by the front end.
39*f4a2713aSLionel Sambuc   void *FETokenInfo;
40*f4a2713aSLionel Sambuc 
41*f4a2713aSLionel Sambuc   void Profile(llvm::FoldingSetNodeID &ID) {
42*f4a2713aSLionel Sambuc     ID.AddInteger(ExtraKindOrNumArgs);
43*f4a2713aSLionel Sambuc     ID.AddPointer(Type.getAsOpaquePtr());
44*f4a2713aSLionel Sambuc   }
45*f4a2713aSLionel Sambuc };
46*f4a2713aSLionel Sambuc 
47*f4a2713aSLionel Sambuc /// CXXOperatorIdName - Contains extra information for the name of an
48*f4a2713aSLionel Sambuc /// overloaded operator in C++, such as "operator+.
49*f4a2713aSLionel Sambuc class CXXOperatorIdName : public DeclarationNameExtra {
50*f4a2713aSLionel Sambuc public:
51*f4a2713aSLionel Sambuc   /// FETokenInfo - Extra information associated with this operator
52*f4a2713aSLionel Sambuc   /// name that can be used by the front end.
53*f4a2713aSLionel Sambuc   void *FETokenInfo;
54*f4a2713aSLionel Sambuc };
55*f4a2713aSLionel Sambuc 
56*f4a2713aSLionel Sambuc /// CXXLiteralOperatorName - Contains the actual identifier that makes up the
57*f4a2713aSLionel Sambuc /// name.
58*f4a2713aSLionel Sambuc ///
59*f4a2713aSLionel Sambuc /// This identifier is stored here rather than directly in DeclarationName so as
60*f4a2713aSLionel Sambuc /// to allow Objective-C selectors, which are about a million times more common,
61*f4a2713aSLionel Sambuc /// to consume minimal memory.
62*f4a2713aSLionel Sambuc class CXXLiteralOperatorIdName
63*f4a2713aSLionel Sambuc   : public DeclarationNameExtra, public llvm::FoldingSetNode {
64*f4a2713aSLionel Sambuc public:
65*f4a2713aSLionel Sambuc   IdentifierInfo *ID;
66*f4a2713aSLionel Sambuc 
67*f4a2713aSLionel Sambuc   /// FETokenInfo - Extra information associated with this operator
68*f4a2713aSLionel Sambuc   /// name that can be used by the front end.
69*f4a2713aSLionel Sambuc   void *FETokenInfo;
70*f4a2713aSLionel Sambuc 
71*f4a2713aSLionel Sambuc   void Profile(llvm::FoldingSetNodeID &FSID) {
72*f4a2713aSLionel Sambuc     FSID.AddPointer(ID);
73*f4a2713aSLionel Sambuc   }
74*f4a2713aSLionel Sambuc };
75*f4a2713aSLionel Sambuc 
76*f4a2713aSLionel Sambuc static int compareInt(unsigned A, unsigned B) {
77*f4a2713aSLionel Sambuc   return (A < B ? -1 : (A > B ? 1 : 0));
78*f4a2713aSLionel Sambuc }
79*f4a2713aSLionel Sambuc 
80*f4a2713aSLionel Sambuc int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
81*f4a2713aSLionel Sambuc   if (LHS.getNameKind() != RHS.getNameKind())
82*f4a2713aSLionel Sambuc     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
83*f4a2713aSLionel Sambuc 
84*f4a2713aSLionel Sambuc   switch (LHS.getNameKind()) {
85*f4a2713aSLionel Sambuc   case DeclarationName::Identifier: {
86*f4a2713aSLionel Sambuc     IdentifierInfo *LII = LHS.getAsIdentifierInfo();
87*f4a2713aSLionel Sambuc     IdentifierInfo *RII = RHS.getAsIdentifierInfo();
88*f4a2713aSLionel Sambuc     if (!LII) return RII ? -1 : 0;
89*f4a2713aSLionel Sambuc     if (!RII) return 1;
90*f4a2713aSLionel Sambuc 
91*f4a2713aSLionel Sambuc     return LII->getName().compare(RII->getName());
92*f4a2713aSLionel Sambuc   }
93*f4a2713aSLionel Sambuc 
94*f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
95*f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
96*f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector: {
97*f4a2713aSLionel Sambuc     Selector LHSSelector = LHS.getObjCSelector();
98*f4a2713aSLionel Sambuc     Selector RHSSelector = RHS.getObjCSelector();
99*f4a2713aSLionel Sambuc     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
100*f4a2713aSLionel Sambuc     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
101*f4a2713aSLionel Sambuc       switch (LHSSelector.getNameForSlot(I).compare(
102*f4a2713aSLionel Sambuc                                                RHSSelector.getNameForSlot(I))) {
103*f4a2713aSLionel Sambuc       case -1: return true;
104*f4a2713aSLionel Sambuc       case 1: return false;
105*f4a2713aSLionel Sambuc       default: break;
106*f4a2713aSLionel Sambuc       }
107*f4a2713aSLionel Sambuc     }
108*f4a2713aSLionel Sambuc 
109*f4a2713aSLionel Sambuc     return compareInt(LN, RN);
110*f4a2713aSLionel Sambuc   }
111*f4a2713aSLionel Sambuc 
112*f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
113*f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
114*f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName:
115*f4a2713aSLionel Sambuc     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
116*f4a2713aSLionel Sambuc       return -1;
117*f4a2713aSLionel Sambuc     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
118*f4a2713aSLionel Sambuc       return 1;
119*f4a2713aSLionel Sambuc     return 0;
120*f4a2713aSLionel Sambuc 
121*f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName:
122*f4a2713aSLionel Sambuc     return compareInt(LHS.getCXXOverloadedOperator(),
123*f4a2713aSLionel Sambuc                       RHS.getCXXOverloadedOperator());
124*f4a2713aSLionel Sambuc 
125*f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName:
126*f4a2713aSLionel Sambuc     return LHS.getCXXLiteralIdentifier()->getName().compare(
127*f4a2713aSLionel Sambuc                                    RHS.getCXXLiteralIdentifier()->getName());
128*f4a2713aSLionel Sambuc 
129*f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
130*f4a2713aSLionel Sambuc     return 0;
131*f4a2713aSLionel Sambuc   }
132*f4a2713aSLionel Sambuc 
133*f4a2713aSLionel Sambuc   llvm_unreachable("Invalid DeclarationName Kind!");
134*f4a2713aSLionel Sambuc }
135*f4a2713aSLionel Sambuc 
136*f4a2713aSLionel Sambuc raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
137*f4a2713aSLionel Sambuc   switch (N.getNameKind()) {
138*f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
139*f4a2713aSLionel Sambuc     if (const IdentifierInfo *II = N.getAsIdentifierInfo())
140*f4a2713aSLionel Sambuc       OS << II->getName();
141*f4a2713aSLionel Sambuc     return OS;
142*f4a2713aSLionel Sambuc 
143*f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
144*f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
145*f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
146*f4a2713aSLionel Sambuc     return OS << N.getObjCSelector().getAsString();
147*f4a2713aSLionel Sambuc 
148*f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName: {
149*f4a2713aSLionel Sambuc     QualType ClassType = N.getCXXNameType();
150*f4a2713aSLionel Sambuc     if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
151*f4a2713aSLionel Sambuc       return OS << *ClassRec->getDecl();
152*f4a2713aSLionel Sambuc     return OS << ClassType.getAsString();
153*f4a2713aSLionel Sambuc   }
154*f4a2713aSLionel Sambuc 
155*f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName: {
156*f4a2713aSLionel Sambuc     OS << '~';
157*f4a2713aSLionel Sambuc     QualType Type = N.getCXXNameType();
158*f4a2713aSLionel Sambuc     if (const RecordType *Rec = Type->getAs<RecordType>())
159*f4a2713aSLionel Sambuc       return OS << *Rec->getDecl();
160*f4a2713aSLionel Sambuc     return OS << Type.getAsString();
161*f4a2713aSLionel Sambuc   }
162*f4a2713aSLionel Sambuc 
163*f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName: {
164*f4a2713aSLionel Sambuc     static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
165*f4a2713aSLionel Sambuc       0,
166*f4a2713aSLionel Sambuc #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
167*f4a2713aSLionel Sambuc       Spelling,
168*f4a2713aSLionel Sambuc #include "clang/Basic/OperatorKinds.def"
169*f4a2713aSLionel Sambuc     };
170*f4a2713aSLionel Sambuc     const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
171*f4a2713aSLionel Sambuc     assert(OpName && "not an overloaded operator");
172*f4a2713aSLionel Sambuc 
173*f4a2713aSLionel Sambuc     OS << "operator";
174*f4a2713aSLionel Sambuc     if (OpName[0] >= 'a' && OpName[0] <= 'z')
175*f4a2713aSLionel Sambuc       OS << ' ';
176*f4a2713aSLionel Sambuc     return OS << OpName;
177*f4a2713aSLionel Sambuc   }
178*f4a2713aSLionel Sambuc 
179*f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName:
180*f4a2713aSLionel Sambuc     return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
181*f4a2713aSLionel Sambuc 
182*f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName: {
183*f4a2713aSLionel Sambuc     OS << "operator ";
184*f4a2713aSLionel Sambuc     QualType Type = N.getCXXNameType();
185*f4a2713aSLionel Sambuc     if (const RecordType *Rec = Type->getAs<RecordType>())
186*f4a2713aSLionel Sambuc       return OS << *Rec->getDecl();
187*f4a2713aSLionel Sambuc     return OS << Type.getAsString();
188*f4a2713aSLionel Sambuc   }
189*f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
190*f4a2713aSLionel Sambuc     return OS << "<using-directive>";
191*f4a2713aSLionel Sambuc   }
192*f4a2713aSLionel Sambuc 
193*f4a2713aSLionel Sambuc   llvm_unreachable("Unexpected declaration name kind");
194*f4a2713aSLionel Sambuc }
195*f4a2713aSLionel Sambuc 
196*f4a2713aSLionel Sambuc } // end namespace clang
197*f4a2713aSLionel Sambuc 
198*f4a2713aSLionel Sambuc DeclarationName::NameKind DeclarationName::getNameKind() const {
199*f4a2713aSLionel Sambuc   switch (getStoredNameKind()) {
200*f4a2713aSLionel Sambuc   case StoredIdentifier:          return Identifier;
201*f4a2713aSLionel Sambuc   case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
202*f4a2713aSLionel Sambuc   case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
203*f4a2713aSLionel Sambuc 
204*f4a2713aSLionel Sambuc   case StoredDeclarationNameExtra:
205*f4a2713aSLionel Sambuc     switch (getExtra()->ExtraKindOrNumArgs) {
206*f4a2713aSLionel Sambuc     case DeclarationNameExtra::CXXConstructor:
207*f4a2713aSLionel Sambuc       return CXXConstructorName;
208*f4a2713aSLionel Sambuc 
209*f4a2713aSLionel Sambuc     case DeclarationNameExtra::CXXDestructor:
210*f4a2713aSLionel Sambuc       return CXXDestructorName;
211*f4a2713aSLionel Sambuc 
212*f4a2713aSLionel Sambuc     case DeclarationNameExtra::CXXConversionFunction:
213*f4a2713aSLionel Sambuc       return CXXConversionFunctionName;
214*f4a2713aSLionel Sambuc 
215*f4a2713aSLionel Sambuc     case DeclarationNameExtra::CXXLiteralOperator:
216*f4a2713aSLionel Sambuc       return CXXLiteralOperatorName;
217*f4a2713aSLionel Sambuc 
218*f4a2713aSLionel Sambuc     case DeclarationNameExtra::CXXUsingDirective:
219*f4a2713aSLionel Sambuc       return CXXUsingDirective;
220*f4a2713aSLionel Sambuc 
221*f4a2713aSLionel Sambuc     default:
222*f4a2713aSLionel Sambuc       // Check if we have one of the CXXOperator* enumeration values.
223*f4a2713aSLionel Sambuc       if (getExtra()->ExtraKindOrNumArgs <
224*f4a2713aSLionel Sambuc             DeclarationNameExtra::CXXUsingDirective)
225*f4a2713aSLionel Sambuc         return CXXOperatorName;
226*f4a2713aSLionel Sambuc 
227*f4a2713aSLionel Sambuc       return ObjCMultiArgSelector;
228*f4a2713aSLionel Sambuc     }
229*f4a2713aSLionel Sambuc   }
230*f4a2713aSLionel Sambuc 
231*f4a2713aSLionel Sambuc   // Can't actually get here.
232*f4a2713aSLionel Sambuc   llvm_unreachable("This should be unreachable!");
233*f4a2713aSLionel Sambuc }
234*f4a2713aSLionel Sambuc 
235*f4a2713aSLionel Sambuc bool DeclarationName::isDependentName() const {
236*f4a2713aSLionel Sambuc   QualType T = getCXXNameType();
237*f4a2713aSLionel Sambuc   return !T.isNull() && T->isDependentType();
238*f4a2713aSLionel Sambuc }
239*f4a2713aSLionel Sambuc 
240*f4a2713aSLionel Sambuc std::string DeclarationName::getAsString() const {
241*f4a2713aSLionel Sambuc   std::string Result;
242*f4a2713aSLionel Sambuc   llvm::raw_string_ostream OS(Result);
243*f4a2713aSLionel Sambuc   OS << *this;
244*f4a2713aSLionel Sambuc   return OS.str();
245*f4a2713aSLionel Sambuc }
246*f4a2713aSLionel Sambuc 
247*f4a2713aSLionel Sambuc QualType DeclarationName::getCXXNameType() const {
248*f4a2713aSLionel Sambuc   if (CXXSpecialName *CXXName = getAsCXXSpecialName())
249*f4a2713aSLionel Sambuc     return CXXName->Type;
250*f4a2713aSLionel Sambuc   else
251*f4a2713aSLionel Sambuc     return QualType();
252*f4a2713aSLionel Sambuc }
253*f4a2713aSLionel Sambuc 
254*f4a2713aSLionel Sambuc OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
255*f4a2713aSLionel Sambuc   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
256*f4a2713aSLionel Sambuc     unsigned value
257*f4a2713aSLionel Sambuc       = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
258*f4a2713aSLionel Sambuc     return static_cast<OverloadedOperatorKind>(value);
259*f4a2713aSLionel Sambuc   } else {
260*f4a2713aSLionel Sambuc     return OO_None;
261*f4a2713aSLionel Sambuc   }
262*f4a2713aSLionel Sambuc }
263*f4a2713aSLionel Sambuc 
264*f4a2713aSLionel Sambuc IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
265*f4a2713aSLionel Sambuc   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
266*f4a2713aSLionel Sambuc     return CXXLit->ID;
267*f4a2713aSLionel Sambuc   else
268*f4a2713aSLionel Sambuc     return 0;
269*f4a2713aSLionel Sambuc }
270*f4a2713aSLionel Sambuc 
271*f4a2713aSLionel Sambuc void *DeclarationName::getFETokenInfoAsVoidSlow() const {
272*f4a2713aSLionel Sambuc   switch (getNameKind()) {
273*f4a2713aSLionel Sambuc   case Identifier:
274*f4a2713aSLionel Sambuc     llvm_unreachable("Handled by getFETokenInfo()");
275*f4a2713aSLionel Sambuc 
276*f4a2713aSLionel Sambuc   case CXXConstructorName:
277*f4a2713aSLionel Sambuc   case CXXDestructorName:
278*f4a2713aSLionel Sambuc   case CXXConversionFunctionName:
279*f4a2713aSLionel Sambuc     return getAsCXXSpecialName()->FETokenInfo;
280*f4a2713aSLionel Sambuc 
281*f4a2713aSLionel Sambuc   case CXXOperatorName:
282*f4a2713aSLionel Sambuc     return getAsCXXOperatorIdName()->FETokenInfo;
283*f4a2713aSLionel Sambuc 
284*f4a2713aSLionel Sambuc   case CXXLiteralOperatorName:
285*f4a2713aSLionel Sambuc     return getAsCXXLiteralOperatorIdName()->FETokenInfo;
286*f4a2713aSLionel Sambuc 
287*f4a2713aSLionel Sambuc   default:
288*f4a2713aSLionel Sambuc     llvm_unreachable("Declaration name has no FETokenInfo");
289*f4a2713aSLionel Sambuc   }
290*f4a2713aSLionel Sambuc }
291*f4a2713aSLionel Sambuc 
292*f4a2713aSLionel Sambuc void DeclarationName::setFETokenInfo(void *T) {
293*f4a2713aSLionel Sambuc   switch (getNameKind()) {
294*f4a2713aSLionel Sambuc   case Identifier:
295*f4a2713aSLionel Sambuc     getAsIdentifierInfo()->setFETokenInfo(T);
296*f4a2713aSLionel Sambuc     break;
297*f4a2713aSLionel Sambuc 
298*f4a2713aSLionel Sambuc   case CXXConstructorName:
299*f4a2713aSLionel Sambuc   case CXXDestructorName:
300*f4a2713aSLionel Sambuc   case CXXConversionFunctionName:
301*f4a2713aSLionel Sambuc     getAsCXXSpecialName()->FETokenInfo = T;
302*f4a2713aSLionel Sambuc     break;
303*f4a2713aSLionel Sambuc 
304*f4a2713aSLionel Sambuc   case CXXOperatorName:
305*f4a2713aSLionel Sambuc     getAsCXXOperatorIdName()->FETokenInfo = T;
306*f4a2713aSLionel Sambuc     break;
307*f4a2713aSLionel Sambuc 
308*f4a2713aSLionel Sambuc   case CXXLiteralOperatorName:
309*f4a2713aSLionel Sambuc     getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
310*f4a2713aSLionel Sambuc     break;
311*f4a2713aSLionel Sambuc 
312*f4a2713aSLionel Sambuc   default:
313*f4a2713aSLionel Sambuc     llvm_unreachable("Declaration name has no FETokenInfo");
314*f4a2713aSLionel Sambuc   }
315*f4a2713aSLionel Sambuc }
316*f4a2713aSLionel Sambuc 
317*f4a2713aSLionel Sambuc DeclarationName DeclarationName::getUsingDirectiveName() {
318*f4a2713aSLionel Sambuc   // Single instance of DeclarationNameExtra for using-directive
319*f4a2713aSLionel Sambuc   static const DeclarationNameExtra UDirExtra =
320*f4a2713aSLionel Sambuc     { DeclarationNameExtra::CXXUsingDirective };
321*f4a2713aSLionel Sambuc 
322*f4a2713aSLionel Sambuc   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
323*f4a2713aSLionel Sambuc   Ptr |= StoredDeclarationNameExtra;
324*f4a2713aSLionel Sambuc 
325*f4a2713aSLionel Sambuc   return DeclarationName(Ptr);
326*f4a2713aSLionel Sambuc }
327*f4a2713aSLionel Sambuc 
328*f4a2713aSLionel Sambuc void DeclarationName::dump() const {
329*f4a2713aSLionel Sambuc   llvm::errs() << *this << '\n';
330*f4a2713aSLionel Sambuc }
331*f4a2713aSLionel Sambuc 
332*f4a2713aSLionel Sambuc DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
333*f4a2713aSLionel Sambuc   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
334*f4a2713aSLionel Sambuc   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
335*f4a2713aSLionel Sambuc 
336*f4a2713aSLionel Sambuc   // Initialize the overloaded operator names.
337*f4a2713aSLionel Sambuc   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
338*f4a2713aSLionel Sambuc   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
339*f4a2713aSLionel Sambuc     CXXOperatorNames[Op].ExtraKindOrNumArgs
340*f4a2713aSLionel Sambuc       = Op + DeclarationNameExtra::CXXConversionFunction;
341*f4a2713aSLionel Sambuc     CXXOperatorNames[Op].FETokenInfo = 0;
342*f4a2713aSLionel Sambuc   }
343*f4a2713aSLionel Sambuc }
344*f4a2713aSLionel Sambuc 
345*f4a2713aSLionel Sambuc DeclarationNameTable::~DeclarationNameTable() {
346*f4a2713aSLionel Sambuc   llvm::FoldingSet<CXXSpecialName> *SpecialNames =
347*f4a2713aSLionel Sambuc     static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
348*f4a2713aSLionel Sambuc   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
349*f4a2713aSLionel Sambuc     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
350*f4a2713aSLionel Sambuc         (CXXLiteralOperatorNames);
351*f4a2713aSLionel Sambuc 
352*f4a2713aSLionel Sambuc   delete SpecialNames;
353*f4a2713aSLionel Sambuc   delete LiteralNames;
354*f4a2713aSLionel Sambuc }
355*f4a2713aSLionel Sambuc 
356*f4a2713aSLionel Sambuc DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
357*f4a2713aSLionel Sambuc   return getCXXSpecialName(DeclarationName::CXXConstructorName,
358*f4a2713aSLionel Sambuc                            Ty.getUnqualifiedType());
359*f4a2713aSLionel Sambuc }
360*f4a2713aSLionel Sambuc 
361*f4a2713aSLionel Sambuc DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
362*f4a2713aSLionel Sambuc   return getCXXSpecialName(DeclarationName::CXXDestructorName,
363*f4a2713aSLionel Sambuc                            Ty.getUnqualifiedType());
364*f4a2713aSLionel Sambuc }
365*f4a2713aSLionel Sambuc 
366*f4a2713aSLionel Sambuc DeclarationName
367*f4a2713aSLionel Sambuc DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
368*f4a2713aSLionel Sambuc   return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
369*f4a2713aSLionel Sambuc }
370*f4a2713aSLionel Sambuc 
371*f4a2713aSLionel Sambuc DeclarationName
372*f4a2713aSLionel Sambuc DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
373*f4a2713aSLionel Sambuc                                         CanQualType Ty) {
374*f4a2713aSLionel Sambuc   assert(Kind >= DeclarationName::CXXConstructorName &&
375*f4a2713aSLionel Sambuc          Kind <= DeclarationName::CXXConversionFunctionName &&
376*f4a2713aSLionel Sambuc          "Kind must be a C++ special name kind");
377*f4a2713aSLionel Sambuc   llvm::FoldingSet<CXXSpecialName> *SpecialNames
378*f4a2713aSLionel Sambuc     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
379*f4a2713aSLionel Sambuc 
380*f4a2713aSLionel Sambuc   DeclarationNameExtra::ExtraKind EKind;
381*f4a2713aSLionel Sambuc   switch (Kind) {
382*f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
383*f4a2713aSLionel Sambuc     EKind = DeclarationNameExtra::CXXConstructor;
384*f4a2713aSLionel Sambuc     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
385*f4a2713aSLionel Sambuc     break;
386*f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
387*f4a2713aSLionel Sambuc     EKind = DeclarationNameExtra::CXXDestructor;
388*f4a2713aSLionel Sambuc     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
389*f4a2713aSLionel Sambuc     break;
390*f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName:
391*f4a2713aSLionel Sambuc     EKind = DeclarationNameExtra::CXXConversionFunction;
392*f4a2713aSLionel Sambuc     break;
393*f4a2713aSLionel Sambuc   default:
394*f4a2713aSLionel Sambuc     return DeclarationName();
395*f4a2713aSLionel Sambuc   }
396*f4a2713aSLionel Sambuc 
397*f4a2713aSLionel Sambuc   // Unique selector, to guarantee there is one per name.
398*f4a2713aSLionel Sambuc   llvm::FoldingSetNodeID ID;
399*f4a2713aSLionel Sambuc   ID.AddInteger(EKind);
400*f4a2713aSLionel Sambuc   ID.AddPointer(Ty.getAsOpaquePtr());
401*f4a2713aSLionel Sambuc 
402*f4a2713aSLionel Sambuc   void *InsertPos = 0;
403*f4a2713aSLionel Sambuc   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
404*f4a2713aSLionel Sambuc     return DeclarationName(Name);
405*f4a2713aSLionel Sambuc 
406*f4a2713aSLionel Sambuc   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
407*f4a2713aSLionel Sambuc   SpecialName->ExtraKindOrNumArgs = EKind;
408*f4a2713aSLionel Sambuc   SpecialName->Type = Ty;
409*f4a2713aSLionel Sambuc   SpecialName->FETokenInfo = 0;
410*f4a2713aSLionel Sambuc 
411*f4a2713aSLionel Sambuc   SpecialNames->InsertNode(SpecialName, InsertPos);
412*f4a2713aSLionel Sambuc   return DeclarationName(SpecialName);
413*f4a2713aSLionel Sambuc }
414*f4a2713aSLionel Sambuc 
415*f4a2713aSLionel Sambuc DeclarationName
416*f4a2713aSLionel Sambuc DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
417*f4a2713aSLionel Sambuc   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
418*f4a2713aSLionel Sambuc }
419*f4a2713aSLionel Sambuc 
420*f4a2713aSLionel Sambuc DeclarationName
421*f4a2713aSLionel Sambuc DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
422*f4a2713aSLionel Sambuc   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
423*f4a2713aSLionel Sambuc     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
424*f4a2713aSLionel Sambuc                                                       (CXXLiteralOperatorNames);
425*f4a2713aSLionel Sambuc 
426*f4a2713aSLionel Sambuc   llvm::FoldingSetNodeID ID;
427*f4a2713aSLionel Sambuc   ID.AddPointer(II);
428*f4a2713aSLionel Sambuc 
429*f4a2713aSLionel Sambuc   void *InsertPos = 0;
430*f4a2713aSLionel Sambuc   if (CXXLiteralOperatorIdName *Name =
431*f4a2713aSLionel Sambuc                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
432*f4a2713aSLionel Sambuc     return DeclarationName (Name);
433*f4a2713aSLionel Sambuc 
434*f4a2713aSLionel Sambuc   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
435*f4a2713aSLionel Sambuc   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
436*f4a2713aSLionel Sambuc   LiteralName->ID = II;
437*f4a2713aSLionel Sambuc   LiteralName->FETokenInfo = 0;
438*f4a2713aSLionel Sambuc 
439*f4a2713aSLionel Sambuc   LiteralNames->InsertNode(LiteralName, InsertPos);
440*f4a2713aSLionel Sambuc   return DeclarationName(LiteralName);
441*f4a2713aSLionel Sambuc }
442*f4a2713aSLionel Sambuc 
443*f4a2713aSLionel Sambuc DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
444*f4a2713aSLionel Sambuc   switch (Name.getNameKind()) {
445*f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
446*f4a2713aSLionel Sambuc     break;
447*f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
448*f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
449*f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName:
450*f4a2713aSLionel Sambuc     NamedType.TInfo = 0;
451*f4a2713aSLionel Sambuc     break;
452*f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName:
453*f4a2713aSLionel Sambuc     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
454*f4a2713aSLionel Sambuc     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
455*f4a2713aSLionel Sambuc     break;
456*f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName:
457*f4a2713aSLionel Sambuc     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
458*f4a2713aSLionel Sambuc     break;
459*f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
460*f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
461*f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
462*f4a2713aSLionel Sambuc     // FIXME: ?
463*f4a2713aSLionel Sambuc     break;
464*f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
465*f4a2713aSLionel Sambuc     break;
466*f4a2713aSLionel Sambuc   }
467*f4a2713aSLionel Sambuc }
468*f4a2713aSLionel Sambuc 
469*f4a2713aSLionel Sambuc bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
470*f4a2713aSLionel Sambuc   switch (Name.getNameKind()) {
471*f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
472*f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
473*f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
474*f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
475*f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName:
476*f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName:
477*f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
478*f4a2713aSLionel Sambuc     return false;
479*f4a2713aSLionel Sambuc 
480*f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
481*f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
482*f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName:
483*f4a2713aSLionel Sambuc     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
484*f4a2713aSLionel Sambuc       return TInfo->getType()->containsUnexpandedParameterPack();
485*f4a2713aSLionel Sambuc 
486*f4a2713aSLionel Sambuc     return Name.getCXXNameType()->containsUnexpandedParameterPack();
487*f4a2713aSLionel Sambuc   }
488*f4a2713aSLionel Sambuc   llvm_unreachable("All name kinds handled.");
489*f4a2713aSLionel Sambuc }
490*f4a2713aSLionel Sambuc 
491*f4a2713aSLionel Sambuc bool DeclarationNameInfo::isInstantiationDependent() const {
492*f4a2713aSLionel Sambuc   switch (Name.getNameKind()) {
493*f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
494*f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
495*f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
496*f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
497*f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName:
498*f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName:
499*f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
500*f4a2713aSLionel Sambuc     return false;
501*f4a2713aSLionel Sambuc 
502*f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
503*f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
504*f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName:
505*f4a2713aSLionel Sambuc     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
506*f4a2713aSLionel Sambuc       return TInfo->getType()->isInstantiationDependentType();
507*f4a2713aSLionel Sambuc 
508*f4a2713aSLionel Sambuc     return Name.getCXXNameType()->isInstantiationDependentType();
509*f4a2713aSLionel Sambuc   }
510*f4a2713aSLionel Sambuc   llvm_unreachable("All name kinds handled.");
511*f4a2713aSLionel Sambuc }
512*f4a2713aSLionel Sambuc 
513*f4a2713aSLionel Sambuc std::string DeclarationNameInfo::getAsString() const {
514*f4a2713aSLionel Sambuc   std::string Result;
515*f4a2713aSLionel Sambuc   llvm::raw_string_ostream OS(Result);
516*f4a2713aSLionel Sambuc   printName(OS);
517*f4a2713aSLionel Sambuc   return OS.str();
518*f4a2713aSLionel Sambuc }
519*f4a2713aSLionel Sambuc 
520*f4a2713aSLionel Sambuc void DeclarationNameInfo::printName(raw_ostream &OS) const {
521*f4a2713aSLionel Sambuc   switch (Name.getNameKind()) {
522*f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
523*f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
524*f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
525*f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
526*f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName:
527*f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName:
528*f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
529*f4a2713aSLionel Sambuc     OS << Name;
530*f4a2713aSLionel Sambuc     return;
531*f4a2713aSLionel Sambuc 
532*f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
533*f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
534*f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName:
535*f4a2713aSLionel Sambuc     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
536*f4a2713aSLionel Sambuc       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
537*f4a2713aSLionel Sambuc         OS << '~';
538*f4a2713aSLionel Sambuc       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
539*f4a2713aSLionel Sambuc         OS << "operator ";
540*f4a2713aSLionel Sambuc       OS << TInfo->getType().getAsString();
541*f4a2713aSLionel Sambuc     } else
542*f4a2713aSLionel Sambuc       OS << Name;
543*f4a2713aSLionel Sambuc     return;
544*f4a2713aSLionel Sambuc   }
545*f4a2713aSLionel Sambuc   llvm_unreachable("Unexpected declaration name kind");
546*f4a2713aSLionel Sambuc }
547*f4a2713aSLionel Sambuc 
548*f4a2713aSLionel Sambuc SourceLocation DeclarationNameInfo::getEndLoc() const {
549*f4a2713aSLionel Sambuc   switch (Name.getNameKind()) {
550*f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
551*f4a2713aSLionel Sambuc     return NameLoc;
552*f4a2713aSLionel Sambuc 
553*f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName: {
554*f4a2713aSLionel Sambuc     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
555*f4a2713aSLionel Sambuc     return SourceLocation::getFromRawEncoding(raw);
556*f4a2713aSLionel Sambuc   }
557*f4a2713aSLionel Sambuc 
558*f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName: {
559*f4a2713aSLionel Sambuc     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
560*f4a2713aSLionel Sambuc     return SourceLocation::getFromRawEncoding(raw);
561*f4a2713aSLionel Sambuc   }
562*f4a2713aSLionel Sambuc 
563*f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
564*f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
565*f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName:
566*f4a2713aSLionel Sambuc     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
567*f4a2713aSLionel Sambuc       return TInfo->getTypeLoc().getEndLoc();
568*f4a2713aSLionel Sambuc     else
569*f4a2713aSLionel Sambuc       return NameLoc;
570*f4a2713aSLionel Sambuc 
571*f4a2713aSLionel Sambuc     // DNInfo work in progress: FIXME.
572*f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
573*f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
574*f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
575*f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
576*f4a2713aSLionel Sambuc     return NameLoc;
577*f4a2713aSLionel Sambuc   }
578*f4a2713aSLionel Sambuc   llvm_unreachable("Unexpected declaration name kind");
579*f4a2713aSLionel Sambuc }
580