]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.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   assert(0 && "This should be unreachable!");
197   return Identifier;
198 }
199
200 bool DeclarationName::isDependentName() const {
201   QualType T = getCXXNameType();
202   return !T.isNull() && T->isDependentType();
203 }
204
205 std::string DeclarationName::getAsString() const {
206   std::string Result;
207   llvm::raw_string_ostream OS(Result);
208   printName(OS);
209   return OS.str();
210 }
211
212 void DeclarationName::printName(llvm::raw_ostream &OS) const {
213   switch (getNameKind()) {
214   case Identifier:
215     if (const IdentifierInfo *II = getAsIdentifierInfo())
216       OS << II->getName();
217     return;
218
219   case ObjCZeroArgSelector:
220   case ObjCOneArgSelector:
221   case ObjCMultiArgSelector:
222     OS << getObjCSelector().getAsString();
223     return;
224
225   case CXXConstructorName: {
226     QualType ClassType = getCXXNameType();
227     if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
228       OS << ClassRec->getDecl();
229     else
230       OS << ClassType.getAsString();
231     return;
232   }
233
234   case CXXDestructorName: {
235     OS << '~';
236     QualType Type = getCXXNameType();
237     if (const RecordType *Rec = Type->getAs<RecordType>())
238       OS << Rec->getDecl();
239     else
240       OS << Type.getAsString();
241     return;
242   }
243
244   case CXXOperatorName: {
245     static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
246       0,
247 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
248       Spelling,
249 #include "clang/Basic/OperatorKinds.def"
250     };
251     const char *OpName = OperatorNames[getCXXOverloadedOperator()];
252     assert(OpName && "not an overloaded operator");
253
254     OS << "operator";
255     if (OpName[0] >= 'a' && OpName[0] <= 'z')
256       OS << ' ';
257     OS << OpName;
258     return;
259   }
260
261   case CXXLiteralOperatorName:
262     OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
263     return;
264
265   case CXXConversionFunctionName: {
266     OS << "operator ";
267     QualType Type = getCXXNameType();
268     if (const RecordType *Rec = Type->getAs<RecordType>())
269       OS << Rec->getDecl();
270     else
271       OS << Type.getAsString();
272     return;
273   }
274   case CXXUsingDirective:
275     OS << "<using-directive>";
276     return;
277   }
278
279   assert(false && "Unexpected declaration name kind");
280 }
281
282 QualType DeclarationName::getCXXNameType() const {
283   if (CXXSpecialName *CXXName = getAsCXXSpecialName())
284     return CXXName->Type;
285   else
286     return QualType();
287 }
288
289 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
290   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
291     unsigned value
292       = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
293     return static_cast<OverloadedOperatorKind>(value);
294   } else {
295     return OO_None;
296   }
297 }
298
299 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
300   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
301     return CXXLit->ID;
302   else
303     return 0;
304 }
305
306 Selector DeclarationName::getObjCSelector() const {
307   switch (getNameKind()) {
308   case ObjCZeroArgSelector:
309     return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
310
311   case ObjCOneArgSelector:
312     return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
313
314   case ObjCMultiArgSelector:
315     return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
316
317   default:
318     break;
319   }
320
321   return Selector();
322 }
323
324 void *DeclarationName::getFETokenInfoAsVoid() const {
325   switch (getNameKind()) {
326   case Identifier:
327     return getAsIdentifierInfo()->getFETokenInfo<void>();
328
329   case CXXConstructorName:
330   case CXXDestructorName:
331   case CXXConversionFunctionName:
332     return getAsCXXSpecialName()->FETokenInfo;
333
334   case CXXOperatorName:
335     return getAsCXXOperatorIdName()->FETokenInfo;
336
337   case CXXLiteralOperatorName:
338     return getCXXLiteralIdentifier()->getFETokenInfo<void>();
339
340   default:
341     assert(false && "Declaration name has no FETokenInfo");
342   }
343   return 0;
344 }
345
346 void DeclarationName::setFETokenInfo(void *T) {
347   switch (getNameKind()) {
348   case Identifier:
349     getAsIdentifierInfo()->setFETokenInfo(T);
350     break;
351
352   case CXXConstructorName:
353   case CXXDestructorName:
354   case CXXConversionFunctionName:
355     getAsCXXSpecialName()->FETokenInfo = T;
356     break;
357
358   case CXXOperatorName:
359     getAsCXXOperatorIdName()->FETokenInfo = T;
360     break;
361
362   case CXXLiteralOperatorName:
363     getCXXLiteralIdentifier()->setFETokenInfo(T);
364     break;
365
366   default:
367     assert(false && "Declaration name has no FETokenInfo");
368   }
369 }
370
371 DeclarationName DeclarationName::getUsingDirectiveName() {
372   // Single instance of DeclarationNameExtra for using-directive
373   static const DeclarationNameExtra UDirExtra =
374     { DeclarationNameExtra::CXXUsingDirective };
375
376   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
377   Ptr |= StoredDeclarationNameExtra;
378
379   return DeclarationName(Ptr);
380 }
381
382 void DeclarationName::dump() const {
383   printName(llvm::errs());
384   llvm::errs() << '\n';
385 }
386
387 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
388   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
389   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
390
391   // Initialize the overloaded operator names.
392   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
393   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
394     CXXOperatorNames[Op].ExtraKindOrNumArgs
395       = Op + DeclarationNameExtra::CXXConversionFunction;
396     CXXOperatorNames[Op].FETokenInfo = 0;
397   }
398 }
399
400 DeclarationNameTable::~DeclarationNameTable() {
401   llvm::FoldingSet<CXXSpecialName> *SpecialNames =
402     static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
403   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
404     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
405         (CXXLiteralOperatorNames);
406
407   delete SpecialNames;
408   delete LiteralNames;
409 }
410
411 DeclarationName
412 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
413                                         CanQualType Ty) {
414   assert(Kind >= DeclarationName::CXXConstructorName &&
415          Kind <= DeclarationName::CXXConversionFunctionName &&
416          "Kind must be a C++ special name kind");
417   llvm::FoldingSet<CXXSpecialName> *SpecialNames
418     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
419
420   DeclarationNameExtra::ExtraKind EKind;
421   switch (Kind) {
422   case DeclarationName::CXXConstructorName:
423     EKind = DeclarationNameExtra::CXXConstructor;
424     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
425     break;
426   case DeclarationName::CXXDestructorName:
427     EKind = DeclarationNameExtra::CXXDestructor;
428     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
429     break;
430   case DeclarationName::CXXConversionFunctionName:
431     EKind = DeclarationNameExtra::CXXConversionFunction;
432     break;
433   default:
434     return DeclarationName();
435   }
436
437   // Unique selector, to guarantee there is one per name.
438   llvm::FoldingSetNodeID ID;
439   ID.AddInteger(EKind);
440   ID.AddPointer(Ty.getAsOpaquePtr());
441
442   void *InsertPos = 0;
443   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
444     return DeclarationName(Name);
445
446   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
447   SpecialName->ExtraKindOrNumArgs = EKind;
448   SpecialName->Type = Ty;
449   SpecialName->FETokenInfo = 0;
450
451   SpecialNames->InsertNode(SpecialName, InsertPos);
452   return DeclarationName(SpecialName);
453 }
454
455 DeclarationName
456 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
457   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
458 }
459
460 DeclarationName
461 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
462   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
463     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
464                                                       (CXXLiteralOperatorNames);
465
466   llvm::FoldingSetNodeID ID;
467   ID.AddPointer(II);
468
469   void *InsertPos = 0;
470   if (CXXLiteralOperatorIdName *Name =
471                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
472     return DeclarationName (Name);
473   
474   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
475   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
476   LiteralName->ID = II;
477
478   LiteralNames->InsertNode(LiteralName, InsertPos);
479   return DeclarationName(LiteralName);
480 }
481
482 unsigned
483 llvm::DenseMapInfo<clang::DeclarationName>::
484 getHashValue(clang::DeclarationName N) {
485   return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
486 }
487
488 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
489   switch (Name.getNameKind()) {
490   case DeclarationName::Identifier:
491     break;
492   case DeclarationName::CXXConstructorName:
493   case DeclarationName::CXXDestructorName:
494   case DeclarationName::CXXConversionFunctionName:
495     NamedType.TInfo = 0;
496     break;
497   case DeclarationName::CXXOperatorName:
498     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
499     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
500     break;
501   case DeclarationName::CXXLiteralOperatorName:
502     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
503     break;
504   case DeclarationName::ObjCZeroArgSelector:
505   case DeclarationName::ObjCOneArgSelector:
506   case DeclarationName::ObjCMultiArgSelector:
507     // FIXME: ?
508     break;
509   case DeclarationName::CXXUsingDirective:
510     break;
511   }
512 }
513
514 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
515   switch (Name.getNameKind()) {
516   case DeclarationName::Identifier:
517   case DeclarationName::ObjCZeroArgSelector:
518   case DeclarationName::ObjCOneArgSelector:
519   case DeclarationName::ObjCMultiArgSelector:
520   case DeclarationName::CXXOperatorName:
521   case DeclarationName::CXXLiteralOperatorName:
522   case DeclarationName::CXXUsingDirective:
523     return false;
524
525   case DeclarationName::CXXConstructorName:
526   case DeclarationName::CXXDestructorName:
527   case DeclarationName::CXXConversionFunctionName:
528     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
529       return TInfo->getType()->containsUnexpandedParameterPack();
530
531     return Name.getCXXNameType()->containsUnexpandedParameterPack();
532   }
533   llvm_unreachable("All name kinds handled.");
534 }
535
536 bool DeclarationNameInfo::isInstantiationDependent() const {
537   switch (Name.getNameKind()) {
538   case DeclarationName::Identifier:
539   case DeclarationName::ObjCZeroArgSelector:
540   case DeclarationName::ObjCOneArgSelector:
541   case DeclarationName::ObjCMultiArgSelector:
542   case DeclarationName::CXXOperatorName:
543   case DeclarationName::CXXLiteralOperatorName:
544   case DeclarationName::CXXUsingDirective:
545     return false;
546     
547   case DeclarationName::CXXConstructorName:
548   case DeclarationName::CXXDestructorName:
549   case DeclarationName::CXXConversionFunctionName:
550     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
551       return TInfo->getType()->isInstantiationDependentType();
552     
553     return Name.getCXXNameType()->isInstantiationDependentType();
554   }
555   llvm_unreachable("All name kinds handled.");
556 }
557
558 std::string DeclarationNameInfo::getAsString() const {
559   std::string Result;
560   llvm::raw_string_ostream OS(Result);
561   printName(OS);
562   return OS.str();
563 }
564
565 void DeclarationNameInfo::printName(llvm::raw_ostream &OS) const {
566   switch (Name.getNameKind()) {
567   case DeclarationName::Identifier:
568   case DeclarationName::ObjCZeroArgSelector:
569   case DeclarationName::ObjCOneArgSelector:
570   case DeclarationName::ObjCMultiArgSelector:
571   case DeclarationName::CXXOperatorName:
572   case DeclarationName::CXXLiteralOperatorName:
573   case DeclarationName::CXXUsingDirective:
574     Name.printName(OS);
575     return;
576
577   case DeclarationName::CXXConstructorName:
578   case DeclarationName::CXXDestructorName:
579   case DeclarationName::CXXConversionFunctionName:
580     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
581       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
582         OS << '~';
583       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
584         OS << "operator ";
585       OS << TInfo->getType().getAsString();
586     }
587     else
588       Name.printName(OS);
589     return;
590   }
591   assert(false && "Unexpected declaration name kind");
592 }
593
594 SourceLocation DeclarationNameInfo::getEndLoc() const {
595   switch (Name.getNameKind()) {
596   case DeclarationName::Identifier:
597     return NameLoc;
598
599   case DeclarationName::CXXOperatorName: {
600     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
601     return SourceLocation::getFromRawEncoding(raw);
602   }
603
604   case DeclarationName::CXXLiteralOperatorName: {
605     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
606     return SourceLocation::getFromRawEncoding(raw);
607   }
608
609   case DeclarationName::CXXConstructorName:
610   case DeclarationName::CXXDestructorName:
611   case DeclarationName::CXXConversionFunctionName:
612     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
613       return TInfo->getTypeLoc().getEndLoc();
614     else
615       return NameLoc;
616
617     // DNInfo work in progress: FIXME.
618   case DeclarationName::ObjCZeroArgSelector:
619   case DeclarationName::ObjCOneArgSelector:
620   case DeclarationName::ObjCMultiArgSelector:
621   case DeclarationName::CXXUsingDirective:
622     return NameLoc;
623   }
624   assert(false && "Unexpected declaration name kind");
625   return SourceLocation();
626 }