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/ADT/iterator_range.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Support/ErrorHandling.h"
25 
26 namespace llvm {
27   class FoldingSetNodeID;
28 }
29 
30 namespace clang {
31 
32 class DiagnosticBuilder;
33 class Expr;
34 struct PrintingPolicy;
35 class TypeSourceInfo;
36 class ValueDecl;
37 
38 /// \brief Represents a template argument.
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 an expression, and we've not resolved it to one
64     /// of the other forms yet, either because it's dependent or because we're
65     /// representing a non-canonical template argument (for instance, in a
66     /// TemplateSpecializationType). Also used to represent a non-dependent
67     /// __uuidof expression (a Microsoft extension).
68     Expression,
69     /// The template argument is actually a parameter pack. Arguments are stored
70     /// in the Args struct.
71     Pack
72   };
73 
74 private:
75   /// \brief The kind of template argument we're storing.
76 
77   struct DA {
78     unsigned Kind;
79     void *QT;
80     ValueDecl *D;
81   };
82   struct I {
83     unsigned Kind;
84     // We store a decomposed APSInt with the data allocated by ASTContext if
85     // BitWidth > 64. The memory may be shared between multiple
86     // TemplateArgument instances.
87     unsigned BitWidth : 31;
88     unsigned IsUnsigned : 1;
89     union {
90       uint64_t VAL;          ///< Used to store the <= 64 bits integer value.
91       const uint64_t *pVal;  ///< Used to store the >64 bits integer value.
92     };
93     void *Type;
94   };
95   struct A {
96     unsigned Kind;
97     unsigned NumArgs;
98     const TemplateArgument *Args;
99   };
100   struct TA {
101     unsigned Kind;
102     unsigned NumExpansions;
103     void *Name;
104   };
105   struct TV {
106     unsigned Kind;
107     uintptr_t V;
108   };
109   union {
110     struct DA DeclArg;
111     struct I Integer;
112     struct A Args;
113     struct TA TemplateArg;
114     struct TV TypeOrValue;
115   };
116 
117   TemplateArgument(TemplateName, bool) = delete;
118 
119 public:
120   /// \brief Construct an empty, invalid template argument.
TemplateArgument()121   TemplateArgument() {
122     TypeOrValue.Kind = Null;
123     TypeOrValue.V = 0;
124   }
125 
126   /// \brief Construct a template type argument.
127   TemplateArgument(QualType T, bool isNullPtr = false) {
128     TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
129     TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
130   }
131 
132   /// \brief Construct a template argument that refers to a
133   /// declaration, which is either an external declaration or a
134   /// template declaration.
TemplateArgument(ValueDecl * D,QualType QT)135   TemplateArgument(ValueDecl *D, QualType QT) {
136     assert(D && "Expected decl");
137     DeclArg.Kind = Declaration;
138     DeclArg.QT = QT.getAsOpaquePtr();
139     DeclArg.D = D;
140   }
141 
142   /// \brief Construct an integral constant template argument. The memory to
143   /// store the value is allocated with Ctx.
144   TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
145 
146   /// \brief Construct an integral constant template argument with the same
147   /// value as Other but a different type.
TemplateArgument(const TemplateArgument & Other,QualType Type)148   TemplateArgument(const TemplateArgument &Other, QualType Type) {
149     Integer = Other.Integer;
150     Integer.Type = Type.getAsOpaquePtr();
151   }
152 
153   /// \brief Construct a template argument that is a template.
154   ///
155   /// This form of template argument is generally used for template template
156   /// parameters. However, the template name could be a dependent template
157   /// name that ends up being instantiated to a function template whose address
158   /// is taken.
159   ///
160   /// \param Name The template name.
TemplateArgument(TemplateName Name)161   TemplateArgument(TemplateName Name) {
162     TemplateArg.Kind = Template;
163     TemplateArg.Name = Name.getAsVoidPointer();
164     TemplateArg.NumExpansions = 0;
165   }
166 
167   /// \brief Construct a template argument that is a template pack expansion.
168   ///
169   /// This form of template argument is generally used for template template
170   /// parameters. However, the template name could be a dependent template
171   /// name that ends up being instantiated to a function template whose address
172   /// is taken.
173   ///
174   /// \param Name The template name.
175   ///
176   /// \param NumExpansions The number of expansions that will be generated by
177   /// instantiating
TemplateArgument(TemplateName Name,Optional<unsigned> NumExpansions)178   TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
179     TemplateArg.Kind = TemplateExpansion;
180     TemplateArg.Name = Name.getAsVoidPointer();
181     if (NumExpansions)
182       TemplateArg.NumExpansions = *NumExpansions + 1;
183     else
184       TemplateArg.NumExpansions = 0;
185   }
186 
187   /// \brief Construct a template argument that is an expression.
188   ///
189   /// This form of template argument only occurs in template argument
190   /// lists used for dependent types and for expression; it will not
191   /// occur in a non-dependent, canonical template argument list.
TemplateArgument(Expr * E)192   TemplateArgument(Expr *E) {
193     TypeOrValue.Kind = Expression;
194     TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
195   }
196 
197   /// \brief Construct a template argument that is a template argument pack.
198   ///
199   /// We assume that storage for the template arguments provided
200   /// outlives the TemplateArgument itself.
TemplateArgument(ArrayRef<TemplateArgument> Args)201   explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
202     this->Args.Kind = Pack;
203     this->Args.Args = Args.data();
204     this->Args.NumArgs = Args.size();
205   }
206 
getEmptyPack()207   static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
208 
209   /// \brief Create a new template argument pack by copying the given set of
210   /// template arguments.
211   static TemplateArgument CreatePackCopy(ASTContext &Context,
212                                          ArrayRef<TemplateArgument> Args);
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 
getParamTypeForDecl()249   QualType getParamTypeForDecl() const {
250     assert(getKind() == Declaration && "Unexpected kind");
251     return QualType::getFromOpaquePtr(DeclArg.QT);
252   }
253 
254   /// \brief Retrieve the type for null non-type template argument.
getNullPtrType()255   QualType getNullPtrType() const {
256     assert(getKind() == NullPtr && "Unexpected kind");
257     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
258   }
259 
260   /// \brief Retrieve the template name for a template name argument.
getAsTemplate()261   TemplateName getAsTemplate() const {
262     assert(getKind() == Template && "Unexpected kind");
263     return TemplateName::getFromVoidPointer(TemplateArg.Name);
264   }
265 
266   /// \brief Retrieve the template argument as a template name; if the argument
267   /// is a pack expansion, return the pattern as a template name.
getAsTemplateOrTemplatePattern()268   TemplateName getAsTemplateOrTemplatePattern() const {
269     assert((getKind() == Template || getKind() == TemplateExpansion) &&
270            "Unexpected kind");
271 
272     return TemplateName::getFromVoidPointer(TemplateArg.Name);
273   }
274 
275   /// \brief Retrieve the number of expansions that a template template argument
276   /// expansion will produce, if known.
277   Optional<unsigned> getNumTemplateExpansions() const;
278 
279   /// \brief Retrieve the template argument as an integral value.
280   // FIXME: Provide a way to read the integral data without copying the value.
getAsIntegral()281   llvm::APSInt getAsIntegral() const {
282     assert(getKind() == Integral && "Unexpected kind");
283     using namespace llvm;
284     if (Integer.BitWidth <= 64)
285       return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
286 
287     unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
288     return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
289                   Integer.IsUnsigned);
290   }
291 
292   /// \brief Retrieve the type of the integral value.
getIntegralType()293   QualType getIntegralType() const {
294     assert(getKind() == Integral && "Unexpected kind");
295     return QualType::getFromOpaquePtr(Integer.Type);
296   }
297 
setIntegralType(QualType T)298   void setIntegralType(QualType T) {
299     assert(getKind() == Integral && "Unexpected kind");
300     Integer.Type = T.getAsOpaquePtr();
301   }
302 
303   /// \brief Retrieve the template argument as an expression.
getAsExpr()304   Expr *getAsExpr() const {
305     assert(getKind() == Expression && "Unexpected kind");
306     return reinterpret_cast<Expr *>(TypeOrValue.V);
307   }
308 
309   /// \brief Iterator that traverses the elements of a template argument pack.
310   typedef const TemplateArgument * pack_iterator;
311 
312   /// \brief Iterator referencing the first argument of a template argument
313   /// pack.
pack_begin()314   pack_iterator pack_begin() const {
315     assert(getKind() == Pack);
316     return Args.Args;
317   }
318 
319   /// \brief Iterator referencing one past the last argument of a template
320   /// argument pack.
pack_end()321   pack_iterator pack_end() const {
322     assert(getKind() == Pack);
323     return Args.Args + Args.NumArgs;
324   }
325 
326   /// \brief Iterator range referencing all of the elements of a template
327   /// argument pack.
pack_elements()328   llvm::iterator_range<pack_iterator> pack_elements() const {
329     return llvm::make_range(pack_begin(), pack_end());
330   }
331 
332   /// \brief The number of template arguments in the given template argument
333   /// pack.
pack_size()334   unsigned pack_size() const {
335     assert(getKind() == Pack);
336     return Args.NumArgs;
337   }
338 
339   /// \brief Return the array of arguments in this template argument pack.
getPackAsArray()340   ArrayRef<TemplateArgument> getPackAsArray() const {
341     assert(getKind() == Pack);
342     return llvm::makeArrayRef(Args.Args, Args.NumArgs);
343   }
344 
345   /// \brief 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   TemplateArgument getPackExpansionPattern() const;
352 
353   /// \brief Print this template argument to the given output stream.
354   void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
355 
356   /// \brief Used to insert TemplateArguments into FoldingSets.
357   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
358 };
359 
360 /// Location information for a TemplateArgument.
361 struct TemplateArgumentLocInfo {
362 private:
363 
364   struct T {
365     // FIXME: We'd like to just use the qualifier in the TemplateName,
366     // but template arguments get canonicalized too quickly.
367     NestedNameSpecifier *Qualifier;
368     void *QualifierLocData;
369     unsigned TemplateNameLoc;
370     unsigned EllipsisLoc;
371   };
372 
373   union {
374     struct T Template;
375     Expr *Expression;
376     TypeSourceInfo *Declarator;
377   };
378 
379 public:
380   TemplateArgumentLocInfo();
381 
TemplateArgumentLocInfoTemplateArgumentLocInfo382   TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
383 
TemplateArgumentLocInfoTemplateArgumentLocInfo384   TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
385 
TemplateArgumentLocInfoTemplateArgumentLocInfo386   TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
387                           SourceLocation TemplateNameLoc,
388                           SourceLocation EllipsisLoc)
389   {
390     Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
391     Template.QualifierLocData = QualifierLoc.getOpaqueData();
392     Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
393     Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
394   }
395 
getAsTypeSourceInfoTemplateArgumentLocInfo396   TypeSourceInfo *getAsTypeSourceInfo() const {
397     return Declarator;
398   }
399 
getAsExprTemplateArgumentLocInfo400   Expr *getAsExpr() const {
401     return Expression;
402   }
403 
getTemplateQualifierLocTemplateArgumentLocInfo404   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
405     return NestedNameSpecifierLoc(Template.Qualifier,
406                                   Template.QualifierLocData);
407   }
408 
getTemplateNameLocTemplateArgumentLocInfo409   SourceLocation getTemplateNameLoc() const {
410     return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
411   }
412 
getTemplateEllipsisLocTemplateArgumentLocInfo413   SourceLocation getTemplateEllipsisLoc() const {
414     return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
415   }
416 };
417 
418 /// Location wrapper for a TemplateArgument.  TemplateArgument is to
419 /// TemplateArgumentLoc as Type is to TypeLoc.
420 class TemplateArgumentLoc {
421   TemplateArgument Argument;
422   TemplateArgumentLocInfo LocInfo;
423 
424 public:
TemplateArgumentLoc()425   TemplateArgumentLoc() {}
426 
TemplateArgumentLoc(const TemplateArgument & Argument,TemplateArgumentLocInfo Opaque)427   TemplateArgumentLoc(const TemplateArgument &Argument,
428                       TemplateArgumentLocInfo Opaque)
429     : Argument(Argument), LocInfo(Opaque) {
430   }
431 
TemplateArgumentLoc(const TemplateArgument & Argument,TypeSourceInfo * TInfo)432   TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
433     : Argument(Argument), LocInfo(TInfo) {
434     assert(Argument.getKind() == TemplateArgument::Type);
435   }
436 
TemplateArgumentLoc(const TemplateArgument & Argument,Expr * E)437   TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
438     : Argument(Argument), LocInfo(E) {
439     assert(Argument.getKind() == TemplateArgument::Expression);
440   }
441 
442   TemplateArgumentLoc(const TemplateArgument &Argument,
443                       NestedNameSpecifierLoc QualifierLoc,
444                       SourceLocation TemplateNameLoc,
445                       SourceLocation EllipsisLoc = SourceLocation())
Argument(Argument)446     : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
447     assert(Argument.getKind() == TemplateArgument::Template ||
448            Argument.getKind() == TemplateArgument::TemplateExpansion);
449   }
450 
451   /// \brief - Fetches the primary location of the argument.
getLocation()452   SourceLocation getLocation() const {
453     if (Argument.getKind() == TemplateArgument::Template ||
454         Argument.getKind() == TemplateArgument::TemplateExpansion)
455       return getTemplateNameLoc();
456 
457     return getSourceRange().getBegin();
458   }
459 
460   /// \brief - Fetches the full source range of the argument.
461   SourceRange getSourceRange() const LLVM_READONLY;
462 
getArgument()463   const TemplateArgument &getArgument() const {
464     return Argument;
465   }
466 
getLocInfo()467   TemplateArgumentLocInfo getLocInfo() const {
468     return LocInfo;
469   }
470 
getTypeSourceInfo()471   TypeSourceInfo *getTypeSourceInfo() const {
472     assert(Argument.getKind() == TemplateArgument::Type);
473     return LocInfo.getAsTypeSourceInfo();
474   }
475 
getSourceExpression()476   Expr *getSourceExpression() const {
477     assert(Argument.getKind() == TemplateArgument::Expression);
478     return LocInfo.getAsExpr();
479   }
480 
getSourceDeclExpression()481   Expr *getSourceDeclExpression() const {
482     assert(Argument.getKind() == TemplateArgument::Declaration);
483     return LocInfo.getAsExpr();
484   }
485 
getSourceNullPtrExpression()486   Expr *getSourceNullPtrExpression() const {
487     assert(Argument.getKind() == TemplateArgument::NullPtr);
488     return LocInfo.getAsExpr();
489   }
490 
getSourceIntegralExpression()491   Expr *getSourceIntegralExpression() const {
492     assert(Argument.getKind() == TemplateArgument::Integral);
493     return LocInfo.getAsExpr();
494   }
495 
getTemplateQualifierLoc()496   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
497     assert(Argument.getKind() == TemplateArgument::Template ||
498            Argument.getKind() == TemplateArgument::TemplateExpansion);
499     return LocInfo.getTemplateQualifierLoc();
500   }
501 
getTemplateNameLoc()502   SourceLocation getTemplateNameLoc() const {
503     assert(Argument.getKind() == TemplateArgument::Template ||
504            Argument.getKind() == TemplateArgument::TemplateExpansion);
505     return LocInfo.getTemplateNameLoc();
506   }
507 
getTemplateEllipsisLoc()508   SourceLocation getTemplateEllipsisLoc() const {
509     assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
510     return LocInfo.getTemplateEllipsisLoc();
511   }
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) = delete;
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 
arguments()544   llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
545     return Arguments;
546   }
547 
548   const TemplateArgumentLoc &operator[](unsigned I) const {
549     return Arguments[I];
550   }
551 
552   TemplateArgumentLoc &operator[](unsigned I) {
553     return Arguments[I];
554   }
555 
addArgument(const TemplateArgumentLoc & Loc)556   void addArgument(const TemplateArgumentLoc &Loc) {
557     Arguments.push_back(Loc);
558   }
559 };
560 
561 /// \brief Represents an explicit template argument list in C++, e.g.,
562 /// the "<int>" in "sort<int>".
563 /// This is safe to be used inside an AST node, in contrast with
564 /// TemplateArgumentListInfo.
565 struct ASTTemplateArgumentListInfo {
566   /// \brief The source location of the left angle bracket ('<').
567   SourceLocation LAngleLoc;
568 
569   /// \brief The source location of the right angle bracket ('>').
570   SourceLocation RAngleLoc;
571 
572   union {
573     /// \brief The number of template arguments in TemplateArgs.
574     /// The actual template arguments (if any) are stored after the
575     /// ExplicitTemplateArgumentList structure.
576     unsigned NumTemplateArgs;
577 
578     /// Force ASTTemplateArgumentListInfo to the right alignment
579     /// for the following array of TemplateArgumentLocs.
580     llvm::AlignedCharArray<
581         llvm::AlignOf<TemplateArgumentLoc>::Alignment, 1> Aligner;
582   };
583 
584   /// \brief Retrieve the template arguments
getTemplateArgsASTTemplateArgumentListInfo585   TemplateArgumentLoc *getTemplateArgs() {
586     return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
587   }
588 
589   /// \brief Retrieve the template arguments
getTemplateArgsASTTemplateArgumentListInfo590   const TemplateArgumentLoc *getTemplateArgs() const {
591     return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
592   }
593 
594   const TemplateArgumentLoc &operator[](unsigned I) const {
595     return getTemplateArgs()[I];
596   }
597 
598   static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
599                                           const TemplateArgumentListInfo &List);
600 
601   void initializeFrom(const TemplateArgumentListInfo &List);
602   void initializeFrom(const TemplateArgumentListInfo &List,
603                       bool &Dependent, bool &InstantiationDependent,
604                       bool &ContainsUnexpandedParameterPack);
605   void copyInto(TemplateArgumentListInfo &List) const;
606   static std::size_t sizeFor(unsigned NumTemplateArgs);
607 };
608 
609 /// \brief Extends ASTTemplateArgumentListInfo with the source location
610 /// information for the template keyword; this is used as part of the
611 /// representation of qualified identifiers, such as S<T>::template apply<T>.
612 struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
613   typedef ASTTemplateArgumentListInfo Base;
614 
615   // NOTE: the source location of the (optional) template keyword is
616   // stored after all template arguments.
617 
618   /// \brief Get the source location of the template keyword.
getTemplateKeywordLocASTTemplateKWAndArgsInfo619   SourceLocation getTemplateKeywordLoc() const {
620     return *reinterpret_cast<const SourceLocation*>
621       (getTemplateArgs() + NumTemplateArgs);
622   }
623 
624   /// \brief Sets the source location of the template keyword.
setTemplateKeywordLocASTTemplateKWAndArgsInfo625   void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
626     *reinterpret_cast<SourceLocation*>
627       (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
628   }
629 
630   static const ASTTemplateKWAndArgsInfo*
631   Create(ASTContext &C, SourceLocation TemplateKWLoc,
632          const TemplateArgumentListInfo &List);
633 
634   void initializeFrom(SourceLocation TemplateKWLoc,
635                       const TemplateArgumentListInfo &List);
636   void initializeFrom(SourceLocation TemplateKWLoc,
637                       const TemplateArgumentListInfo &List,
638                       bool &Dependent, bool &InstantiationDependent,
639                       bool &ContainsUnexpandedParameterPack);
640   void initializeFrom(SourceLocation TemplateKWLoc);
641 
642   static std::size_t sizeFor(unsigned NumTemplateArgs);
643 };
644 
645 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
646                                     const TemplateArgument &Arg);
647 
648 inline TemplateSpecializationType::iterator
end()649     TemplateSpecializationType::end() const {
650   return getArgs() + getNumArgs();
651 }
652 
653 inline DependentTemplateSpecializationType::iterator
end()654     DependentTemplateSpecializationType::end() const {
655   return getArgs() + getNumArgs();
656 }
657 
658 inline const TemplateArgument &
getArg(unsigned Idx)659     TemplateSpecializationType::getArg(unsigned Idx) const {
660   assert(Idx < getNumArgs() && "Template argument out of range");
661   return getArgs()[Idx];
662 }
663 
664 inline const TemplateArgument &
getArg(unsigned Idx)665     DependentTemplateSpecializationType::getArg(unsigned Idx) const {
666   assert(Idx < getNumArgs() && "Template argument out of range");
667   return getArgs()[Idx];
668 }
669 
670 } // end namespace clang
671 
672 #endif
673