1//===- TemplateBase.cpp - Common template AST class implementation --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements common classes used throughout C++ template
10// representations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/TemplateBase.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclTemplate.h"
19#include "clang/AST/DependenceFlags.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/// 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.
53///
54/// \param IncludeType If set, ensure that the type of the expression printed
55/// matches the type of the template argument.
56static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
57                          const PrintingPolicy &Policy, bool IncludeType) {
58  const Type *T = TemplArg.getIntegralType().getTypePtr();
59  const llvm::APSInt &Val = TemplArg.getAsIntegral();
60
61  if (const EnumType *ET = T->getAs<EnumType>()) {
62    for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
63      // In Sema::CheckTemplateArugment, enum template arguments value are
64      // extended to the size of the integer underlying the enum type.  This
65      // may create a size difference between the enum value and template
66      // argument value, requiring isSameValue here instead of operator==.
67      if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
68        ECD->printQualifiedName(Out, Policy);
69        return;
70      }
71    }
72  }
73
74  if (Policy.MSVCFormatting)
75    IncludeType = false;
76
77  if (T->isBooleanType()) {
78    if (!Policy.MSVCFormatting)
79      Out << (Val.getBoolValue() ? "true" : "false");
80    else
81      Out << Val;
82  } else if (T->isCharType()) {
83    if (IncludeType) {
84      if (T->isSpecificBuiltinType(BuiltinType::SChar))
85        Out << "(signed char)";
86      else if (T->isSpecificBuiltinType(BuiltinType::UChar))
87        Out << "(unsigned char)";
88    }
89    CharacterLiteral::print(Val.getZExtValue(), CharacterLiteral::Ascii, Out);
90  } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
91    CharacterLiteral::CharacterKind Kind;
92    if (T->isWideCharType())
93      Kind = CharacterLiteral::Wide;
94    else if (T->isChar8Type())
95      Kind = CharacterLiteral::UTF8;
96    else if (T->isChar16Type())
97      Kind = CharacterLiteral::UTF16;
98    else if (T->isChar32Type())
99      Kind = CharacterLiteral::UTF32;
100    else
101      Kind = CharacterLiteral::Ascii;
102    CharacterLiteral::print(Val.getExtValue(), Kind, Out);
103  } else if (IncludeType) {
104    if (const auto *BT = T->getAs<BuiltinType>()) {
105      switch (BT->getKind()) {
106      case BuiltinType::ULongLong:
107        Out << Val << "ULL";
108        break;
109      case BuiltinType::LongLong:
110        Out << Val << "LL";
111        break;
112      case BuiltinType::ULong:
113        Out << Val << "UL";
114        break;
115      case BuiltinType::Long:
116        Out << Val << "L";
117        break;
118      case BuiltinType::UInt:
119        Out << Val << "U";
120        break;
121      case BuiltinType::Int:
122        Out << Val;
123        break;
124      default:
125        Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
126            << Val;
127        break;
128      }
129    } else
130      Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
131          << Val;
132  } else
133    Out << Val;
134}
135
136static unsigned getArrayDepth(QualType type) {
137  unsigned count = 0;
138  while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
139    count++;
140    type = arrayType->getElementType();
141  }
142  return count;
143}
144
145static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) {
146  // Generally, if the parameter type is a pointer, we must be taking the
147  // address of something and need a &.  However, if the argument is an array,
148  // this could be implicit via array-to-pointer decay.
149  if (!paramType->isPointerType())
150    return paramType->isMemberPointerType();
151  if (argType->isArrayType())
152    return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
153  return true;
154}
155
156//===----------------------------------------------------------------------===//
157// TemplateArgument Implementation
158//===----------------------------------------------------------------------===//
159
160TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
161                                   QualType Type) {
162  Integer.Kind = Integral;
163  // Copy the APSInt value into our decomposed form.
164  Integer.BitWidth = Value.getBitWidth();
165  Integer.IsUnsigned = Value.isUnsigned();
166  // If the value is large, we have to get additional memory from the ASTContext
167  unsigned NumWords = Value.getNumWords();
168  if (NumWords > 1) {
169    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
170    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
171    Integer.pVal = static_cast<uint64_t *>(Mem);
172  } else {
173    Integer.VAL = Value.getZExtValue();
174  }
175
176  Integer.Type = Type.getAsOpaquePtr();
177}
178
179TemplateArgument
180TemplateArgument::CreatePackCopy(ASTContext &Context,
181                                 ArrayRef<TemplateArgument> Args) {
182  if (Args.empty())
183    return getEmptyPack();
184
185  return TemplateArgument(Args.copy(Context));
186}
187
188TemplateArgumentDependence TemplateArgument::getDependence() const {
189  auto Deps = TemplateArgumentDependence::None;
190  switch (getKind()) {
191  case Null:
192    llvm_unreachable("Should not have a NULL template argument");
193
194  case Type:
195    Deps = toTemplateArgumentDependence(getAsType()->getDependence());
196    if (isa<PackExpansionType>(getAsType()))
197      Deps |= TemplateArgumentDependence::Dependent;
198    return Deps;
199
200  case Template:
201    return toTemplateArgumentDependence(getAsTemplate().getDependence());
202
203  case TemplateExpansion:
204    return TemplateArgumentDependence::Dependent |
205           TemplateArgumentDependence::Instantiation;
206
207  case Declaration: {
208    auto *DC = dyn_cast<DeclContext>(getAsDecl());
209    if (!DC)
210      DC = getAsDecl()->getDeclContext();
211    if (DC->isDependentContext())
212      Deps = TemplateArgumentDependence::Dependent |
213             TemplateArgumentDependence::Instantiation;
214    return Deps;
215  }
216
217  case NullPtr:
218  case Integral:
219    return TemplateArgumentDependence::None;
220
221  case Expression:
222    Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
223    if (isa<PackExpansionExpr>(getAsExpr()))
224      Deps |= TemplateArgumentDependence::Dependent |
225              TemplateArgumentDependence::Instantiation;
226    return Deps;
227
228  case Pack:
229    for (const auto &P : pack_elements())
230      Deps |= P.getDependence();
231    return Deps;
232  }
233  llvm_unreachable("unhandled ArgKind");
234}
235
236bool TemplateArgument::isDependent() const {
237  return getDependence() & TemplateArgumentDependence::Dependent;
238}
239
240bool TemplateArgument::isInstantiationDependent() const {
241  return getDependence() & TemplateArgumentDependence::Instantiation;
242}
243
244bool TemplateArgument::isPackExpansion() const {
245  switch (getKind()) {
246  case Null:
247  case Declaration:
248  case Integral:
249  case Pack:
250  case Template:
251  case NullPtr:
252    return false;
253
254  case TemplateExpansion:
255    return true;
256
257  case Type:
258    return isa<PackExpansionType>(getAsType());
259
260  case Expression:
261    return isa<PackExpansionExpr>(getAsExpr());
262  }
263
264  llvm_unreachable("Invalid TemplateArgument Kind!");
265}
266
267bool TemplateArgument::containsUnexpandedParameterPack() const {
268  return getDependence() & TemplateArgumentDependence::UnexpandedPack;
269}
270
271Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
272  assert(getKind() == TemplateExpansion);
273  if (TemplateArg.NumExpansions)
274    return TemplateArg.NumExpansions - 1;
275
276  return None;
277}
278
279QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
280  switch (getKind()) {
281  case TemplateArgument::Null:
282  case TemplateArgument::Type:
283  case TemplateArgument::Template:
284  case TemplateArgument::TemplateExpansion:
285  case TemplateArgument::Pack:
286    return QualType();
287
288  case TemplateArgument::Integral:
289    return getIntegralType();
290
291  case TemplateArgument::Expression:
292    return getAsExpr()->getType();
293
294  case TemplateArgument::Declaration:
295    return getParamTypeForDecl();
296
297  case TemplateArgument::NullPtr:
298    return getNullPtrType();
299  }
300
301  llvm_unreachable("Invalid TemplateArgument Kind!");
302}
303
304void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
305                               const ASTContext &Context) const {
306  ID.AddInteger(getKind());
307  switch (getKind()) {
308  case Null:
309    break;
310
311  case Type:
312    getAsType().Profile(ID);
313    break;
314
315  case NullPtr:
316    getNullPtrType().Profile(ID);
317    break;
318
319  case Declaration:
320    getParamTypeForDecl().Profile(ID);
321    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
322    break;
323
324  case Template:
325  case TemplateExpansion: {
326    TemplateName Template = getAsTemplateOrTemplatePattern();
327    if (TemplateTemplateParmDecl *TTP
328          = dyn_cast_or_null<TemplateTemplateParmDecl>(
329                                                Template.getAsTemplateDecl())) {
330      ID.AddBoolean(true);
331      ID.AddInteger(TTP->getDepth());
332      ID.AddInteger(TTP->getPosition());
333      ID.AddBoolean(TTP->isParameterPack());
334    } else {
335      ID.AddBoolean(false);
336      ID.AddPointer(Context.getCanonicalTemplateName(Template)
337                                                          .getAsVoidPointer());
338    }
339    break;
340  }
341
342  case Integral:
343    getAsIntegral().Profile(ID);
344    getIntegralType().Profile(ID);
345    break;
346
347  case Expression:
348    getAsExpr()->Profile(ID, Context, true);
349    break;
350
351  case Pack:
352    ID.AddInteger(Args.NumArgs);
353    for (unsigned I = 0; I != Args.NumArgs; ++I)
354      Args.Args[I].Profile(ID, Context);
355  }
356}
357
358bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
359  if (getKind() != Other.getKind()) return false;
360
361  switch (getKind()) {
362  case Null:
363  case Type:
364  case Expression:
365  case NullPtr:
366    return TypeOrValue.V == Other.TypeOrValue.V;
367
368  case Template:
369  case TemplateExpansion:
370    return TemplateArg.Name == Other.TemplateArg.Name &&
371           TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
372
373  case Declaration:
374    return getAsDecl() == Other.getAsDecl();
375
376  case Integral:
377    return getIntegralType() == Other.getIntegralType() &&
378           getAsIntegral() == Other.getAsIntegral();
379
380  case Pack:
381    if (Args.NumArgs != Other.Args.NumArgs) return false;
382    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
383      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
384        return false;
385    return true;
386  }
387
388  llvm_unreachable("Invalid TemplateArgument Kind!");
389}
390
391TemplateArgument TemplateArgument::getPackExpansionPattern() const {
392  assert(isPackExpansion());
393
394  switch (getKind()) {
395  case Type:
396    return getAsType()->castAs<PackExpansionType>()->getPattern();
397
398  case Expression:
399    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
400
401  case TemplateExpansion:
402    return TemplateArgument(getAsTemplateOrTemplatePattern());
403
404  case Declaration:
405  case Integral:
406  case Pack:
407  case Null:
408  case Template:
409  case NullPtr:
410    return TemplateArgument();
411  }
412
413  llvm_unreachable("Invalid TemplateArgument Kind!");
414}
415
416void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
417                             bool IncludeType) const {
418
419  switch (getKind()) {
420  case Null:
421    Out << "(no value)";
422    break;
423
424  case Type: {
425    PrintingPolicy SubPolicy(Policy);
426    SubPolicy.SuppressStrongLifetime = true;
427    getAsType().print(Out, SubPolicy);
428    break;
429  }
430
431  case Declaration: {
432    // FIXME: Include the type if it's not obvious from the context.
433    NamedDecl *ND = getAsDecl();
434    if (getParamTypeForDecl()->isRecordType()) {
435      if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
436        TPO->printAsInit(Out);
437        break;
438      }
439    }
440    if (auto *VD = dyn_cast<ValueDecl>(ND)) {
441      if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType()))
442        Out << "&";
443    }
444    ND->printQualifiedName(Out);
445    break;
446  }
447
448  case NullPtr:
449    // FIXME: Include the type if it's not obvious from the context.
450    Out << "nullptr";
451    break;
452
453  case Template:
454    getAsTemplate().print(Out, Policy);
455    break;
456
457  case TemplateExpansion:
458    getAsTemplateOrTemplatePattern().print(Out, Policy);
459    Out << "...";
460    break;
461
462  case Integral:
463    printIntegral(*this, Out, Policy, IncludeType);
464    break;
465
466  case Expression:
467    getAsExpr()->printPretty(Out, nullptr, Policy);
468    break;
469
470  case Pack:
471    Out << "<";
472    bool First = true;
473    for (const auto &P : pack_elements()) {
474      if (First)
475        First = false;
476      else
477        Out << ", ";
478
479      P.print(Policy, Out, IncludeType);
480    }
481    Out << ">";
482    break;
483  }
484}
485
486void TemplateArgument::dump(raw_ostream &Out) const {
487  LangOptions LO; // FIXME! see also TemplateName::dump().
488  LO.CPlusPlus = true;
489  LO.Bool = true;
490  print(PrintingPolicy(LO), Out, /*IncludeType*/ true);
491}
492
493LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
494
495//===----------------------------------------------------------------------===//
496// TemplateArgumentLoc Implementation
497//===----------------------------------------------------------------------===//
498
499SourceRange TemplateArgumentLoc::getSourceRange() const {
500  switch (Argument.getKind()) {
501  case TemplateArgument::Expression:
502    return getSourceExpression()->getSourceRange();
503
504  case TemplateArgument::Declaration:
505    return getSourceDeclExpression()->getSourceRange();
506
507  case TemplateArgument::NullPtr:
508    return getSourceNullPtrExpression()->getSourceRange();
509
510  case TemplateArgument::Type:
511    if (TypeSourceInfo *TSI = getTypeSourceInfo())
512      return TSI->getTypeLoc().getSourceRange();
513    else
514      return SourceRange();
515
516  case TemplateArgument::Template:
517    if (getTemplateQualifierLoc())
518      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
519                         getTemplateNameLoc());
520    return SourceRange(getTemplateNameLoc());
521
522  case TemplateArgument::TemplateExpansion:
523    if (getTemplateQualifierLoc())
524      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
525                         getTemplateEllipsisLoc());
526    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
527
528  case TemplateArgument::Integral:
529    return getSourceIntegralExpression()->getSourceRange();
530
531  case TemplateArgument::Pack:
532  case TemplateArgument::Null:
533    return SourceRange();
534  }
535
536  llvm_unreachable("Invalid TemplateArgument Kind!");
537}
538
539template <typename T>
540static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
541  switch (Arg.getKind()) {
542  case TemplateArgument::Null:
543    // This is bad, but not as bad as crashing because of argument
544    // count mismatches.
545    return DB << "(null template argument)";
546
547  case TemplateArgument::Type:
548    return DB << Arg.getAsType();
549
550  case TemplateArgument::Declaration:
551    return DB << Arg.getAsDecl();
552
553  case TemplateArgument::NullPtr:
554    return DB << "nullptr";
555
556  case TemplateArgument::Integral:
557    return DB << Arg.getAsIntegral().toString(10);
558
559  case TemplateArgument::Template:
560    return DB << Arg.getAsTemplate();
561
562  case TemplateArgument::TemplateExpansion:
563    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
564
565  case TemplateArgument::Expression: {
566    // This shouldn't actually ever happen, so it's okay that we're
567    // regurgitating an expression here.
568    // FIXME: We're guessing at LangOptions!
569    SmallString<32> Str;
570    llvm::raw_svector_ostream OS(Str);
571    LangOptions LangOpts;
572    LangOpts.CPlusPlus = true;
573    PrintingPolicy Policy(LangOpts);
574    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
575    return DB << OS.str();
576  }
577
578  case TemplateArgument::Pack: {
579    // FIXME: We're guessing at LangOptions!
580    SmallString<32> Str;
581    llvm::raw_svector_ostream OS(Str);
582    LangOptions LangOpts;
583    LangOpts.CPlusPlus = true;
584    PrintingPolicy Policy(LangOpts);
585    Arg.print(Policy, OS, /*IncludeType*/ true);
586    return DB << OS.str();
587  }
588  }
589
590  llvm_unreachable("Invalid TemplateArgument Kind!");
591}
592
593const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
594                                             const TemplateArgument &Arg) {
595  return DiagTemplateArg(DB, Arg);
596}
597
598clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
599    ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
600    SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
601  TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
602  Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
603  Template->QualifierLocData = QualifierLoc.getOpaqueData();
604  Template->TemplateNameLoc = TemplateNameLoc;
605  Template->EllipsisLoc = EllipsisLoc;
606  Pointer = Template;
607}
608
609const ASTTemplateArgumentListInfo *
610ASTTemplateArgumentListInfo::Create(const ASTContext &C,
611                                    const TemplateArgumentListInfo &List) {
612  std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
613  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
614  return new (Mem) ASTTemplateArgumentListInfo(List);
615}
616
617ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
618    const TemplateArgumentListInfo &Info) {
619  LAngleLoc = Info.getLAngleLoc();
620  RAngleLoc = Info.getRAngleLoc();
621  NumTemplateArgs = Info.size();
622
623  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
624  for (unsigned i = 0; i != NumTemplateArgs; ++i)
625    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
626}
627
628void ASTTemplateKWAndArgsInfo::initializeFrom(
629    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
630    TemplateArgumentLoc *OutArgArray) {
631  this->TemplateKWLoc = TemplateKWLoc;
632  LAngleLoc = Info.getLAngleLoc();
633  RAngleLoc = Info.getRAngleLoc();
634  NumTemplateArgs = Info.size();
635
636  for (unsigned i = 0; i != NumTemplateArgs; ++i)
637    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
638}
639
640void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
641  assert(TemplateKWLoc.isValid());
642  LAngleLoc = SourceLocation();
643  RAngleLoc = SourceLocation();
644  this->TemplateKWLoc = TemplateKWLoc;
645  NumTemplateArgs = 0;
646}
647
648void ASTTemplateKWAndArgsInfo::initializeFrom(
649    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
650    TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
651  this->TemplateKWLoc = TemplateKWLoc;
652  LAngleLoc = Info.getLAngleLoc();
653  RAngleLoc = Info.getRAngleLoc();
654  NumTemplateArgs = Info.size();
655
656  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
657    Deps |= Info[i].getArgument().getDependence();
658
659    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
660  }
661}
662
663void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
664                                        TemplateArgumentListInfo &Info) const {
665  Info.setLAngleLoc(LAngleLoc);
666  Info.setRAngleLoc(RAngleLoc);
667  for (unsigned I = 0; I != NumTemplateArgs; ++I)
668    Info.addArgument(ArgArray[I]);
669}
670