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