]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp
MFC r234353:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / AST / TemplateBase.cpp
1 //===--- TemplateBase.cpp - Common template AST class implementation ------===//
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 common classes used throughout C++ template
11 // representations.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/AST/TemplateBase.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/DeclBase.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/Type.h"
22 #include "clang/AST/TypeLoc.h"
23 #include "clang/Basic/Diagnostic.h"
24 #include "llvm/ADT/FoldingSet.h"
25 #include "llvm/ADT/SmallString.h"
26 #include <algorithm>
27 #include <cctype>
28
29 using namespace clang;
30
31 /// \brief Print a template integral argument value.
32 ///
33 /// \param TemplArg the TemplateArgument instance to print.
34 ///
35 /// \param Out the raw_ostream instance to use for printing.
36 static void printIntegral(const TemplateArgument &TemplArg,
37                           raw_ostream &Out) {
38   const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
39   const llvm::APSInt *Val = TemplArg.getAsIntegral();
40
41   if (T->isBooleanType()) {
42     Out << (Val->getBoolValue() ? "true" : "false");
43   } else if (T->isCharType()) {
44     const char Ch = Val->getZExtValue();
45     Out << ((Ch == '\'') ? "'\\" : "'");
46     Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
47     Out << "'";
48   } else {
49     Out << Val->toString(10);
50   }
51 }
52
53 //===----------------------------------------------------------------------===//
54 // TemplateArgument Implementation
55 //===----------------------------------------------------------------------===//
56
57 TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
58                                                   const TemplateArgument *Args,
59                                                   unsigned NumArgs) {
60   if (NumArgs == 0)
61     return TemplateArgument(0, 0);
62   
63   TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
64   std::copy(Args, Args + NumArgs, Storage);
65   return TemplateArgument(Storage, NumArgs);
66 }
67
68 bool TemplateArgument::isDependent() const {
69   switch (getKind()) {
70   case Null:
71     llvm_unreachable("Should not have a NULL template argument");
72
73   case Type:
74     return getAsType()->isDependentType();
75
76   case Template:
77     return getAsTemplate().isDependent();
78
79   case TemplateExpansion:
80     return true;
81
82   case Declaration:
83     if (Decl *D = getAsDecl()) {
84       if (DeclContext *DC = dyn_cast<DeclContext>(D))
85         return DC->isDependentContext();
86       return D->getDeclContext()->isDependentContext();
87     }
88       
89     return false;
90
91   case Integral:
92     // Never dependent
93     return false;
94
95   case Expression:
96     return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
97
98   case Pack:
99     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
100       if (P->isDependent())
101         return true;
102     }
103
104     return false;
105   }
106
107   llvm_unreachable("Invalid TemplateArgument Kind!");
108 }
109
110 bool TemplateArgument::isInstantiationDependent() const {
111   switch (getKind()) {
112   case Null:
113     llvm_unreachable("Should not have a NULL template argument");
114     
115   case Type:
116     return getAsType()->isInstantiationDependentType();
117     
118   case Template:
119     return getAsTemplate().isInstantiationDependent();
120     
121   case TemplateExpansion:
122     return true;
123     
124   case Declaration:
125     if (Decl *D = getAsDecl()) {
126       if (DeclContext *DC = dyn_cast<DeclContext>(D))
127         return DC->isDependentContext();
128       return D->getDeclContext()->isDependentContext();
129     }
130     return false;
131       
132   case Integral:
133     // Never dependent
134     return false;
135     
136   case Expression:
137     return getAsExpr()->isInstantiationDependent();
138     
139   case Pack:
140     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
141       if (P->isInstantiationDependent())
142         return true;
143     }
144     
145     return false;
146   }
147
148   llvm_unreachable("Invalid TemplateArgument Kind!");
149 }
150
151 bool TemplateArgument::isPackExpansion() const {
152   switch (getKind()) {
153   case Null:
154   case Declaration:
155   case Integral:
156   case Pack:    
157   case Template:
158     return false;
159       
160   case TemplateExpansion:
161     return true;
162       
163   case Type:
164     return isa<PackExpansionType>(getAsType());
165           
166   case Expression:
167     return isa<PackExpansionExpr>(getAsExpr());
168   }
169
170   llvm_unreachable("Invalid TemplateArgument Kind!");
171 }
172
173 bool TemplateArgument::containsUnexpandedParameterPack() const {
174   switch (getKind()) {
175   case Null:
176   case Declaration:
177   case Integral:
178   case TemplateExpansion:
179     break;
180
181   case Type:
182     if (getAsType()->containsUnexpandedParameterPack())
183       return true;
184     break;
185
186   case Template:
187     if (getAsTemplate().containsUnexpandedParameterPack())
188       return true;
189     break;
190         
191   case Expression:
192     if (getAsExpr()->containsUnexpandedParameterPack())
193       return true;
194     break;
195
196   case Pack:
197     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
198       if (P->containsUnexpandedParameterPack())
199         return true;
200
201     break;
202   }
203
204   return false;
205 }
206
207 llvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
208   assert(Kind == TemplateExpansion);
209   if (TemplateArg.NumExpansions)
210     return TemplateArg.NumExpansions - 1;
211   
212   return llvm::Optional<unsigned>();
213 }
214
215 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
216                                const ASTContext &Context) const {
217   ID.AddInteger(Kind);
218   switch (Kind) {
219   case Null:
220     break;
221
222   case Type:
223     getAsType().Profile(ID);
224     break;
225
226   case Declaration:
227     ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
228     break;
229
230   case Template:
231   case TemplateExpansion: {
232     TemplateName Template = getAsTemplateOrTemplatePattern();
233     if (TemplateTemplateParmDecl *TTP
234           = dyn_cast_or_null<TemplateTemplateParmDecl>(
235                                                 Template.getAsTemplateDecl())) {
236       ID.AddBoolean(true);
237       ID.AddInteger(TTP->getDepth());
238       ID.AddInteger(TTP->getPosition());
239       ID.AddBoolean(TTP->isParameterPack());
240     } else {
241       ID.AddBoolean(false);
242       ID.AddPointer(Context.getCanonicalTemplateName(Template)
243                                                           .getAsVoidPointer());
244     }
245     break;
246   }
247       
248   case Integral:
249     getAsIntegral()->Profile(ID);
250     getIntegralType().Profile(ID);
251     break;
252
253   case Expression:
254     getAsExpr()->Profile(ID, Context, true);
255     break;
256
257   case Pack:
258     ID.AddInteger(Args.NumArgs);
259     for (unsigned I = 0; I != Args.NumArgs; ++I)
260       Args.Args[I].Profile(ID, Context);
261   }
262 }
263
264 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
265   if (getKind() != Other.getKind()) return false;
266
267   switch (getKind()) {
268   case Null:
269   case Type:
270   case Declaration:
271   case Expression:      
272   case Template:
273   case TemplateExpansion:
274     return TypeOrValue == Other.TypeOrValue;
275
276   case Integral:
277     return getIntegralType() == Other.getIntegralType() &&
278            *getAsIntegral() == *Other.getAsIntegral();
279
280   case Pack:
281     if (Args.NumArgs != Other.Args.NumArgs) return false;
282     for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
283       if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
284         return false;
285     return true;
286   }
287
288   llvm_unreachable("Invalid TemplateArgument Kind!");
289 }
290
291 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
292   assert(isPackExpansion());
293   
294   switch (getKind()) {
295   case Type:
296     return getAsType()->getAs<PackExpansionType>()->getPattern();
297     
298   case Expression:
299     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
300     
301   case TemplateExpansion:
302     return TemplateArgument(getAsTemplateOrTemplatePattern());
303     
304   case Declaration:
305   case Integral:
306   case Pack:
307   case Null:
308   case Template:
309     return TemplateArgument();
310   }
311
312   llvm_unreachable("Invalid TemplateArgument Kind!");
313 }
314
315 void TemplateArgument::print(const PrintingPolicy &Policy, 
316                              raw_ostream &Out) const {
317   switch (getKind()) {
318   case Null:
319     Out << "<no value>";
320     break;
321     
322   case Type: {
323     PrintingPolicy SubPolicy(Policy);
324     SubPolicy.SuppressStrongLifetime = true;
325     std::string TypeStr;
326     getAsType().getAsStringInternal(TypeStr, SubPolicy);
327     Out << TypeStr;
328     break;
329   }
330     
331   case Declaration: {
332     if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
333       if (ND->getDeclName()) {
334         Out << *ND;
335       } else {
336         Out << "<anonymous>";
337       }
338     } else {
339       Out << "nullptr";
340     }
341     break;
342   }
343     
344   case Template:
345     getAsTemplate().print(Out, Policy);
346     break;
347
348   case TemplateExpansion:
349     getAsTemplateOrTemplatePattern().print(Out, Policy);
350     Out << "...";
351     break;
352       
353   case Integral: {
354     printIntegral(*this, Out);
355     break;
356   }
357     
358   case Expression:
359     getAsExpr()->printPretty(Out, 0, Policy);
360     break;
361     
362   case Pack:
363     Out << "<";
364     bool First = true;
365     for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
366          P != PEnd; ++P) {
367       if (First)
368         First = false;
369       else
370         Out << ", ";
371       
372       P->print(Policy, Out);
373     }
374     Out << ">";
375     break;        
376   }
377 }
378
379 //===----------------------------------------------------------------------===//
380 // TemplateArgumentLoc Implementation
381 //===----------------------------------------------------------------------===//
382
383 TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
384   memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
385 }
386
387 SourceRange TemplateArgumentLoc::getSourceRange() const {
388   switch (Argument.getKind()) {
389   case TemplateArgument::Expression:
390     return getSourceExpression()->getSourceRange();
391
392   case TemplateArgument::Declaration:
393     return getSourceDeclExpression()->getSourceRange();
394
395   case TemplateArgument::Type:
396     if (TypeSourceInfo *TSI = getTypeSourceInfo())
397       return TSI->getTypeLoc().getSourceRange();
398     else
399       return SourceRange();
400
401   case TemplateArgument::Template:
402     if (getTemplateQualifierLoc())
403       return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 
404                          getTemplateNameLoc());
405     return SourceRange(getTemplateNameLoc());
406
407   case TemplateArgument::TemplateExpansion:
408     if (getTemplateQualifierLoc())
409       return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 
410                          getTemplateEllipsisLoc());
411     return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
412
413   case TemplateArgument::Integral:
414   case TemplateArgument::Pack:
415   case TemplateArgument::Null:
416     return SourceRange();
417   }
418
419   llvm_unreachable("Invalid TemplateArgument Kind!");
420 }
421
422 TemplateArgumentLoc 
423 TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
424                                        llvm::Optional<unsigned> &NumExpansions,
425                                              ASTContext &Context) const {
426   assert(Argument.isPackExpansion());
427   
428   switch (Argument.getKind()) {
429   case TemplateArgument::Type: {
430     // FIXME: We shouldn't ever have to worry about missing
431     // type-source info!
432     TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
433     if (!ExpansionTSInfo)
434       ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
435                                                      getArgument().getAsType(),
436                                                          Ellipsis);
437     PackExpansionTypeLoc Expansion
438       = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
439     Ellipsis = Expansion.getEllipsisLoc();
440     
441     TypeLoc Pattern = Expansion.getPatternLoc();
442     NumExpansions = Expansion.getTypePtr()->getNumExpansions();
443     
444     // FIXME: This is horrible. We know where the source location data is for
445     // the pattern, and we have the pattern's type, but we are forced to copy
446     // them into an ASTContext because TypeSourceInfo bundles them together
447     // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
448     TypeSourceInfo *PatternTSInfo
449       = Context.CreateTypeSourceInfo(Pattern.getType(),
450                                      Pattern.getFullDataSize());
451     memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(), 
452            Pattern.getOpaqueData(), Pattern.getFullDataSize());
453     return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
454                                PatternTSInfo);
455   }
456       
457   case TemplateArgument::Expression: {
458     PackExpansionExpr *Expansion
459       = cast<PackExpansionExpr>(Argument.getAsExpr());
460     Expr *Pattern = Expansion->getPattern();
461     Ellipsis = Expansion->getEllipsisLoc();
462     NumExpansions = Expansion->getNumExpansions();
463     return TemplateArgumentLoc(Pattern, Pattern);
464   }
465
466   case TemplateArgument::TemplateExpansion:
467     Ellipsis = getTemplateEllipsisLoc();
468     NumExpansions = Argument.getNumTemplateExpansions();
469     return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
470                                getTemplateQualifierLoc(),
471                                getTemplateNameLoc());
472     
473   case TemplateArgument::Declaration:
474   case TemplateArgument::Template:
475   case TemplateArgument::Integral:
476   case TemplateArgument::Pack:
477   case TemplateArgument::Null:
478     return TemplateArgumentLoc();
479   }
480
481   llvm_unreachable("Invalid TemplateArgument Kind!");
482 }
483
484 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
485                                            const TemplateArgument &Arg) {
486   switch (Arg.getKind()) {
487   case TemplateArgument::Null:
488     // This is bad, but not as bad as crashing because of argument
489     // count mismatches.
490     return DB << "(null template argument)";
491       
492   case TemplateArgument::Type:
493     return DB << Arg.getAsType();
494       
495   case TemplateArgument::Declaration:
496     if (Decl *D = Arg.getAsDecl())
497       return DB << D;
498     return DB << "nullptr";
499       
500   case TemplateArgument::Integral:
501     return DB << Arg.getAsIntegral()->toString(10);
502       
503   case TemplateArgument::Template:
504     return DB << Arg.getAsTemplate();
505
506   case TemplateArgument::TemplateExpansion:
507     return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
508
509   case TemplateArgument::Expression: {
510     // This shouldn't actually ever happen, so it's okay that we're
511     // regurgitating an expression here.
512     // FIXME: We're guessing at LangOptions!
513     SmallString<32> Str;
514     llvm::raw_svector_ostream OS(Str);
515     LangOptions LangOpts;
516     LangOpts.CPlusPlus = true;
517     PrintingPolicy Policy(LangOpts);
518     Arg.getAsExpr()->printPretty(OS, 0, Policy);
519     return DB << OS.str();
520   }
521       
522   case TemplateArgument::Pack: {
523     // FIXME: We're guessing at LangOptions!
524     SmallString<32> Str;
525     llvm::raw_svector_ostream OS(Str);
526     LangOptions LangOpts;
527     LangOpts.CPlusPlus = true;
528     PrintingPolicy Policy(LangOpts);
529     Arg.print(Policy, OS);
530     return DB << OS.str();
531   }
532   }
533
534   llvm_unreachable("Invalid TemplateArgument Kind!");
535 }
536
537 const ASTTemplateArgumentListInfo *
538 ASTTemplateArgumentListInfo::Create(ASTContext &C,
539                                     const TemplateArgumentListInfo &List) {
540   std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
541                      ASTTemplateArgumentListInfo::sizeFor(List.size());
542   void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
543   ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
544   TAI->initializeFrom(List);
545   return TAI;
546 }
547
548 void ASTTemplateArgumentListInfo::initializeFrom(
549                                       const TemplateArgumentListInfo &Info) {
550   LAngleLoc = Info.getLAngleLoc();
551   RAngleLoc = Info.getRAngleLoc();
552   NumTemplateArgs = Info.size();
553
554   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
555   for (unsigned i = 0; i != NumTemplateArgs; ++i)
556     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
557 }
558
559 void ASTTemplateArgumentListInfo::initializeFrom(
560                                           const TemplateArgumentListInfo &Info,
561                                                   bool &Dependent, 
562                                                   bool &InstantiationDependent,
563                                        bool &ContainsUnexpandedParameterPack) {
564   LAngleLoc = Info.getLAngleLoc();
565   RAngleLoc = Info.getRAngleLoc();
566   NumTemplateArgs = Info.size();
567
568   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
569   for (unsigned i = 0; i != NumTemplateArgs; ++i) {
570     Dependent = Dependent || Info[i].getArgument().isDependent();
571     InstantiationDependent = InstantiationDependent || 
572                              Info[i].getArgument().isInstantiationDependent();
573     ContainsUnexpandedParameterPack 
574       = ContainsUnexpandedParameterPack || 
575         Info[i].getArgument().containsUnexpandedParameterPack();
576
577     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
578   }
579 }
580
581 void ASTTemplateArgumentListInfo::copyInto(
582                                       TemplateArgumentListInfo &Info) const {
583   Info.setLAngleLoc(LAngleLoc);
584   Info.setRAngleLoc(RAngleLoc);
585   for (unsigned I = 0; I != NumTemplateArgs; ++I)
586     Info.addArgument(getTemplateArgs()[I]);
587 }
588
589 std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
590   return sizeof(ASTTemplateArgumentListInfo) +
591          sizeof(TemplateArgumentLoc) * NumTemplateArgs;
592 }
593
594 void
595 ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc,
596                                          const TemplateArgumentListInfo &Info) {
597   Base::initializeFrom(Info);
598   setTemplateKeywordLoc(TemplateKWLoc);
599 }
600
601 void
602 ASTTemplateKWAndArgsInfo
603 ::initializeFrom(SourceLocation TemplateKWLoc,
604                  const TemplateArgumentListInfo &Info,
605                  bool &Dependent,
606                  bool &InstantiationDependent,
607                  bool &ContainsUnexpandedParameterPack) {
608   Base::initializeFrom(Info, Dependent, InstantiationDependent,
609                        ContainsUnexpandedParameterPack);
610   setTemplateKeywordLoc(TemplateKWLoc);
611 }
612
613 void
614 ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
615   // No explicit template arguments, but template keyword loc is valid.
616   assert(TemplateKWLoc.isValid());
617   LAngleLoc = SourceLocation();
618   RAngleLoc = SourceLocation();
619   NumTemplateArgs = 0;
620   setTemplateKeywordLoc(TemplateKWLoc);
621 }
622
623 std::size_t
624 ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
625   // Add space for the template keyword location.
626   return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation);
627 }
628