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