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