Home | History | Annotate | Line # | Download | only in AST
      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 
     44 using 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.
     56 static 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 
    136 static 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 
    145 static 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 
    160 TemplateArgument::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 
    179 TemplateArgument
    180 TemplateArgument::CreatePackCopy(ASTContext &Context,
    181                                  ArrayRef<TemplateArgument> Args) {
    182   if (Args.empty())
    183     return getEmptyPack();
    184 
    185   return TemplateArgument(Args.copy(Context));
    186 }
    187 
    188 TemplateArgumentDependence 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 
    236 bool TemplateArgument::isDependent() const {
    237   return getDependence() & TemplateArgumentDependence::Dependent;
    238 }
    239 
    240 bool TemplateArgument::isInstantiationDependent() const {
    241   return getDependence() & TemplateArgumentDependence::Instantiation;
    242 }
    243 
    244 bool 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 
    267 bool TemplateArgument::containsUnexpandedParameterPack() const {
    268   return getDependence() & TemplateArgumentDependence::UnexpandedPack;
    269 }
    270 
    271 Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
    272   assert(getKind() == TemplateExpansion);
    273   if (TemplateArg.NumExpansions)
    274     return TemplateArg.NumExpansions - 1;
    275 
    276   return None;
    277 }
    278 
    279 QualType 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 
    304 void 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 
    358 bool 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 
    391 TemplateArgument 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 
    416 void 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 
    486 void 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 
    493 LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
    494 
    495 //===----------------------------------------------------------------------===//
    496 // TemplateArgumentLoc Implementation
    497 //===----------------------------------------------------------------------===//
    498 
    499 SourceRange 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 
    539 template <typename T>
    540 static 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 
    593 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
    594                                              const TemplateArgument &Arg) {
    595   return DiagTemplateArg(DB, Arg);
    596 }
    597 
    598 clang::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 
    609 const ASTTemplateArgumentListInfo *
    610 ASTTemplateArgumentListInfo::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 
    617 ASTTemplateArgumentListInfo::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 
    628 void 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 
    640 void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
    641   assert(TemplateKWLoc.isValid());
    642   LAngleLoc = SourceLocation();
    643   RAngleLoc = SourceLocation();
    644   this->TemplateKWLoc = TemplateKWLoc;
    645   NumTemplateArgs = 0;
    646 }
    647 
    648 void 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 
    663 void 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