1 //===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===//
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 provides definitions which are common for all kinds of
10 //  template representation.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
15 #define LLVM_CLANG_AST_TEMPLATEBASE_H
16 
17 #include "clang/AST/DependenceFlags.h"
18 #include "clang/AST/NestedNameSpecifier.h"
19 #include "clang/AST/TemplateName.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/LLVM.h"
22 #include "clang/Basic/SourceLocation.h"
23 #include "llvm/ADT/APInt.h"
24 #include "llvm/ADT/APSInt.h"
25 #include "llvm/ADT/ArrayRef.h"
26 #include "llvm/ADT/None.h"
27 #include "llvm/ADT/Optional.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/TrailingObjects.h"
31 #include <cassert>
32 #include <cstddef>
33 #include <cstdint>
34 
35 namespace llvm {
36 
37 class FoldingSetNodeID;
38 
39 // Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a
40 // full definition of Expr, but this file only sees a forward del because of
41 // the dependency.
42 template <> struct PointerLikeTypeTraits<clang::Expr *> {
43   static inline void *getAsVoidPointer(clang::Expr *P) { return P; }
44   static inline clang::Expr *getFromVoidPointer(void *P) {
45     return static_cast<clang::Expr *>(P);
46   }
47   static constexpr int NumLowBitsAvailable = 2;
48 };
49 
50 } // namespace llvm
51 
52 namespace clang {
53 
54 class ASTContext;
55 class Expr;
56 struct PrintingPolicy;
57 class TypeSourceInfo;
58 class ValueDecl;
59 
60 /// Represents a template argument.
61 class TemplateArgument {
62 public:
63   /// The kind of template argument we're storing.
64   enum ArgKind {
65     /// Represents an empty template argument, e.g., one that has not
66     /// been deduced.
67     Null = 0,
68 
69     /// The template argument is a type.
70     Type,
71 
72     /// The template argument is a declaration that was provided for a pointer,
73     /// reference, or pointer to member non-type template parameter.
74     Declaration,
75 
76     /// The template argument is a null pointer or null pointer to member that
77     /// was provided for a non-type template parameter.
78     NullPtr,
79 
80     /// The template argument is an integral value stored in an llvm::APSInt
81     /// that was provided for an integral non-type template parameter.
82     Integral,
83 
84     /// The template argument is a template name that was provided for a
85     /// template template parameter.
86     Template,
87 
88     /// The template argument is a pack expansion of a template name that was
89     /// provided for a template template parameter.
90     TemplateExpansion,
91 
92     /// The template argument is an expression, and we've not resolved it to one
93     /// of the other forms yet, either because it's dependent or because we're
94     /// representing a non-canonical template argument (for instance, in a
95     /// TemplateSpecializationType).
96     Expression,
97 
98     /// The template argument is actually a parameter pack. Arguments are stored
99     /// in the Args struct.
100     Pack
101   };
102 
103 private:
104   /// The kind of template argument we're storing.
105 
106   struct DA {
107     unsigned Kind;
108     void *QT;
109     ValueDecl *D;
110   };
111   struct I {
112     unsigned Kind;
113     // We store a decomposed APSInt with the data allocated by ASTContext if
114     // BitWidth > 64. The memory may be shared between multiple
115     // TemplateArgument instances.
116     unsigned BitWidth : 31;
117     unsigned IsUnsigned : 1;
118     union {
119       /// Used to store the <= 64 bits integer value.
120       uint64_t VAL;
121 
122       /// Used to store the >64 bits integer value.
123       const uint64_t *pVal;
124     };
125     void *Type;
126   };
127   struct A {
128     unsigned Kind;
129     unsigned NumArgs;
130     const TemplateArgument *Args;
131   };
132   struct TA {
133     unsigned Kind;
134     unsigned NumExpansions;
135     void *Name;
136   };
137   struct TV {
138     unsigned Kind;
139     uintptr_t V;
140   };
141   union {
142     struct DA DeclArg;
143     struct I Integer;
144     struct A Args;
145     struct TA TemplateArg;
146     struct TV TypeOrValue;
147   };
148 
149 public:
150   /// Construct an empty, invalid template argument.
151   constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
152 
153   /// Construct a template type argument.
154   TemplateArgument(QualType T, bool isNullPtr = false) {
155     TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
156     TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
157   }
158 
159   /// Construct a template argument that refers to a
160   /// declaration, which is either an external declaration or a
161   /// template declaration.
162   TemplateArgument(ValueDecl *D, QualType QT) {
163     assert(D && "Expected decl");
164     DeclArg.Kind = Declaration;
165     DeclArg.QT = QT.getAsOpaquePtr();
166     DeclArg.D = D;
167   }
168 
169   /// Construct an integral constant template argument. The memory to
170   /// store the value is allocated with Ctx.
171   TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
172 
173   /// Construct an integral constant template argument with the same
174   /// value as Other but a different type.
175   TemplateArgument(const TemplateArgument &Other, QualType Type) {
176     Integer = Other.Integer;
177     Integer.Type = Type.getAsOpaquePtr();
178   }
179 
180   /// Construct a template argument that is a template.
181   ///
182   /// This form of template argument is generally used for template template
183   /// parameters. However, the template name could be a dependent template
184   /// name that ends up being instantiated to a function template whose address
185   /// is taken.
186   ///
187   /// \param Name The template name.
188   TemplateArgument(TemplateName Name) {
189     TemplateArg.Kind = Template;
190     TemplateArg.Name = Name.getAsVoidPointer();
191     TemplateArg.NumExpansions = 0;
192   }
193 
194   /// Construct a template argument that is a template pack expansion.
195   ///
196   /// This form of template argument is generally used for template template
197   /// parameters. However, the template name could be a dependent template
198   /// name that ends up being instantiated to a function template whose address
199   /// is taken.
200   ///
201   /// \param Name The template name.
202   ///
203   /// \param NumExpansions The number of expansions that will be generated by
204   /// instantiating
205   TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
206     TemplateArg.Kind = TemplateExpansion;
207     TemplateArg.Name = Name.getAsVoidPointer();
208     if (NumExpansions)
209       TemplateArg.NumExpansions = *NumExpansions + 1;
210     else
211       TemplateArg.NumExpansions = 0;
212   }
213 
214   /// Construct a template argument that is an expression.
215   ///
216   /// This form of template argument only occurs in template argument
217   /// lists used for dependent types and for expression; it will not
218   /// occur in a non-dependent, canonical template argument list.
219   TemplateArgument(Expr *E) {
220     TypeOrValue.Kind = Expression;
221     TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
222   }
223 
224   /// Construct a template argument that is a template argument pack.
225   ///
226   /// We assume that storage for the template arguments provided
227   /// outlives the TemplateArgument itself.
228   explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
229     this->Args.Kind = Pack;
230     this->Args.Args = Args.data();
231     this->Args.NumArgs = Args.size();
232   }
233 
234   TemplateArgument(TemplateName, bool) = delete;
235 
236   static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
237 
238   /// Create a new template argument pack by copying the given set of
239   /// template arguments.
240   static TemplateArgument CreatePackCopy(ASTContext &Context,
241                                          ArrayRef<TemplateArgument> Args);
242 
243   /// Return the kind of stored template argument.
244   ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
245 
246   /// Determine whether this template argument has no value.
247   bool isNull() const { return getKind() == Null; }
248 
249   TemplateArgumentDependence getDependence() const;
250 
251   /// Whether this template argument is dependent on a template
252   /// parameter such that its result can change from one instantiation to
253   /// another.
254   bool isDependent() const;
255 
256   /// Whether this template argument is dependent on a template
257   /// parameter.
258   bool isInstantiationDependent() const;
259 
260   /// Whether this template argument contains an unexpanded
261   /// parameter pack.
262   bool containsUnexpandedParameterPack() const;
263 
264   /// Determine whether this template argument is a pack expansion.
265   bool isPackExpansion() const;
266 
267   /// Retrieve the type for a type template argument.
268   QualType getAsType() const {
269     assert(getKind() == Type && "Unexpected kind");
270     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
271   }
272 
273   /// Retrieve the declaration for a declaration non-type
274   /// template argument.
275   ValueDecl *getAsDecl() const {
276     assert(getKind() == Declaration && "Unexpected kind");
277     return DeclArg.D;
278   }
279 
280   QualType getParamTypeForDecl() const {
281     assert(getKind() == Declaration && "Unexpected kind");
282     return QualType::getFromOpaquePtr(DeclArg.QT);
283   }
284 
285   /// Retrieve the type for null non-type template argument.
286   QualType getNullPtrType() const {
287     assert(getKind() == NullPtr && "Unexpected kind");
288     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
289   }
290 
291   /// Retrieve the template name for a template name argument.
292   TemplateName getAsTemplate() const {
293     assert(getKind() == Template && "Unexpected kind");
294     return TemplateName::getFromVoidPointer(TemplateArg.Name);
295   }
296 
297   /// Retrieve the template argument as a template name; if the argument
298   /// is a pack expansion, return the pattern as a template name.
299   TemplateName getAsTemplateOrTemplatePattern() const {
300     assert((getKind() == Template || getKind() == TemplateExpansion) &&
301            "Unexpected kind");
302 
303     return TemplateName::getFromVoidPointer(TemplateArg.Name);
304   }
305 
306   /// Retrieve the number of expansions that a template template argument
307   /// expansion will produce, if known.
308   Optional<unsigned> getNumTemplateExpansions() const;
309 
310   /// Retrieve the template argument as an integral value.
311   // FIXME: Provide a way to read the integral data without copying the value.
312   llvm::APSInt getAsIntegral() const {
313     assert(getKind() == Integral && "Unexpected kind");
314 
315     using namespace llvm;
316 
317     if (Integer.BitWidth <= 64)
318       return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
319 
320     unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
321     return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
322                   Integer.IsUnsigned);
323   }
324 
325   /// Retrieve the type of the integral value.
326   QualType getIntegralType() const {
327     assert(getKind() == Integral && "Unexpected kind");
328     return QualType::getFromOpaquePtr(Integer.Type);
329   }
330 
331   void setIntegralType(QualType T) {
332     assert(getKind() == Integral && "Unexpected kind");
333     Integer.Type = T.getAsOpaquePtr();
334   }
335 
336   /// If this is a non-type template argument, get its type. Otherwise,
337   /// returns a null QualType.
338   QualType getNonTypeTemplateArgumentType() const;
339 
340   /// Retrieve the template argument as an expression.
341   Expr *getAsExpr() const {
342     assert(getKind() == Expression && "Unexpected kind");
343     return reinterpret_cast<Expr *>(TypeOrValue.V);
344   }
345 
346   /// Iterator that traverses the elements of a template argument pack.
347   using pack_iterator = const TemplateArgument *;
348 
349   /// Iterator referencing the first argument of a template argument
350   /// pack.
351   pack_iterator pack_begin() const {
352     assert(getKind() == Pack);
353     return Args.Args;
354   }
355 
356   /// Iterator referencing one past the last argument of a template
357   /// argument pack.
358   pack_iterator pack_end() const {
359     assert(getKind() == Pack);
360     return Args.Args + Args.NumArgs;
361   }
362 
363   /// Iterator range referencing all of the elements of a template
364   /// argument pack.
365   ArrayRef<TemplateArgument> pack_elements() const {
366     return llvm::makeArrayRef(pack_begin(), pack_end());
367   }
368 
369   /// The number of template arguments in the given template argument
370   /// pack.
371   unsigned pack_size() const {
372     assert(getKind() == Pack);
373     return Args.NumArgs;
374   }
375 
376   /// Return the array of arguments in this template argument pack.
377   ArrayRef<TemplateArgument> getPackAsArray() const {
378     assert(getKind() == Pack);
379     return llvm::makeArrayRef(Args.Args, Args.NumArgs);
380   }
381 
382   /// Determines whether two template arguments are superficially the
383   /// same.
384   bool structurallyEquals(const TemplateArgument &Other) const;
385 
386   /// When the template argument is a pack expansion, returns
387   /// the pattern of the pack expansion.
388   TemplateArgument getPackExpansionPattern() const;
389 
390   /// Print this template argument to the given output stream.
391   void print(const PrintingPolicy &Policy, raw_ostream &Out,
392              bool IncludeType) const;
393 
394   /// Debugging aid that dumps the template argument.
395   void dump(raw_ostream &Out) const;
396 
397   /// Debugging aid that dumps the template argument to standard error.
398   void dump() const;
399 
400   /// Used to insert TemplateArguments into FoldingSets.
401   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
402 };
403 
404 /// Location information for a TemplateArgument.
405 struct TemplateArgumentLocInfo {
406 private:
407   struct TemplateTemplateArgLocInfo {
408     // FIXME: We'd like to just use the qualifier in the TemplateName,
409     // but template arguments get canonicalized too quickly.
410     NestedNameSpecifier *Qualifier;
411     void *QualifierLocData;
412     SourceLocation TemplateNameLoc;
413     SourceLocation EllipsisLoc;
414   };
415 
416   llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
417       Pointer;
418 
419   TemplateTemplateArgLocInfo *getTemplate() const {
420     return Pointer.get<TemplateTemplateArgLocInfo *>();
421   }
422 
423 public:
424   TemplateArgumentLocInfo() {}
425   TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
426 
427   TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
428   // Ctx is used for allocation -- this case is unusually large and also rare,
429   // so we store the payload out-of-line.
430   TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
431                           SourceLocation TemplateNameLoc,
432                           SourceLocation EllipsisLoc);
433 
434   TypeSourceInfo *getAsTypeSourceInfo() const {
435     return Pointer.get<TypeSourceInfo *>();
436   }
437 
438   Expr *getAsExpr() const { return Pointer.get<Expr *>(); }
439 
440   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
441     const auto *Template = getTemplate();
442     return NestedNameSpecifierLoc(Template->Qualifier,
443                                   Template->QualifierLocData);
444   }
445 
446   SourceLocation getTemplateNameLoc() const {
447     return getTemplate()->TemplateNameLoc;
448   }
449 
450   SourceLocation getTemplateEllipsisLoc() const {
451     return getTemplate()->EllipsisLoc;
452   }
453 };
454 
455 /// Location wrapper for a TemplateArgument.  TemplateArgument is to
456 /// TemplateArgumentLoc as Type is to TypeLoc.
457 class TemplateArgumentLoc {
458   TemplateArgument Argument;
459   TemplateArgumentLocInfo LocInfo;
460 
461 public:
462   TemplateArgumentLoc() {}
463 
464   TemplateArgumentLoc(const TemplateArgument &Argument,
465                       TemplateArgumentLocInfo Opaque)
466       : Argument(Argument), LocInfo(Opaque) {}
467 
468   TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
469       : Argument(Argument), LocInfo(TInfo) {
470     assert(Argument.getKind() == TemplateArgument::Type);
471   }
472 
473   TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
474       : Argument(Argument), LocInfo(E) {
475 
476     // Permit any kind of template argument that can be represented with an
477     // expression.
478     assert(Argument.getKind() == TemplateArgument::NullPtr ||
479            Argument.getKind() == TemplateArgument::Integral ||
480            Argument.getKind() == TemplateArgument::Declaration ||
481            Argument.getKind() == TemplateArgument::Expression);
482   }
483 
484   TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
485                       NestedNameSpecifierLoc QualifierLoc,
486                       SourceLocation TemplateNameLoc,
487                       SourceLocation EllipsisLoc = SourceLocation())
488       : Argument(Argument),
489         LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
490     assert(Argument.getKind() == TemplateArgument::Template ||
491            Argument.getKind() == TemplateArgument::TemplateExpansion);
492   }
493 
494   /// - Fetches the primary location of the argument.
495   SourceLocation getLocation() const {
496     if (Argument.getKind() == TemplateArgument::Template ||
497         Argument.getKind() == TemplateArgument::TemplateExpansion)
498       return getTemplateNameLoc();
499 
500     return getSourceRange().getBegin();
501   }
502 
503   /// - Fetches the full source range of the argument.
504   SourceRange getSourceRange() const LLVM_READONLY;
505 
506   const TemplateArgument &getArgument() const {
507     return Argument;
508   }
509 
510   TemplateArgumentLocInfo getLocInfo() const {
511     return LocInfo;
512   }
513 
514   TypeSourceInfo *getTypeSourceInfo() const {
515     if (Argument.getKind() != TemplateArgument::Type)
516       return nullptr;
517     return LocInfo.getAsTypeSourceInfo();
518   }
519 
520   Expr *getSourceExpression() const {
521     assert(Argument.getKind() == TemplateArgument::Expression);
522     return LocInfo.getAsExpr();
523   }
524 
525   Expr *getSourceDeclExpression() const {
526     assert(Argument.getKind() == TemplateArgument::Declaration);
527     return LocInfo.getAsExpr();
528   }
529 
530   Expr *getSourceNullPtrExpression() const {
531     assert(Argument.getKind() == TemplateArgument::NullPtr);
532     return LocInfo.getAsExpr();
533   }
534 
535   Expr *getSourceIntegralExpression() const {
536     assert(Argument.getKind() == TemplateArgument::Integral);
537     return LocInfo.getAsExpr();
538   }
539 
540   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
541     if (Argument.getKind() != TemplateArgument::Template &&
542         Argument.getKind() != TemplateArgument::TemplateExpansion)
543       return NestedNameSpecifierLoc();
544     return LocInfo.getTemplateQualifierLoc();
545   }
546 
547   SourceLocation getTemplateNameLoc() const {
548     if (Argument.getKind() != TemplateArgument::Template &&
549         Argument.getKind() != TemplateArgument::TemplateExpansion)
550       return SourceLocation();
551     return LocInfo.getTemplateNameLoc();
552   }
553 
554   SourceLocation getTemplateEllipsisLoc() const {
555     if (Argument.getKind() != TemplateArgument::TemplateExpansion)
556       return SourceLocation();
557     return LocInfo.getTemplateEllipsisLoc();
558   }
559 };
560 
561 /// A convenient class for passing around template argument
562 /// information.  Designed to be passed by reference.
563 class TemplateArgumentListInfo {
564   SmallVector<TemplateArgumentLoc, 8> Arguments;
565   SourceLocation LAngleLoc;
566   SourceLocation RAngleLoc;
567 
568 public:
569   TemplateArgumentListInfo() = default;
570 
571   TemplateArgumentListInfo(SourceLocation LAngleLoc,
572                            SourceLocation RAngleLoc)
573       : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
574 
575   // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
576   // instead.
577   void *operator new(size_t bytes, ASTContext &C) = delete;
578 
579   SourceLocation getLAngleLoc() const { return LAngleLoc; }
580   SourceLocation getRAngleLoc() const { return RAngleLoc; }
581 
582   void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
583   void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
584 
585   unsigned size() const { return Arguments.size(); }
586 
587   const TemplateArgumentLoc *getArgumentArray() const {
588     return Arguments.data();
589   }
590 
591   llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
592     return Arguments;
593   }
594 
595   const TemplateArgumentLoc &operator[](unsigned I) const {
596     return Arguments[I];
597   }
598 
599   TemplateArgumentLoc &operator[](unsigned I) {
600     return Arguments[I];
601   }
602 
603   void addArgument(const TemplateArgumentLoc &Loc) {
604     Arguments.push_back(Loc);
605   }
606 };
607 
608 /// Represents an explicit template argument list in C++, e.g.,
609 /// the "<int>" in "sort<int>".
610 /// This is safe to be used inside an AST node, in contrast with
611 /// TemplateArgumentListInfo.
612 struct ASTTemplateArgumentListInfo final
613     : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
614                                     TemplateArgumentLoc> {
615 private:
616   friend class ASTNodeImporter;
617   friend TrailingObjects;
618 
619   ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
620 
621   // FIXME: Is it ever necessary to copy to another context?
622   ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List);
623 
624 public:
625   /// The source location of the left angle bracket ('<').
626   SourceLocation LAngleLoc;
627 
628   /// The source location of the right angle bracket ('>').
629   SourceLocation RAngleLoc;
630 
631   /// The number of template arguments in TemplateArgs.
632   unsigned NumTemplateArgs;
633 
634   SourceLocation getLAngleLoc() const { return LAngleLoc; }
635   SourceLocation getRAngleLoc() const { return RAngleLoc; }
636 
637   /// Retrieve the template arguments
638   const TemplateArgumentLoc *getTemplateArgs() const {
639     return getTrailingObjects<TemplateArgumentLoc>();
640   }
641   unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
642 
643   llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
644     return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
645   }
646 
647   const TemplateArgumentLoc &operator[](unsigned I) const {
648     return getTemplateArgs()[I];
649   }
650 
651   static const ASTTemplateArgumentListInfo *
652   Create(const ASTContext &C, const TemplateArgumentListInfo &List);
653 
654   // FIXME: Is it ever necessary to copy to another context?
655   static const ASTTemplateArgumentListInfo *
656   Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List);
657 };
658 
659 /// Represents an explicit template argument list in C++, e.g.,
660 /// the "<int>" in "sort<int>".
661 ///
662 /// It is intended to be used as a trailing object on AST nodes, and
663 /// as such, doesn't contain the array of TemplateArgumentLoc itself,
664 /// but expects the containing object to also provide storage for
665 /// that.
666 struct alignas(void *) ASTTemplateKWAndArgsInfo {
667   /// The source location of the left angle bracket ('<').
668   SourceLocation LAngleLoc;
669 
670   /// The source location of the right angle bracket ('>').
671   SourceLocation RAngleLoc;
672 
673   /// The source location of the template keyword; this is used
674   /// as part of the representation of qualified identifiers, such as
675   /// S<T>::template apply<T>.  Will be empty if this expression does
676   /// not have a template keyword.
677   SourceLocation TemplateKWLoc;
678 
679   /// The number of template arguments in TemplateArgs.
680   unsigned NumTemplateArgs;
681 
682   void initializeFrom(SourceLocation TemplateKWLoc,
683                       const TemplateArgumentListInfo &List,
684                       TemplateArgumentLoc *OutArgArray);
685   // FIXME: The parameter Deps is the result populated by this method, the
686   // caller doesn't need it since it is populated by computeDependence. remove
687   // it.
688   void initializeFrom(SourceLocation TemplateKWLoc,
689                       const TemplateArgumentListInfo &List,
690                       TemplateArgumentLoc *OutArgArray,
691                       TemplateArgumentDependence &Deps);
692   void initializeFrom(SourceLocation TemplateKWLoc);
693 
694   void copyInto(const TemplateArgumentLoc *ArgArray,
695                 TemplateArgumentListInfo &List) const;
696 };
697 
698 const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
699                                       const TemplateArgument &Arg);
700 
701 inline TemplateSpecializationType::iterator
702     TemplateSpecializationType::end() const {
703   return getArgs() + getNumArgs();
704 }
705 
706 inline DependentTemplateSpecializationType::iterator
707     DependentTemplateSpecializationType::end() const {
708   return getArgs() + getNumArgs();
709 }
710 
711 inline const TemplateArgument &
712     TemplateSpecializationType::getArg(unsigned Idx) const {
713   assert(Idx < getNumArgs() && "Template argument out of range");
714   return getArgs()[Idx];
715 }
716 
717 inline const TemplateArgument &
718     DependentTemplateSpecializationType::getArg(unsigned Idx) const {
719   assert(Idx < getNumArgs() && "Template argument out of range");
720   return getArgs()[Idx];
721 }
722 
723 inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
724   assert(Idx < getNumArgs() && "Template argument out of range");
725   return getArgs()[Idx];
726 }
727 
728 } // namespace clang
729 
730 #endif // LLVM_CLANG_AST_TEMPLATEBASE_H
731