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