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