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