1212795Sdim//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/ 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim//===----------------------------------------------------------------------===/ 8212795Sdim// 9212795Sdim// This file provides types used in the semantic analysis of C++ templates. 10212795Sdim// 11212795Sdim//===----------------------------------------------------------------------===/ 12212795Sdim#ifndef LLVM_CLANG_SEMA_TEMPLATE_H 13212795Sdim#define LLVM_CLANG_SEMA_TEMPLATE_H 14212795Sdim 15212795Sdim#include "clang/AST/DeclTemplate.h" 16218893Sdim#include "clang/AST/DeclVisitor.h" 17249423Sdim#include "clang/Sema/Sema.h" 18212795Sdim#include "llvm/ADT/SmallVector.h" 19212795Sdim#include <cassert> 20218893Sdim#include <utility> 21212795Sdim 22212795Sdimnamespace clang { 23212795Sdim /// \brief Data structure that captures multiple levels of template argument 24212795Sdim /// lists for use in template instantiation. 25212795Sdim /// 26212795Sdim /// Multiple levels of template arguments occur when instantiating the 27212795Sdim /// definitions of member templates. For example: 28212795Sdim /// 29212795Sdim /// \code 30212795Sdim /// template<typename T> 31212795Sdim /// struct X { 32212795Sdim /// template<T Value> 33212795Sdim /// struct Y { 34212795Sdim /// void f(); 35212795Sdim /// }; 36212795Sdim /// }; 37212795Sdim /// \endcode 38212795Sdim /// 39212795Sdim /// When instantiating X<int>::Y<17>::f, the multi-level template argument 40212795Sdim /// list will contain a template argument list (int) at depth 0 and a 41212795Sdim /// template argument list (17) at depth 1. 42212795Sdim class MultiLevelTemplateArgumentList { 43251662Sdim /// \brief The template argument list at a certain template depth 44251662Sdim typedef ArrayRef<TemplateArgument> ArgList; 45251662Sdim 46212795Sdim /// \brief The template argument lists, stored from the innermost template 47212795Sdim /// argument list (first) to the outermost template argument list (last). 48226633Sdim SmallVector<ArgList, 4> TemplateArgumentLists; 49212795Sdim 50212795Sdim public: 51212795Sdim /// \brief Construct an empty set of template argument lists. 52212795Sdim MultiLevelTemplateArgumentList() { } 53212795Sdim 54212795Sdim /// \brief Construct a single-level template argument list. 55212795Sdim explicit 56212795Sdim MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) { 57212795Sdim addOuterTemplateArguments(&TemplateArgs); 58212795Sdim } 59212795Sdim 60212795Sdim /// \brief Determine the number of levels in this template argument 61212795Sdim /// list. 62212795Sdim unsigned getNumLevels() const { return TemplateArgumentLists.size(); } 63212795Sdim 64212795Sdim /// \brief Retrieve the template argument at a given depth and index. 65212795Sdim const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { 66212795Sdim assert(Depth < TemplateArgumentLists.size()); 67251662Sdim assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); 68251662Sdim return TemplateArgumentLists[getNumLevels() - Depth - 1][Index]; 69212795Sdim } 70212795Sdim 71212795Sdim /// \brief Determine whether there is a non-NULL template argument at the 72212795Sdim /// given depth and index. 73212795Sdim /// 74212795Sdim /// There must exist a template argument list at the given depth. 75212795Sdim bool hasTemplateArgument(unsigned Depth, unsigned Index) const { 76212795Sdim assert(Depth < TemplateArgumentLists.size()); 77212795Sdim 78251662Sdim if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size()) 79212795Sdim return false; 80212795Sdim 81212795Sdim return !(*this)(Depth, Index).isNull(); 82212795Sdim } 83212795Sdim 84218893Sdim /// \brief Clear out a specific template argument. 85218893Sdim void setArgument(unsigned Depth, unsigned Index, 86218893Sdim TemplateArgument Arg) { 87218893Sdim assert(Depth < TemplateArgumentLists.size()); 88251662Sdim assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); 89218893Sdim const_cast<TemplateArgument&>( 90251662Sdim TemplateArgumentLists[getNumLevels() - Depth - 1][Index]) 91218893Sdim = Arg; 92218893Sdim } 93218893Sdim 94212795Sdim /// \brief Add a new outermost level to the multi-level template argument 95212795Sdim /// list. 96212795Sdim void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { 97251662Sdim addOuterTemplateArguments(ArgList(TemplateArgs->data(), 98251662Sdim TemplateArgs->size())); 99212795Sdim } 100251662Sdim 101251662Sdim /// \brief Add a new outmost level to the multi-level template argument 102251662Sdim /// list. 103251662Sdim void addOuterTemplateArguments(ArgList Args) { 104251662Sdim TemplateArgumentLists.push_back(Args); 105251662Sdim } 106251662Sdim 107212795Sdim /// \brief Retrieve the innermost template argument list. 108212795Sdim const ArgList &getInnermost() const { 109212795Sdim return TemplateArgumentLists.front(); 110212795Sdim } 111212795Sdim }; 112212795Sdim 113212795Sdim /// \brief The context in which partial ordering of function templates occurs. 114212795Sdim enum TPOC { 115212795Sdim /// \brief Partial ordering of function templates for a function call. 116212795Sdim TPOC_Call, 117212795Sdim /// \brief Partial ordering of function templates for a call to a 118212795Sdim /// conversion function. 119212795Sdim TPOC_Conversion, 120212795Sdim /// \brief Partial ordering of function templates in other contexts, e.g., 121212795Sdim /// taking the address of a function template or matching a function 122212795Sdim /// template specialization to a function template. 123212795Sdim TPOC_Other 124212795Sdim }; 125212795Sdim 126212795Sdim // This is lame but unavoidable in a world without forward 127212795Sdim // declarations of enums. The alternatives are to either pollute 128212795Sdim // Sema.h (by including this file) or sacrifice type safety (by 129212795Sdim // making Sema.h declare things as enums). 130212795Sdim class TemplatePartialOrderingContext { 131212795Sdim TPOC Value; 132212795Sdim public: 133212795Sdim TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} 134212795Sdim operator TPOC() const { return Value; } 135212795Sdim }; 136212795Sdim 137212795Sdim /// \brief Captures a template argument whose value has been deduced 138212795Sdim /// via c++ template argument deduction. 139212795Sdim class DeducedTemplateArgument : public TemplateArgument { 140212795Sdim /// \brief For a non-type template argument, whether the value was 141212795Sdim /// deduced from an array bound. 142212795Sdim bool DeducedFromArrayBound; 143212795Sdim 144212795Sdim public: 145212795Sdim DeducedTemplateArgument() 146212795Sdim : TemplateArgument(), DeducedFromArrayBound(false) { } 147212795Sdim 148212795Sdim DeducedTemplateArgument(const TemplateArgument &Arg, 149212795Sdim bool DeducedFromArrayBound = false) 150212795Sdim : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { } 151212795Sdim 152212795Sdim /// \brief Construct an integral non-type template argument that 153218893Sdim /// has been deduced, possibly from an array bound. 154239462Sdim DeducedTemplateArgument(ASTContext &Ctx, 155239462Sdim const llvm::APSInt &Value, 156212795Sdim QualType ValueType, 157212795Sdim bool DeducedFromArrayBound) 158239462Sdim : TemplateArgument(Ctx, Value, ValueType), 159212795Sdim DeducedFromArrayBound(DeducedFromArrayBound) { } 160212795Sdim 161212795Sdim /// \brief For a non-type template argument, determine whether the 162212795Sdim /// template argument was deduced from an array bound. 163212795Sdim bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } 164212795Sdim 165212795Sdim /// \brief Specify whether the given non-type template argument 166212795Sdim /// was deduced from an array bound. 167212795Sdim void setDeducedFromArrayBound(bool Deduced) { 168212795Sdim DeducedFromArrayBound = Deduced; 169212795Sdim } 170212795Sdim }; 171212795Sdim 172212795Sdim /// \brief A stack-allocated class that identifies which local 173212795Sdim /// variable declaration instantiations are present in this scope. 174212795Sdim /// 175212795Sdim /// A new instance of this class type will be created whenever we 176212795Sdim /// instantiate a new function declaration, which will have its own 177212795Sdim /// set of parameter declarations. 178212795Sdim class LocalInstantiationScope { 179218893Sdim public: 180218893Sdim /// \brief A set of declarations. 181226633Sdim typedef SmallVector<Decl *, 4> DeclArgumentPack; 182218893Sdim 183218893Sdim private: 184212795Sdim /// \brief Reference to the semantic analysis that is performing 185212795Sdim /// this template instantiation. 186212795Sdim Sema &SemaRef; 187212795Sdim 188251662Sdim typedef llvm::SmallDenseMap< 189251662Sdim const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4> 190251662Sdim LocalDeclsMap; 191251662Sdim 192212795Sdim /// \brief A mapping from local declarations that occur 193212795Sdim /// within a template to their instantiations. 194212795Sdim /// 195212795Sdim /// This mapping is used during instantiation to keep track of, 196212795Sdim /// e.g., function parameter and variable declarations. For example, 197212795Sdim /// given: 198212795Sdim /// 199212795Sdim /// \code 200212795Sdim /// template<typename T> T add(T x, T y) { return x + y; } 201212795Sdim /// \endcode 202212795Sdim /// 203212795Sdim /// when we instantiate add<int>, we will introduce a mapping from 204212795Sdim /// the ParmVarDecl for 'x' that occurs in the template to the 205212795Sdim /// instantiated ParmVarDecl for 'x'. 206218893Sdim /// 207218893Sdim /// For a parameter pack, the local instantiation scope may contain a 208218893Sdim /// set of instantiated parameters. This is stored as a DeclArgumentPack 209218893Sdim /// pointer. 210218893Sdim LocalDeclsMap LocalDecls; 211212795Sdim 212218893Sdim /// \brief The set of argument packs we've allocated. 213226633Sdim SmallVector<DeclArgumentPack *, 1> ArgumentPacks; 214218893Sdim 215212795Sdim /// \brief The outer scope, which contains local variable 216212795Sdim /// definitions from some other instantiation (that may not be 217212795Sdim /// relevant to this particular scope). 218212795Sdim LocalInstantiationScope *Outer; 219212795Sdim 220212795Sdim /// \brief Whether we have already exited this scope. 221212795Sdim bool Exited; 222212795Sdim 223212795Sdim /// \brief Whether to combine this scope with the outer scope, such that 224212795Sdim /// lookup will search our outer scope. 225212795Sdim bool CombineWithOuterScope; 226212795Sdim 227218893Sdim /// \brief If non-NULL, the template parameter pack that has been 228218893Sdim /// partially substituted per C++0x [temp.arg.explicit]p9. 229218893Sdim NamedDecl *PartiallySubstitutedPack; 230218893Sdim 231218893Sdim /// \brief If \c PartiallySubstitutedPack is non-null, the set of 232218893Sdim /// explicitly-specified template arguments in that pack. 233218893Sdim const TemplateArgument *ArgsInPartiallySubstitutedPack; 234218893Sdim 235218893Sdim /// \brief If \c PartiallySubstitutedPack, the number of 236218893Sdim /// explicitly-specified template arguments in 237218893Sdim /// ArgsInPartiallySubstitutedPack. 238218893Sdim unsigned NumArgsInPartiallySubstitutedPack; 239218893Sdim 240212795Sdim // This class is non-copyable 241243830Sdim LocalInstantiationScope( 242243830Sdim const LocalInstantiationScope &) LLVM_DELETED_FUNCTION; 243243830Sdim void operator=(const LocalInstantiationScope &) LLVM_DELETED_FUNCTION; 244212795Sdim 245212795Sdim public: 246212795Sdim LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) 247212795Sdim : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 248218893Sdim Exited(false), CombineWithOuterScope(CombineWithOuterScope), 249218893Sdim PartiallySubstitutedPack(0) 250212795Sdim { 251212795Sdim SemaRef.CurrentInstantiationScope = this; 252212795Sdim } 253212795Sdim 254212795Sdim ~LocalInstantiationScope() { 255212795Sdim Exit(); 256212795Sdim } 257218893Sdim 258218893Sdim const Sema &getSema() const { return SemaRef; } 259212795Sdim 260212795Sdim /// \brief Exit this local instantiation scope early. 261212795Sdim void Exit() { 262212795Sdim if (Exited) 263212795Sdim return; 264212795Sdim 265218893Sdim for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) 266218893Sdim delete ArgumentPacks[I]; 267218893Sdim 268212795Sdim SemaRef.CurrentInstantiationScope = Outer; 269212795Sdim Exited = true; 270212795Sdim } 271212795Sdim 272234353Sdim /// \brief Clone this scope, and all outer scopes, down to the given 273234353Sdim /// outermost scope. 274234353Sdim LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) { 275234353Sdim if (this == Outermost) return this; 276234353Sdim LocalInstantiationScope *newScope = 277234353Sdim new LocalInstantiationScope(SemaRef, CombineWithOuterScope); 278234353Sdim 279234353Sdim newScope->Outer = 0; 280234353Sdim if (Outer) 281234353Sdim newScope->Outer = Outer->cloneScopes(Outermost); 282234353Sdim 283234353Sdim newScope->PartiallySubstitutedPack = PartiallySubstitutedPack; 284234353Sdim newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack; 285234353Sdim newScope->NumArgsInPartiallySubstitutedPack = 286234353Sdim NumArgsInPartiallySubstitutedPack; 287234353Sdim 288234353Sdim for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end(); 289234353Sdim I != E; ++I) { 290234353Sdim const Decl *D = I->first; 291234353Sdim llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = 292234353Sdim newScope->LocalDecls[D]; 293234353Sdim if (I->second.is<Decl *>()) { 294234353Sdim Stored = I->second.get<Decl *>(); 295234353Sdim } else { 296234353Sdim DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>(); 297234353Sdim DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); 298234353Sdim Stored = NewPack; 299234353Sdim newScope->ArgumentPacks.push_back(NewPack); 300234353Sdim } 301234353Sdim } 302234353Sdim return newScope; 303234353Sdim } 304234353Sdim 305234353Sdim /// \brief deletes the given scope, and all otuer scopes, down to the 306234353Sdim /// given outermost scope. 307234353Sdim static void deleteScopes(LocalInstantiationScope *Scope, 308234353Sdim LocalInstantiationScope *Outermost) { 309234353Sdim while (Scope && Scope != Outermost) { 310234353Sdim LocalInstantiationScope *Out = Scope->Outer; 311234353Sdim delete Scope; 312234353Sdim Scope = Out; 313234353Sdim } 314234353Sdim } 315234353Sdim 316218893Sdim /// \brief Find the instantiation of the declaration D within the current 317218893Sdim /// instantiation scope. 318218893Sdim /// 319218893Sdim /// \param D The declaration whose instantiation we are searching for. 320218893Sdim /// 321218893Sdim /// \returns A pointer to the declaration or argument pack of declarations 322218893Sdim /// to which the declaration \c D is instantiataed, if found. Otherwise, 323218893Sdim /// returns NULL. 324218893Sdim llvm::PointerUnion<Decl *, DeclArgumentPack *> * 325218893Sdim findInstantiationOf(const Decl *D); 326212795Sdim 327218893Sdim void InstantiatedLocal(const Decl *D, Decl *Inst); 328218893Sdim void InstantiatedLocalPackArg(const Decl *D, Decl *Inst); 329218893Sdim void MakeInstantiatedLocalArgPack(const Decl *D); 330218893Sdim 331218893Sdim /// \brief Note that the given parameter pack has been partially substituted 332218893Sdim /// via explicit specification of template arguments 333218893Sdim /// (C++0x [temp.arg.explicit]p9). 334218893Sdim /// 335218893Sdim /// \param Pack The parameter pack, which will always be a template 336218893Sdim /// parameter pack. 337218893Sdim /// 338218893Sdim /// \param ExplicitArgs The explicitly-specified template arguments provided 339218893Sdim /// for this parameter pack. 340218893Sdim /// 341218893Sdim /// \param NumExplicitArgs The number of explicitly-specified template 342218893Sdim /// arguments provided for this parameter pack. 343218893Sdim void SetPartiallySubstitutedPack(NamedDecl *Pack, 344218893Sdim const TemplateArgument *ExplicitArgs, 345218893Sdim unsigned NumExplicitArgs); 346249423Sdim 347249423Sdim /// \brief Reset the partially-substituted pack when it is no longer of 348249423Sdim /// interest. 349249423Sdim void ResetPartiallySubstitutedPack() { 350249423Sdim assert(PartiallySubstitutedPack && "No partially-substituted pack"); 351249423Sdim PartiallySubstitutedPack = 0; 352249423Sdim ArgsInPartiallySubstitutedPack = 0; 353249423Sdim NumArgsInPartiallySubstitutedPack = 0; 354249423Sdim } 355249423Sdim 356218893Sdim /// \brief Retrieve the partially-substitued template parameter pack. 357218893Sdim /// 358218893Sdim /// If there is no partially-substituted parameter pack, returns NULL. 359218893Sdim NamedDecl *getPartiallySubstitutedPack( 360218893Sdim const TemplateArgument **ExplicitArgs = 0, 361218893Sdim unsigned *NumExplicitArgs = 0) const; 362218893Sdim }; 363218893Sdim 364218893Sdim class TemplateDeclInstantiator 365218893Sdim : public DeclVisitor<TemplateDeclInstantiator, Decl *> 366218893Sdim { 367218893Sdim Sema &SemaRef; 368218893Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; 369218893Sdim DeclContext *Owner; 370218893Sdim const MultiLevelTemplateArgumentList &TemplateArgs; 371234353Sdim Sema::LateInstantiatedAttrVec* LateAttrs; 372234353Sdim LocalInstantiationScope *StartingScope; 373218893Sdim 374218893Sdim /// \brief A list of out-of-line class template partial 375218893Sdim /// specializations that will need to be instantiated after the 376218893Sdim /// enclosing class's instantiation is complete. 377226633Sdim SmallVector<std::pair<ClassTemplateDecl *, 378218893Sdim ClassTemplatePartialSpecializationDecl *>, 4> 379218893Sdim OutOfLinePartialSpecs; 380218893Sdim 381263508Sdim /// \brief A list of out-of-line variable template partial 382263508Sdim /// specializations that will need to be instantiated after the 383263508Sdim /// enclosing variable's instantiation is complete. 384263508Sdim /// FIXME: Verify that this is needed. 385263508Sdim SmallVector< 386263508Sdim std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> 387263508Sdim OutOfLineVarPartialSpecs; 388263508Sdim 389218893Sdim public: 390218893Sdim TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, 391218893Sdim const MultiLevelTemplateArgumentList &TemplateArgs) 392239462Sdim : SemaRef(SemaRef), 393239462Sdim SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), 394239462Sdim Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0) 395239462Sdim { } 396218893Sdim 397263508Sdim// Define all the decl visitors using DeclNodes.inc 398263508Sdim#define DECL(DERIVED, BASE) \ 399263508Sdim Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); 400263508Sdim#define ABSTRACT_DECL(DECL) 401263508Sdim 402263508Sdim// Decls which never appear inside a class or function. 403263508Sdim#define OBJCCONTAINER(DERIVED, BASE) 404263508Sdim#define FILESCOPEASM(DERIVED, BASE) 405263508Sdim#define IMPORT(DERIVED, BASE) 406263508Sdim#define LINKAGESPEC(DERIVED, BASE) 407263508Sdim#define OBJCCOMPATIBLEALIAS(DERIVED, BASE) 408263508Sdim#define OBJCMETHOD(DERIVED, BASE) 409263508Sdim#define OBJCIVAR(DERIVED, BASE) 410263508Sdim#define OBJCPROPERTY(DERIVED, BASE) 411263508Sdim#define OBJCPROPERTYIMPL(DERIVED, BASE) 412263508Sdim#define EMPTY(DERIVED, BASE) 413263508Sdim 414263508Sdim// Decls which use special-case instantiation code. 415263508Sdim#define BLOCK(DERIVED, BASE) 416263508Sdim#define CAPTURED(DERIVED, BASE) 417263508Sdim#define IMPLICITPARAM(DERIVED, BASE) 418263508Sdim 419263508Sdim#include "clang/AST/DeclNodes.inc" 420263508Sdim 421263508Sdim // A few supplemental visitor functions. 422218893Sdim Decl *VisitCXXMethodDecl(CXXMethodDecl *D, 423263508Sdim TemplateParameterList *TemplateParams, 424226633Sdim bool IsClassScopeSpecialization = false); 425263508Sdim Decl *VisitFunctionDecl(FunctionDecl *D, 426263508Sdim TemplateParameterList *TemplateParams); 427263508Sdim Decl *VisitDecl(Decl *D); 428263508Sdim Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate); 429218893Sdim 430234353Sdim // Enable late instantiation of attributes. Late instantiated attributes 431234353Sdim // will be stored in LA. 432234353Sdim void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { 433234353Sdim LateAttrs = LA; 434234353Sdim StartingScope = SemaRef.CurrentInstantiationScope; 435234353Sdim } 436234353Sdim 437234353Sdim // Disable late instantiation of attributes. 438234353Sdim void disableLateAttributeInstantiation() { 439234353Sdim LateAttrs = 0; 440234353Sdim StartingScope = 0; 441234353Sdim } 442234353Sdim 443234353Sdim LocalInstantiationScope *getStartingScope() const { return StartingScope; } 444234353Sdim 445218893Sdim typedef 446226633Sdim SmallVectorImpl<std::pair<ClassTemplateDecl *, 447218893Sdim ClassTemplatePartialSpecializationDecl *> > 448218893Sdim ::iterator 449218893Sdim delayed_partial_spec_iterator; 450212795Sdim 451263508Sdim typedef SmallVectorImpl<std::pair< 452263508Sdim VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator 453263508Sdim delayed_var_partial_spec_iterator; 454263508Sdim 455218893Sdim /// \brief Return an iterator to the beginning of the set of 456218893Sdim /// "delayed" partial specializations, which must be passed to 457218893Sdim /// InstantiateClassTemplatePartialSpecialization once the class 458218893Sdim /// definition has been completed. 459218893Sdim delayed_partial_spec_iterator delayed_partial_spec_begin() { 460218893Sdim return OutOfLinePartialSpecs.begin(); 461212795Sdim } 462212795Sdim 463263508Sdim delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { 464263508Sdim return OutOfLineVarPartialSpecs.begin(); 465263508Sdim } 466263508Sdim 467218893Sdim /// \brief Return an iterator to the end of the set of 468218893Sdim /// "delayed" partial specializations, which must be passed to 469218893Sdim /// InstantiateClassTemplatePartialSpecialization once the class 470218893Sdim /// definition has been completed. 471218893Sdim delayed_partial_spec_iterator delayed_partial_spec_end() { 472218893Sdim return OutOfLinePartialSpecs.end(); 473212795Sdim } 474212795Sdim 475263508Sdim delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { 476263508Sdim return OutOfLineVarPartialSpecs.end(); 477263508Sdim } 478263508Sdim 479218893Sdim // Helper functions for instantiating methods. 480218893Sdim TypeSourceInfo *SubstFunctionType(FunctionDecl *D, 481226633Sdim SmallVectorImpl<ParmVarDecl *> &Params); 482218893Sdim bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); 483218893Sdim bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); 484218893Sdim 485218893Sdim TemplateParameterList * 486218893Sdim SubstTemplateParams(TemplateParameterList *List); 487218893Sdim 488218893Sdim bool SubstQualifier(const DeclaratorDecl *OldDecl, 489218893Sdim DeclaratorDecl *NewDecl); 490218893Sdim bool SubstQualifier(const TagDecl *OldDecl, 491218893Sdim TagDecl *NewDecl); 492263508Sdim 493263508Sdim Decl *VisitVarTemplateSpecializationDecl( 494263508Sdim VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos, 495263508Sdim const TemplateArgumentListInfo &TemplateArgsInfo, 496263508Sdim llvm::ArrayRef<TemplateArgument> Converted); 497263508Sdim 498223017Sdim Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); 499218893Sdim ClassTemplatePartialSpecializationDecl * 500218893Sdim InstantiateClassTemplatePartialSpecialization( 501218893Sdim ClassTemplateDecl *ClassTemplate, 502218893Sdim ClassTemplatePartialSpecializationDecl *PartialSpec); 503263508Sdim VarTemplatePartialSpecializationDecl * 504263508Sdim InstantiateVarTemplatePartialSpecialization( 505263508Sdim VarTemplateDecl *VarTemplate, 506263508Sdim VarTemplatePartialSpecializationDecl *PartialSpec); 507234353Sdim void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); 508218893Sdim }; 509212795Sdim} 510212795Sdim 511212795Sdim#endif // LLVM_CLANG_SEMA_TEMPLATE_H 512