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