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