clang API Documentation

TemplateBase.h
Go to the documentation of this file.
00001 //===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file provides definitions which are common for all kinds of
00011 //  template representation.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
00016 #define LLVM_CLANG_AST_TEMPLATEBASE_H
00017 
00018 #include "clang/AST/TemplateName.h"
00019 #include "clang/AST/Type.h"
00020 #include "llvm/ADT/APSInt.h"
00021 #include "llvm/ADT/iterator_range.h"
00022 #include "llvm/ADT/SmallVector.h"
00023 #include "llvm/Support/Compiler.h"
00024 #include "llvm/Support/ErrorHandling.h"
00025 
00026 namespace llvm {
00027   class FoldingSetNodeID;
00028 }
00029 
00030 namespace clang {
00031 
00032 class DiagnosticBuilder;
00033 class Expr;
00034 struct PrintingPolicy;
00035 class TypeSourceInfo;
00036 class ValueDecl;
00037 
00038 /// \brief Represents a template argument.
00039 class TemplateArgument {
00040 public:
00041   /// \brief The kind of template argument we're storing.
00042   enum ArgKind {
00043     /// \brief Represents an empty template argument, e.g., one that has not
00044     /// been deduced.
00045     Null = 0,
00046     /// The template argument is a type.
00047     Type,
00048     /// The template argument is a declaration that was provided for a pointer,
00049     /// reference, or pointer to member non-type template parameter.
00050     Declaration,
00051     /// The template argument is a null pointer or null pointer to member that
00052     /// was provided for a non-type template parameter.
00053     NullPtr,
00054     /// The template argument is an integral value stored in an llvm::APSInt
00055     /// that was provided for an integral non-type template parameter.
00056     Integral,
00057     /// The template argument is a template name that was provided for a
00058     /// template template parameter.
00059     Template,
00060     /// The template argument is a pack expansion of a template name that was
00061     /// provided for a template template parameter.
00062     TemplateExpansion,
00063     /// The template argument is an expression, and we've not resolved it to one
00064     /// of the other forms yet, either because it's dependent or because we're
00065     /// representing a non-canonical template argument (for instance, in a
00066     /// TemplateSpecializationType). Also used to represent a non-dependent
00067     /// __uuidof expression (a Microsoft extension).
00068     Expression,
00069     /// The template argument is actually a parameter pack. Arguments are stored
00070     /// in the Args struct.
00071     Pack
00072   };
00073 
00074 private:
00075   /// \brief The kind of template argument we're storing.
00076 
00077   struct DA {
00078     unsigned Kind;
00079     void *QT;
00080     ValueDecl *D;
00081   };
00082   struct I {
00083     unsigned Kind;
00084     // We store a decomposed APSInt with the data allocated by ASTContext if
00085     // BitWidth > 64. The memory may be shared between multiple
00086     // TemplateArgument instances.
00087     unsigned BitWidth : 31;
00088     unsigned IsUnsigned : 1;
00089     union {
00090       uint64_t VAL;          ///< Used to store the <= 64 bits integer value.
00091       const uint64_t *pVal;  ///< Used to store the >64 bits integer value.
00092     };
00093     void *Type;
00094   };
00095   struct A {
00096     unsigned Kind;
00097     unsigned NumArgs;
00098     const TemplateArgument *Args;
00099   };
00100   struct TA {
00101     unsigned Kind;
00102     unsigned NumExpansions;
00103     void *Name;
00104   };
00105   struct TV {
00106     unsigned Kind;
00107     uintptr_t V;
00108   };
00109   union {
00110     struct DA DeclArg;
00111     struct I Integer;
00112     struct A Args;
00113     struct TA TemplateArg;
00114     struct TV TypeOrValue;
00115   };
00116 
00117   TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
00118   
00119 public:
00120   /// \brief Construct an empty, invalid template argument.
00121   TemplateArgument() {
00122     TypeOrValue.Kind = Null;
00123     TypeOrValue.V = 0;
00124   }
00125 
00126   /// \brief Construct a template type argument.
00127   TemplateArgument(QualType T, bool isNullPtr = false) {
00128     TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
00129     TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
00130   }
00131 
00132   /// \brief Construct a template argument that refers to a
00133   /// declaration, which is either an external declaration or a
00134   /// template declaration.
00135   TemplateArgument(ValueDecl *D, QualType QT) {
00136     assert(D && "Expected decl");
00137     DeclArg.Kind = Declaration;
00138     DeclArg.QT = QT.getAsOpaquePtr();
00139     DeclArg.D = D;
00140   }
00141 
00142   /// \brief Construct an integral constant template argument. The memory to
00143   /// store the value is allocated with Ctx.
00144   TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
00145 
00146   /// \brief Construct an integral constant template argument with the same
00147   /// value as Other but a different type.
00148   TemplateArgument(const TemplateArgument &Other, QualType Type) {
00149     Integer = Other.Integer;
00150     Integer.Type = Type.getAsOpaquePtr();
00151   }
00152 
00153   /// \brief Construct a template argument that is a template.
00154   ///
00155   /// This form of template argument is generally used for template template
00156   /// parameters. However, the template name could be a dependent template
00157   /// name that ends up being instantiated to a function template whose address
00158   /// is taken.
00159   ///
00160   /// \param Name The template name.
00161   TemplateArgument(TemplateName Name) {
00162     TemplateArg.Kind = Template;
00163     TemplateArg.Name = Name.getAsVoidPointer();
00164     TemplateArg.NumExpansions = 0;
00165   }
00166 
00167   /// \brief Construct a template argument that is a template pack expansion.
00168   ///
00169   /// This form of template argument is generally used for template template
00170   /// parameters. However, the template name could be a dependent template
00171   /// name that ends up being instantiated to a function template whose address
00172   /// is taken.
00173   ///
00174   /// \param Name The template name.
00175   ///
00176   /// \param NumExpansions The number of expansions that will be generated by
00177   /// instantiating
00178   TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
00179     TemplateArg.Kind = TemplateExpansion;
00180     TemplateArg.Name = Name.getAsVoidPointer();
00181     if (NumExpansions)
00182       TemplateArg.NumExpansions = *NumExpansions + 1;
00183     else
00184       TemplateArg.NumExpansions = 0;
00185   }
00186 
00187   /// \brief Construct a template argument that is an expression.
00188   ///
00189   /// This form of template argument only occurs in template argument
00190   /// lists used for dependent types and for expression; it will not
00191   /// occur in a non-dependent, canonical template argument list.
00192   TemplateArgument(Expr *E) {
00193     TypeOrValue.Kind = Expression;
00194     TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
00195   }
00196 
00197   /// \brief Construct a template argument that is a template argument pack.
00198   ///
00199   /// We assume that storage for the template arguments provided
00200   /// outlives the TemplateArgument itself.
00201   TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) {
00202     this->Args.Kind = Pack;
00203     this->Args.Args = Args;
00204     this->Args.NumArgs = NumArgs;
00205   }
00206 
00207   static TemplateArgument getEmptyPack() {
00208     return TemplateArgument((TemplateArgument*)nullptr, 0);
00209   }
00210 
00211   /// \brief Create a new template argument pack by copying the given set of
00212   /// template arguments.
00213   static TemplateArgument CreatePackCopy(ASTContext &Context,
00214                                          const TemplateArgument *Args,
00215                                          unsigned NumArgs);
00216   
00217   /// \brief Return the kind of stored template argument.
00218   ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
00219 
00220   /// \brief Determine whether this template argument has no value.
00221   bool isNull() const { return getKind() == Null; }
00222 
00223   /// \brief Whether this template argument is dependent on a template
00224   /// parameter such that its result can change from one instantiation to
00225   /// another.
00226   bool isDependent() const;
00227 
00228   /// \brief Whether this template argument is dependent on a template
00229   /// parameter.
00230   bool isInstantiationDependent() const;
00231 
00232   /// \brief Whether this template argument contains an unexpanded
00233   /// parameter pack.
00234   bool containsUnexpandedParameterPack() const;
00235 
00236   /// \brief Determine whether this template argument is a pack expansion.
00237   bool isPackExpansion() const;
00238   
00239   /// \brief Retrieve the type for a type template argument.
00240   QualType getAsType() const {
00241     assert(getKind() == Type && "Unexpected kind");
00242     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
00243   }
00244 
00245   /// \brief Retrieve the declaration for a declaration non-type
00246   /// template argument.
00247   ValueDecl *getAsDecl() const {
00248     assert(getKind() == Declaration && "Unexpected kind");
00249     return DeclArg.D;
00250   }
00251 
00252   QualType getParamTypeForDecl() const {
00253     assert(getKind() == Declaration && "Unexpected kind");
00254     return QualType::getFromOpaquePtr(DeclArg.QT);
00255   }
00256 
00257   /// \brief Retrieve the type for null non-type template argument.
00258   QualType getNullPtrType() const {
00259     assert(getKind() == NullPtr && "Unexpected kind");
00260     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
00261   }
00262 
00263   /// \brief Retrieve the template name for a template name argument.
00264   TemplateName getAsTemplate() const {
00265     assert(getKind() == Template && "Unexpected kind");
00266     return TemplateName::getFromVoidPointer(TemplateArg.Name);
00267   }
00268 
00269   /// \brief Retrieve the template argument as a template name; if the argument
00270   /// is a pack expansion, return the pattern as a template name.
00271   TemplateName getAsTemplateOrTemplatePattern() const {
00272     assert((getKind() == Template || getKind() == TemplateExpansion) &&
00273            "Unexpected kind");
00274     
00275     return TemplateName::getFromVoidPointer(TemplateArg.Name);
00276   }
00277 
00278   /// \brief Retrieve the number of expansions that a template template argument
00279   /// expansion will produce, if known.
00280   Optional<unsigned> getNumTemplateExpansions() const;
00281   
00282   /// \brief Retrieve the template argument as an integral value.
00283   // FIXME: Provide a way to read the integral data without copying the value.
00284   llvm::APSInt getAsIntegral() const {
00285     assert(getKind() == Integral && "Unexpected kind");
00286     using namespace llvm;
00287     if (Integer.BitWidth <= 64)
00288       return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
00289 
00290     unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
00291     return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
00292                   Integer.IsUnsigned);
00293   }
00294 
00295   /// \brief Retrieve the type of the integral value.
00296   QualType getIntegralType() const {
00297     assert(getKind() == Integral && "Unexpected kind");
00298     return QualType::getFromOpaquePtr(Integer.Type);
00299   }
00300 
00301   void setIntegralType(QualType T) {
00302     assert(getKind() == Integral && "Unexpected kind");
00303     Integer.Type = T.getAsOpaquePtr();
00304   }
00305 
00306   /// \brief Retrieve the template argument as an expression.
00307   Expr *getAsExpr() const {
00308     assert(getKind() == Expression && "Unexpected kind");
00309     return reinterpret_cast<Expr *>(TypeOrValue.V);
00310   }
00311 
00312   /// \brief Iterator that traverses the elements of a template argument pack.
00313   typedef const TemplateArgument * pack_iterator;
00314 
00315   /// \brief Iterator referencing the first argument of a template argument
00316   /// pack.
00317   pack_iterator pack_begin() const {
00318     assert(getKind() == Pack);
00319     return Args.Args;
00320   }
00321 
00322   /// \brief Iterator referencing one past the last argument of a template
00323   /// argument pack.
00324   pack_iterator pack_end() const {
00325     assert(getKind() == Pack);
00326     return Args.Args + Args.NumArgs;
00327   }
00328 
00329   /// \brief Iterator range referencing all of the elements of a template
00330   /// argument pack.
00331   llvm::iterator_range<pack_iterator> pack_elements() const {
00332     return llvm::make_range(pack_begin(), pack_end());
00333   }
00334 
00335   /// \brief The number of template arguments in the given template argument
00336   /// pack.
00337   unsigned pack_size() const {
00338     assert(getKind() == Pack);
00339     return Args.NumArgs;
00340   }
00341 
00342   /// \brief Return the array of arguments in this template argument pack.
00343   ArrayRef<TemplateArgument> getPackAsArray() const {
00344     assert(getKind() == Pack);
00345     return llvm::makeArrayRef(Args.Args, Args.NumArgs);
00346   }
00347 
00348   /// \brief Determines whether two template arguments are superficially the
00349   /// same.
00350   bool structurallyEquals(const TemplateArgument &Other) const;
00351 
00352   /// \brief When the template argument is a pack expansion, returns
00353   /// the pattern of the pack expansion.
00354   TemplateArgument getPackExpansionPattern() const;
00355 
00356   /// \brief Print this template argument to the given output stream.
00357   void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
00358              
00359   /// \brief Used to insert TemplateArguments into FoldingSets.
00360   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
00361 };
00362 
00363 /// Location information for a TemplateArgument.
00364 struct TemplateArgumentLocInfo {
00365 private:
00366 
00367   struct T {
00368     // FIXME: We'd like to just use the qualifier in the TemplateName,
00369     // but template arguments get canonicalized too quickly.
00370     NestedNameSpecifier *Qualifier;
00371     void *QualifierLocData;
00372     unsigned TemplateNameLoc;
00373     unsigned EllipsisLoc;
00374   };
00375 
00376   union {
00377     struct T Template;
00378     Expr *Expression;
00379     TypeSourceInfo *Declarator;
00380   };
00381 
00382 public:
00383   TemplateArgumentLocInfo();
00384   
00385   TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
00386   
00387   TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
00388   
00389   TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
00390                           SourceLocation TemplateNameLoc,
00391                           SourceLocation EllipsisLoc)
00392   {
00393     Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
00394     Template.QualifierLocData = QualifierLoc.getOpaqueData();
00395     Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
00396     Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
00397   }
00398 
00399   TypeSourceInfo *getAsTypeSourceInfo() const {
00400     return Declarator;
00401   }
00402 
00403   Expr *getAsExpr() const {
00404     return Expression;
00405   }
00406 
00407   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
00408     return NestedNameSpecifierLoc(Template.Qualifier, 
00409                                   Template.QualifierLocData);
00410   }
00411   
00412   SourceLocation getTemplateNameLoc() const {
00413     return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
00414   }
00415   
00416   SourceLocation getTemplateEllipsisLoc() const {
00417     return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
00418   }
00419 };
00420 
00421 /// Location wrapper for a TemplateArgument.  TemplateArgument is to
00422 /// TemplateArgumentLoc as Type is to TypeLoc.
00423 class TemplateArgumentLoc {
00424   TemplateArgument Argument;
00425   TemplateArgumentLocInfo LocInfo;
00426 
00427 public:
00428   TemplateArgumentLoc() {}
00429 
00430   TemplateArgumentLoc(const TemplateArgument &Argument,
00431                       TemplateArgumentLocInfo Opaque)
00432     : Argument(Argument), LocInfo(Opaque) {
00433   }
00434 
00435   TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
00436     : Argument(Argument), LocInfo(TInfo) {
00437     assert(Argument.getKind() == TemplateArgument::Type);
00438   }
00439 
00440   TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
00441     : Argument(Argument), LocInfo(E) {
00442     assert(Argument.getKind() == TemplateArgument::Expression);
00443   }
00444 
00445   TemplateArgumentLoc(const TemplateArgument &Argument, 
00446                       NestedNameSpecifierLoc QualifierLoc,
00447                       SourceLocation TemplateNameLoc,
00448                       SourceLocation EllipsisLoc = SourceLocation())
00449     : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
00450     assert(Argument.getKind() == TemplateArgument::Template ||
00451            Argument.getKind() == TemplateArgument::TemplateExpansion);
00452   }
00453   
00454   /// \brief - Fetches the primary location of the argument.
00455   SourceLocation getLocation() const {
00456     if (Argument.getKind() == TemplateArgument::Template ||
00457         Argument.getKind() == TemplateArgument::TemplateExpansion)
00458       return getTemplateNameLoc();
00459     
00460     return getSourceRange().getBegin();
00461   }
00462 
00463   /// \brief - Fetches the full source range of the argument.
00464   SourceRange getSourceRange() const LLVM_READONLY;
00465 
00466   const TemplateArgument &getArgument() const {
00467     return Argument;
00468   }
00469 
00470   TemplateArgumentLocInfo getLocInfo() const {
00471     return LocInfo;
00472   }
00473 
00474   TypeSourceInfo *getTypeSourceInfo() const {
00475     assert(Argument.getKind() == TemplateArgument::Type);
00476     return LocInfo.getAsTypeSourceInfo();
00477   }
00478 
00479   Expr *getSourceExpression() const {
00480     assert(Argument.getKind() == TemplateArgument::Expression);
00481     return LocInfo.getAsExpr();
00482   }
00483 
00484   Expr *getSourceDeclExpression() const {
00485     assert(Argument.getKind() == TemplateArgument::Declaration);
00486     return LocInfo.getAsExpr();
00487   }
00488 
00489   Expr *getSourceNullPtrExpression() const {
00490     assert(Argument.getKind() == TemplateArgument::NullPtr);
00491     return LocInfo.getAsExpr();
00492   }
00493 
00494   Expr *getSourceIntegralExpression() const {
00495     assert(Argument.getKind() == TemplateArgument::Integral);
00496     return LocInfo.getAsExpr();
00497   }
00498 
00499   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
00500     assert(Argument.getKind() == TemplateArgument::Template ||
00501            Argument.getKind() == TemplateArgument::TemplateExpansion);
00502     return LocInfo.getTemplateQualifierLoc();
00503   }
00504   
00505   SourceLocation getTemplateNameLoc() const {
00506     assert(Argument.getKind() == TemplateArgument::Template ||
00507            Argument.getKind() == TemplateArgument::TemplateExpansion);
00508     return LocInfo.getTemplateNameLoc();
00509   }  
00510   
00511   SourceLocation getTemplateEllipsisLoc() const {
00512     assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
00513     return LocInfo.getTemplateEllipsisLoc();
00514   }
00515 };
00516 
00517 /// A convenient class for passing around template argument
00518 /// information.  Designed to be passed by reference.
00519 class TemplateArgumentListInfo {
00520   SmallVector<TemplateArgumentLoc, 8> Arguments;
00521   SourceLocation LAngleLoc;
00522   SourceLocation RAngleLoc;
00523 
00524   // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
00525   // instead.
00526   void* operator new(size_t bytes, ASTContext& C);
00527 
00528 public:
00529   TemplateArgumentListInfo() {}
00530 
00531   TemplateArgumentListInfo(SourceLocation LAngleLoc,
00532                            SourceLocation RAngleLoc)
00533     : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
00534 
00535   SourceLocation getLAngleLoc() const { return LAngleLoc; }
00536   SourceLocation getRAngleLoc() const { return RAngleLoc; }
00537 
00538   void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
00539   void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
00540 
00541   unsigned size() const { return Arguments.size(); }
00542 
00543   const TemplateArgumentLoc *getArgumentArray() const {
00544     return Arguments.data();
00545   }
00546 
00547   const TemplateArgumentLoc &operator[](unsigned I) const {
00548     return Arguments[I];
00549   }
00550 
00551   TemplateArgumentLoc &operator[](unsigned I) {
00552     return Arguments[I];
00553   }
00554 
00555   void addArgument(const TemplateArgumentLoc &Loc) {
00556     Arguments.push_back(Loc);
00557   }
00558 };
00559 
00560 /// \brief Represents an explicit template argument list in C++, e.g.,
00561 /// the "<int>" in "sort<int>".
00562 /// This is safe to be used inside an AST node, in contrast with
00563 /// TemplateArgumentListInfo.
00564 struct ASTTemplateArgumentListInfo {
00565   /// \brief The source location of the left angle bracket ('<').
00566   SourceLocation LAngleLoc;
00567   
00568   /// \brief The source location of the right angle bracket ('>').
00569   SourceLocation RAngleLoc;
00570   
00571   union {
00572     /// \brief The number of template arguments in TemplateArgs.
00573     /// The actual template arguments (if any) are stored after the
00574     /// ExplicitTemplateArgumentList structure.
00575     unsigned NumTemplateArgs;
00576 
00577     /// Force ASTTemplateArgumentListInfo to the right alignment
00578     /// for the following array of TemplateArgumentLocs.
00579     llvm::AlignedCharArray<
00580         llvm::AlignOf<TemplateArgumentLoc>::Alignment, 1> Aligner;
00581   };
00582 
00583   /// \brief Retrieve the template arguments
00584   TemplateArgumentLoc *getTemplateArgs() {
00585     return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
00586   }
00587   
00588   /// \brief Retrieve the template arguments
00589   const TemplateArgumentLoc *getTemplateArgs() const {
00590     return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
00591   }
00592 
00593   const TemplateArgumentLoc &operator[](unsigned I) const {
00594     return getTemplateArgs()[I];
00595   }
00596 
00597   static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
00598                                           const TemplateArgumentListInfo &List);
00599 
00600   void initializeFrom(const TemplateArgumentListInfo &List);
00601   void initializeFrom(const TemplateArgumentListInfo &List,
00602                       bool &Dependent, bool &InstantiationDependent,
00603                       bool &ContainsUnexpandedParameterPack);
00604   void copyInto(TemplateArgumentListInfo &List) const;
00605   static std::size_t sizeFor(unsigned NumTemplateArgs);
00606 };
00607 
00608 /// \brief Extends ASTTemplateArgumentListInfo with the source location
00609 /// information for the template keyword; this is used as part of the
00610 /// representation of qualified identifiers, such as S<T>::template apply<T>.
00611 struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
00612   typedef ASTTemplateArgumentListInfo Base;
00613 
00614   // NOTE: the source location of the (optional) template keyword is
00615   // stored after all template arguments.
00616 
00617   /// \brief Get the source location of the template keyword.
00618   SourceLocation getTemplateKeywordLoc() const {
00619     return *reinterpret_cast<const SourceLocation*>
00620       (getTemplateArgs() + NumTemplateArgs);
00621   }
00622 
00623   /// \brief Sets the source location of the template keyword.
00624   void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
00625     *reinterpret_cast<SourceLocation*>
00626       (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
00627   }
00628 
00629   static const ASTTemplateKWAndArgsInfo*
00630   Create(ASTContext &C, SourceLocation TemplateKWLoc,
00631          const TemplateArgumentListInfo &List);
00632 
00633   void initializeFrom(SourceLocation TemplateKWLoc,
00634                       const TemplateArgumentListInfo &List);
00635   void initializeFrom(SourceLocation TemplateKWLoc,
00636                       const TemplateArgumentListInfo &List,
00637                       bool &Dependent, bool &InstantiationDependent,
00638                       bool &ContainsUnexpandedParameterPack);
00639   void initializeFrom(SourceLocation TemplateKWLoc);
00640 
00641   static std::size_t sizeFor(unsigned NumTemplateArgs);
00642 };
00643 
00644 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00645                                     const TemplateArgument &Arg);
00646 
00647 inline TemplateSpecializationType::iterator
00648     TemplateSpecializationType::end() const {
00649   return getArgs() + getNumArgs();
00650 }
00651 
00652 inline DependentTemplateSpecializationType::iterator
00653     DependentTemplateSpecializationType::end() const {
00654   return getArgs() + getNumArgs();
00655 }
00656 
00657 inline const TemplateArgument &
00658     TemplateSpecializationType::getArg(unsigned Idx) const {
00659   assert(Idx < getNumArgs() && "Template argument out of range");
00660   return getArgs()[Idx];
00661 }
00662 
00663 inline const TemplateArgument &
00664     DependentTemplateSpecializationType::getArg(unsigned Idx) const {
00665   assert(Idx < getNumArgs() && "Template argument out of range");
00666   return getArgs()[Idx];
00667 }
00668   
00669 } // end namespace clang
00670 
00671 #endif