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.
printIntegral(const TemplateArgument & TemplArg,raw_ostream & Out,const PrintingPolicy & Policy,bool IncludeType)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 
getArrayDepth(QualType type)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 
needsAmpersandOnTemplateArg(QualType paramType,QualType argType)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 
TemplateArgument(ASTContext & Ctx,const llvm::APSInt & Value,QualType Type)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
CreatePackCopy(ASTContext & Context,ArrayRef<TemplateArgument> Args)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 
getDependence() const188 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 
isDependent() const236 bool TemplateArgument::isDependent() const {
237   return getDependence() & TemplateArgumentDependence::Dependent;
238 }
239 
isInstantiationDependent() const240 bool TemplateArgument::isInstantiationDependent() const {
241   return getDependence() & TemplateArgumentDependence::Instantiation;
242 }
243 
isPackExpansion() const244 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 
containsUnexpandedParameterPack() const267 bool TemplateArgument::containsUnexpandedParameterPack() const {
268   return getDependence() & TemplateArgumentDependence::UnexpandedPack;
269 }
270 
getNumTemplateExpansions() const271 Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
272   assert(getKind() == TemplateExpansion);
273   if (TemplateArg.NumExpansions)
274     return TemplateArg.NumExpansions - 1;
275 
276   return None;
277 }
278 
getNonTypeTemplateArgumentType() const279 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 
Profile(llvm::FoldingSetNodeID & ID,const ASTContext & Context) const304 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 
structurallyEquals(const TemplateArgument & Other) const358 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 
getPackExpansionPattern() const391 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 
print(const PrintingPolicy & Policy,raw_ostream & Out,bool IncludeType) const416 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 
dump(raw_ostream & Out) const486 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 
dump() const493 LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
494 
495 //===----------------------------------------------------------------------===//
496 // TemplateArgumentLoc Implementation
497 //===----------------------------------------------------------------------===//
498 
getSourceRange() const499 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>
DiagTemplateArg(const T & DB,const TemplateArgument & Arg)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 
operator <<(const StreamingDiagnostic & DB,const TemplateArgument & Arg)593 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
594                                              const TemplateArgument &Arg) {
595   return DiagTemplateArg(DB, Arg);
596 }
597 
TemplateArgumentLocInfo(ASTContext & Ctx,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateNameLoc,SourceLocation EllipsisLoc)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 *
Create(const ASTContext & C,const TemplateArgumentListInfo & List)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 
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo & Info)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 
initializeFrom(SourceLocation TemplateKWLoc,const TemplateArgumentListInfo & Info,TemplateArgumentLoc * OutArgArray)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 
initializeFrom(SourceLocation TemplateKWLoc)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 
initializeFrom(SourceLocation TemplateKWLoc,const TemplateArgumentListInfo & Info,TemplateArgumentLoc * OutArgArray,TemplateArgumentDependence & Deps)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 
copyInto(const TemplateArgumentLoc * ArgArray,TemplateArgumentListInfo & Info) const663 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