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