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