]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/AST/DeclarationName.cpp
Update clang to r89205.
[FreeBSD/FreeBSD.git] / lib / AST / DeclarationName.cpp
1 //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the DeclarationName and DeclarationNameTable
11 // classes.
12 //
13 //===----------------------------------------------------------------------===//
14 #include "clang/AST/DeclarationName.h"
15 #include "clang/AST/Type.h"
16 #include "clang/AST/TypeOrdering.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/Basic/IdentifierTable.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/FoldingSet.h"
21 #include <cstdio>
22 using namespace clang;
23
24 namespace clang {
25 /// CXXSpecialName - Records the type associated with one of the
26 /// "special" kinds of declaration names in C++, e.g., constructors,
27 /// destructors, and conversion functions.
28 class CXXSpecialName
29   : public DeclarationNameExtra, public llvm::FoldingSetNode {
30 public:
31   /// Type - The type associated with this declaration name.
32   QualType Type;
33
34   /// FETokenInfo - Extra information associated with this declaration
35   /// name that can be used by the front end.
36   void *FETokenInfo;
37
38   void Profile(llvm::FoldingSetNodeID &ID) {
39     ID.AddInteger(ExtraKindOrNumArgs);
40     ID.AddPointer(Type.getAsOpaquePtr());
41   }
42 };
43
44 /// CXXOperatorIdName - Contains extra information for the name of an
45 /// overloaded operator in C++, such as "operator+.
46 class CXXOperatorIdName : public DeclarationNameExtra {
47 public:
48   /// FETokenInfo - Extra information associated with this operator
49   /// name that can be used by the front end.
50   void *FETokenInfo;
51 };
52
53 bool operator<(DeclarationName LHS, DeclarationName RHS) {
54   if (LHS.getNameKind() != RHS.getNameKind())
55     return LHS.getNameKind() < RHS.getNameKind();
56   
57   switch (LHS.getNameKind()) {
58   case DeclarationName::Identifier:
59     return LHS.getAsIdentifierInfo()->getName() < 
60                                          RHS.getAsIdentifierInfo()->getName();
61
62   case DeclarationName::ObjCZeroArgSelector:
63   case DeclarationName::ObjCOneArgSelector:
64   case DeclarationName::ObjCMultiArgSelector: {
65     Selector LHSSelector = LHS.getObjCSelector();
66     Selector RHSSelector = RHS.getObjCSelector();
67     for (unsigned I = 0, 
68                N = std::min(LHSSelector.getNumArgs(), RHSSelector.getNumArgs());
69          I != N; ++I) {
70       IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
71       IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
72       if (!LHSId || !RHSId)
73         return LHSId && !RHSId;
74         
75       switch (LHSId->getName().compare(RHSId->getName())) {
76       case -1: return true;
77       case 1: return false;
78       default: break;
79       }
80     }
81     
82     return LHSSelector.getNumArgs() < RHSSelector.getNumArgs();
83   }
84   
85   case DeclarationName::CXXConstructorName:
86   case DeclarationName::CXXDestructorName:
87   case DeclarationName::CXXConversionFunctionName:
88     return QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType());
89               
90   case DeclarationName::CXXOperatorName:
91     return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator();
92               
93   case DeclarationName::CXXUsingDirective:
94     return false;
95   }
96               
97   return false;
98 }
99
100 } // end namespace clang
101
102 DeclarationName::DeclarationName(Selector Sel) {
103   if (!Sel.getAsOpaquePtr()) {
104     Ptr = 0;
105     return;
106   }
107
108   switch (Sel.getNumArgs()) {
109   case 0:
110     Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
111     assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
112     Ptr |= StoredObjCZeroArgSelector;
113     break;
114
115   case 1:
116     Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
117     assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
118     Ptr |= StoredObjCOneArgSelector;
119     break;
120
121   default:
122     Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
123     assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
124     Ptr |= StoredDeclarationNameExtra;
125     break;
126   }
127 }
128
129 DeclarationName::NameKind DeclarationName::getNameKind() const {
130   switch (getStoredNameKind()) {
131   case StoredIdentifier:          return Identifier;
132   case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
133   case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
134
135   case StoredDeclarationNameExtra:
136     switch (getExtra()->ExtraKindOrNumArgs) {
137     case DeclarationNameExtra::CXXConstructor:
138       return CXXConstructorName;
139
140     case DeclarationNameExtra::CXXDestructor:
141       return CXXDestructorName;
142
143     case DeclarationNameExtra::CXXConversionFunction:
144       return CXXConversionFunctionName;
145
146     case DeclarationNameExtra::CXXUsingDirective:
147       return CXXUsingDirective;
148
149     default:
150       // Check if we have one of the CXXOperator* enumeration values.
151       if (getExtra()->ExtraKindOrNumArgs <
152             DeclarationNameExtra::CXXUsingDirective)
153         return CXXOperatorName;
154
155       return ObjCMultiArgSelector;
156     }
157     break;
158   }
159
160   // Can't actually get here.
161   assert(0 && "This should be unreachable!");
162   return Identifier;
163 }
164
165 std::string DeclarationName::getAsString() const {
166   switch (getNameKind()) {
167   case Identifier:
168     if (const IdentifierInfo *II = getAsIdentifierInfo())
169       return II->getName();
170     return "";
171
172   case ObjCZeroArgSelector:
173   case ObjCOneArgSelector:
174   case ObjCMultiArgSelector:
175     return getObjCSelector().getAsString();
176
177   case CXXConstructorName: {
178     QualType ClassType = getCXXNameType();
179     if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
180       return ClassRec->getDecl()->getNameAsString();
181     return ClassType.getAsString();
182   }
183
184   case CXXDestructorName: {
185     std::string Result = "~";
186     QualType Type = getCXXNameType();
187     if (const RecordType *Rec = Type->getAs<RecordType>())
188       Result += Rec->getDecl()->getNameAsString();
189     else
190       Result += Type.getAsString();
191     return Result;
192   }
193
194   case CXXOperatorName: {
195     static const char *OperatorNames[NUM_OVERLOADED_OPERATORS] = {
196       0,
197 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
198       Spelling,
199 #include "clang/Basic/OperatorKinds.def"
200     };
201     const char *OpName = OperatorNames[getCXXOverloadedOperator()];
202     assert(OpName && "not an overloaded operator");
203
204     std::string Result = "operator";
205     if (OpName[0] >= 'a' && OpName[0] <= 'z')
206       Result += ' ';
207     Result += OpName;
208     return Result;
209   }
210
211   case CXXConversionFunctionName: {
212     std::string Result = "operator ";
213     QualType Type = getCXXNameType();
214     if (const RecordType *Rec = Type->getAs<RecordType>())
215       Result += Rec->getDecl()->getNameAsString();
216     else
217       Result += Type.getAsString();
218     return Result;
219   }
220   case CXXUsingDirective:
221     return "<using-directive>";
222   }
223
224   assert(false && "Unexpected declaration name kind");
225   return "";
226 }
227
228 QualType DeclarationName::getCXXNameType() const {
229   if (CXXSpecialName *CXXName = getAsCXXSpecialName())
230     return CXXName->Type;
231   else
232     return QualType();
233 }
234
235 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
236   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
237     unsigned value
238       = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
239     return static_cast<OverloadedOperatorKind>(value);
240   } else {
241     return OO_None;
242   }
243 }
244
245 Selector DeclarationName::getObjCSelector() const {
246   switch (getNameKind()) {
247   case ObjCZeroArgSelector:
248     return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
249
250   case ObjCOneArgSelector:
251     return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
252
253   case ObjCMultiArgSelector:
254     return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
255
256   default:
257     break;
258   }
259
260   return Selector();
261 }
262
263 void *DeclarationName::getFETokenInfoAsVoid() const {
264   switch (getNameKind()) {
265   case Identifier:
266     return getAsIdentifierInfo()->getFETokenInfo<void>();
267
268   case CXXConstructorName:
269   case CXXDestructorName:
270   case CXXConversionFunctionName:
271     return getAsCXXSpecialName()->FETokenInfo;
272
273   case CXXOperatorName:
274     return getAsCXXOperatorIdName()->FETokenInfo;
275
276   default:
277     assert(false && "Declaration name has no FETokenInfo");
278   }
279   return 0;
280 }
281
282 void DeclarationName::setFETokenInfo(void *T) {
283   switch (getNameKind()) {
284   case Identifier:
285     getAsIdentifierInfo()->setFETokenInfo(T);
286     break;
287
288   case CXXConstructorName:
289   case CXXDestructorName:
290   case CXXConversionFunctionName:
291     getAsCXXSpecialName()->FETokenInfo = T;
292     break;
293
294   case CXXOperatorName:
295     getAsCXXOperatorIdName()->FETokenInfo = T;
296     break;
297
298   default:
299     assert(false && "Declaration name has no FETokenInfo");
300   }
301 }
302
303 DeclarationName DeclarationName::getUsingDirectiveName() {
304   // Single instance of DeclarationNameExtra for using-directive
305   static DeclarationNameExtra UDirExtra =
306     { DeclarationNameExtra::CXXUsingDirective };
307
308   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
309   Ptr |= StoredDeclarationNameExtra;
310
311   return DeclarationName(Ptr);
312 }
313
314 void DeclarationName::dump() const {
315   fprintf(stderr, "%s\n", getAsString().c_str());
316 }
317
318 DeclarationNameTable::DeclarationNameTable() {
319   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
320
321   // Initialize the overloaded operator names.
322   CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
323   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
324     CXXOperatorNames[Op].ExtraKindOrNumArgs
325       = Op + DeclarationNameExtra::CXXConversionFunction;
326     CXXOperatorNames[Op].FETokenInfo = 0;
327   }
328 }
329
330 DeclarationNameTable::~DeclarationNameTable() {
331   llvm::FoldingSet<CXXSpecialName> *set =
332     static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
333   llvm::FoldingSetIterator<CXXSpecialName> I = set->begin(), E = set->end();
334
335   while (I != E) {
336     CXXSpecialName *n = &*I++;
337     delete n;
338   }
339
340   delete set;
341   delete [] CXXOperatorNames;
342 }
343
344 DeclarationName
345 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
346                                         CanQualType Ty) {
347   assert(Kind >= DeclarationName::CXXConstructorName &&
348          Kind <= DeclarationName::CXXConversionFunctionName &&
349          "Kind must be a C++ special name kind");
350   llvm::FoldingSet<CXXSpecialName> *SpecialNames
351     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
352
353   DeclarationNameExtra::ExtraKind EKind;
354   switch (Kind) {
355   case DeclarationName::CXXConstructorName:
356     EKind = DeclarationNameExtra::CXXConstructor;
357     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
358     break;
359   case DeclarationName::CXXDestructorName:
360     EKind = DeclarationNameExtra::CXXDestructor;
361     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
362     break;
363   case DeclarationName::CXXConversionFunctionName:
364     EKind = DeclarationNameExtra::CXXConversionFunction;
365     break;
366   default:
367     return DeclarationName();
368   }
369
370   // Unique selector, to guarantee there is one per name.
371   llvm::FoldingSetNodeID ID;
372   ID.AddInteger(EKind);
373   ID.AddPointer(Ty.getAsOpaquePtr());
374
375   void *InsertPos = 0;
376   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
377     return DeclarationName(Name);
378
379   CXXSpecialName *SpecialName = new CXXSpecialName;
380   SpecialName->ExtraKindOrNumArgs = EKind;
381   SpecialName->Type = Ty;
382   SpecialName->FETokenInfo = 0;
383
384   SpecialNames->InsertNode(SpecialName, InsertPos);
385   return DeclarationName(SpecialName);
386 }
387
388 DeclarationName
389 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
390   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
391 }
392
393 unsigned
394 llvm::DenseMapInfo<clang::DeclarationName>::
395 getHashValue(clang::DeclarationName N) {
396   return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
397 }
398