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