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