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