]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / tools / clang / 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/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
26
27 namespace clang {
28 /// CXXSpecialName - Records the type associated with one of the
29 /// "special" kinds of declaration names in C++, e.g., constructors,
30 /// destructors, and conversion functions.
31 class CXXSpecialName
32   : public DeclarationNameExtra, public llvm::FoldingSetNode {
33 public:
34   /// Type - The type associated with this declaration name.
35   QualType Type;
36
37   /// FETokenInfo - Extra information associated with this declaration
38   /// name that can be used by the front end.
39   void *FETokenInfo;
40
41   void Profile(llvm::FoldingSetNodeID &ID) {
42     ID.AddInteger(ExtraKindOrNumArgs);
43     ID.AddPointer(Type.getAsOpaquePtr());
44   }
45 };
46
47 /// CXXOperatorIdName - Contains extra information for the name of an
48 /// overloaded operator in C++, such as "operator+.
49 class CXXOperatorIdName : public DeclarationNameExtra {
50 public:
51   /// FETokenInfo - Extra information associated with this operator
52   /// name that can be used by the front end.
53   void *FETokenInfo;
54 };
55
56 /// CXXLiberalOperatorName - Contains the actual identifier that makes up the
57 /// name.
58 ///
59 /// This identifier is stored here rather than directly in DeclarationName so as
60 /// to allow Objective-C selectors, which are about a million times more common,
61 /// to consume minimal memory.
62 class CXXLiteralOperatorIdName
63   : public DeclarationNameExtra, public llvm::FoldingSetNode {
64 public:
65   IdentifierInfo *ID;
66
67   void Profile(llvm::FoldingSetNodeID &FSID) {
68     FSID.AddPointer(ID);
69   }
70 };
71
72 static int compareInt(unsigned A, unsigned B) {
73   return (A < B ? -1 : (A > B ? 1 : 0));
74 }
75
76 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
77   if (LHS.getNameKind() != RHS.getNameKind())
78     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
79   
80   switch (LHS.getNameKind()) {
81   case DeclarationName::Identifier: {
82     IdentifierInfo *LII = LHS.getAsIdentifierInfo();
83     IdentifierInfo *RII = RHS.getAsIdentifierInfo();
84     if (!LII) return RII ? -1 : 0;
85     if (!RII) return 1;
86     
87     return LII->getName().compare(RII->getName());
88   }
89
90   case DeclarationName::ObjCZeroArgSelector:
91   case DeclarationName::ObjCOneArgSelector:
92   case DeclarationName::ObjCMultiArgSelector: {
93     Selector LHSSelector = LHS.getObjCSelector();
94     Selector RHSSelector = RHS.getObjCSelector();
95     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
96     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
97       switch (LHSSelector.getNameForSlot(I).compare(
98                                                RHSSelector.getNameForSlot(I))) {
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   llvm_unreachable("This should be unreachable!");
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(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   llvm_unreachable("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     llvm_unreachable("Declaration name has no FETokenInfo");
341   }
342 }
343
344 void DeclarationName::setFETokenInfo(void *T) {
345   switch (getNameKind()) {
346   case Identifier:
347     getAsIdentifierInfo()->setFETokenInfo(T);
348     break;
349
350   case CXXConstructorName:
351   case CXXDestructorName:
352   case CXXConversionFunctionName:
353     getAsCXXSpecialName()->FETokenInfo = T;
354     break;
355
356   case CXXOperatorName:
357     getAsCXXOperatorIdName()->FETokenInfo = T;
358     break;
359
360   case CXXLiteralOperatorName:
361     getCXXLiteralIdentifier()->setFETokenInfo(T);
362     break;
363
364   default:
365     llvm_unreachable("Declaration name has no FETokenInfo");
366   }
367 }
368
369 DeclarationName DeclarationName::getUsingDirectiveName() {
370   // Single instance of DeclarationNameExtra for using-directive
371   static const DeclarationNameExtra UDirExtra =
372     { DeclarationNameExtra::CXXUsingDirective };
373
374   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
375   Ptr |= StoredDeclarationNameExtra;
376
377   return DeclarationName(Ptr);
378 }
379
380 void DeclarationName::dump() const {
381   printName(llvm::errs());
382   llvm::errs() << '\n';
383 }
384
385 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
386   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
387   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
388
389   // Initialize the overloaded operator names.
390   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
391   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
392     CXXOperatorNames[Op].ExtraKindOrNumArgs
393       = Op + DeclarationNameExtra::CXXConversionFunction;
394     CXXOperatorNames[Op].FETokenInfo = 0;
395   }
396 }
397
398 DeclarationNameTable::~DeclarationNameTable() {
399   llvm::FoldingSet<CXXSpecialName> *SpecialNames =
400     static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
401   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
402     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
403         (CXXLiteralOperatorNames);
404
405   delete SpecialNames;
406   delete LiteralNames;
407 }
408
409 DeclarationName
410 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
411                                         CanQualType Ty) {
412   assert(Kind >= DeclarationName::CXXConstructorName &&
413          Kind <= DeclarationName::CXXConversionFunctionName &&
414          "Kind must be a C++ special name kind");
415   llvm::FoldingSet<CXXSpecialName> *SpecialNames
416     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
417
418   DeclarationNameExtra::ExtraKind EKind;
419   switch (Kind) {
420   case DeclarationName::CXXConstructorName:
421     EKind = DeclarationNameExtra::CXXConstructor;
422     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
423     break;
424   case DeclarationName::CXXDestructorName:
425     EKind = DeclarationNameExtra::CXXDestructor;
426     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
427     break;
428   case DeclarationName::CXXConversionFunctionName:
429     EKind = DeclarationNameExtra::CXXConversionFunction;
430     break;
431   default:
432     return DeclarationName();
433   }
434
435   // Unique selector, to guarantee there is one per name.
436   llvm::FoldingSetNodeID ID;
437   ID.AddInteger(EKind);
438   ID.AddPointer(Ty.getAsOpaquePtr());
439
440   void *InsertPos = 0;
441   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
442     return DeclarationName(Name);
443
444   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
445   SpecialName->ExtraKindOrNumArgs = EKind;
446   SpecialName->Type = Ty;
447   SpecialName->FETokenInfo = 0;
448
449   SpecialNames->InsertNode(SpecialName, InsertPos);
450   return DeclarationName(SpecialName);
451 }
452
453 DeclarationName
454 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
455   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
456 }
457
458 DeclarationName
459 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
460   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
461     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
462                                                       (CXXLiteralOperatorNames);
463
464   llvm::FoldingSetNodeID ID;
465   ID.AddPointer(II);
466
467   void *InsertPos = 0;
468   if (CXXLiteralOperatorIdName *Name =
469                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
470     return DeclarationName (Name);
471   
472   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
473   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
474   LiteralName->ID = II;
475
476   LiteralNames->InsertNode(LiteralName, InsertPos);
477   return DeclarationName(LiteralName);
478 }
479
480 unsigned
481 llvm::DenseMapInfo<clang::DeclarationName>::
482 getHashValue(clang::DeclarationName N) {
483   return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
484 }
485
486 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
487   switch (Name.getNameKind()) {
488   case DeclarationName::Identifier:
489     break;
490   case DeclarationName::CXXConstructorName:
491   case DeclarationName::CXXDestructorName:
492   case DeclarationName::CXXConversionFunctionName:
493     NamedType.TInfo = 0;
494     break;
495   case DeclarationName::CXXOperatorName:
496     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
497     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
498     break;
499   case DeclarationName::CXXLiteralOperatorName:
500     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
501     break;
502   case DeclarationName::ObjCZeroArgSelector:
503   case DeclarationName::ObjCOneArgSelector:
504   case DeclarationName::ObjCMultiArgSelector:
505     // FIXME: ?
506     break;
507   case DeclarationName::CXXUsingDirective:
508     break;
509   }
510 }
511
512 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
513   switch (Name.getNameKind()) {
514   case DeclarationName::Identifier:
515   case DeclarationName::ObjCZeroArgSelector:
516   case DeclarationName::ObjCOneArgSelector:
517   case DeclarationName::ObjCMultiArgSelector:
518   case DeclarationName::CXXOperatorName:
519   case DeclarationName::CXXLiteralOperatorName:
520   case DeclarationName::CXXUsingDirective:
521     return false;
522
523   case DeclarationName::CXXConstructorName:
524   case DeclarationName::CXXDestructorName:
525   case DeclarationName::CXXConversionFunctionName:
526     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
527       return TInfo->getType()->containsUnexpandedParameterPack();
528
529     return Name.getCXXNameType()->containsUnexpandedParameterPack();
530   }
531   llvm_unreachable("All name kinds handled.");
532 }
533
534 bool DeclarationNameInfo::isInstantiationDependent() const {
535   switch (Name.getNameKind()) {
536   case DeclarationName::Identifier:
537   case DeclarationName::ObjCZeroArgSelector:
538   case DeclarationName::ObjCOneArgSelector:
539   case DeclarationName::ObjCMultiArgSelector:
540   case DeclarationName::CXXOperatorName:
541   case DeclarationName::CXXLiteralOperatorName:
542   case DeclarationName::CXXUsingDirective:
543     return false;
544     
545   case DeclarationName::CXXConstructorName:
546   case DeclarationName::CXXDestructorName:
547   case DeclarationName::CXXConversionFunctionName:
548     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
549       return TInfo->getType()->isInstantiationDependentType();
550     
551     return Name.getCXXNameType()->isInstantiationDependentType();
552   }
553   llvm_unreachable("All name kinds handled.");
554 }
555
556 std::string DeclarationNameInfo::getAsString() const {
557   std::string Result;
558   llvm::raw_string_ostream OS(Result);
559   printName(OS);
560   return OS.str();
561 }
562
563 void DeclarationNameInfo::printName(raw_ostream &OS) const {
564   switch (Name.getNameKind()) {
565   case DeclarationName::Identifier:
566   case DeclarationName::ObjCZeroArgSelector:
567   case DeclarationName::ObjCOneArgSelector:
568   case DeclarationName::ObjCMultiArgSelector:
569   case DeclarationName::CXXOperatorName:
570   case DeclarationName::CXXLiteralOperatorName:
571   case DeclarationName::CXXUsingDirective:
572     Name.printName(OS);
573     return;
574
575   case DeclarationName::CXXConstructorName:
576   case DeclarationName::CXXDestructorName:
577   case DeclarationName::CXXConversionFunctionName:
578     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
579       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
580         OS << '~';
581       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
582         OS << "operator ";
583       OS << TInfo->getType().getAsString();
584     }
585     else
586       Name.printName(OS);
587     return;
588   }
589   llvm_unreachable("Unexpected declaration name kind");
590 }
591
592 SourceLocation DeclarationNameInfo::getEndLoc() const {
593   switch (Name.getNameKind()) {
594   case DeclarationName::Identifier:
595     return NameLoc;
596
597   case DeclarationName::CXXOperatorName: {
598     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
599     return SourceLocation::getFromRawEncoding(raw);
600   }
601
602   case DeclarationName::CXXLiteralOperatorName: {
603     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
604     return SourceLocation::getFromRawEncoding(raw);
605   }
606
607   case DeclarationName::CXXConstructorName:
608   case DeclarationName::CXXDestructorName:
609   case DeclarationName::CXXConversionFunctionName:
610     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
611       return TInfo->getTypeLoc().getEndLoc();
612     else
613       return NameLoc;
614
615     // DNInfo work in progress: FIXME.
616   case DeclarationName::ObjCZeroArgSelector:
617   case DeclarationName::ObjCOneArgSelector:
618   case DeclarationName::ObjCMultiArgSelector:
619   case DeclarationName::CXXUsingDirective:
620     return NameLoc;
621   }
622   llvm_unreachable("Unexpected declaration name kind");
623 }