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