1193326Sed//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9239462Sdim/// 10239462Sdim/// \file 11239462Sdim/// \brief Defines the C++ template declaration subclasses. 12239462Sdim/// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed 15193326Sed#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H 16193326Sed#define LLVM_CLANG_AST_DECLTEMPLATE_H 17193326Sed 18193326Sed#include "clang/AST/DeclCXX.h" 19234353Sdim#include "clang/AST/Redeclarable.h" 20198893Srdivacky#include "clang/AST/TemplateBase.h" 21194179Sed#include "llvm/ADT/PointerUnion.h" 22234353Sdim#include "llvm/Support/Compiler.h" 23194613Sed#include <limits> 24193326Sed 25193326Sednamespace clang { 26193326Sed 27193326Sedclass TemplateParameterList; 28193326Sedclass TemplateDecl; 29212904Sdimclass RedeclarableTemplateDecl; 30193326Sedclass FunctionTemplateDecl; 31193326Sedclass ClassTemplateDecl; 32193326Sedclass ClassTemplatePartialSpecializationDecl; 33193326Sedclass TemplateTypeParmDecl; 34193326Sedclass NonTypeTemplateParmDecl; 35193326Sedclass TemplateTemplateParmDecl; 36223017Sdimclass TypeAliasTemplateDecl; 37263508Sdimclass VarTemplateDecl; 38263508Sdimclass VarTemplatePartialSpecializationDecl; 39193326Sed 40194179Sed/// \brief Stores a template parameter of any kind. 41194179Sedtypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*, 42194179Sed TemplateTemplateParmDecl*> TemplateParameter; 43194179Sed 44239462Sdim/// \brief Stores a list of template parameters for a TemplateDecl and its 45239462Sdim/// derived classes. 46193326Sedclass TemplateParameterList { 47193326Sed /// The location of the 'template' keyword. 48193326Sed SourceLocation TemplateLoc; 49193326Sed 50193326Sed /// The locations of the '<' and '>' angle brackets. 51193326Sed SourceLocation LAngleLoc, RAngleLoc; 52193326Sed 53193326Sed /// The number of template parameters in this template 54193326Sed /// parameter list. 55243830Sdim unsigned NumParams : 31; 56193326Sed 57243830Sdim /// Whether this template parameter list contains an unexpanded parameter 58243830Sdim /// pack. 59243830Sdim unsigned ContainsUnexpandedParameterPack : 1; 60243830Sdim 61219077Sdimprotected: 62193326Sed TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, 63198092Srdivacky NamedDecl **Params, unsigned NumParams, 64193326Sed SourceLocation RAngleLoc); 65193326Sed 66193326Sedpublic: 67218893Sdim static TemplateParameterList *Create(const ASTContext &C, 68193326Sed SourceLocation TemplateLoc, 69193326Sed SourceLocation LAngleLoc, 70198092Srdivacky NamedDecl **Params, 71193326Sed unsigned NumParams, 72193326Sed SourceLocation RAngleLoc); 73193326Sed 74239462Sdim /// \brief Iterates through the template parameters in this list. 75198092Srdivacky typedef NamedDecl** iterator; 76193326Sed 77239462Sdim /// \brief Iterates through the template parameters in this list. 78198092Srdivacky typedef NamedDecl* const* const_iterator; 79193326Sed 80198092Srdivacky iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); } 81193326Sed const_iterator begin() const { 82198092Srdivacky return reinterpret_cast<NamedDecl * const *>(this + 1); 83193326Sed } 84193326Sed iterator end() { return begin() + NumParams; } 85193326Sed const_iterator end() const { return begin() + NumParams; } 86193326Sed 87193326Sed unsigned size() const { return NumParams; } 88193326Sed 89249423Sdim llvm::ArrayRef<NamedDecl*> asArray() { 90249423Sdim return llvm::ArrayRef<NamedDecl*>(begin(), size()); 91249423Sdim } 92249423Sdim llvm::ArrayRef<const NamedDecl*> asArray() const { 93249423Sdim return llvm::ArrayRef<const NamedDecl*>(begin(), size()); 94249423Sdim } 95249423Sdim 96198092Srdivacky NamedDecl* getParam(unsigned Idx) { 97194179Sed assert(Idx < size() && "Template parameter index out-of-range"); 98194179Sed return begin()[Idx]; 99194179Sed } 100194179Sed 101198092Srdivacky const NamedDecl* getParam(unsigned Idx) const { 102193326Sed assert(Idx < size() && "Template parameter index out-of-range"); 103193326Sed return begin()[Idx]; 104193326Sed } 105193326Sed 106218893Sdim /// \brief Returns the minimum number of arguments needed to form a 107239462Sdim /// template specialization. 108239462Sdim /// 109239462Sdim /// This may be fewer than the number of template parameters, if some of 110239462Sdim /// the parameters have default arguments or if there is a parameter pack. 111193326Sed unsigned getMinRequiredArguments() const; 112193326Sed 113198893Srdivacky /// \brief Get the depth of this template parameter list in the set of 114198893Srdivacky /// template parameter lists. 115198893Srdivacky /// 116198893Srdivacky /// The first template parameter list in a declaration will have depth 0, 117198893Srdivacky /// the second template parameter list will have depth 1, etc. 118198893Srdivacky unsigned getDepth() const; 119234353Sdim 120243830Sdim /// \brief Determine whether this template parameter list contains an 121243830Sdim /// unexpanded parameter pack. 122243830Sdim bool containsUnexpandedParameterPack() const { 123243830Sdim return ContainsUnexpandedParameterPack; 124243830Sdim } 125243830Sdim 126193326Sed SourceLocation getTemplateLoc() const { return TemplateLoc; } 127193326Sed SourceLocation getLAngleLoc() const { return LAngleLoc; } 128193326Sed SourceLocation getRAngleLoc() const { return RAngleLoc; } 129193326Sed 130234353Sdim SourceRange getSourceRange() const LLVM_READONLY { 131193326Sed return SourceRange(TemplateLoc, RAngleLoc); 132193326Sed } 133193326Sed}; 134193326Sed 135239462Sdim/// \brief Stores a list of template parameters for a TemplateDecl and its 136239462Sdim/// derived classes. Suitable for creating on the stack. 137219077Sdimtemplate<size_t N> 138219077Sdimclass FixedSizeTemplateParameterList : public TemplateParameterList { 139219077Sdim NamedDecl *Params[N]; 140219077Sdim 141219077Sdimpublic: 142234353Sdim FixedSizeTemplateParameterList(SourceLocation TemplateLoc, 143234353Sdim SourceLocation LAngleLoc, 144219077Sdim NamedDecl **Params, SourceLocation RAngleLoc) : 145219077Sdim TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) { 146219077Sdim } 147219077Sdim}; 148219077Sdim 149195341Sed/// \brief A template argument list. 150195341Sedclass TemplateArgumentList { 151195341Sed /// \brief The template argument list. 152195341Sed /// 153195341Sed /// The integer value will be non-zero to indicate that this 154208600Srdivacky /// template argument list does own the pointer. 155218893Sdim llvm::PointerIntPair<const TemplateArgument *, 1> Arguments; 156198092Srdivacky 157195341Sed /// \brief The number of template arguments in this template 158195341Sed /// argument list. 159218893Sdim unsigned NumArguments; 160198092Srdivacky 161243830Sdim TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; 162243830Sdim void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; 163198092Srdivacky 164218893Sdim TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, 165218893Sdim bool Owned) 166218893Sdim : Arguments(Args, Owned), NumArguments(NumArgs) { } 167210299Sed 168218893Sdimpublic: 169234353Sdim /// \brief Type used to indicate that the template argument list itself is a 170218893Sdim /// stack object. It does not own its template arguments. 171218893Sdim enum OnStackType { OnStack }; 172210299Sed 173218893Sdim /// \brief Create a new template argument list that copies the given set of 174218893Sdim /// template arguments. 175218893Sdim static TemplateArgumentList *CreateCopy(ASTContext &Context, 176218893Sdim const TemplateArgument *Args, 177218893Sdim unsigned NumArgs); 178210299Sed 179218893Sdim /// \brief Construct a new, temporary template argument list on the stack. 180218893Sdim /// 181218893Sdim /// The template argument list does not own the template arguments 182218893Sdim /// provided. 183234353Sdim explicit TemplateArgumentList(OnStackType, 184218893Sdim const TemplateArgument *Args, unsigned NumArgs) 185218893Sdim : Arguments(Args, false), NumArguments(NumArgs) { } 186234353Sdim 187234353Sdim /// \brief Produces a shallow copy of the given template argument list. 188234353Sdim /// 189218893Sdim /// This operation assumes that the input argument list outlives it. 190218893Sdim /// This takes the list as a pointer to avoid looking like a copy 191218893Sdim /// constructor, since this really really isn't safe to use that 192218893Sdim /// way. 193218893Sdim explicit TemplateArgumentList(const TemplateArgumentList *Other) 194218893Sdim : Arguments(Other->data(), false), NumArguments(Other->size()) { } 195198092Srdivacky 196195341Sed /// \brief Retrieve the template argument at a given index. 197198092Srdivacky const TemplateArgument &get(unsigned Idx) const { 198218893Sdim assert(Idx < NumArguments && "Invalid template argument index"); 199218893Sdim return data()[Idx]; 200195341Sed } 201198092Srdivacky 202195341Sed /// \brief Retrieve the template argument at a given index. 203195341Sed const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); } 204198092Srdivacky 205249423Sdim /// \brief Produce this as an array ref. 206249423Sdim llvm::ArrayRef<TemplateArgument> asArray() const { 207249423Sdim return llvm::ArrayRef<TemplateArgument>(data(), size()); 208249423Sdim } 209249423Sdim 210195341Sed /// \brief Retrieve the number of template arguments in this 211195341Sed /// template argument list. 212218893Sdim unsigned size() const { return NumArguments; } 213198092Srdivacky 214218893Sdim /// \brief Retrieve a pointer to the template argument list. 215218893Sdim const TemplateArgument *data() const { 216218893Sdim return Arguments.getPointer(); 217195341Sed } 218195341Sed}; 219198092Srdivacky 220193326Sed//===----------------------------------------------------------------------===// 221193326Sed// Kinds of Templates 222193326Sed//===----------------------------------------------------------------------===// 223193326Sed 224239462Sdim/// \brief The base class of all kinds of template declarations (e.g., 225239462Sdim/// class, function, etc.). 226239462Sdim/// 227239462Sdim/// The TemplateDecl class stores the list of template parameters and a 228239462Sdim/// reference to the templated scoped declaration: the underlying AST node. 229193326Sedclass TemplateDecl : public NamedDecl { 230234353Sdim virtual void anchor(); 231193326Sedprotected: 232193326Sed // This is probably never used. 233193326Sed TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, 234193326Sed DeclarationName Name) 235198092Srdivacky : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { } 236193326Sed 237193326Sed // Construct a template decl with the given name and parameters. 238193326Sed // Used when there is not templated element (tt-params, alias?). 239193326Sed TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, 240193326Sed DeclarationName Name, TemplateParameterList *Params) 241198092Srdivacky : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { } 242193326Sed 243193326Sed // Construct a template decl with name, parameters, and templated element. 244193326Sed TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, 245193326Sed DeclarationName Name, TemplateParameterList *Params, 246193326Sed NamedDecl *Decl) 247193326Sed : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), 248193326Sed TemplateParams(Params) { } 249193326Sedpublic: 250193326Sed /// Get the list of template parameters 251193326Sed TemplateParameterList *getTemplateParameters() const { 252193326Sed return TemplateParams; 253193326Sed } 254193326Sed 255193326Sed /// Get the underlying, templated declaration. 256193326Sed NamedDecl *getTemplatedDecl() const { return TemplatedDecl; } 257193326Sed 258193326Sed // Implement isa/cast/dyncast/etc. 259203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 260203955Srdivacky static bool classofKind(Kind K) { 261210299Sed return K >= firstTemplate && K <= lastTemplate; 262203955Srdivacky } 263193326Sed 264234353Sdim SourceRange getSourceRange() const LLVM_READONLY { 265210299Sed return SourceRange(TemplateParams->getTemplateLoc(), 266210299Sed TemplatedDecl->getSourceRange().getEnd()); 267210299Sed } 268210299Sed 269193326Sedprotected: 270193326Sed NamedDecl *TemplatedDecl; 271193326Sed TemplateParameterList* TemplateParams; 272234353Sdim 273210299Sedpublic: 274210299Sed /// \brief Initialize the underlying templated declaration and 275210299Sed /// template parameters. 276210299Sed void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) { 277210299Sed assert(TemplatedDecl == 0 && "TemplatedDecl already set!"); 278210299Sed assert(TemplateParams == 0 && "TemplateParams already set!"); 279210299Sed TemplatedDecl = templatedDecl; 280210299Sed TemplateParams = templateParams; 281210299Sed } 282193326Sed}; 283198092Srdivacky 284198092Srdivacky/// \brief Provides information about a function template specialization, 285195341Sed/// which is a FunctionDecl that has been explicitly specialization or 286195341Sed/// instantiated from a function template. 287195341Sedclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode { 288218893Sdim FunctionTemplateSpecializationInfo(FunctionDecl *FD, 289218893Sdim FunctionTemplateDecl *Template, 290218893Sdim TemplateSpecializationKind TSK, 291218893Sdim const TemplateArgumentList *TemplateArgs, 292226633Sdim const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, 293218893Sdim SourceLocation POI) 294218893Sdim : Function(FD), 295218893Sdim Template(Template, TSK - 1), 296218893Sdim TemplateArguments(TemplateArgs), 297218893Sdim TemplateArgumentsAsWritten(TemplateArgsAsWritten), 298218893Sdim PointOfInstantiation(POI) { } 299218893Sdim 300195341Sedpublic: 301218893Sdim static FunctionTemplateSpecializationInfo * 302218893Sdim Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, 303218893Sdim TemplateSpecializationKind TSK, 304218893Sdim const TemplateArgumentList *TemplateArgs, 305218893Sdim const TemplateArgumentListInfo *TemplateArgsAsWritten, 306226633Sdim SourceLocation POI); 307218893Sdim 308198092Srdivacky /// \brief The function template specialization that this structure 309195341Sed /// describes. 310195341Sed FunctionDecl *Function; 311198092Srdivacky 312198092Srdivacky /// \brief The function template from which this function template 313195341Sed /// specialization was generated. 314195341Sed /// 315198092Srdivacky /// The two bits are contain the top 4 values of TemplateSpecializationKind. 316198092Srdivacky llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template; 317198092Srdivacky 318195341Sed /// \brief The template arguments used to produce the function template 319195341Sed /// specialization from the function template. 320195341Sed const TemplateArgumentList *TemplateArguments; 321198092Srdivacky 322208600Srdivacky /// \brief The template arguments as written in the sources, if provided. 323226633Sdim const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten; 324208600Srdivacky 325198092Srdivacky /// \brief The point at which this function template specialization was 326234353Sdim /// first instantiated. 327198092Srdivacky SourceLocation PointOfInstantiation; 328234353Sdim 329195341Sed /// \brief Retrieve the template from which this function was specialized. 330195341Sed FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); } 331198092Srdivacky 332198092Srdivacky /// \brief Determine what kind of template specialization this is. 333198092Srdivacky TemplateSpecializationKind getTemplateSpecializationKind() const { 334198092Srdivacky return (TemplateSpecializationKind)(Template.getInt() + 1); 335198092Srdivacky } 336198092Srdivacky 337224145Sdim bool isExplicitSpecialization() const { 338224145Sdim return getTemplateSpecializationKind() == TSK_ExplicitSpecialization; 339224145Sdim } 340224145Sdim 341249423Sdim /// \brief True if this declaration is an explicit specialization, 342249423Sdim /// explicit instantiation declaration, or explicit instantiation 343249423Sdim /// definition. 344249423Sdim bool isExplicitInstantiationOrSpecialization() const { 345249423Sdim switch (getTemplateSpecializationKind()) { 346249423Sdim case TSK_ExplicitSpecialization: 347249423Sdim case TSK_ExplicitInstantiationDeclaration: 348249423Sdim case TSK_ExplicitInstantiationDefinition: 349249423Sdim return true; 350249423Sdim 351249423Sdim case TSK_Undeclared: 352249423Sdim case TSK_ImplicitInstantiation: 353249423Sdim return false; 354249423Sdim } 355249423Sdim llvm_unreachable("bad template specialization kind"); 356249423Sdim } 357249423Sdim 358198092Srdivacky /// \brief Set the template specialization kind. 359198092Srdivacky void setTemplateSpecializationKind(TemplateSpecializationKind TSK) { 360198092Srdivacky assert(TSK != TSK_Undeclared && 361198092Srdivacky "Cannot encode TSK_Undeclared for a function template specialization"); 362198092Srdivacky Template.setInt(TSK - 1); 363198092Srdivacky } 364198092Srdivacky 365198092Srdivacky /// \brief Retrieve the first point of instantiation of this function 366198092Srdivacky /// template specialization. 367198092Srdivacky /// 368198092Srdivacky /// The point of instantiation may be an invalid source location if this 369198092Srdivacky /// function has yet to be instantiated. 370234353Sdim SourceLocation getPointOfInstantiation() const { 371234353Sdim return PointOfInstantiation; 372198092Srdivacky } 373234353Sdim 374198092Srdivacky /// \brief Set the (first) point of instantiation of this function template 375198092Srdivacky /// specialization. 376198092Srdivacky void setPointOfInstantiation(SourceLocation POI) { 377198092Srdivacky PointOfInstantiation = POI; 378195341Sed } 379234353Sdim 380195341Sed void Profile(llvm::FoldingSetNodeID &ID) { 381218893Sdim Profile(ID, TemplateArguments->data(), 382218893Sdim TemplateArguments->size(), 383198092Srdivacky Function->getASTContext()); 384195341Sed } 385198092Srdivacky 386198092Srdivacky static void 387198092Srdivacky Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs, 388198092Srdivacky unsigned NumTemplateArgs, ASTContext &Context) { 389195341Sed ID.AddInteger(NumTemplateArgs); 390195341Sed for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg) 391198092Srdivacky TemplateArgs[Arg].Profile(ID, Context); 392198092Srdivacky } 393195341Sed}; 394198092Srdivacky 395234353Sdim/// \brief Provides information a specialization of a member of a class 396234353Sdim/// template, which may be a member function, static data member, 397234353Sdim/// member class or member enumeration. 398198092Srdivackyclass MemberSpecializationInfo { 399198092Srdivacky // The member declaration from which this member was instantiated, and the 400198092Srdivacky // manner in which the instantiation occurred (in the lower two bits). 401198092Srdivacky llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK; 402234353Sdim 403198092Srdivacky // The point at which this member was first instantiated. 404198092Srdivacky SourceLocation PointOfInstantiation; 405234353Sdim 406198092Srdivackypublic: 407234353Sdim explicit 408210299Sed MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, 409210299Sed SourceLocation POI = SourceLocation()) 410210299Sed : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) { 411234353Sdim assert(TSK != TSK_Undeclared && 412198092Srdivacky "Cannot encode undeclared template specializations for members"); 413198092Srdivacky } 414234353Sdim 415198092Srdivacky /// \brief Retrieve the member declaration from which this member was 416198092Srdivacky /// instantiated. 417198092Srdivacky NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); } 418234353Sdim 419198092Srdivacky /// \brief Determine what kind of template specialization this is. 420198092Srdivacky TemplateSpecializationKind getTemplateSpecializationKind() const { 421198092Srdivacky return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1); 422198092Srdivacky } 423234353Sdim 424249423Sdim bool isExplicitSpecialization() const { 425249423Sdim return getTemplateSpecializationKind() == TSK_ExplicitSpecialization; 426249423Sdim } 427249423Sdim 428198092Srdivacky /// \brief Set the template specialization kind. 429198092Srdivacky void setTemplateSpecializationKind(TemplateSpecializationKind TSK) { 430234353Sdim assert(TSK != TSK_Undeclared && 431198092Srdivacky "Cannot encode undeclared template specializations for members"); 432198092Srdivacky MemberAndTSK.setInt(TSK - 1); 433198092Srdivacky } 434234353Sdim 435234353Sdim /// \brief Retrieve the first point of instantiation of this member. 436198092Srdivacky /// If the point of instantiation is an invalid location, then this member 437198092Srdivacky /// has not yet been instantiated. 438234353Sdim SourceLocation getPointOfInstantiation() const { 439234353Sdim return PointOfInstantiation; 440198092Srdivacky } 441234353Sdim 442198092Srdivacky /// \brief Set the first point of instantiation. 443198092Srdivacky void setPointOfInstantiation(SourceLocation POI) { 444198092Srdivacky PointOfInstantiation = POI; 445198092Srdivacky } 446198092Srdivacky}; 447207619Srdivacky 448207619Srdivacky/// \brief Provides information about a dependent function-template 449239462Sdim/// specialization declaration. 450207619Srdivacky/// 451239462Sdim/// Since explicit function template specialization and instantiation 452239462Sdim/// declarations can only appear in namespace scope, and you can only 453239462Sdim/// specialize a member of a fully-specialized class, the only way to 454239462Sdim/// get one of these is in a friend declaration like the following: 455239462Sdim/// 456239462Sdim/// \code 457239462Sdim/// template \<class T> void foo(T); 458239462Sdim/// template \<class T> class A { 459207619Srdivacky/// friend void foo<>(T); 460207619Srdivacky/// }; 461239462Sdim/// \endcode 462207619Srdivackyclass DependentFunctionTemplateSpecializationInfo { 463249423Sdim struct CA { 464249423Sdim /// The number of potential template candidates. 465249423Sdim unsigned NumTemplates; 466249423Sdim 467249423Sdim /// The number of template arguments. 468249423Sdim unsigned NumArgs; 469249423Sdim }; 470249423Sdim 471207619Srdivacky union { 472207619Srdivacky // Force sizeof to be a multiple of sizeof(void*) so that the 473207619Srdivacky // trailing data is aligned. 474234353Sdim void *Aligner; 475249423Sdim struct CA d; 476207619Srdivacky }; 477207619Srdivacky 478207619Srdivacky /// The locations of the left and right angle brackets. 479207619Srdivacky SourceRange AngleLocs; 480207619Srdivacky 481207619Srdivacky FunctionTemplateDecl * const *getTemplates() const { 482207619Srdivacky return reinterpret_cast<FunctionTemplateDecl*const*>(this+1); 483207619Srdivacky } 484207619Srdivacky 485207619Srdivackypublic: 486207619Srdivacky DependentFunctionTemplateSpecializationInfo( 487207619Srdivacky const UnresolvedSetImpl &Templates, 488207619Srdivacky const TemplateArgumentListInfo &TemplateArgs); 489207619Srdivacky 490207619Srdivacky /// \brief Returns the number of function templates that this might 491207619Srdivacky /// be a specialization of. 492207619Srdivacky unsigned getNumTemplates() const { 493207619Srdivacky return d.NumTemplates; 494207619Srdivacky } 495207619Srdivacky 496207619Srdivacky /// \brief Returns the i'th template candidate. 497207619Srdivacky FunctionTemplateDecl *getTemplate(unsigned I) const { 498207619Srdivacky assert(I < getNumTemplates() && "template index out of range"); 499207619Srdivacky return getTemplates()[I]; 500207619Srdivacky } 501207619Srdivacky 502218893Sdim /// \brief Returns the explicit template arguments that were given. 503218893Sdim const TemplateArgumentLoc *getTemplateArgs() const { 504218893Sdim return reinterpret_cast<const TemplateArgumentLoc*>( 505234353Sdim &getTemplates()[getNumTemplates()]); 506218893Sdim } 507218893Sdim 508207619Srdivacky /// \brief Returns the number of explicit template arguments that were given. 509207619Srdivacky unsigned getNumTemplateArgs() const { 510207619Srdivacky return d.NumArgs; 511207619Srdivacky } 512207619Srdivacky 513207619Srdivacky /// \brief Returns the nth template argument. 514207619Srdivacky const TemplateArgumentLoc &getTemplateArg(unsigned I) const { 515207619Srdivacky assert(I < getNumTemplateArgs() && "template arg index out of range"); 516207619Srdivacky return getTemplateArgs()[I]; 517207619Srdivacky } 518207619Srdivacky 519207619Srdivacky SourceLocation getLAngleLoc() const { 520207619Srdivacky return AngleLocs.getBegin(); 521207619Srdivacky } 522207619Srdivacky 523207619Srdivacky SourceLocation getRAngleLoc() const { 524207619Srdivacky return AngleLocs.getEnd(); 525207619Srdivacky } 526207619Srdivacky}; 527234353Sdim 528212904Sdim/// Declaration of a redeclarable template. 529234353Sdimclass RedeclarableTemplateDecl : public TemplateDecl, 530234353Sdim public Redeclarable<RedeclarableTemplateDecl> 531234353Sdim{ 532234353Sdim typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base; 533234353Sdim virtual RedeclarableTemplateDecl *getNextRedeclaration() { 534234353Sdim return RedeclLink.getNext(); 535212904Sdim } 536234353Sdim virtual RedeclarableTemplateDecl *getPreviousDeclImpl() { 537234353Sdim return getPreviousDecl(); 538212904Sdim } 539234353Sdim virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() { 540234353Sdim return getMostRecentDecl(); 541212904Sdim } 542212904Sdim 543193326Sedprotected: 544212904Sdim template <typename EntryType> struct SpecEntryTraits { 545212904Sdim typedef EntryType DeclType; 546198092Srdivacky 547234353Sdim static DeclType *getMostRecentDecl(EntryType *D) { 548234353Sdim return D->getMostRecentDecl(); 549212904Sdim } 550212904Sdim }; 551198092Srdivacky 552212904Sdim template <typename EntryType, 553212904Sdim typename _SETraits = SpecEntryTraits<EntryType>, 554212904Sdim typename _DeclType = typename _SETraits::DeclType> 555212904Sdim class SpecIterator : public std::iterator<std::forward_iterator_tag, 556212904Sdim _DeclType*, ptrdiff_t, 557212904Sdim _DeclType*, _DeclType*> { 558212904Sdim typedef _SETraits SETraits; 559212904Sdim typedef _DeclType DeclType; 560212904Sdim 561239462Sdim typedef typename llvm::FoldingSetVector<EntryType>::iterator 562239462Sdim SetIteratorType; 563212904Sdim 564212904Sdim SetIteratorType SetIter; 565212904Sdim 566212904Sdim public: 567212904Sdim SpecIterator() : SetIter() {} 568212904Sdim SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {} 569212904Sdim 570212904Sdim DeclType *operator*() const { 571234353Sdim return SETraits::getMostRecentDecl(&*SetIter); 572212904Sdim } 573212904Sdim DeclType *operator->() const { return **this; } 574212904Sdim 575212904Sdim SpecIterator &operator++() { ++SetIter; return *this; } 576212904Sdim SpecIterator operator++(int) { 577212904Sdim SpecIterator tmp(*this); 578212904Sdim ++(*this); 579212904Sdim return tmp; 580212904Sdim } 581212904Sdim 582212904Sdim bool operator==(SpecIterator Other) const { 583212904Sdim return SetIter == Other.SetIter; 584212904Sdim } 585212904Sdim bool operator!=(SpecIterator Other) const { 586212904Sdim return SetIter != Other.SetIter; 587212904Sdim } 588212904Sdim }; 589212904Sdim 590212904Sdim template <typename EntryType> 591249423Sdim static SpecIterator<EntryType> 592239462Sdim makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) { 593212904Sdim return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin()); 594212904Sdim } 595212904Sdim 596212904Sdim template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType* 597239462Sdim findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs, 598212904Sdim const TemplateArgument *Args, unsigned NumArgs, 599212904Sdim void *&InsertPos); 600212904Sdim 601212904Sdim struct CommonBase { 602212904Sdim CommonBase() : InstantiatedFromMember(0, false) { } 603212904Sdim 604212904Sdim /// \brief The template from which this was most 605198092Srdivacky /// directly instantiated (or null). 606198092Srdivacky /// 607212904Sdim /// The boolean value indicates whether this template 608198092Srdivacky /// was explicitly specialized. 609212904Sdim llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool> 610212904Sdim InstantiatedFromMember; 611195341Sed }; 612198092Srdivacky 613234353Sdim /// \brief Pointer to the common data shared by all declarations of this 614234353Sdim /// template. 615249423Sdim mutable CommonBase *Common; 616234353Sdim 617212904Sdim /// \brief Retrieves the "common" pointer shared by all (re-)declarations of 618212904Sdim /// the same template. Calling this routine may implicitly allocate memory 619212904Sdim /// for the common pointer. 620249423Sdim CommonBase *getCommonPtr() const; 621198092Srdivacky 622249423Sdim virtual CommonBase *newCommon(ASTContext &C) const = 0; 623198092Srdivacky 624212904Sdim // Construct a template decl with name, parameters, and templated element. 625212904Sdim RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, 626212904Sdim DeclarationName Name, TemplateParameterList *Params, 627212904Sdim NamedDecl *Decl) 628234353Sdim : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { } 629212904Sdim 630193326Sedpublic: 631212904Sdim template <class decl_type> friend class RedeclarableTemplate; 632198092Srdivacky 633239462Sdim /// \brief Retrieves the canonical declaration of this template. 634263508Sdim RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); } 635263508Sdim const RedeclarableTemplateDecl *getCanonicalDecl() const { 636263508Sdim return getFirstDecl(); 637193326Sed } 638193326Sed 639234353Sdim /// \brief Determines whether this template was a specialization of a 640212904Sdim /// member template. 641212904Sdim /// 642212904Sdim /// In the following example, the function template \c X<int>::f and the 643212904Sdim /// member template \c X<int>::Inner are member specializations. 644212904Sdim /// 645212904Sdim /// \code 646212904Sdim /// template<typename T> 647212904Sdim /// struct X { 648212904Sdim /// template<typename U> void f(T, U); 649212904Sdim /// template<typename U> struct Inner; 650212904Sdim /// }; 651212904Sdim /// 652212904Sdim /// template<> template<typename T> 653212904Sdim /// void X<int>::f(int, T); 654212904Sdim /// template<> template<typename T> 655212904Sdim /// struct X<int>::Inner { /* ... */ }; 656212904Sdim /// \endcode 657249423Sdim bool isMemberSpecialization() const { 658212904Sdim return getCommonPtr()->InstantiatedFromMember.getInt(); 659212904Sdim } 660234353Sdim 661212904Sdim /// \brief Note that this member template is a specialization. 662212904Sdim void setMemberSpecialization() { 663212904Sdim assert(getCommonPtr()->InstantiatedFromMember.getPointer() && 664212904Sdim "Only member templates can be member template specializations"); 665212904Sdim getCommonPtr()->InstantiatedFromMember.setInt(true); 666212904Sdim } 667234353Sdim 668234353Sdim /// \brief Retrieve the member template from which this template was 669234353Sdim /// instantiated, or NULL if this template was not instantiated from a 670234353Sdim /// member template. 671234353Sdim /// 672234353Sdim /// A template is instantiated from a member template when the member 673234353Sdim /// template itself is part of a class template (or member thereof). For 674234353Sdim /// example, given 675234353Sdim /// 676234353Sdim /// \code 677234353Sdim /// template<typename T> 678234353Sdim /// struct X { 679234353Sdim /// template<typename U> void f(T, U); 680234353Sdim /// }; 681234353Sdim /// 682234353Sdim /// void test(X<int> x) { 683234353Sdim /// x.f(1, 'a'); 684234353Sdim /// }; 685234353Sdim /// \endcode 686234353Sdim /// 687234353Sdim /// \c X<int>::f is a FunctionTemplateDecl that describes the function 688234353Sdim /// template 689234353Sdim /// 690234353Sdim /// \code 691234353Sdim /// template<typename U> void X<int>::f(int, U); 692234353Sdim /// \endcode 693234353Sdim /// 694234353Sdim /// which was itself created during the instantiation of \c X<int>. Calling 695234353Sdim /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will 696239462Sdim /// retrieve the FunctionTemplateDecl for the original template \c f within 697234353Sdim /// the class template \c X<T>, i.e., 698234353Sdim /// 699234353Sdim /// \code 700234353Sdim /// template<typename T> 701234353Sdim /// template<typename U> 702234353Sdim /// void X<T>::f(T, U); 703234353Sdim /// \endcode 704249423Sdim RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const { 705234353Sdim return getCommonPtr()->InstantiatedFromMember.getPointer(); 706212904Sdim } 707212904Sdim 708234353Sdim void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) { 709234353Sdim assert(!getCommonPtr()->InstantiatedFromMember.getPointer()); 710234353Sdim getCommonPtr()->InstantiatedFromMember.setPointer(TD); 711234353Sdim } 712212904Sdim 713234353Sdim typedef redeclarable_base::redecl_iterator redecl_iterator; 714234353Sdim using redeclarable_base::redecls_begin; 715234353Sdim using redeclarable_base::redecls_end; 716234353Sdim using redeclarable_base::getPreviousDecl; 717234353Sdim using redeclarable_base::getMostRecentDecl; 718263508Sdim using redeclarable_base::isFirstDecl; 719234353Sdim 720212904Sdim // Implement isa/cast/dyncast/etc. 721212904Sdim static bool classof(const Decl *D) { return classofKind(D->getKind()); } 722212904Sdim static bool classofKind(Kind K) { 723212904Sdim return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate; 724212904Sdim } 725212904Sdim 726234353Sdim friend class ASTReader; 727212904Sdim friend class ASTDeclReader; 728212904Sdim friend class ASTDeclWriter; 729212904Sdim}; 730212904Sdim 731212904Sdimtemplate <> struct RedeclarableTemplateDecl:: 732212904SdimSpecEntryTraits<FunctionTemplateSpecializationInfo> { 733212904Sdim typedef FunctionDecl DeclType; 734212904Sdim 735212904Sdim static DeclType * 736234353Sdim getMostRecentDecl(FunctionTemplateSpecializationInfo *I) { 737234353Sdim return I->Function->getMostRecentDecl(); 738198092Srdivacky } 739212904Sdim}; 740212904Sdim 741212904Sdim/// Declaration of a template function. 742234353Sdimclass FunctionTemplateDecl : public RedeclarableTemplateDecl { 743212904Sdim static void DeallocateCommon(void *Ptr); 744212904Sdim 745212904Sdimprotected: 746212904Sdim /// \brief Data that is common to all of the declarations of a given 747212904Sdim /// function template. 748212904Sdim struct Common : CommonBase { 749263508Sdim Common() : InjectedArgs(), LazySpecializations() { } 750234353Sdim 751212904Sdim /// \brief The function template specializations for this function 752212904Sdim /// template, including explicit specializations and instantiations. 753239462Sdim llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations; 754234353Sdim 755221345Sdim /// \brief The set of "injected" template arguments used within this 756221345Sdim /// function template. 757221345Sdim /// 758221345Sdim /// This pointer refers to the template arguments (there are as 759221345Sdim /// many template arguments as template parameaters) for the function 760221345Sdim /// template, and is allocated lazily, since most function templates do not 761221345Sdim /// require the use of this information. 762221345Sdim TemplateArgument *InjectedArgs; 763263508Sdim 764263508Sdim /// \brief If non-null, points to an array of specializations known only 765263508Sdim /// by their external declaration IDs. 766263508Sdim /// 767263508Sdim /// The first value in the array is the number of of specializations 768263508Sdim /// that follow. 769263508Sdim uint32_t *LazySpecializations; 770212904Sdim }; 771212904Sdim 772212904Sdim FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, 773212904Sdim TemplateParameterList *Params, NamedDecl *Decl) 774212904Sdim : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { } 775212904Sdim 776249423Sdim CommonBase *newCommon(ASTContext &C) const; 777212904Sdim 778249423Sdim Common *getCommonPtr() const { 779212904Sdim return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); 780212904Sdim } 781212904Sdim 782218893Sdim friend class FunctionDecl; 783212904Sdim 784263508Sdim /// \brief Load any lazily-loaded specializations from the external source. 785263508Sdim void LoadLazySpecializations() const; 786263508Sdim 787212904Sdim /// \brief Retrieve the set of function template specializations of this 788212904Sdim /// function template. 789239462Sdim llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & 790263508Sdim getSpecializations() const; 791221345Sdim 792221345Sdim /// \brief Add a specialization of this function template. 793221345Sdim /// 794239462Sdim /// \param InsertPos Insert position in the FoldingSetVector, must have been 795221345Sdim /// retrieved by an earlier call to findSpecialization(). 796221345Sdim void addSpecialization(FunctionTemplateSpecializationInfo* Info, 797221345Sdim void *InsertPos); 798234353Sdim 799212904Sdimpublic: 800212904Sdim /// Get the underlying function declaration of the template. 801212904Sdim FunctionDecl *getTemplatedDecl() const { 802212904Sdim return static_cast<FunctionDecl*>(TemplatedDecl); 803198092Srdivacky } 804212904Sdim 805212904Sdim /// Returns whether this template declaration defines the primary 806212904Sdim /// pattern. 807212904Sdim bool isThisDeclarationADefinition() const { 808212904Sdim return getTemplatedDecl()->isThisDeclarationADefinition(); 809212904Sdim } 810212904Sdim 811212904Sdim /// \brief Return the specialization with the provided arguments if it exists, 812212904Sdim /// otherwise return the insertion point. 813212904Sdim FunctionDecl *findSpecialization(const TemplateArgument *Args, 814212904Sdim unsigned NumArgs, void *&InsertPos); 815212904Sdim 816212904Sdim FunctionTemplateDecl *getCanonicalDecl() { 817234353Sdim return cast<FunctionTemplateDecl>( 818234353Sdim RedeclarableTemplateDecl::getCanonicalDecl()); 819212904Sdim } 820212904Sdim const FunctionTemplateDecl *getCanonicalDecl() const { 821234353Sdim return cast<FunctionTemplateDecl>( 822234353Sdim RedeclarableTemplateDecl::getCanonicalDecl()); 823212904Sdim } 824212904Sdim 825212904Sdim /// \brief Retrieve the previous declaration of this function template, or 826212904Sdim /// NULL if no such declaration exists. 827234353Sdim FunctionTemplateDecl *getPreviousDecl() { 828234353Sdim return cast_or_null<FunctionTemplateDecl>( 829263508Sdim static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); 830212904Sdim } 831212904Sdim 832212904Sdim /// \brief Retrieve the previous declaration of this function template, or 833212904Sdim /// NULL if no such declaration exists. 834234353Sdim const FunctionTemplateDecl *getPreviousDecl() const { 835234353Sdim return cast_or_null<FunctionTemplateDecl>( 836263508Sdim static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl()); 837212904Sdim } 838212904Sdim 839212904Sdim FunctionTemplateDecl *getInstantiatedFromMemberTemplate() { 840234353Sdim return cast_or_null<FunctionTemplateDecl>( 841234353Sdim RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); 842212904Sdim } 843212904Sdim 844212904Sdim typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator; 845212904Sdim 846249423Sdim spec_iterator spec_begin() const { 847212904Sdim return makeSpecIterator(getSpecializations(), false); 848212904Sdim } 849212904Sdim 850249423Sdim spec_iterator spec_end() const { 851212904Sdim return makeSpecIterator(getSpecializations(), true); 852212904Sdim } 853212904Sdim 854221345Sdim /// \brief Retrieve the "injected" template arguments that correspond to the 855221345Sdim /// template parameters of this function template. 856234353Sdim /// 857221345Sdim /// Although the C++ standard has no notion of the "injected" template 858221345Sdim /// arguments for a function template, the notion is convenient when 859221345Sdim /// we need to perform substitutions inside the definition of a function 860234353Sdim /// template. 861263508Sdim ArrayRef<TemplateArgument> getInjectedTemplateArgs(); 862234353Sdim 863221345Sdim /// \brief Create a function template node. 864193326Sed static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC, 865193326Sed SourceLocation L, 866193326Sed DeclarationName Name, 867193326Sed TemplateParameterList *Params, 868193326Sed NamedDecl *Decl); 869193326Sed 870221345Sdim /// \brief Create an empty function template node. 871234353Sdim static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); 872221345Sdim 873193326Sed // Implement isa/cast/dyncast support 874203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 875203955Srdivacky static bool classofKind(Kind K) { return K == FunctionTemplate; } 876210299Sed 877212904Sdim friend class ASTDeclReader; 878212904Sdim friend class ASTDeclWriter; 879193326Sed}; 880193326Sed 881193326Sed//===----------------------------------------------------------------------===// 882193326Sed// Kinds of Template Parameters 883193326Sed//===----------------------------------------------------------------------===// 884193326Sed 885239462Sdim/// \brief Defines the position of a template parameter within a template 886239462Sdim/// parameter list. 887239462Sdim/// 888239462Sdim/// Because template parameter can be listed 889193326Sed/// sequentially for out-of-line template members, each template parameter is 890193326Sed/// given a Depth - the nesting of template parameter scopes - and a Position - 891193326Sed/// the occurrence within the parameter list. 892193326Sed/// This class is inheritedly privately by different kinds of template 893193326Sed/// parameters and is not part of the Decl hierarchy. Just a facility. 894198092Srdivackyclass TemplateParmPosition { 895193326Sedprotected: 896193326Sed // FIXME: This should probably never be called, but it's here as 897193326Sed TemplateParmPosition() 898193326Sed : Depth(0), Position(0) 899226633Sdim { /* llvm_unreachable("Cannot create positionless template parameter"); */ } 900193326Sed 901193326Sed TemplateParmPosition(unsigned D, unsigned P) 902193326Sed : Depth(D), Position(P) 903193326Sed { } 904193326Sed 905193326Sed // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for 906193326Sed // position? Maybe? 907193326Sed unsigned Depth; 908193326Sed unsigned Position; 909193326Sed 910193326Sedpublic: 911193326Sed /// Get the nesting depth of the template parameter. 912193326Sed unsigned getDepth() const { return Depth; } 913210299Sed void setDepth(unsigned D) { Depth = D; } 914193326Sed 915193326Sed /// Get the position of the template parameter within its parameter list. 916193326Sed unsigned getPosition() const { return Position; } 917210299Sed void setPosition(unsigned P) { Position = P; } 918198092Srdivacky 919193576Sed /// Get the index of the template parameter within its parameter list. 920193576Sed unsigned getIndex() const { return Position; } 921193326Sed}; 922193326Sed 923239462Sdim/// \brief Declaration of a template type parameter. 924239462Sdim/// 925239462Sdim/// For example, "T" in 926239462Sdim/// \code 927193326Sed/// template<typename T> class vector; 928239462Sdim/// \endcode 929193326Sedclass TemplateTypeParmDecl : public TypeDecl { 930193326Sed /// \brief Whether this template type parameter was declaration with 931239462Sdim /// the 'typename' keyword. 932239462Sdim /// 933239462Sdim /// If false, it was declared with the 'class' keyword. 934193326Sed bool Typename : 1; 935193326Sed 936193326Sed /// \brief Whether this template type parameter inherited its 937193326Sed /// default argument. 938193326Sed bool InheritedDefault : 1; 939193326Sed 940193326Sed /// \brief The default template argument, if any. 941200583Srdivacky TypeSourceInfo *DefaultArgument; 942193326Sed 943221345Sdim TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc, 944221345Sdim SourceLocation IdLoc, IdentifierInfo *Id, 945221345Sdim bool Typename) 946221345Sdim : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename), 947221345Sdim InheritedDefault(false), DefaultArgument() { } 948193326Sed 949219077Sdim /// Sema creates these on the stack during auto type deduction. 950219077Sdim friend class Sema; 951219077Sdim 952193326Sedpublic: 953218893Sdim static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC, 954221345Sdim SourceLocation KeyLoc, 955221345Sdim SourceLocation NameLoc, 956221345Sdim unsigned D, unsigned P, 957194179Sed IdentifierInfo *Id, bool Typename, 958194179Sed bool ParameterPack); 959234353Sdim static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, 960234353Sdim unsigned ID); 961193326Sed 962193326Sed /// \brief Whether this template type parameter was declared with 963239462Sdim /// the 'typename' keyword. 964239462Sdim /// 965239462Sdim /// If not, it was declared with the 'class' keyword. 966193326Sed bool wasDeclaredWithTypename() const { return Typename; } 967193326Sed 968193326Sed /// \brief Determine whether this template parameter has a default 969193326Sed /// argument. 970198893Srdivacky bool hasDefaultArgument() const { return DefaultArgument != 0; } 971193326Sed 972193326Sed /// \brief Retrieve the default argument, if any. 973198893Srdivacky QualType getDefaultArgument() const { return DefaultArgument->getType(); } 974193326Sed 975198893Srdivacky /// \brief Retrieves the default argument's source information, if any. 976200583Srdivacky TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; } 977193326Sed 978198893Srdivacky /// \brief Retrieves the location of the default argument declaration. 979198893Srdivacky SourceLocation getDefaultArgumentLoc() const; 980198893Srdivacky 981193326Sed /// \brief Determines whether the default argument was inherited 982193326Sed /// from a previous declaration of this template. 983193326Sed bool defaultArgumentWasInherited() const { return InheritedDefault; } 984193326Sed 985193326Sed /// \brief Set the default argument for this template parameter, and 986193326Sed /// whether that default argument was inherited from another 987193326Sed /// declaration. 988200583Srdivacky void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) { 989193326Sed DefaultArgument = DefArg; 990193326Sed InheritedDefault = Inherited; 991193326Sed } 992193326Sed 993198893Srdivacky /// \brief Removes the default argument of this template parameter. 994198893Srdivacky void removeDefaultArgument() { 995198893Srdivacky DefaultArgument = 0; 996198893Srdivacky InheritedDefault = false; 997198893Srdivacky } 998234353Sdim 999210299Sed /// \brief Set whether this template type parameter was declared with 1000210299Sed /// the 'typename' or 'class' keyword. 1001210299Sed void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; } 1002198893Srdivacky 1003198893Srdivacky /// \brief Retrieve the depth of the template parameter. 1004198893Srdivacky unsigned getDepth() const; 1005234353Sdim 1006198893Srdivacky /// \brief Retrieve the index of the template parameter. 1007198893Srdivacky unsigned getIndex() const; 1008198893Srdivacky 1009194179Sed /// \brief Returns whether this is a parameter pack. 1010221345Sdim bool isParameterPack() const; 1011194179Sed 1012234353Sdim SourceRange getSourceRange() const LLVM_READONLY; 1013221345Sdim 1014193326Sed // Implement isa/cast/dyncast/etc. 1015203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1016203955Srdivacky static bool classofKind(Kind K) { return K == TemplateTypeParm; } 1017193326Sed}; 1018193326Sed 1019193326Sed/// NonTypeTemplateParmDecl - Declares a non-type template parameter, 1020193326Sed/// e.g., "Size" in 1021193326Sed/// @code 1022193326Sed/// template<int Size> class array { }; 1023193326Sed/// @endcode 1024193326Sedclass NonTypeTemplateParmDecl 1025218893Sdim : public DeclaratorDecl, protected TemplateParmPosition { 1026210299Sed /// \brief The default template argument, if any, and whether or not 1027210299Sed /// it was inherited. 1028210299Sed llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited; 1029193326Sed 1030218893Sdim // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index 1031218893Sdim // down here to save memory. 1032234353Sdim 1033218893Sdim /// \brief Whether this non-type template parameter is a parameter pack. 1034218893Sdim bool ParameterPack; 1035234353Sdim 1036234353Sdim /// \brief Whether this non-type template parameter is an "expanded" 1037218893Sdim /// parameter pack, meaning that its type is a pack expansion and we 1038218893Sdim /// already know the set of types that expansion expands to. 1039218893Sdim bool ExpandedParameterPack; 1040234353Sdim 1041218893Sdim /// \brief The number of types in an expanded parameter pack. 1042218893Sdim unsigned NumExpandedTypes; 1043234353Sdim 1044221345Sdim NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, 1045221345Sdim SourceLocation IdLoc, unsigned D, unsigned P, 1046221345Sdim IdentifierInfo *Id, QualType T, 1047218893Sdim bool ParameterPack, TypeSourceInfo *TInfo) 1048221345Sdim : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 1049218893Sdim TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false), 1050218893Sdim ParameterPack(ParameterPack), ExpandedParameterPack(false), 1051218893Sdim NumExpandedTypes(0) 1052193326Sed { } 1053193326Sed 1054221345Sdim NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, 1055221345Sdim SourceLocation IdLoc, unsigned D, unsigned P, 1056221345Sdim IdentifierInfo *Id, QualType T, 1057218893Sdim TypeSourceInfo *TInfo, 1058218893Sdim const QualType *ExpandedTypes, 1059218893Sdim unsigned NumExpandedTypes, 1060218893Sdim TypeSourceInfo **ExpandedTInfos); 1061218893Sdim 1062218893Sdim friend class ASTDeclReader; 1063234353Sdim 1064193326Sedpublic: 1065193326Sed static NonTypeTemplateParmDecl * 1066221345Sdim Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 1067221345Sdim SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, 1068221345Sdim QualType T, bool ParameterPack, TypeSourceInfo *TInfo); 1069193326Sed 1070218893Sdim static NonTypeTemplateParmDecl * 1071221345Sdim Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 1072221345Sdim SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, 1073221345Sdim QualType T, TypeSourceInfo *TInfo, 1074218893Sdim const QualType *ExpandedTypes, unsigned NumExpandedTypes, 1075218893Sdim TypeSourceInfo **ExpandedTInfos); 1076218893Sdim 1077234353Sdim static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, 1078234353Sdim unsigned ID); 1079234353Sdim static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, 1080234353Sdim unsigned ID, 1081234353Sdim unsigned NumExpandedTypes); 1082234353Sdim 1083193326Sed using TemplateParmPosition::getDepth; 1084210299Sed using TemplateParmPosition::setDepth; 1085193326Sed using TemplateParmPosition::getPosition; 1086210299Sed using TemplateParmPosition::setPosition; 1087193576Sed using TemplateParmPosition::getIndex; 1088198092Srdivacky 1089234353Sdim SourceRange getSourceRange() const LLVM_READONLY; 1090218893Sdim 1091193326Sed /// \brief Determine whether this template parameter has a default 1092193326Sed /// argument. 1093210299Sed bool hasDefaultArgument() const { 1094210299Sed return DefaultArgumentAndInherited.getPointer() != 0; 1095210299Sed } 1096193326Sed 1097193326Sed /// \brief Retrieve the default argument, if any. 1098210299Sed Expr *getDefaultArgument() const { 1099210299Sed return DefaultArgumentAndInherited.getPointer(); 1100210299Sed } 1101193326Sed 1102193326Sed /// \brief Retrieve the location of the default argument, if any. 1103193326Sed SourceLocation getDefaultArgumentLoc() const; 1104193326Sed 1105210299Sed /// \brief Determines whether the default argument was inherited 1106210299Sed /// from a previous declaration of this template. 1107210299Sed bool defaultArgumentWasInherited() const { 1108210299Sed return DefaultArgumentAndInherited.getInt(); 1109193326Sed } 1110193326Sed 1111210299Sed /// \brief Set the default argument for this template parameter, and 1112210299Sed /// whether that default argument was inherited from another 1113210299Sed /// declaration. 1114210299Sed void setDefaultArgument(Expr *DefArg, bool Inherited) { 1115210299Sed DefaultArgumentAndInherited.setPointer(DefArg); 1116210299Sed DefaultArgumentAndInherited.setInt(Inherited); 1117210299Sed } 1118210299Sed 1119210299Sed /// \brief Removes the default argument of this template parameter. 1120210299Sed void removeDefaultArgument() { 1121210299Sed DefaultArgumentAndInherited.setPointer(0); 1122210299Sed DefaultArgumentAndInherited.setInt(false); 1123210299Sed } 1124210299Sed 1125218893Sdim /// \brief Whether this parameter is a non-type template parameter pack. 1126218893Sdim /// 1127218893Sdim /// If the parameter is a parameter pack, the type may be a 1128218893Sdim /// \c PackExpansionType. In the following example, the \c Dims parameter 1129218893Sdim /// is a parameter pack (whose type is 'unsigned'). 1130218893Sdim /// 1131218893Sdim /// \code 1132218893Sdim /// template<typename T, unsigned ...Dims> struct multi_array; 1133218893Sdim /// \endcode 1134218893Sdim bool isParameterPack() const { return ParameterPack; } 1135234353Sdim 1136243830Sdim /// \brief Whether this parameter pack is a pack expansion. 1137243830Sdim /// 1138243830Sdim /// A non-type template parameter pack is a pack expansion if its type 1139243830Sdim /// contains an unexpanded parameter pack. In this case, we will have 1140243830Sdim /// built a PackExpansionType wrapping the type. 1141243830Sdim bool isPackExpansion() const { 1142243830Sdim return ParameterPack && getType()->getAs<PackExpansionType>(); 1143243830Sdim } 1144243830Sdim 1145218893Sdim /// \brief Whether this parameter is a non-type template parameter pack 1146243830Sdim /// that has a known list of different types at different positions. 1147218893Sdim /// 1148218893Sdim /// A parameter pack is an expanded parameter pack when the original 1149218893Sdim /// parameter pack's type was itself a pack expansion, and that expansion 1150218893Sdim /// has already been expanded. For example, given: 1151218893Sdim /// 1152218893Sdim /// \code 1153218893Sdim /// template<typename ...Types> 1154218893Sdim /// struct X { 1155218893Sdim /// template<Types ...Values> 1156218893Sdim /// struct Y { /* ... */ }; 1157218893Sdim /// }; 1158218893Sdim /// \endcode 1159234353Sdim /// 1160218893Sdim /// The parameter pack \c Values has a \c PackExpansionType as its type, 1161218893Sdim /// which expands \c Types. When \c Types is supplied with template arguments 1162234353Sdim /// by instantiating \c X, the instantiation of \c Values becomes an 1163234353Sdim /// expanded parameter pack. For example, instantiating 1164218893Sdim /// \c X<int, unsigned int> results in \c Values being an expanded parameter 1165218893Sdim /// pack with expansion types \c int and \c unsigned int. 1166218893Sdim /// 1167234353Sdim /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions 1168218893Sdim /// return the expansion types. 1169218893Sdim bool isExpandedParameterPack() const { return ExpandedParameterPack; } 1170234353Sdim 1171234353Sdim /// \brief Retrieves the number of expansion types in an expanded parameter 1172234353Sdim /// pack. 1173218893Sdim unsigned getNumExpansionTypes() const { 1174218893Sdim assert(ExpandedParameterPack && "Not an expansion parameter pack"); 1175218893Sdim return NumExpandedTypes; 1176218893Sdim } 1177218893Sdim 1178234353Sdim /// \brief Retrieve a particular expansion type within an expanded parameter 1179218893Sdim /// pack. 1180218893Sdim QualType getExpansionType(unsigned I) const { 1181218893Sdim assert(I < NumExpandedTypes && "Out-of-range expansion type index"); 1182218893Sdim void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1); 1183218893Sdim return QualType::getFromOpaquePtr(TypesAndInfos[2*I]); 1184218893Sdim } 1185218893Sdim 1186234353Sdim /// \brief Retrieve a particular expansion type source info within an 1187218893Sdim /// expanded parameter pack. 1188218893Sdim TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const { 1189218893Sdim assert(I < NumExpandedTypes && "Out-of-range expansion type index"); 1190218893Sdim void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1); 1191218893Sdim return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]); 1192218893Sdim } 1193218893Sdim 1194193326Sed // Implement isa/cast/dyncast/etc. 1195203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1196203955Srdivacky static bool classofKind(Kind K) { return K == NonTypeTemplateParm; } 1197193326Sed}; 1198193326Sed 1199193326Sed/// TemplateTemplateParmDecl - Declares a template template parameter, 1200193326Sed/// e.g., "T" in 1201193326Sed/// @code 1202193326Sed/// template <template <typename> class T> class container { }; 1203193326Sed/// @endcode 1204193326Sed/// A template template parameter is a TemplateDecl because it defines the 1205193326Sed/// name of a template and the template parameters allowable for substitution. 1206234353Sdimclass TemplateTemplateParmDecl : public TemplateDecl, 1207234353Sdim protected TemplateParmPosition 1208234353Sdim{ 1209234353Sdim virtual void anchor(); 1210193326Sed 1211210299Sed /// DefaultArgument - The default template argument, if any. 1212199482Srdivacky TemplateArgumentLoc DefaultArgument; 1213210299Sed /// Whether or not the default argument was inherited. 1214210299Sed bool DefaultArgumentWasInherited; 1215193326Sed 1216218893Sdim /// \brief Whether this parameter is a parameter pack. 1217218893Sdim bool ParameterPack; 1218234353Sdim 1219243830Sdim /// \brief Whether this template template parameter is an "expanded" 1220243830Sdim /// parameter pack, meaning that it is a pack expansion and we 1221243830Sdim /// already know the set of template parameters that expansion expands to. 1222243830Sdim bool ExpandedParameterPack; 1223243830Sdim 1224243830Sdim /// \brief The number of parameters in an expanded parameter pack. 1225243830Sdim unsigned NumExpandedParams; 1226243830Sdim 1227193326Sed TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, 1228218893Sdim unsigned D, unsigned P, bool ParameterPack, 1229193326Sed IdentifierInfo *Id, TemplateParameterList *Params) 1230193326Sed : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 1231210299Sed TemplateParmPosition(D, P), DefaultArgument(), 1232243830Sdim DefaultArgumentWasInherited(false), ParameterPack(ParameterPack), 1233243830Sdim ExpandedParameterPack(false), NumExpandedParams(0) 1234193326Sed { } 1235193326Sed 1236243830Sdim TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, 1237243830Sdim unsigned D, unsigned P, 1238243830Sdim IdentifierInfo *Id, TemplateParameterList *Params, 1239243830Sdim unsigned NumExpansions, 1240243830Sdim TemplateParameterList * const *Expansions); 1241243830Sdim 1242193326Sedpublic: 1243218893Sdim static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, 1244193326Sed SourceLocation L, unsigned D, 1245218893Sdim unsigned P, bool ParameterPack, 1246218893Sdim IdentifierInfo *Id, 1247193326Sed TemplateParameterList *Params); 1248243830Sdim static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, 1249243830Sdim SourceLocation L, unsigned D, 1250243830Sdim unsigned P, 1251243830Sdim IdentifierInfo *Id, 1252243830Sdim TemplateParameterList *Params, 1253249423Sdim ArrayRef<TemplateParameterList *> Expansions); 1254193326Sed 1255243830Sdim static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, 1256234353Sdim unsigned ID); 1257243830Sdim static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, 1258243830Sdim unsigned ID, 1259243830Sdim unsigned NumExpansions); 1260234353Sdim 1261193326Sed using TemplateParmPosition::getDepth; 1262193326Sed using TemplateParmPosition::getPosition; 1263193576Sed using TemplateParmPosition::getIndex; 1264198092Srdivacky 1265218893Sdim /// \brief Whether this template template parameter is a template 1266218893Sdim /// parameter pack. 1267218893Sdim /// 1268218893Sdim /// \code 1269218893Sdim /// template<template <class T> ...MetaFunctions> struct Apply; 1270218893Sdim /// \endcode 1271218893Sdim bool isParameterPack() const { return ParameterPack; } 1272218893Sdim 1273243830Sdim /// \brief Whether this parameter pack is a pack expansion. 1274243830Sdim /// 1275243830Sdim /// A template template parameter pack is a pack expansion if its template 1276243830Sdim /// parameter list contains an unexpanded parameter pack. 1277243830Sdim bool isPackExpansion() const { 1278243830Sdim return ParameterPack && 1279243830Sdim getTemplateParameters()->containsUnexpandedParameterPack(); 1280243830Sdim } 1281243830Sdim 1282243830Sdim /// \brief Whether this parameter is a template template parameter pack that 1283243830Sdim /// has a known list of different template parameter lists at different 1284243830Sdim /// positions. 1285243830Sdim /// 1286243830Sdim /// A parameter pack is an expanded parameter pack when the original parameter 1287243830Sdim /// pack's template parameter list was itself a pack expansion, and that 1288243830Sdim /// expansion has already been expanded. For exampe, given: 1289243830Sdim /// 1290243830Sdim /// \code 1291243830Sdim /// template<typename...Types> struct Outer { 1292243830Sdim /// template<template<Types> class...Templates> struct Inner; 1293243830Sdim /// }; 1294243830Sdim /// \endcode 1295243830Sdim /// 1296243830Sdim /// The parameter pack \c Templates is a pack expansion, which expands the 1297243830Sdim /// pack \c Types. When \c Types is supplied with template arguments by 1298243830Sdim /// instantiating \c Outer, the instantiation of \c Templates is an expanded 1299243830Sdim /// parameter pack. 1300243830Sdim bool isExpandedParameterPack() const { return ExpandedParameterPack; } 1301243830Sdim 1302243830Sdim /// \brief Retrieves the number of expansion template parameters in 1303243830Sdim /// an expanded parameter pack. 1304243830Sdim unsigned getNumExpansionTemplateParameters() const { 1305243830Sdim assert(ExpandedParameterPack && "Not an expansion parameter pack"); 1306243830Sdim return NumExpandedParams; 1307243830Sdim } 1308243830Sdim 1309243830Sdim /// \brief Retrieve a particular expansion type within an expanded parameter 1310243830Sdim /// pack. 1311243830Sdim TemplateParameterList *getExpansionTemplateParameters(unsigned I) const { 1312243830Sdim assert(I < NumExpandedParams && "Out-of-range expansion type index"); 1313243830Sdim return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I]; 1314243830Sdim } 1315243830Sdim 1316193326Sed /// \brief Determine whether this template parameter has a default 1317193326Sed /// argument. 1318210299Sed bool hasDefaultArgument() const { 1319210299Sed return !DefaultArgument.getArgument().isNull(); 1320199482Srdivacky } 1321193326Sed 1322193326Sed /// \brief Retrieve the default argument, if any. 1323210299Sed const TemplateArgumentLoc &getDefaultArgument() const { 1324210299Sed return DefaultArgument; 1325199482Srdivacky } 1326193326Sed 1327210299Sed /// \brief Retrieve the location of the default argument, if any. 1328210299Sed SourceLocation getDefaultArgumentLoc() const; 1329210299Sed 1330210299Sed /// \brief Determines whether the default argument was inherited 1331210299Sed /// from a previous declaration of this template. 1332210299Sed bool defaultArgumentWasInherited() const { 1333210299Sed return DefaultArgumentWasInherited; 1334210299Sed } 1335210299Sed 1336210299Sed /// \brief Set the default argument for this template parameter, and 1337210299Sed /// whether that default argument was inherited from another 1338210299Sed /// declaration. 1339210299Sed void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) { 1340193326Sed DefaultArgument = DefArg; 1341210299Sed DefaultArgumentWasInherited = Inherited; 1342193326Sed } 1343193326Sed 1344210299Sed /// \brief Removes the default argument of this template parameter. 1345210299Sed void removeDefaultArgument() { 1346210299Sed DefaultArgument = TemplateArgumentLoc(); 1347210299Sed DefaultArgumentWasInherited = false; 1348210299Sed } 1349210299Sed 1350234353Sdim SourceRange getSourceRange() const LLVM_READONLY { 1351212904Sdim SourceLocation End = getLocation(); 1352212904Sdim if (hasDefaultArgument() && !defaultArgumentWasInherited()) 1353212904Sdim End = getDefaultArgument().getSourceRange().getEnd(); 1354212904Sdim return SourceRange(getTemplateParameters()->getTemplateLoc(), End); 1355212904Sdim } 1356212904Sdim 1357193326Sed // Implement isa/cast/dyncast/etc. 1358203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1359203955Srdivacky static bool classofKind(Kind K) { return K == TemplateTemplateParm; } 1360210299Sed 1361212904Sdim friend class ASTDeclReader; 1362212904Sdim friend class ASTDeclWriter; 1363193326Sed}; 1364193326Sed 1365193326Sed/// \brief Represents a class template specialization, which refers to 1366193326Sed/// a class template with a given set of template arguments. 1367193326Sed/// 1368193326Sed/// Class template specializations represent both explicit 1369193326Sed/// specialization of class templates, as in the example below, and 1370193326Sed/// implicit instantiations of class templates. 1371193326Sed/// 1372193326Sed/// \code 1373193326Sed/// template<typename T> class array; 1374198092Srdivacky/// 1375198092Srdivacky/// template<> 1376193326Sed/// class array<bool> { }; // class template specialization array<bool> 1377193326Sed/// \endcode 1378198092Srdivackyclass ClassTemplateSpecializationDecl 1379193326Sed : public CXXRecordDecl, public llvm::FoldingSetNode { 1380198092Srdivacky 1381198092Srdivacky /// \brief Structure that stores information about a class template 1382198092Srdivacky /// specialization that was instantiated from a class template partial 1383198092Srdivacky /// specialization. 1384198092Srdivacky struct SpecializedPartialSpecialization { 1385198092Srdivacky /// \brief The class template partial specialization from which this 1386198092Srdivacky /// class template specialization was instantiated. 1387198092Srdivacky ClassTemplatePartialSpecializationDecl *PartialSpecialization; 1388198092Srdivacky 1389198092Srdivacky /// \brief The template argument list deduced for the class template 1390198092Srdivacky /// partial specialization itself. 1391263508Sdim const TemplateArgumentList *TemplateArgs; 1392198092Srdivacky }; 1393198092Srdivacky 1394193326Sed /// \brief The template that this specialization specializes 1395198092Srdivacky llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *> 1396198092Srdivacky SpecializedTemplate; 1397193326Sed 1398210299Sed /// \brief Further info for explicit template specialization/instantiation. 1399210299Sed struct ExplicitSpecializationInfo { 1400210299Sed /// \brief The type-as-written. 1401210299Sed TypeSourceInfo *TypeAsWritten; 1402210299Sed /// \brief The location of the extern keyword. 1403210299Sed SourceLocation ExternLoc; 1404210299Sed /// \brief The location of the template keyword. 1405210299Sed SourceLocation TemplateKeywordLoc; 1406210299Sed 1407210299Sed ExplicitSpecializationInfo() 1408210299Sed : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {} 1409210299Sed }; 1410210299Sed 1411210299Sed /// \brief Further info for explicit template specialization/instantiation. 1412204962Srdivacky /// Does not apply to implicit specializations. 1413210299Sed ExplicitSpecializationInfo *ExplicitInfo; 1414204962Srdivacky 1415193326Sed /// \brief The template arguments used to describe this specialization. 1416263508Sdim const TemplateArgumentList *TemplateArgs; 1417193326Sed 1418198092Srdivacky /// \brief The point where this template was instantiated (if any) 1419198092Srdivacky SourceLocation PointOfInstantiation; 1420198092Srdivacky 1421193326Sed /// \brief The kind of specialization this declaration refers to. 1422193326Sed /// Really a value of type TemplateSpecializationKind. 1423198092Srdivacky unsigned SpecializationKind : 3; 1424193326Sed 1425193326Sedprotected: 1426208600Srdivacky ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 1427221345Sdim DeclContext *DC, SourceLocation StartLoc, 1428221345Sdim SourceLocation IdLoc, 1429193326Sed ClassTemplateDecl *SpecializedTemplate, 1430218893Sdim const TemplateArgument *Args, 1431218893Sdim unsigned NumArgs, 1432198092Srdivacky ClassTemplateSpecializationDecl *PrevDecl); 1433198092Srdivacky 1434210299Sed explicit ClassTemplateSpecializationDecl(Kind DK); 1435210299Sed 1436193326Sedpublic: 1437193326Sed static ClassTemplateSpecializationDecl * 1438221345Sdim Create(ASTContext &Context, TagKind TK, DeclContext *DC, 1439221345Sdim SourceLocation StartLoc, SourceLocation IdLoc, 1440193326Sed ClassTemplateDecl *SpecializedTemplate, 1441218893Sdim const TemplateArgument *Args, 1442218893Sdim unsigned NumArgs, 1443193326Sed ClassTemplateSpecializationDecl *PrevDecl); 1444210299Sed static ClassTemplateSpecializationDecl * 1445234353Sdim CreateDeserialized(ASTContext &C, unsigned ID); 1446193326Sed 1447249423Sdim virtual void getNameForDiagnostic(raw_ostream &OS, 1448198092Srdivacky const PrintingPolicy &Policy, 1449198092Srdivacky bool Qualified) const; 1450198092Srdivacky 1451234353Sdim ClassTemplateSpecializationDecl *getMostRecentDecl() { 1452263508Sdim CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>( 1453263508Sdim this)->getMostRecentDecl(); 1454263508Sdim while (!isa<ClassTemplateSpecializationDecl>(Recent)) { 1455212904Sdim // FIXME: Does injected class name need to be in the redeclarations chain? 1456234353Sdim assert(Recent->isInjectedClassName() && Recent->getPreviousDecl()); 1457234353Sdim Recent = Recent->getPreviousDecl(); 1458212904Sdim } 1459212904Sdim return cast<ClassTemplateSpecializationDecl>(Recent); 1460212904Sdim } 1461212904Sdim 1462193326Sed /// \brief Retrieve the template that this specialization specializes. 1463198092Srdivacky ClassTemplateDecl *getSpecializedTemplate() const; 1464193326Sed 1465198092Srdivacky /// \brief Retrieve the template arguments of the class template 1466198092Srdivacky /// specialization. 1467198092Srdivacky const TemplateArgumentList &getTemplateArgs() const { 1468218893Sdim return *TemplateArgs; 1469193326Sed } 1470193326Sed 1471193326Sed /// \brief Determine the kind of specialization that this 1472193326Sed /// declaration represents. 1473193326Sed TemplateSpecializationKind getSpecializationKind() const { 1474193326Sed return static_cast<TemplateSpecializationKind>(SpecializationKind); 1475193326Sed } 1476193326Sed 1477224145Sdim bool isExplicitSpecialization() const { 1478224145Sdim return getSpecializationKind() == TSK_ExplicitSpecialization; 1479224145Sdim } 1480224145Sdim 1481249423Sdim /// \brief True if this declaration is an explicit specialization, 1482249423Sdim /// explicit instantiation declaration, or explicit instantiation 1483249423Sdim /// definition. 1484249423Sdim bool isExplicitInstantiationOrSpecialization() const { 1485249423Sdim switch (getTemplateSpecializationKind()) { 1486249423Sdim case TSK_ExplicitSpecialization: 1487249423Sdim case TSK_ExplicitInstantiationDeclaration: 1488249423Sdim case TSK_ExplicitInstantiationDefinition: 1489249423Sdim return true; 1490249423Sdim 1491249423Sdim case TSK_Undeclared: 1492249423Sdim case TSK_ImplicitInstantiation: 1493249423Sdim return false; 1494249423Sdim } 1495249423Sdim llvm_unreachable("bad template specialization kind"); 1496249423Sdim } 1497249423Sdim 1498193326Sed void setSpecializationKind(TemplateSpecializationKind TSK) { 1499193326Sed SpecializationKind = TSK; 1500193326Sed } 1501193326Sed 1502198092Srdivacky /// \brief Get the point of instantiation (if any), or null if none. 1503198092Srdivacky SourceLocation getPointOfInstantiation() const { 1504198092Srdivacky return PointOfInstantiation; 1505198092Srdivacky } 1506198092Srdivacky 1507198092Srdivacky void setPointOfInstantiation(SourceLocation Loc) { 1508198092Srdivacky assert(Loc.isValid() && "point of instantiation must be valid!"); 1509198092Srdivacky PointOfInstantiation = Loc; 1510198092Srdivacky } 1511198092Srdivacky 1512198092Srdivacky /// \brief If this class template specialization is an instantiation of 1513198092Srdivacky /// a template (rather than an explicit specialization), return the 1514198092Srdivacky /// class template or class template partial specialization from which it 1515198092Srdivacky /// was instantiated. 1516198092Srdivacky llvm::PointerUnion<ClassTemplateDecl *, 1517198092Srdivacky ClassTemplatePartialSpecializationDecl *> 1518198092Srdivacky getInstantiatedFrom() const { 1519198092Srdivacky if (getSpecializationKind() != TSK_ImplicitInstantiation && 1520198092Srdivacky getSpecializationKind() != TSK_ExplicitInstantiationDefinition && 1521198092Srdivacky getSpecializationKind() != TSK_ExplicitInstantiationDeclaration) 1522212904Sdim return llvm::PointerUnion<ClassTemplateDecl *, 1523212904Sdim ClassTemplatePartialSpecializationDecl *>(); 1524198092Srdivacky 1525198092Srdivacky if (SpecializedPartialSpecialization *PartialSpec 1526198092Srdivacky = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 1527198092Srdivacky return PartialSpec->PartialSpecialization; 1528198092Srdivacky 1529249423Sdim return SpecializedTemplate.get<ClassTemplateDecl*>(); 1530198092Srdivacky } 1531198092Srdivacky 1532210299Sed /// \brief Retrieve the class template or class template partial 1533210299Sed /// specialization which was specialized by this. 1534210299Sed llvm::PointerUnion<ClassTemplateDecl *, 1535210299Sed ClassTemplatePartialSpecializationDecl *> 1536210299Sed getSpecializedTemplateOrPartial() const { 1537210299Sed if (SpecializedPartialSpecialization *PartialSpec 1538210299Sed = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 1539210299Sed return PartialSpec->PartialSpecialization; 1540210299Sed 1541249423Sdim return SpecializedTemplate.get<ClassTemplateDecl*>(); 1542210299Sed } 1543210299Sed 1544198092Srdivacky /// \brief Retrieve the set of template arguments that should be used 1545198092Srdivacky /// to instantiate members of the class template or class template partial 1546198092Srdivacky /// specialization from which this class template specialization was 1547198092Srdivacky /// instantiated. 1548198092Srdivacky /// 1549198092Srdivacky /// \returns For a class template specialization instantiated from the primary 1550198092Srdivacky /// template, this function will return the same template arguments as 1551198092Srdivacky /// getTemplateArgs(). For a class template specialization instantiated from 1552198092Srdivacky /// a class template partial specialization, this function will return the 1553198092Srdivacky /// deduced template arguments for the class template partial specialization 1554198092Srdivacky /// itself. 1555198092Srdivacky const TemplateArgumentList &getTemplateInstantiationArgs() const { 1556198092Srdivacky if (SpecializedPartialSpecialization *PartialSpec 1557198092Srdivacky = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 1558198092Srdivacky return *PartialSpec->TemplateArgs; 1559198092Srdivacky 1560198092Srdivacky return getTemplateArgs(); 1561198092Srdivacky } 1562198092Srdivacky 1563198092Srdivacky /// \brief Note that this class template specialization is actually an 1564198092Srdivacky /// instantiation of the given class template partial specialization whose 1565198092Srdivacky /// template arguments have been deduced. 1566198092Srdivacky void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, 1567263508Sdim const TemplateArgumentList *TemplateArgs) { 1568210299Sed assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() && 1569210299Sed "Already set to a class template partial specialization!"); 1570198092Srdivacky SpecializedPartialSpecialization *PS 1571198092Srdivacky = new (getASTContext()) SpecializedPartialSpecialization(); 1572198092Srdivacky PS->PartialSpecialization = PartialSpec; 1573198092Srdivacky PS->TemplateArgs = TemplateArgs; 1574198092Srdivacky SpecializedTemplate = PS; 1575198092Srdivacky } 1576198092Srdivacky 1577210299Sed /// \brief Note that this class template specialization is an instantiation 1578210299Sed /// of the given class template. 1579210299Sed void setInstantiationOf(ClassTemplateDecl *TemplDecl) { 1580210299Sed assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() && 1581210299Sed "Previously set to a class template partial specialization!"); 1582210299Sed SpecializedTemplate = TemplDecl; 1583210299Sed } 1584210299Sed 1585193326Sed /// \brief Sets the type of this specialization as it was written by 1586193326Sed /// the user. This will be a class template specialization type. 1587204962Srdivacky void setTypeAsWritten(TypeSourceInfo *T) { 1588212904Sdim if (!ExplicitInfo) 1589212904Sdim ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; 1590210299Sed ExplicitInfo->TypeAsWritten = T; 1591193326Sed } 1592204962Srdivacky /// \brief Gets the type of this specialization as it was written by 1593204962Srdivacky /// the user, if it was so written. 1594204962Srdivacky TypeSourceInfo *getTypeAsWritten() const { 1595210299Sed return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0; 1596204962Srdivacky } 1597204962Srdivacky 1598210299Sed /// \brief Gets the location of the extern keyword, if present. 1599210299Sed SourceLocation getExternLoc() const { 1600210299Sed return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation(); 1601210299Sed } 1602210299Sed /// \brief Sets the location of the extern keyword. 1603210299Sed void setExternLoc(SourceLocation Loc) { 1604212904Sdim if (!ExplicitInfo) 1605212904Sdim ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; 1606210299Sed ExplicitInfo->ExternLoc = Loc; 1607210299Sed } 1608210299Sed 1609210299Sed /// \brief Sets the location of the template keyword. 1610210299Sed void setTemplateKeywordLoc(SourceLocation Loc) { 1611212904Sdim if (!ExplicitInfo) 1612212904Sdim ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; 1613210299Sed ExplicitInfo->TemplateKeywordLoc = Loc; 1614210299Sed } 1615210299Sed /// \brief Gets the location of the template keyword, if present. 1616210299Sed SourceLocation getTemplateKeywordLoc() const { 1617210299Sed return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); 1618210299Sed } 1619210299Sed 1620234353Sdim SourceRange getSourceRange() const LLVM_READONLY; 1621210299Sed 1622193326Sed void Profile(llvm::FoldingSetNodeID &ID) const { 1623218893Sdim Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext()); 1624193326Sed } 1625193326Sed 1626198092Srdivacky static void 1627198092Srdivacky Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs, 1628198092Srdivacky unsigned NumTemplateArgs, ASTContext &Context) { 1629194179Sed ID.AddInteger(NumTemplateArgs); 1630193326Sed for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg) 1631198092Srdivacky TemplateArgs[Arg].Profile(ID, Context); 1632193326Sed } 1633193326Sed 1634203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1635203955Srdivacky static bool classofKind(Kind K) { 1636210299Sed return K >= firstClassTemplateSpecialization && 1637210299Sed K <= lastClassTemplateSpecialization; 1638193326Sed } 1639193326Sed 1640218893Sdim friend class ASTDeclReader; 1641218893Sdim friend class ASTDeclWriter; 1642193326Sed}; 1643193326Sed 1644198092Srdivackyclass ClassTemplatePartialSpecializationDecl 1645198092Srdivacky : public ClassTemplateSpecializationDecl { 1646234353Sdim virtual void anchor(); 1647234353Sdim 1648198092Srdivacky /// \brief The list of template parameters 1649193326Sed TemplateParameterList* TemplateParams; 1650193326Sed 1651198893Srdivacky /// \brief The source info for the template arguments as written. 1652204962Srdivacky /// FIXME: redundant with TypeAsWritten? 1653263508Sdim const ASTTemplateArgumentListInfo *ArgsAsWritten; 1654198893Srdivacky 1655234353Sdim /// \brief The class template partial specialization from which this 1656198893Srdivacky /// class template partial specialization was instantiated. 1657198893Srdivacky /// 1658198893Srdivacky /// The boolean value will be true to indicate that this class template 1659198893Srdivacky /// partial specialization was specialized at this level. 1660198893Srdivacky llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool> 1661198893Srdivacky InstantiatedFromMember; 1662234353Sdim 1663208600Srdivacky ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 1664221345Sdim DeclContext *DC, 1665221345Sdim SourceLocation StartLoc, 1666221345Sdim SourceLocation IdLoc, 1667193326Sed TemplateParameterList *Params, 1668193326Sed ClassTemplateDecl *SpecializedTemplate, 1669218893Sdim const TemplateArgument *Args, 1670218893Sdim unsigned NumArgs, 1671263508Sdim const ASTTemplateArgumentListInfo *ArgsAsWritten, 1672263508Sdim ClassTemplatePartialSpecializationDecl *PrevDecl); 1673234353Sdim 1674210299Sed ClassTemplatePartialSpecializationDecl() 1675210299Sed : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization), 1676263508Sdim TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { } 1677193326Sed 1678193326Sedpublic: 1679193326Sed static ClassTemplatePartialSpecializationDecl * 1680234353Sdim Create(ASTContext &Context, TagKind TK, DeclContext *DC, 1681221345Sdim SourceLocation StartLoc, SourceLocation IdLoc, 1682193326Sed TemplateParameterList *Params, 1683193326Sed ClassTemplateDecl *SpecializedTemplate, 1684218893Sdim const TemplateArgument *Args, 1685218893Sdim unsigned NumArgs, 1686199990Srdivacky const TemplateArgumentListInfo &ArgInfos, 1687204962Srdivacky QualType CanonInjectedType, 1688263508Sdim ClassTemplatePartialSpecializationDecl *PrevDecl); 1689193326Sed 1690210299Sed static ClassTemplatePartialSpecializationDecl * 1691234353Sdim CreateDeserialized(ASTContext &C, unsigned ID); 1692210299Sed 1693234353Sdim ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { 1694212904Sdim return cast<ClassTemplatePartialSpecializationDecl>( 1695263508Sdim static_cast<ClassTemplateSpecializationDecl *>( 1696263508Sdim this)->getMostRecentDecl()); 1697212904Sdim } 1698212904Sdim 1699193326Sed /// Get the list of template parameters 1700193326Sed TemplateParameterList *getTemplateParameters() const { 1701193326Sed return TemplateParams; 1702193326Sed } 1703193326Sed 1704198893Srdivacky /// Get the template arguments as written. 1705263508Sdim const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { 1706198893Srdivacky return ArgsAsWritten; 1707198893Srdivacky } 1708198893Srdivacky 1709198893Srdivacky /// \brief Retrieve the member class template partial specialization from 1710198893Srdivacky /// which this particular class template partial specialization was 1711198893Srdivacky /// instantiated. 1712198893Srdivacky /// 1713198893Srdivacky /// \code 1714198893Srdivacky /// template<typename T> 1715198893Srdivacky /// struct Outer { 1716198893Srdivacky /// template<typename U> struct Inner; 1717198893Srdivacky /// template<typename U> struct Inner<U*> { }; // #1 1718198893Srdivacky /// }; 1719198893Srdivacky /// 1720198893Srdivacky /// Outer<float>::Inner<int*> ii; 1721198893Srdivacky /// \endcode 1722198893Srdivacky /// 1723198893Srdivacky /// In this example, the instantiation of \c Outer<float>::Inner<int*> will 1724234353Sdim /// end up instantiating the partial specialization 1725234353Sdim /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class 1726234353Sdim /// template partial specialization \c Outer<T>::Inner<U*>. Given 1727198893Srdivacky /// \c Outer<float>::Inner<U*>, this function would return 1728198893Srdivacky /// \c Outer<T>::Inner<U*>. 1729198893Srdivacky ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() { 1730263508Sdim ClassTemplatePartialSpecializationDecl *First = 1731263508Sdim cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); 1732198893Srdivacky return First->InstantiatedFromMember.getPointer(); 1733198893Srdivacky } 1734234353Sdim 1735198893Srdivacky void setInstantiatedFromMember( 1736198893Srdivacky ClassTemplatePartialSpecializationDecl *PartialSpec) { 1737263508Sdim ClassTemplatePartialSpecializationDecl *First = 1738263508Sdim cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); 1739198893Srdivacky First->InstantiatedFromMember.setPointer(PartialSpec); 1740198893Srdivacky } 1741234353Sdim 1742234353Sdim /// \brief Determines whether this class template partial specialization 1743198893Srdivacky /// template was a specialization of a member partial specialization. 1744198893Srdivacky /// 1745198893Srdivacky /// In the following example, the member template partial specialization 1746198893Srdivacky /// \c X<int>::Inner<T*> is a member specialization. 1747198893Srdivacky /// 1748198893Srdivacky /// \code 1749198893Srdivacky /// template<typename T> 1750198893Srdivacky /// struct X { 1751198893Srdivacky /// template<typename U> struct Inner; 1752198893Srdivacky /// template<typename U> struct Inner<U*>; 1753198893Srdivacky /// }; 1754198893Srdivacky /// 1755198893Srdivacky /// template<> template<typename T> 1756198893Srdivacky /// struct X<int>::Inner<T*> { /* ... */ }; 1757198893Srdivacky /// \endcode 1758198893Srdivacky bool isMemberSpecialization() { 1759263508Sdim ClassTemplatePartialSpecializationDecl *First = 1760263508Sdim cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); 1761198893Srdivacky return First->InstantiatedFromMember.getInt(); 1762198893Srdivacky } 1763234353Sdim 1764198893Srdivacky /// \brief Note that this member template is a specialization. 1765198893Srdivacky void setMemberSpecialization() { 1766263508Sdim ClassTemplatePartialSpecializationDecl *First = 1767263508Sdim cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); 1768198893Srdivacky assert(First->InstantiatedFromMember.getPointer() && 1769198893Srdivacky "Only member templates can be member template specializations"); 1770198893Srdivacky return First->InstantiatedFromMember.setInt(true); 1771198893Srdivacky } 1772207619Srdivacky 1773207619Srdivacky /// Retrieves the injected specialization type for this partial 1774207619Srdivacky /// specialization. This is not the same as the type-decl-type for 1775207619Srdivacky /// this partial specialization, which is an InjectedClassNameType. 1776207619Srdivacky QualType getInjectedSpecializationType() const { 1777207619Srdivacky assert(getTypeForDecl() && "partial specialization has no type set!"); 1778207619Srdivacky return cast<InjectedClassNameType>(getTypeForDecl()) 1779207619Srdivacky ->getInjectedSpecializationType(); 1780207619Srdivacky } 1781234353Sdim 1782193326Sed // FIXME: Add Profile support! 1783193326Sed 1784203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1785203955Srdivacky static bool classofKind(Kind K) { 1786203955Srdivacky return K == ClassTemplatePartialSpecialization; 1787193326Sed } 1788193326Sed 1789218893Sdim friend class ASTDeclReader; 1790218893Sdim friend class ASTDeclWriter; 1791193326Sed}; 1792193326Sed 1793193326Sed/// Declaration of a class template. 1794234353Sdimclass ClassTemplateDecl : public RedeclarableTemplateDecl { 1795208600Srdivacky static void DeallocateCommon(void *Ptr); 1796234353Sdim 1797193326Sedprotected: 1798193326Sed /// \brief Data that is common to all of the declarations of a given 1799193326Sed /// class template. 1800212904Sdim struct Common : CommonBase { 1801218893Sdim Common() : LazySpecializations() { } 1802234353Sdim 1803193326Sed /// \brief The class template specializations for this class 1804193326Sed /// template, including explicit specializations and instantiations. 1805239462Sdim llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations; 1806193326Sed 1807193326Sed /// \brief The class template partial specializations for this class 1808193326Sed /// template. 1809239462Sdim llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> 1810193326Sed PartialSpecializations; 1811193326Sed 1812193326Sed /// \brief The injected-class-name type for this class template. 1813193326Sed QualType InjectedClassNameType; 1814234353Sdim 1815218893Sdim /// \brief If non-null, points to an array of specializations (including 1816263508Sdim /// partial specializations) known only by their external declaration IDs. 1817218893Sdim /// 1818218893Sdim /// The first value in the array is the number of of specializations/ 1819218893Sdim /// partial specializations that follow. 1820218893Sdim uint32_t *LazySpecializations; 1821193326Sed }; 1822193326Sed 1823218893Sdim /// \brief Load any lazily-loaded specializations from the external source. 1824249423Sdim void LoadLazySpecializations() const; 1825234353Sdim 1826212904Sdim /// \brief Retrieve the set of specializations of this class template. 1827249423Sdim llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 1828249423Sdim getSpecializations() const; 1829193326Sed 1830212904Sdim /// \brief Retrieve the set of partial specializations of this class 1831212904Sdim /// template. 1832239462Sdim llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 1833218893Sdim getPartialSpecializations(); 1834198092Srdivacky 1835193326Sed ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, 1836210299Sed TemplateParameterList *Params, NamedDecl *Decl) 1837212904Sdim : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { } 1838193326Sed 1839221345Sdim ClassTemplateDecl(EmptyShell Empty) 1840221345Sdim : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(), 1841221345Sdim DeclarationName(), 0, 0) { } 1842221345Sdim 1843249423Sdim CommonBase *newCommon(ASTContext &C) const; 1844212904Sdim 1845249423Sdim Common *getCommonPtr() const { 1846212904Sdim return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); 1847212904Sdim } 1848212904Sdim 1849193326Sedpublic: 1850239462Sdim /// \brief Get the underlying class declarations of the template. 1851193326Sed CXXRecordDecl *getTemplatedDecl() const { 1852193326Sed return static_cast<CXXRecordDecl *>(TemplatedDecl); 1853193326Sed } 1854193326Sed 1855239462Sdim /// \brief Returns whether this template declaration defines the primary 1856212904Sdim /// class pattern. 1857212904Sdim bool isThisDeclarationADefinition() const { 1858212904Sdim return getTemplatedDecl()->isThisDeclarationADefinition(); 1859193326Sed } 1860193326Sed 1861239462Sdim /// \brief Create a class template node. 1862212904Sdim static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC, 1863212904Sdim SourceLocation L, 1864212904Sdim DeclarationName Name, 1865212904Sdim TemplateParameterList *Params, 1866212904Sdim NamedDecl *Decl, 1867212904Sdim ClassTemplateDecl *PrevDecl); 1868212904Sdim 1869239462Sdim /// \brief Create an empty class template node. 1870234353Sdim static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1871221345Sdim 1872212904Sdim /// \brief Return the specialization with the provided arguments if it exists, 1873212904Sdim /// otherwise return the insertion point. 1874212904Sdim ClassTemplateSpecializationDecl * 1875212904Sdim findSpecialization(const TemplateArgument *Args, unsigned NumArgs, 1876212904Sdim void *&InsertPos); 1877212904Sdim 1878212904Sdim /// \brief Insert the specified specialization knowing that it is not already 1879212904Sdim /// in. InsertPos must be obtained from findSpecialization. 1880218893Sdim void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos); 1881212904Sdim 1882212904Sdim ClassTemplateDecl *getCanonicalDecl() { 1883234353Sdim return cast<ClassTemplateDecl>( 1884234353Sdim RedeclarableTemplateDecl::getCanonicalDecl()); 1885212904Sdim } 1886212904Sdim const ClassTemplateDecl *getCanonicalDecl() const { 1887234353Sdim return cast<ClassTemplateDecl>( 1888234353Sdim RedeclarableTemplateDecl::getCanonicalDecl()); 1889212904Sdim } 1890212904Sdim 1891212904Sdim /// \brief Retrieve the previous declaration of this class template, or 1892210299Sed /// NULL if no such declaration exists. 1893234353Sdim ClassTemplateDecl *getPreviousDecl() { 1894234353Sdim return cast_or_null<ClassTemplateDecl>( 1895263508Sdim static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); 1896210299Sed } 1897210299Sed 1898212904Sdim /// \brief Retrieve the previous declaration of this class template, or 1899212904Sdim /// NULL if no such declaration exists. 1900234353Sdim const ClassTemplateDecl *getPreviousDecl() const { 1901234353Sdim return cast_or_null<ClassTemplateDecl>( 1902263508Sdim static_cast<const RedeclarableTemplateDecl *>( 1903263508Sdim this)->getPreviousDecl()); 1904210299Sed } 1905210299Sed 1906263508Sdim ClassTemplateDecl *getMostRecentDecl() { 1907263508Sdim return cast<ClassTemplateDecl>( 1908263508Sdim static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl()); 1909263508Sdim } 1910263508Sdim const ClassTemplateDecl *getMostRecentDecl() const { 1911263508Sdim return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl(); 1912263508Sdim } 1913263508Sdim 1914212904Sdim ClassTemplateDecl *getInstantiatedFromMemberTemplate() { 1915234353Sdim return cast_or_null<ClassTemplateDecl>( 1916234353Sdim RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); 1917210299Sed } 1918210299Sed 1919212904Sdim /// \brief Return the partial specialization with the provided arguments if it 1920212904Sdim /// exists, otherwise return the insertion point. 1921212904Sdim ClassTemplatePartialSpecializationDecl * 1922212904Sdim findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs, 1923212904Sdim void *&InsertPos); 1924193326Sed 1925212904Sdim /// \brief Insert the specified partial specialization knowing that it is not 1926212904Sdim /// already in. InsertPos must be obtained from findPartialSpecialization. 1927212904Sdim void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, 1928218893Sdim void *InsertPos); 1929193326Sed 1930207619Srdivacky /// \brief Retrieve the partial specializations as an ordered list. 1931207619Srdivacky void getPartialSpecializations( 1932226633Sdim SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS); 1933234353Sdim 1934198092Srdivacky /// \brief Find a class template partial specialization with the given 1935198092Srdivacky /// type T. 1936198092Srdivacky /// 1937212904Sdim /// \param T a dependent type that names a specialization of this class 1938198092Srdivacky /// template. 1939198092Srdivacky /// 1940198092Srdivacky /// \returns the class template partial specialization that exactly matches 1941198092Srdivacky /// the type \p T, or NULL if no such partial specialization exists. 1942198092Srdivacky ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T); 1943234353Sdim 1944212904Sdim /// \brief Find a class template partial specialization which was instantiated 1945212904Sdim /// from the given member partial specialization. 1946212904Sdim /// 1947212904Sdim /// \param D a member class template partial specialization. 1948212904Sdim /// 1949212904Sdim /// \returns the class template partial specialization which was instantiated 1950212904Sdim /// from the given member partial specialization, or NULL if no such partial 1951212904Sdim /// specialization exists. 1952212904Sdim ClassTemplatePartialSpecializationDecl * 1953212904Sdim findPartialSpecInstantiatedFromMember( 1954212904Sdim ClassTemplatePartialSpecializationDecl *D); 1955198092Srdivacky 1956204962Srdivacky /// \brief Retrieve the template specialization type of the 1957204962Srdivacky /// injected-class-name for this class template. 1958193326Sed /// 1959193326Sed /// The injected-class-name for a class template \c X is \c 1960193326Sed /// X<template-args>, where \c template-args is formed from the 1961193326Sed /// template arguments that correspond to the template parameters of 1962193326Sed /// \c X. For example: 1963193326Sed /// 1964193326Sed /// \code 1965193326Sed /// template<typename T, int N> 1966193326Sed /// struct array { 1967193326Sed /// typedef array this_type; // "array" is equivalent to "array<T, N>" 1968193326Sed /// }; 1969193326Sed /// \endcode 1970210299Sed QualType getInjectedClassNameSpecialization(); 1971193326Sed 1972212904Sdim typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator; 1973212904Sdim 1974249423Sdim spec_iterator spec_begin() const { 1975212904Sdim return makeSpecIterator(getSpecializations(), false); 1976198092Srdivacky } 1977198092Srdivacky 1978249423Sdim spec_iterator spec_end() const { 1979212904Sdim return makeSpecIterator(getSpecializations(), true); 1980198092Srdivacky } 1981198092Srdivacky 1982212904Sdim typedef SpecIterator<ClassTemplatePartialSpecializationDecl> 1983212904Sdim partial_spec_iterator; 1984212904Sdim 1985212904Sdim partial_spec_iterator partial_spec_begin() { 1986212904Sdim return makeSpecIterator(getPartialSpecializations(), false); 1987198092Srdivacky } 1988212904Sdim 1989212904Sdim partial_spec_iterator partial_spec_end() { 1990212904Sdim return makeSpecIterator(getPartialSpecializations(), true); 1991198092Srdivacky } 1992212904Sdim 1993193326Sed // Implement isa/cast/dyncast support 1994203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1995203955Srdivacky static bool classofKind(Kind K) { return K == ClassTemplate; } 1996193326Sed 1997212904Sdim friend class ASTDeclReader; 1998212904Sdim friend class ASTDeclWriter; 1999193326Sed}; 2000193326Sed 2001239462Sdim/// \brief Declaration of a friend template. 2002198092Srdivacky/// 2003239462Sdim/// For example: 2004239462Sdim/// \code 2005239462Sdim/// template \<typename T> class A { 2006198092Srdivacky/// friend class MyVector<T>; // not a friend template 2007239462Sdim/// template \<typename U> friend class B; // not a friend template 2008239462Sdim/// template \<typename U> friend class Foo<T>::Nested; // friend template 2009212904Sdim/// }; 2010239462Sdim/// \endcode 2011239462Sdim/// 2012239462Sdim/// \note This class is not currently in use. All of the above 2013212904Sdim/// will yield a FriendDecl, not a FriendTemplateDecl. 2014198092Srdivackyclass FriendTemplateDecl : public Decl { 2015234353Sdim virtual void anchor(); 2016198092Srdivackypublic: 2017206084Srdivacky typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion; 2018198092Srdivacky 2019198092Srdivackyprivate: 2020198092Srdivacky // The number of template parameters; always non-zero. 2021198092Srdivacky unsigned NumParams; 2022198092Srdivacky 2023198092Srdivacky // The parameter list. 2024198092Srdivacky TemplateParameterList **Params; 2025198092Srdivacky 2026198092Srdivacky // The declaration that's a friend of this class. 2027198092Srdivacky FriendUnion Friend; 2028198092Srdivacky 2029198092Srdivacky // Location of the 'friend' specifier. 2030198092Srdivacky SourceLocation FriendLoc; 2031198092Srdivacky 2032198092Srdivacky 2033198092Srdivacky FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, 2034234353Sdim unsigned NParams, 2035198092Srdivacky TemplateParameterList **Params, 2036198092Srdivacky FriendUnion Friend, 2037198092Srdivacky SourceLocation FriendLoc) 2038198092Srdivacky : Decl(Decl::FriendTemplate, DC, Loc), 2039198092Srdivacky NumParams(NParams), 2040198092Srdivacky Params(Params), 2041198092Srdivacky Friend(Friend), 2042198092Srdivacky FriendLoc(FriendLoc) 2043198092Srdivacky {} 2044198092Srdivacky 2045212904Sdim FriendTemplateDecl(EmptyShell Empty) 2046212904Sdim : Decl(Decl::FriendTemplate, Empty), 2047212904Sdim NumParams(0), 2048212904Sdim Params(0) 2049212904Sdim {} 2050212904Sdim 2051198092Srdivackypublic: 2052198092Srdivacky static FriendTemplateDecl *Create(ASTContext &Context, 2053198092Srdivacky DeclContext *DC, SourceLocation Loc, 2054234353Sdim unsigned NParams, 2055198092Srdivacky TemplateParameterList **Params, 2056198092Srdivacky FriendUnion Friend, 2057198092Srdivacky SourceLocation FriendLoc); 2058198092Srdivacky 2059234353Sdim static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); 2060212904Sdim 2061198092Srdivacky /// If this friend declaration names a templated type (or 2062198092Srdivacky /// a dependent member type of a templated type), return that 2063198092Srdivacky /// type; otherwise return null. 2064206084Srdivacky TypeSourceInfo *getFriendType() const { 2065206084Srdivacky return Friend.dyn_cast<TypeSourceInfo*>(); 2066198092Srdivacky } 2067198092Srdivacky 2068198092Srdivacky /// If this friend declaration names a templated function (or 2069198092Srdivacky /// a member function of a templated type), return that type; 2070198092Srdivacky /// otherwise return null. 2071198092Srdivacky NamedDecl *getFriendDecl() const { 2072198092Srdivacky return Friend.dyn_cast<NamedDecl*>(); 2073198092Srdivacky } 2074198092Srdivacky 2075239462Sdim /// \brief Retrieves the location of the 'friend' keyword. 2076198092Srdivacky SourceLocation getFriendLoc() const { 2077198092Srdivacky return FriendLoc; 2078198092Srdivacky } 2079198092Srdivacky 2080198092Srdivacky TemplateParameterList *getTemplateParameterList(unsigned i) const { 2081198092Srdivacky assert(i <= NumParams); 2082198092Srdivacky return Params[i]; 2083198092Srdivacky } 2084198092Srdivacky 2085198092Srdivacky unsigned getNumTemplateParameters() const { 2086198092Srdivacky return NumParams; 2087198092Srdivacky } 2088198092Srdivacky 2089198092Srdivacky // Implement isa/cast/dyncast/etc. 2090203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2091203955Srdivacky static bool classofKind(Kind K) { return K == Decl::FriendTemplate; } 2092212904Sdim 2093212904Sdim friend class ASTDeclReader; 2094198092Srdivacky}; 2095198092Srdivacky 2096239462Sdim/// \brief Declaration of an alias template. 2097223017Sdim/// 2098239462Sdim/// For example: 2099239462Sdim/// \code 2100239462Sdim/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>; 2101239462Sdim/// \endcode 2102234353Sdimclass TypeAliasTemplateDecl : public RedeclarableTemplateDecl { 2103223017Sdim static void DeallocateCommon(void *Ptr); 2104223017Sdim 2105223017Sdimprotected: 2106223017Sdim typedef CommonBase Common; 2107223017Sdim 2108223017Sdim TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, 2109223017Sdim TemplateParameterList *Params, NamedDecl *Decl) 2110223017Sdim : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { } 2111223017Sdim 2112249423Sdim CommonBase *newCommon(ASTContext &C) const; 2113223017Sdim 2114223017Sdim Common *getCommonPtr() { 2115223017Sdim return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); 2116223017Sdim } 2117223017Sdim 2118223017Sdimpublic: 2119223017Sdim /// Get the underlying function declaration of the template. 2120223017Sdim TypeAliasDecl *getTemplatedDecl() const { 2121223017Sdim return static_cast<TypeAliasDecl*>(TemplatedDecl); 2122223017Sdim } 2123223017Sdim 2124223017Sdim 2125223017Sdim TypeAliasTemplateDecl *getCanonicalDecl() { 2126234353Sdim return cast<TypeAliasTemplateDecl>( 2127234353Sdim RedeclarableTemplateDecl::getCanonicalDecl()); 2128223017Sdim } 2129223017Sdim const TypeAliasTemplateDecl *getCanonicalDecl() const { 2130234353Sdim return cast<TypeAliasTemplateDecl>( 2131234353Sdim RedeclarableTemplateDecl::getCanonicalDecl()); 2132223017Sdim } 2133223017Sdim 2134223017Sdim /// \brief Retrieve the previous declaration of this function template, or 2135223017Sdim /// NULL if no such declaration exists. 2136234353Sdim TypeAliasTemplateDecl *getPreviousDecl() { 2137234353Sdim return cast_or_null<TypeAliasTemplateDecl>( 2138263508Sdim static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); 2139223017Sdim } 2140223017Sdim 2141223017Sdim /// \brief Retrieve the previous declaration of this function template, or 2142223017Sdim /// NULL if no such declaration exists. 2143234353Sdim const TypeAliasTemplateDecl *getPreviousDecl() const { 2144234353Sdim return cast_or_null<TypeAliasTemplateDecl>( 2145263508Sdim static_cast<const RedeclarableTemplateDecl *>( 2146263508Sdim this)->getPreviousDecl()); 2147223017Sdim } 2148223017Sdim 2149223017Sdim TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() { 2150234353Sdim return cast_or_null<TypeAliasTemplateDecl>( 2151234353Sdim RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); 2152223017Sdim } 2153223017Sdim 2154234353Sdim 2155223017Sdim /// \brief Create a function template node. 2156223017Sdim static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC, 2157223017Sdim SourceLocation L, 2158223017Sdim DeclarationName Name, 2159223017Sdim TemplateParameterList *Params, 2160223017Sdim NamedDecl *Decl); 2161223017Sdim 2162223017Sdim /// \brief Create an empty alias template node. 2163234353Sdim static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); 2164223017Sdim 2165223017Sdim // Implement isa/cast/dyncast support 2166223017Sdim static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2167223017Sdim static bool classofKind(Kind K) { return K == TypeAliasTemplate; } 2168223017Sdim 2169223017Sdim friend class ASTDeclReader; 2170223017Sdim friend class ASTDeclWriter; 2171223017Sdim}; 2172223017Sdim 2173239462Sdim/// \brief Declaration of a function specialization at template class scope. 2174239462Sdim/// 2175226633Sdim/// This is a non standard extension needed to support MSVC. 2176239462Sdim/// 2177226633Sdim/// For example: 2178239462Sdim/// \code 2179226633Sdim/// template <class T> 2180226633Sdim/// class A { 2181226633Sdim/// template <class U> void foo(U a) { } 2182226633Sdim/// template<> void foo(int a) { } 2183226633Sdim/// } 2184239462Sdim/// \endcode 2185226633Sdim/// 2186226633Sdim/// "template<> foo(int a)" will be saved in Specialization as a normal 2187226633Sdim/// CXXMethodDecl. Then during an instantiation of class A, it will be 2188226633Sdim/// transformed into an actual function specialization. 2189226633Sdimclass ClassScopeFunctionSpecializationDecl : public Decl { 2190234353Sdim virtual void anchor(); 2191234353Sdim 2192226633Sdim ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc, 2193239462Sdim CXXMethodDecl *FD, bool Args, 2194239462Sdim TemplateArgumentListInfo TemplArgs) 2195226633Sdim : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc), 2196239462Sdim Specialization(FD), HasExplicitTemplateArgs(Args), 2197239462Sdim TemplateArgs(TemplArgs) {} 2198226633Sdim 2199226633Sdim ClassScopeFunctionSpecializationDecl(EmptyShell Empty) 2200226633Sdim : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {} 2201226633Sdim 2202226633Sdim CXXMethodDecl *Specialization; 2203239462Sdim bool HasExplicitTemplateArgs; 2204239462Sdim TemplateArgumentListInfo TemplateArgs; 2205226633Sdim 2206226633Sdimpublic: 2207226633Sdim CXXMethodDecl *getSpecialization() const { return Specialization; } 2208239462Sdim bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } 2209239462Sdim const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; } 2210226633Sdim 2211226633Sdim static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C, 2212226633Sdim DeclContext *DC, 2213226633Sdim SourceLocation Loc, 2214239462Sdim CXXMethodDecl *FD, 2215239462Sdim bool HasExplicitTemplateArgs, 2216239462Sdim TemplateArgumentListInfo TemplateArgs) { 2217239462Sdim return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD, 2218239462Sdim HasExplicitTemplateArgs, 2219239462Sdim TemplateArgs); 2220226633Sdim } 2221226633Sdim 2222234353Sdim static ClassScopeFunctionSpecializationDecl * 2223234353Sdim CreateDeserialized(ASTContext &Context, unsigned ID); 2224234353Sdim 2225226633Sdim // Implement isa/cast/dyncast/etc. 2226226633Sdim static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2227226633Sdim static bool classofKind(Kind K) { 2228226633Sdim return K == Decl::ClassScopeFunctionSpecialization; 2229226633Sdim } 2230226633Sdim 2231226633Sdim friend class ASTDeclReader; 2232226633Sdim friend class ASTDeclWriter; 2233226633Sdim}; 2234226633Sdim 2235195099Sed/// Implementation of inline functions that require the template declarations 2236198092Srdivackyinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD) 2237195099Sed : Function(FTD) { } 2238195099Sed 2239263508Sdim/// \brief Represents a variable template specialization, which refers to 2240263508Sdim/// a variable template with a given set of template arguments. 2241263508Sdim/// 2242263508Sdim/// Variable template specializations represent both explicit 2243263508Sdim/// specializations of variable templates, as in the example below, and 2244263508Sdim/// implicit instantiations of variable templates. 2245263508Sdim/// 2246263508Sdim/// \code 2247263508Sdim/// template<typename T> constexpr T pi = T(3.1415926535897932385); 2248263508Sdim/// 2249263508Sdim/// template<> 2250263508Sdim/// constexpr float pi<float>; // variable template specialization pi<float> 2251263508Sdim/// \endcode 2252263508Sdimclass VarTemplateSpecializationDecl : public VarDecl, 2253263508Sdim public llvm::FoldingSetNode { 2254263508Sdim 2255263508Sdim /// \brief Structure that stores information about a variable template 2256263508Sdim /// specialization that was instantiated from a variable template partial 2257263508Sdim /// specialization. 2258263508Sdim struct SpecializedPartialSpecialization { 2259263508Sdim /// \brief The variable template partial specialization from which this 2260263508Sdim /// variable template specialization was instantiated. 2261263508Sdim VarTemplatePartialSpecializationDecl *PartialSpecialization; 2262263508Sdim 2263263508Sdim /// \brief The template argument list deduced for the variable template 2264263508Sdim /// partial specialization itself. 2265263508Sdim const TemplateArgumentList *TemplateArgs; 2266263508Sdim }; 2267263508Sdim 2268263508Sdim /// \brief The template that this specialization specializes. 2269263508Sdim llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *> 2270263508Sdim SpecializedTemplate; 2271263508Sdim 2272263508Sdim /// \brief Further info for explicit template specialization/instantiation. 2273263508Sdim struct ExplicitSpecializationInfo { 2274263508Sdim /// \brief The type-as-written. 2275263508Sdim TypeSourceInfo *TypeAsWritten; 2276263508Sdim /// \brief The location of the extern keyword. 2277263508Sdim SourceLocation ExternLoc; 2278263508Sdim /// \brief The location of the template keyword. 2279263508Sdim SourceLocation TemplateKeywordLoc; 2280263508Sdim 2281263508Sdim ExplicitSpecializationInfo() 2282263508Sdim : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {} 2283263508Sdim }; 2284263508Sdim 2285263508Sdim /// \brief Further info for explicit template specialization/instantiation. 2286263508Sdim /// Does not apply to implicit specializations. 2287263508Sdim ExplicitSpecializationInfo *ExplicitInfo; 2288263508Sdim 2289263508Sdim /// \brief The template arguments used to describe this specialization. 2290263508Sdim const TemplateArgumentList *TemplateArgs; 2291263508Sdim TemplateArgumentListInfo TemplateArgsInfo; 2292263508Sdim 2293263508Sdim /// \brief The point where this template was instantiated (if any). 2294263508Sdim SourceLocation PointOfInstantiation; 2295263508Sdim 2296263508Sdim /// \brief The kind of specialization this declaration refers to. 2297263508Sdim /// Really a value of type TemplateSpecializationKind. 2298263508Sdim unsigned SpecializationKind : 3; 2299263508Sdim 2300263508Sdimprotected: 2301263508Sdim VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC, 2302263508Sdim SourceLocation StartLoc, SourceLocation IdLoc, 2303263508Sdim VarTemplateDecl *SpecializedTemplate, 2304263508Sdim QualType T, TypeSourceInfo *TInfo, 2305263508Sdim StorageClass S, const TemplateArgument *Args, 2306263508Sdim unsigned NumArgs); 2307263508Sdim 2308263508Sdim explicit VarTemplateSpecializationDecl(Kind DK); 2309263508Sdim 2310263508Sdimpublic: 2311263508Sdim static VarTemplateSpecializationDecl * 2312263508Sdim Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 2313263508Sdim SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 2314263508Sdim TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 2315263508Sdim unsigned NumArgs); 2316263508Sdim static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, 2317263508Sdim unsigned ID); 2318263508Sdim 2319263508Sdim virtual void getNameForDiagnostic(raw_ostream &OS, 2320263508Sdim const PrintingPolicy &Policy, 2321263508Sdim bool Qualified) const; 2322263508Sdim 2323263508Sdim VarTemplateSpecializationDecl *getMostRecentDecl() { 2324263508Sdim VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl(); 2325263508Sdim return cast<VarTemplateSpecializationDecl>(Recent); 2326263508Sdim } 2327263508Sdim 2328263508Sdim /// \brief Retrieve the template that this specialization specializes. 2329263508Sdim VarTemplateDecl *getSpecializedTemplate() const; 2330263508Sdim 2331263508Sdim /// \brief Retrieve the template arguments of the variable template 2332263508Sdim /// specialization. 2333263508Sdim const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; } 2334263508Sdim 2335263508Sdim // TODO: Always set this when creating the new specialization? 2336263508Sdim void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo); 2337263508Sdim 2338263508Sdim const TemplateArgumentListInfo &getTemplateArgsInfo() const { 2339263508Sdim return TemplateArgsInfo; 2340263508Sdim } 2341263508Sdim 2342263508Sdim /// \brief Determine the kind of specialization that this 2343263508Sdim /// declaration represents. 2344263508Sdim TemplateSpecializationKind getSpecializationKind() const { 2345263508Sdim return static_cast<TemplateSpecializationKind>(SpecializationKind); 2346263508Sdim } 2347263508Sdim 2348263508Sdim bool isExplicitSpecialization() const { 2349263508Sdim return getSpecializationKind() == TSK_ExplicitSpecialization; 2350263508Sdim } 2351263508Sdim 2352263508Sdim /// \brief True if this declaration is an explicit specialization, 2353263508Sdim /// explicit instantiation declaration, or explicit instantiation 2354263508Sdim /// definition. 2355263508Sdim bool isExplicitInstantiationOrSpecialization() const { 2356263508Sdim switch (getTemplateSpecializationKind()) { 2357263508Sdim case TSK_ExplicitSpecialization: 2358263508Sdim case TSK_ExplicitInstantiationDeclaration: 2359263508Sdim case TSK_ExplicitInstantiationDefinition: 2360263508Sdim return true; 2361263508Sdim 2362263508Sdim case TSK_Undeclared: 2363263508Sdim case TSK_ImplicitInstantiation: 2364263508Sdim return false; 2365263508Sdim } 2366263508Sdim llvm_unreachable("bad template specialization kind"); 2367263508Sdim } 2368263508Sdim 2369263508Sdim void setSpecializationKind(TemplateSpecializationKind TSK) { 2370263508Sdim SpecializationKind = TSK; 2371263508Sdim } 2372263508Sdim 2373263508Sdim /// \brief Get the point of instantiation (if any), or null if none. 2374263508Sdim SourceLocation getPointOfInstantiation() const { 2375263508Sdim return PointOfInstantiation; 2376263508Sdim } 2377263508Sdim 2378263508Sdim void setPointOfInstantiation(SourceLocation Loc) { 2379263508Sdim assert(Loc.isValid() && "point of instantiation must be valid!"); 2380263508Sdim PointOfInstantiation = Loc; 2381263508Sdim } 2382263508Sdim 2383263508Sdim /// \brief If this variable template specialization is an instantiation of 2384263508Sdim /// a template (rather than an explicit specialization), return the 2385263508Sdim /// variable template or variable template partial specialization from which 2386263508Sdim /// it was instantiated. 2387263508Sdim llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> 2388263508Sdim getInstantiatedFrom() const { 2389263508Sdim if (getSpecializationKind() != TSK_ImplicitInstantiation && 2390263508Sdim getSpecializationKind() != TSK_ExplicitInstantiationDefinition && 2391263508Sdim getSpecializationKind() != TSK_ExplicitInstantiationDeclaration) 2392263508Sdim return llvm::PointerUnion<VarTemplateDecl *, 2393263508Sdim VarTemplatePartialSpecializationDecl *>(); 2394263508Sdim 2395263508Sdim if (SpecializedPartialSpecialization *PartialSpec = 2396263508Sdim SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 2397263508Sdim return PartialSpec->PartialSpecialization; 2398263508Sdim 2399263508Sdim return SpecializedTemplate.get<VarTemplateDecl *>(); 2400263508Sdim } 2401263508Sdim 2402263508Sdim /// \brief Retrieve the variable template or variable template partial 2403263508Sdim /// specialization which was specialized by this. 2404263508Sdim llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> 2405263508Sdim getSpecializedTemplateOrPartial() const { 2406263508Sdim if (SpecializedPartialSpecialization *PartialSpec = 2407263508Sdim SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 2408263508Sdim return PartialSpec->PartialSpecialization; 2409263508Sdim 2410263508Sdim return SpecializedTemplate.get<VarTemplateDecl *>(); 2411263508Sdim } 2412263508Sdim 2413263508Sdim /// \brief Retrieve the set of template arguments that should be used 2414263508Sdim /// to instantiate the initializer of the variable template or variable 2415263508Sdim /// template partial specialization from which this variable template 2416263508Sdim /// specialization was instantiated. 2417263508Sdim /// 2418263508Sdim /// \returns For a variable template specialization instantiated from the 2419263508Sdim /// primary template, this function will return the same template arguments 2420263508Sdim /// as getTemplateArgs(). For a variable template specialization instantiated 2421263508Sdim /// from a variable template partial specialization, this function will the 2422263508Sdim /// return deduced template arguments for the variable template partial 2423263508Sdim /// specialization itself. 2424263508Sdim const TemplateArgumentList &getTemplateInstantiationArgs() const { 2425263508Sdim if (SpecializedPartialSpecialization *PartialSpec = 2426263508Sdim SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 2427263508Sdim return *PartialSpec->TemplateArgs; 2428263508Sdim 2429263508Sdim return getTemplateArgs(); 2430263508Sdim } 2431263508Sdim 2432263508Sdim /// \brief Note that this variable template specialization is actually an 2433263508Sdim /// instantiation of the given variable template partial specialization whose 2434263508Sdim /// template arguments have been deduced. 2435263508Sdim void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, 2436263508Sdim const TemplateArgumentList *TemplateArgs) { 2437263508Sdim assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() && 2438263508Sdim "Already set to a variable template partial specialization!"); 2439263508Sdim SpecializedPartialSpecialization *PS = 2440263508Sdim new (getASTContext()) SpecializedPartialSpecialization(); 2441263508Sdim PS->PartialSpecialization = PartialSpec; 2442263508Sdim PS->TemplateArgs = TemplateArgs; 2443263508Sdim SpecializedTemplate = PS; 2444263508Sdim } 2445263508Sdim 2446263508Sdim /// \brief Note that this variable template specialization is an instantiation 2447263508Sdim /// of the given variable template. 2448263508Sdim void setInstantiationOf(VarTemplateDecl *TemplDecl) { 2449263508Sdim assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() && 2450263508Sdim "Previously set to a variable template partial specialization!"); 2451263508Sdim SpecializedTemplate = TemplDecl; 2452263508Sdim } 2453263508Sdim 2454263508Sdim /// \brief Sets the type of this specialization as it was written by 2455263508Sdim /// the user. 2456263508Sdim void setTypeAsWritten(TypeSourceInfo *T) { 2457263508Sdim if (!ExplicitInfo) 2458263508Sdim ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; 2459263508Sdim ExplicitInfo->TypeAsWritten = T; 2460263508Sdim } 2461263508Sdim /// \brief Gets the type of this specialization as it was written by 2462263508Sdim /// the user, if it was so written. 2463263508Sdim TypeSourceInfo *getTypeAsWritten() const { 2464263508Sdim return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0; 2465263508Sdim } 2466263508Sdim 2467263508Sdim /// \brief Gets the location of the extern keyword, if present. 2468263508Sdim SourceLocation getExternLoc() const { 2469263508Sdim return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation(); 2470263508Sdim } 2471263508Sdim /// \brief Sets the location of the extern keyword. 2472263508Sdim void setExternLoc(SourceLocation Loc) { 2473263508Sdim if (!ExplicitInfo) 2474263508Sdim ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; 2475263508Sdim ExplicitInfo->ExternLoc = Loc; 2476263508Sdim } 2477263508Sdim 2478263508Sdim /// \brief Sets the location of the template keyword. 2479263508Sdim void setTemplateKeywordLoc(SourceLocation Loc) { 2480263508Sdim if (!ExplicitInfo) 2481263508Sdim ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; 2482263508Sdim ExplicitInfo->TemplateKeywordLoc = Loc; 2483263508Sdim } 2484263508Sdim /// \brief Gets the location of the template keyword, if present. 2485263508Sdim SourceLocation getTemplateKeywordLoc() const { 2486263508Sdim return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); 2487263508Sdim } 2488263508Sdim 2489263508Sdim void Profile(llvm::FoldingSetNodeID &ID) const { 2490263508Sdim Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext()); 2491263508Sdim } 2492263508Sdim 2493263508Sdim static void Profile(llvm::FoldingSetNodeID &ID, 2494263508Sdim const TemplateArgument *TemplateArgs, 2495263508Sdim unsigned NumTemplateArgs, ASTContext &Context) { 2496263508Sdim ID.AddInteger(NumTemplateArgs); 2497263508Sdim for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg) 2498263508Sdim TemplateArgs[Arg].Profile(ID, Context); 2499263508Sdim } 2500263508Sdim 2501263508Sdim static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2502263508Sdim static bool classofKind(Kind K) { 2503263508Sdim return K >= firstVarTemplateSpecialization && 2504263508Sdim K <= lastVarTemplateSpecialization; 2505263508Sdim } 2506263508Sdim 2507263508Sdim friend class ASTDeclReader; 2508263508Sdim friend class ASTDeclWriter; 2509263508Sdim}; 2510263508Sdim 2511263508Sdimclass VarTemplatePartialSpecializationDecl 2512263508Sdim : public VarTemplateSpecializationDecl { 2513263508Sdim virtual void anchor(); 2514263508Sdim 2515263508Sdim /// \brief The list of template parameters 2516263508Sdim TemplateParameterList *TemplateParams; 2517263508Sdim 2518263508Sdim /// \brief The source info for the template arguments as written. 2519263508Sdim /// FIXME: redundant with TypeAsWritten? 2520263508Sdim const ASTTemplateArgumentListInfo *ArgsAsWritten; 2521263508Sdim 2522263508Sdim /// \brief The variable template partial specialization from which this 2523263508Sdim /// variable template partial specialization was instantiated. 2524263508Sdim /// 2525263508Sdim /// The boolean value will be true to indicate that this variable template 2526263508Sdim /// partial specialization was specialized at this level. 2527263508Sdim llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool> 2528263508Sdim InstantiatedFromMember; 2529263508Sdim 2530263508Sdim VarTemplatePartialSpecializationDecl( 2531263508Sdim ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 2532263508Sdim SourceLocation IdLoc, TemplateParameterList *Params, 2533263508Sdim VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 2534263508Sdim StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 2535263508Sdim const ASTTemplateArgumentListInfo *ArgInfos); 2536263508Sdim 2537263508Sdim VarTemplatePartialSpecializationDecl() 2538263508Sdim : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization), 2539263508Sdim TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {} 2540263508Sdim 2541263508Sdimpublic: 2542263508Sdim static VarTemplatePartialSpecializationDecl * 2543263508Sdim Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 2544263508Sdim SourceLocation IdLoc, TemplateParameterList *Params, 2545263508Sdim VarTemplateDecl *SpecializedTemplate, QualType T, 2546263508Sdim TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 2547263508Sdim unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos); 2548263508Sdim 2549263508Sdim static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, 2550263508Sdim unsigned ID); 2551263508Sdim 2552263508Sdim VarTemplatePartialSpecializationDecl *getMostRecentDecl() { 2553263508Sdim return cast<VarTemplatePartialSpecializationDecl>( 2554263508Sdim static_cast<VarTemplateSpecializationDecl *>( 2555263508Sdim this)->getMostRecentDecl()); 2556263508Sdim } 2557263508Sdim 2558263508Sdim /// Get the list of template parameters 2559263508Sdim TemplateParameterList *getTemplateParameters() const { 2560263508Sdim return TemplateParams; 2561263508Sdim } 2562263508Sdim 2563263508Sdim /// Get the template arguments as written. 2564263508Sdim const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { 2565263508Sdim return ArgsAsWritten; 2566263508Sdim } 2567263508Sdim 2568263508Sdim /// \brief Retrieve the member variable template partial specialization from 2569263508Sdim /// which this particular variable template partial specialization was 2570263508Sdim /// instantiated. 2571263508Sdim /// 2572263508Sdim /// \code 2573263508Sdim /// template<typename T> 2574263508Sdim /// struct Outer { 2575263508Sdim /// template<typename U> U Inner; 2576263508Sdim /// template<typename U> U* Inner<U*> = (U*)(0); // #1 2577263508Sdim /// }; 2578263508Sdim /// 2579263508Sdim /// template int* Outer<float>::Inner<int*>; 2580263508Sdim /// \endcode 2581263508Sdim /// 2582263508Sdim /// In this example, the instantiation of \c Outer<float>::Inner<int*> will 2583263508Sdim /// end up instantiating the partial specialization 2584263508Sdim /// \c Outer<float>::Inner<U*>, which itself was instantiated from the 2585263508Sdim /// variable template partial specialization \c Outer<T>::Inner<U*>. Given 2586263508Sdim /// \c Outer<float>::Inner<U*>, this function would return 2587263508Sdim /// \c Outer<T>::Inner<U*>. 2588263508Sdim VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() { 2589263508Sdim VarTemplatePartialSpecializationDecl *First = 2590263508Sdim cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); 2591263508Sdim return First->InstantiatedFromMember.getPointer(); 2592263508Sdim } 2593263508Sdim 2594263508Sdim void 2595263508Sdim setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) { 2596263508Sdim VarTemplatePartialSpecializationDecl *First = 2597263508Sdim cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); 2598263508Sdim First->InstantiatedFromMember.setPointer(PartialSpec); 2599263508Sdim } 2600263508Sdim 2601263508Sdim /// \brief Determines whether this variable template partial specialization 2602263508Sdim /// was a specialization of a member partial specialization. 2603263508Sdim /// 2604263508Sdim /// In the following example, the member template partial specialization 2605263508Sdim /// \c X<int>::Inner<T*> is a member specialization. 2606263508Sdim /// 2607263508Sdim /// \code 2608263508Sdim /// template<typename T> 2609263508Sdim /// struct X { 2610263508Sdim /// template<typename U> U Inner; 2611263508Sdim /// template<typename U> U* Inner<U*> = (U*)(0); 2612263508Sdim /// }; 2613263508Sdim /// 2614263508Sdim /// template<> template<typename T> 2615263508Sdim /// U* X<int>::Inner<T*> = (T*)(0) + 1; 2616263508Sdim /// \endcode 2617263508Sdim bool isMemberSpecialization() { 2618263508Sdim VarTemplatePartialSpecializationDecl *First = 2619263508Sdim cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); 2620263508Sdim return First->InstantiatedFromMember.getInt(); 2621263508Sdim } 2622263508Sdim 2623263508Sdim /// \brief Note that this member template is a specialization. 2624263508Sdim void setMemberSpecialization() { 2625263508Sdim VarTemplatePartialSpecializationDecl *First = 2626263508Sdim cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); 2627263508Sdim assert(First->InstantiatedFromMember.getPointer() && 2628263508Sdim "Only member templates can be member template specializations"); 2629263508Sdim return First->InstantiatedFromMember.setInt(true); 2630263508Sdim } 2631263508Sdim 2632263508Sdim static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2633263508Sdim static bool classofKind(Kind K) { 2634263508Sdim return K == VarTemplatePartialSpecialization; 2635263508Sdim } 2636263508Sdim 2637263508Sdim friend class ASTDeclReader; 2638263508Sdim friend class ASTDeclWriter; 2639263508Sdim}; 2640263508Sdim 2641263508Sdim/// Declaration of a variable template. 2642263508Sdimclass VarTemplateDecl : public RedeclarableTemplateDecl { 2643263508Sdim static void DeallocateCommon(void *Ptr); 2644263508Sdim 2645263508Sdimprotected: 2646263508Sdim /// \brief Data that is common to all of the declarations of a given 2647263508Sdim /// variable template. 2648263508Sdim struct Common : CommonBase { 2649263508Sdim Common() : LazySpecializations() {} 2650263508Sdim 2651263508Sdim /// \brief The variable template specializations for this variable 2652263508Sdim /// template, including explicit specializations and instantiations. 2653263508Sdim llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations; 2654263508Sdim 2655263508Sdim /// \brief The variable template partial specializations for this variable 2656263508Sdim /// template. 2657263508Sdim llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> 2658263508Sdim PartialSpecializations; 2659263508Sdim 2660263508Sdim /// \brief If non-null, points to an array of specializations (including 2661263508Sdim /// partial specializations) known ownly by their external declaration IDs. 2662263508Sdim /// 2663263508Sdim /// The first value in the array is the number of of specializations/ 2664263508Sdim /// partial specializations that follow. 2665263508Sdim uint32_t *LazySpecializations; 2666263508Sdim }; 2667263508Sdim 2668263508Sdim /// \brief Load any lazily-loaded specializations from the external source. 2669263508Sdim void LoadLazySpecializations() const; 2670263508Sdim 2671263508Sdim /// \brief Retrieve the set of specializations of this variable template. 2672263508Sdim llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 2673263508Sdim getSpecializations() const; 2674263508Sdim 2675263508Sdim /// \brief Retrieve the set of partial specializations of this class 2676263508Sdim /// template. 2677263508Sdim llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 2678263508Sdim getPartialSpecializations(); 2679263508Sdim 2680263508Sdim VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, 2681263508Sdim TemplateParameterList *Params, NamedDecl *Decl) 2682263508Sdim : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {} 2683263508Sdim 2684263508Sdim VarTemplateDecl(EmptyShell Empty) 2685263508Sdim : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(), 2686263508Sdim DeclarationName(), 0, 0) {} 2687263508Sdim 2688263508Sdim CommonBase *newCommon(ASTContext &C) const; 2689263508Sdim 2690263508Sdim Common *getCommonPtr() const { 2691263508Sdim return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); 2692263508Sdim } 2693263508Sdim 2694263508Sdimpublic: 2695263508Sdim /// \brief Get the underlying variable declarations of the template. 2696263508Sdim VarDecl *getTemplatedDecl() const { 2697263508Sdim return static_cast<VarDecl *>(TemplatedDecl); 2698263508Sdim } 2699263508Sdim 2700263508Sdim /// \brief Returns whether this template declaration defines the primary 2701263508Sdim /// variable pattern. 2702263508Sdim bool isThisDeclarationADefinition() const { 2703263508Sdim return getTemplatedDecl()->isThisDeclarationADefinition(); 2704263508Sdim } 2705263508Sdim 2706263508Sdim VarTemplateDecl *getDefinition(); 2707263508Sdim 2708263508Sdim /// \brief Create a variable template node. 2709263508Sdim static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC, 2710263508Sdim SourceLocation L, DeclarationName Name, 2711263508Sdim TemplateParameterList *Params, NamedDecl *Decl, 2712263508Sdim VarTemplateDecl *PrevDecl); 2713263508Sdim 2714263508Sdim /// \brief Create an empty variable template node. 2715263508Sdim static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); 2716263508Sdim 2717263508Sdim /// \brief Return the specialization with the provided arguments if it exists, 2718263508Sdim /// otherwise return the insertion point. 2719263508Sdim VarTemplateSpecializationDecl * 2720263508Sdim findSpecialization(const TemplateArgument *Args, unsigned NumArgs, 2721263508Sdim void *&InsertPos); 2722263508Sdim 2723263508Sdim /// \brief Insert the specified specialization knowing that it is not already 2724263508Sdim /// in. InsertPos must be obtained from findSpecialization. 2725263508Sdim void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos); 2726263508Sdim 2727263508Sdim VarTemplateDecl *getCanonicalDecl() { 2728263508Sdim return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl()); 2729263508Sdim } 2730263508Sdim const VarTemplateDecl *getCanonicalDecl() const { 2731263508Sdim return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl()); 2732263508Sdim } 2733263508Sdim 2734263508Sdim /// \brief Retrieve the previous declaration of this variable template, or 2735263508Sdim /// NULL if no such declaration exists. 2736263508Sdim VarTemplateDecl *getPreviousDecl() { 2737263508Sdim return cast_or_null<VarTemplateDecl>( 2738263508Sdim static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); 2739263508Sdim } 2740263508Sdim 2741263508Sdim /// \brief Retrieve the previous declaration of this variable template, or 2742263508Sdim /// NULL if no such declaration exists. 2743263508Sdim const VarTemplateDecl *getPreviousDecl() const { 2744263508Sdim return cast_or_null<VarTemplateDecl>( 2745263508Sdim static_cast<const RedeclarableTemplateDecl *>( 2746263508Sdim this)->getPreviousDecl()); 2747263508Sdim } 2748263508Sdim 2749263508Sdim VarTemplateDecl *getInstantiatedFromMemberTemplate() { 2750263508Sdim return cast_or_null<VarTemplateDecl>( 2751263508Sdim RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); 2752263508Sdim } 2753263508Sdim 2754263508Sdim /// \brief Return the partial specialization with the provided arguments if it 2755263508Sdim /// exists, otherwise return the insertion point. 2756263508Sdim VarTemplatePartialSpecializationDecl * 2757263508Sdim findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs, 2758263508Sdim void *&InsertPos); 2759263508Sdim 2760263508Sdim /// \brief Insert the specified partial specialization knowing that it is not 2761263508Sdim /// already in. InsertPos must be obtained from findPartialSpecialization. 2762263508Sdim void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, 2763263508Sdim void *InsertPos); 2764263508Sdim 2765263508Sdim /// \brief Retrieve the partial specializations as an ordered list. 2766263508Sdim void getPartialSpecializations( 2767263508Sdim SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS); 2768263508Sdim 2769263508Sdim /// \brief Find a variable template partial specialization which was 2770263508Sdim /// instantiated 2771263508Sdim /// from the given member partial specialization. 2772263508Sdim /// 2773263508Sdim /// \param D a member variable template partial specialization. 2774263508Sdim /// 2775263508Sdim /// \returns the variable template partial specialization which was 2776263508Sdim /// instantiated 2777263508Sdim /// from the given member partial specialization, or NULL if no such partial 2778263508Sdim /// specialization exists. 2779263508Sdim VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember( 2780263508Sdim VarTemplatePartialSpecializationDecl *D); 2781263508Sdim 2782263508Sdim typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator; 2783263508Sdim 2784263508Sdim spec_iterator spec_begin() const { 2785263508Sdim return makeSpecIterator(getSpecializations(), false); 2786263508Sdim } 2787263508Sdim 2788263508Sdim spec_iterator spec_end() const { 2789263508Sdim return makeSpecIterator(getSpecializations(), true); 2790263508Sdim } 2791263508Sdim 2792263508Sdim typedef SpecIterator<VarTemplatePartialSpecializationDecl> 2793263508Sdim partial_spec_iterator; 2794263508Sdim 2795263508Sdim partial_spec_iterator partial_spec_begin() { 2796263508Sdim return makeSpecIterator(getPartialSpecializations(), false); 2797263508Sdim } 2798263508Sdim 2799263508Sdim partial_spec_iterator partial_spec_end() { 2800263508Sdim return makeSpecIterator(getPartialSpecializations(), true); 2801263508Sdim } 2802263508Sdim 2803263508Sdim // Implement isa/cast/dyncast support 2804263508Sdim static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2805263508Sdim static bool classofKind(Kind K) { return K == VarTemplate; } 2806263508Sdim 2807263508Sdim friend class ASTDeclReader; 2808263508Sdim friend class ASTDeclWriter; 2809263508Sdim}; 2810263508Sdim 2811193326Sed} /* end of namespace clang */ 2812193326Sed 2813193326Sed#endif 2814