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