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