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