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 "llvm/Support/raw_ostream.h"
27 #include <algorithm>
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;
50   }
51 }
52 
53 //===----------------------------------------------------------------------===//
54 // TemplateArgument Implementation
55 //===----------------------------------------------------------------------===//
56 
57 TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
58                                    QualType Type) {
59   Integer.Kind = Integral;
60   // Copy the APSInt value into our decomposed form.
61   Integer.BitWidth = Value.getBitWidth();
62   Integer.IsUnsigned = Value.isUnsigned();
63   // If the value is large, we have to get additional memory from the ASTContext
64   unsigned NumWords = Value.getNumWords();
65   if (NumWords > 1) {
66     void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
67     std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
68     Integer.pVal = static_cast<uint64_t *>(Mem);
69   } else {
70     Integer.VAL = Value.getZExtValue();
71   }
72 
73   Integer.Type = Type.getAsOpaquePtr();
74 }
75 
76 TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
77                                                   const TemplateArgument *Args,
78                                                   unsigned NumArgs) {
79   if (NumArgs == 0)
80     return getEmptyPack();
81 
82   TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
83   std::copy(Args, Args + NumArgs, Storage);
84   return TemplateArgument(Storage, NumArgs);
85 }
86 
87 bool TemplateArgument::isDependent() const {
88   switch (getKind()) {
89   case Null:
90     llvm_unreachable("Should not have a NULL template argument");
91 
92   case Type:
93     return getAsType()->isDependentType() ||
94            isa<PackExpansionType>(getAsType());
95 
96   case Template:
97     return getAsTemplate().isDependent();
98 
99   case TemplateExpansion:
100     return true;
101 
102   case Declaration:
103     if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
104       return DC->isDependentContext();
105     return getAsDecl()->getDeclContext()->isDependentContext();
106 
107   case NullPtr:
108     return false;
109 
110   case Integral:
111     // Never dependent
112     return false;
113 
114   case Expression:
115     return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
116             isa<PackExpansionExpr>(getAsExpr()));
117 
118   case Pack:
119     for (const auto &P : pack_elements())
120       if (P.isDependent())
121         return true;
122     return false;
123   }
124 
125   llvm_unreachable("Invalid TemplateArgument Kind!");
126 }
127 
128 bool TemplateArgument::isInstantiationDependent() const {
129   switch (getKind()) {
130   case Null:
131     llvm_unreachable("Should not have a NULL template argument");
132 
133   case Type:
134     return getAsType()->isInstantiationDependentType();
135 
136   case Template:
137     return getAsTemplate().isInstantiationDependent();
138 
139   case TemplateExpansion:
140     return true;
141 
142   case Declaration:
143     if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
144       return DC->isDependentContext();
145     return getAsDecl()->getDeclContext()->isDependentContext();
146 
147   case NullPtr:
148     return false;
149 
150   case Integral:
151     // Never dependent
152     return false;
153 
154   case Expression:
155     return getAsExpr()->isInstantiationDependent();
156 
157   case Pack:
158     for (const auto &P : pack_elements())
159       if (P.isInstantiationDependent())
160         return true;
161     return false;
162   }
163 
164   llvm_unreachable("Invalid TemplateArgument Kind!");
165 }
166 
167 bool TemplateArgument::isPackExpansion() const {
168   switch (getKind()) {
169   case Null:
170   case Declaration:
171   case Integral:
172   case Pack:
173   case Template:
174   case NullPtr:
175     return false;
176 
177   case TemplateExpansion:
178     return true;
179 
180   case Type:
181     return isa<PackExpansionType>(getAsType());
182 
183   case Expression:
184     return isa<PackExpansionExpr>(getAsExpr());
185   }
186 
187   llvm_unreachable("Invalid TemplateArgument Kind!");
188 }
189 
190 bool TemplateArgument::containsUnexpandedParameterPack() const {
191   switch (getKind()) {
192   case Null:
193   case Declaration:
194   case Integral:
195   case TemplateExpansion:
196   case NullPtr:
197     break;
198 
199   case Type:
200     if (getAsType()->containsUnexpandedParameterPack())
201       return true;
202     break;
203 
204   case Template:
205     if (getAsTemplate().containsUnexpandedParameterPack())
206       return true;
207     break;
208 
209   case Expression:
210     if (getAsExpr()->containsUnexpandedParameterPack())
211       return true;
212     break;
213 
214   case Pack:
215     for (const auto &P : pack_elements())
216       if (P.containsUnexpandedParameterPack())
217         return true;
218 
219     break;
220   }
221 
222   return false;
223 }
224 
225 Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
226   assert(getKind() == TemplateExpansion);
227   if (TemplateArg.NumExpansions)
228     return TemplateArg.NumExpansions - 1;
229 
230   return None;
231 }
232 
233 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
234                                const ASTContext &Context) const {
235   ID.AddInteger(getKind());
236   switch (getKind()) {
237   case Null:
238     break;
239 
240   case Type:
241     getAsType().Profile(ID);
242     break;
243 
244   case NullPtr:
245     getNullPtrType().Profile(ID);
246     break;
247 
248   case Declaration:
249     ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
250     break;
251 
252   case Template:
253   case TemplateExpansion: {
254     TemplateName Template = getAsTemplateOrTemplatePattern();
255     if (TemplateTemplateParmDecl *TTP
256           = dyn_cast_or_null<TemplateTemplateParmDecl>(
257                                                 Template.getAsTemplateDecl())) {
258       ID.AddBoolean(true);
259       ID.AddInteger(TTP->getDepth());
260       ID.AddInteger(TTP->getPosition());
261       ID.AddBoolean(TTP->isParameterPack());
262     } else {
263       ID.AddBoolean(false);
264       ID.AddPointer(Context.getCanonicalTemplateName(Template)
265                                                           .getAsVoidPointer());
266     }
267     break;
268   }
269 
270   case Integral:
271     getAsIntegral().Profile(ID);
272     getIntegralType().Profile(ID);
273     break;
274 
275   case Expression:
276     getAsExpr()->Profile(ID, Context, true);
277     break;
278 
279   case Pack:
280     ID.AddInteger(Args.NumArgs);
281     for (unsigned I = 0; I != Args.NumArgs; ++I)
282       Args.Args[I].Profile(ID, Context);
283   }
284 }
285 
286 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
287   if (getKind() != Other.getKind()) return false;
288 
289   switch (getKind()) {
290   case Null:
291   case Type:
292   case Expression:
293   case Template:
294   case TemplateExpansion:
295   case NullPtr:
296     return TypeOrValue.V == Other.TypeOrValue.V;
297 
298   case Declaration:
299     return getAsDecl() == Other.getAsDecl();
300 
301   case Integral:
302     return getIntegralType() == Other.getIntegralType() &&
303            getAsIntegral() == Other.getAsIntegral();
304 
305   case Pack:
306     if (Args.NumArgs != Other.Args.NumArgs) return false;
307     for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
308       if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
309         return false;
310     return true;
311   }
312 
313   llvm_unreachable("Invalid TemplateArgument Kind!");
314 }
315 
316 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
317   assert(isPackExpansion());
318 
319   switch (getKind()) {
320   case Type:
321     return getAsType()->getAs<PackExpansionType>()->getPattern();
322 
323   case Expression:
324     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
325 
326   case TemplateExpansion:
327     return TemplateArgument(getAsTemplateOrTemplatePattern());
328 
329   case Declaration:
330   case Integral:
331   case Pack:
332   case Null:
333   case Template:
334   case NullPtr:
335     return TemplateArgument();
336   }
337 
338   llvm_unreachable("Invalid TemplateArgument Kind!");
339 }
340 
341 void TemplateArgument::print(const PrintingPolicy &Policy,
342                              raw_ostream &Out) const {
343   switch (getKind()) {
344   case Null:
345     Out << "(no value)";
346     break;
347 
348   case Type: {
349     PrintingPolicy SubPolicy(Policy);
350     SubPolicy.SuppressStrongLifetime = true;
351     getAsType().print(Out, SubPolicy);
352     break;
353   }
354 
355   case Declaration: {
356     NamedDecl *ND = cast<NamedDecl>(getAsDecl());
357     Out << '&';
358     if (ND->getDeclName()) {
359       // FIXME: distinguish between pointer and reference args?
360       ND->printQualifiedName(Out);
361     } else {
362       Out << "(anonymous)";
363     }
364     break;
365   }
366 
367   case NullPtr:
368     Out << "nullptr";
369     break;
370 
371   case Template:
372     getAsTemplate().print(Out, Policy);
373     break;
374 
375   case TemplateExpansion:
376     getAsTemplateOrTemplatePattern().print(Out, Policy);
377     Out << "...";
378     break;
379 
380   case Integral: {
381     printIntegral(*this, Out);
382     break;
383   }
384 
385   case Expression:
386     getAsExpr()->printPretty(Out, nullptr, Policy);
387     break;
388 
389   case Pack:
390     Out << "<";
391     bool First = true;
392     for (const auto &P : pack_elements()) {
393       if (First)
394         First = false;
395       else
396         Out << ", ";
397 
398       P.print(Policy, Out);
399     }
400     Out << ">";
401     break;
402   }
403 }
404 
405 //===----------------------------------------------------------------------===//
406 // TemplateArgumentLoc Implementation
407 //===----------------------------------------------------------------------===//
408 
409 TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
410   memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
411 }
412 
413 SourceRange TemplateArgumentLoc::getSourceRange() const {
414   switch (Argument.getKind()) {
415   case TemplateArgument::Expression:
416     return getSourceExpression()->getSourceRange();
417 
418   case TemplateArgument::Declaration:
419     return getSourceDeclExpression()->getSourceRange();
420 
421   case TemplateArgument::NullPtr:
422     return getSourceNullPtrExpression()->getSourceRange();
423 
424   case TemplateArgument::Type:
425     if (TypeSourceInfo *TSI = getTypeSourceInfo())
426       return TSI->getTypeLoc().getSourceRange();
427     else
428       return SourceRange();
429 
430   case TemplateArgument::Template:
431     if (getTemplateQualifierLoc())
432       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
433                          getTemplateNameLoc());
434     return SourceRange(getTemplateNameLoc());
435 
436   case TemplateArgument::TemplateExpansion:
437     if (getTemplateQualifierLoc())
438       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
439                          getTemplateEllipsisLoc());
440     return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
441 
442   case TemplateArgument::Integral:
443     return getSourceIntegralExpression()->getSourceRange();
444 
445   case TemplateArgument::Pack:
446   case TemplateArgument::Null:
447     return SourceRange();
448   }
449 
450   llvm_unreachable("Invalid TemplateArgument Kind!");
451 }
452 
453 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
454                                            const TemplateArgument &Arg) {
455   switch (Arg.getKind()) {
456   case TemplateArgument::Null:
457     // This is bad, but not as bad as crashing because of argument
458     // count mismatches.
459     return DB << "(null template argument)";
460 
461   case TemplateArgument::Type:
462     return DB << Arg.getAsType();
463 
464   case TemplateArgument::Declaration:
465     return DB << Arg.getAsDecl();
466 
467   case TemplateArgument::NullPtr:
468     return DB << "nullptr";
469 
470   case TemplateArgument::Integral:
471     return DB << Arg.getAsIntegral().toString(10);
472 
473   case TemplateArgument::Template:
474     return DB << Arg.getAsTemplate();
475 
476   case TemplateArgument::TemplateExpansion:
477     return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
478 
479   case TemplateArgument::Expression: {
480     // This shouldn't actually ever happen, so it's okay that we're
481     // regurgitating an expression here.
482     // FIXME: We're guessing at LangOptions!
483     SmallString<32> Str;
484     llvm::raw_svector_ostream OS(Str);
485     LangOptions LangOpts;
486     LangOpts.CPlusPlus = true;
487     PrintingPolicy Policy(LangOpts);
488     Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
489     return DB << OS.str();
490   }
491 
492   case TemplateArgument::Pack: {
493     // FIXME: We're guessing at LangOptions!
494     SmallString<32> Str;
495     llvm::raw_svector_ostream OS(Str);
496     LangOptions LangOpts;
497     LangOpts.CPlusPlus = true;
498     PrintingPolicy Policy(LangOpts);
499     Arg.print(Policy, OS);
500     return DB << OS.str();
501   }
502   }
503 
504   llvm_unreachable("Invalid TemplateArgument Kind!");
505 }
506 
507 const ASTTemplateArgumentListInfo *
508 ASTTemplateArgumentListInfo::Create(ASTContext &C,
509                                     const TemplateArgumentListInfo &List) {
510   assert(llvm::alignOf<ASTTemplateArgumentListInfo>() >=
511          llvm::alignOf<TemplateArgumentLoc>());
512   std::size_t size = ASTTemplateArgumentListInfo::sizeFor(List.size());
513   void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
514   ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
515   TAI->initializeFrom(List);
516   return TAI;
517 }
518 
519 void ASTTemplateArgumentListInfo::initializeFrom(
520                                       const TemplateArgumentListInfo &Info) {
521   LAngleLoc = Info.getLAngleLoc();
522   RAngleLoc = Info.getRAngleLoc();
523   NumTemplateArgs = Info.size();
524 
525   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
526   for (unsigned i = 0; i != NumTemplateArgs; ++i)
527     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
528 }
529 
530 void ASTTemplateArgumentListInfo::initializeFrom(
531                                           const TemplateArgumentListInfo &Info,
532                                                   bool &Dependent,
533                                                   bool &InstantiationDependent,
534                                        bool &ContainsUnexpandedParameterPack) {
535   LAngleLoc = Info.getLAngleLoc();
536   RAngleLoc = Info.getRAngleLoc();
537   NumTemplateArgs = Info.size();
538 
539   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
540   for (unsigned i = 0; i != NumTemplateArgs; ++i) {
541     Dependent = Dependent || Info[i].getArgument().isDependent();
542     InstantiationDependent = InstantiationDependent ||
543                              Info[i].getArgument().isInstantiationDependent();
544     ContainsUnexpandedParameterPack
545       = ContainsUnexpandedParameterPack ||
546         Info[i].getArgument().containsUnexpandedParameterPack();
547 
548     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
549   }
550 }
551 
552 void ASTTemplateArgumentListInfo::copyInto(
553                                       TemplateArgumentListInfo &Info) const {
554   Info.setLAngleLoc(LAngleLoc);
555   Info.setRAngleLoc(RAngleLoc);
556   for (unsigned I = 0; I != NumTemplateArgs; ++I)
557     Info.addArgument(getTemplateArgs()[I]);
558 }
559 
560 std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
561   return sizeof(ASTTemplateArgumentListInfo) +
562          sizeof(TemplateArgumentLoc) * NumTemplateArgs;
563 }
564 
565 void
566 ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc,
567                                          const TemplateArgumentListInfo &Info) {
568   Base::initializeFrom(Info);
569   setTemplateKeywordLoc(TemplateKWLoc);
570 }
571 
572 void
573 ASTTemplateKWAndArgsInfo
574 ::initializeFrom(SourceLocation TemplateKWLoc,
575                  const TemplateArgumentListInfo &Info,
576                  bool &Dependent,
577                  bool &InstantiationDependent,
578                  bool &ContainsUnexpandedParameterPack) {
579   Base::initializeFrom(Info, Dependent, InstantiationDependent,
580                        ContainsUnexpandedParameterPack);
581   setTemplateKeywordLoc(TemplateKWLoc);
582 }
583 
584 void
585 ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
586   // No explicit template arguments, but template keyword loc is valid.
587   assert(TemplateKWLoc.isValid());
588   LAngleLoc = SourceLocation();
589   RAngleLoc = SourceLocation();
590   NumTemplateArgs = 0;
591   setTemplateKeywordLoc(TemplateKWLoc);
592 }
593 
594 std::size_t
595 ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
596   // Add space for the template keyword location.
597   // FIXME: There's room for this in the padding before the template args in
598   //        64-bit builds.
599   return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation);
600 }
601