10b57cec5SDimitry Andric //===- SemaTemplate.h - C++ Templates ---------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 70b57cec5SDimitry Andric // 80b57cec5SDimitry Andric // This file provides types used in the semantic analysis of C++ templates. 90b57cec5SDimitry Andric // 100b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #ifndef LLVM_CLANG_SEMA_TEMPLATE_H 130b57cec5SDimitry Andric #define LLVM_CLANG_SEMA_TEMPLATE_H 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 160b57cec5SDimitry Andric #include "clang/AST/DeclVisitor.h" 170b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h" 180b57cec5SDimitry Andric #include "clang/AST/Type.h" 190b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 200b57cec5SDimitry Andric #include "clang/Sema/Sema.h" 210b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 220b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 230b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h" 240b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 250b57cec5SDimitry Andric #include <cassert> 26bdd1243dSDimitry Andric #include <optional> 270b57cec5SDimitry Andric #include <utility> 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric namespace clang { 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric class ASTContext; 320b57cec5SDimitry Andric class BindingDecl; 330b57cec5SDimitry Andric class CXXMethodDecl; 340b57cec5SDimitry Andric class Decl; 350b57cec5SDimitry Andric class DeclaratorDecl; 360b57cec5SDimitry Andric class DeclContext; 370b57cec5SDimitry Andric class EnumDecl; 380b57cec5SDimitry Andric class FunctionDecl; 390b57cec5SDimitry Andric class NamedDecl; 400b57cec5SDimitry Andric class ParmVarDecl; 410b57cec5SDimitry Andric class TagDecl; 420b57cec5SDimitry Andric class TypedefNameDecl; 430b57cec5SDimitry Andric class TypeSourceInfo; 440b57cec5SDimitry Andric class VarDecl; 450b57cec5SDimitry Andric 465ffd83dbSDimitry Andric /// The kind of template substitution being performed. 475ffd83dbSDimitry Andric enum class TemplateSubstitutionKind : char { 485ffd83dbSDimitry Andric /// We are substituting template parameters for template arguments in order 495ffd83dbSDimitry Andric /// to form a template specialization. 505ffd83dbSDimitry Andric Specialization, 515ffd83dbSDimitry Andric /// We are substituting template parameters for (typically) other template 525ffd83dbSDimitry Andric /// parameters in order to rewrite a declaration as a different declaration 535ffd83dbSDimitry Andric /// (for example, when forming a deduction guide from a constructor). 545ffd83dbSDimitry Andric Rewrite, 555ffd83dbSDimitry Andric }; 565ffd83dbSDimitry Andric 570b57cec5SDimitry Andric /// Data structure that captures multiple levels of template argument 580b57cec5SDimitry Andric /// lists for use in template instantiation. 590b57cec5SDimitry Andric /// 600b57cec5SDimitry Andric /// Multiple levels of template arguments occur when instantiating the 610b57cec5SDimitry Andric /// definitions of member templates. For example: 620b57cec5SDimitry Andric /// 630b57cec5SDimitry Andric /// \code 640b57cec5SDimitry Andric /// template<typename T> 650b57cec5SDimitry Andric /// struct X { 660b57cec5SDimitry Andric /// template<T Value> 670b57cec5SDimitry Andric /// struct Y { 680b57cec5SDimitry Andric /// void f(); 690b57cec5SDimitry Andric /// }; 700b57cec5SDimitry Andric /// }; 710b57cec5SDimitry Andric /// \endcode 720b57cec5SDimitry Andric /// 730b57cec5SDimitry Andric /// When instantiating X<int>::Y<17>::f, the multi-level template argument 740b57cec5SDimitry Andric /// list will contain a template argument list (int) at depth 0 and a 750b57cec5SDimitry Andric /// template argument list (17) at depth 1. 760b57cec5SDimitry Andric class MultiLevelTemplateArgumentList { 770b57cec5SDimitry Andric /// The template argument list at a certain template depth 78bdd1243dSDimitry Andric 790b57cec5SDimitry Andric using ArgList = ArrayRef<TemplateArgument>; 80bdd1243dSDimitry Andric struct ArgumentListLevel { 81bdd1243dSDimitry Andric llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal; 82bdd1243dSDimitry Andric ArgList Args; 83bdd1243dSDimitry Andric }; 84bdd1243dSDimitry Andric using ContainerType = SmallVector<ArgumentListLevel, 4>; 85bdd1243dSDimitry Andric 86bdd1243dSDimitry Andric using ArgListsIterator = ContainerType::iterator; 87bdd1243dSDimitry Andric using ConstArgListsIterator = ContainerType::const_iterator; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric /// The template argument lists, stored from the innermost template 900b57cec5SDimitry Andric /// argument list (first) to the outermost template argument list (last). 91bdd1243dSDimitry Andric ContainerType TemplateArgumentLists; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric /// The number of outer levels of template arguments that are not 940b57cec5SDimitry Andric /// being substituted. 950b57cec5SDimitry Andric unsigned NumRetainedOuterLevels = 0; 960b57cec5SDimitry Andric 975ffd83dbSDimitry Andric /// The kind of substitution described by this argument list. 985ffd83dbSDimitry Andric TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization; 995ffd83dbSDimitry Andric 1000b57cec5SDimitry Andric public: 1010b57cec5SDimitry Andric /// Construct an empty set of template argument lists. 1020b57cec5SDimitry Andric MultiLevelTemplateArgumentList() = default; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric /// Construct a single-level template argument list. MultiLevelTemplateArgumentList(Decl * D,ArgList Args,bool Final)105bdd1243dSDimitry Andric MultiLevelTemplateArgumentList(Decl *D, ArgList Args, bool Final) { 106bdd1243dSDimitry Andric addOuterTemplateArguments(D, Args, Final); 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric setKind(TemplateSubstitutionKind K)1095ffd83dbSDimitry Andric void setKind(TemplateSubstitutionKind K) { Kind = K; } 1105ffd83dbSDimitry Andric 1115ffd83dbSDimitry Andric /// Determine the kind of template substitution being performed. getKind()1125ffd83dbSDimitry Andric TemplateSubstitutionKind getKind() const { return Kind; } 1135ffd83dbSDimitry Andric 1145ffd83dbSDimitry Andric /// Determine whether we are rewriting template parameters rather than 1155ffd83dbSDimitry Andric /// substituting for them. If so, we should not leave references to the 1165ffd83dbSDimitry Andric /// original template parameters behind. isRewrite()1175ffd83dbSDimitry Andric bool isRewrite() const { 1185ffd83dbSDimitry Andric return Kind == TemplateSubstitutionKind::Rewrite; 1195ffd83dbSDimitry Andric } 1205ffd83dbSDimitry Andric 1210b57cec5SDimitry Andric /// Determine the number of levels in this template argument 1220b57cec5SDimitry Andric /// list. getNumLevels()1230b57cec5SDimitry Andric unsigned getNumLevels() const { 1240b57cec5SDimitry Andric return TemplateArgumentLists.size() + NumRetainedOuterLevels; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric /// Determine the number of substituted levels in this template 1280b57cec5SDimitry Andric /// argument list. getNumSubstitutedLevels()1290b57cec5SDimitry Andric unsigned getNumSubstitutedLevels() const { 1300b57cec5SDimitry Andric return TemplateArgumentLists.size(); 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 133972a253aSDimitry Andric // Determine the number of substituted args at 'Depth'. getNumSubsitutedArgs(unsigned Depth)134972a253aSDimitry Andric unsigned getNumSubsitutedArgs(unsigned Depth) const { 135972a253aSDimitry Andric assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 136bdd1243dSDimitry Andric return TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size(); 137972a253aSDimitry Andric } 138972a253aSDimitry Andric getNumRetainedOuterLevels()1395ffd83dbSDimitry Andric unsigned getNumRetainedOuterLevels() const { 1405ffd83dbSDimitry Andric return NumRetainedOuterLevels; 1415ffd83dbSDimitry Andric } 1425ffd83dbSDimitry Andric 143cd675bb6SDimitry Andric /// Determine how many of the \p OldDepth outermost template parameter 144cd675bb6SDimitry Andric /// lists would be removed by substituting these arguments. getNewDepth(unsigned OldDepth)145cd675bb6SDimitry Andric unsigned getNewDepth(unsigned OldDepth) const { 146cd675bb6SDimitry Andric if (OldDepth < NumRetainedOuterLevels) 147cd675bb6SDimitry Andric return OldDepth; 148cd675bb6SDimitry Andric if (OldDepth < getNumLevels()) 149cd675bb6SDimitry Andric return NumRetainedOuterLevels; 150cd675bb6SDimitry Andric return OldDepth - TemplateArgumentLists.size(); 151cd675bb6SDimitry Andric } 152cd675bb6SDimitry Andric 1530b57cec5SDimitry Andric /// Retrieve the template argument at a given depth and index. operator()1540b57cec5SDimitry Andric const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { 1550b57cec5SDimitry Andric assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 156bdd1243dSDimitry Andric assert(Index < 157bdd1243dSDimitry Andric TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()); 158bdd1243dSDimitry Andric return TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]; 159bdd1243dSDimitry Andric } 160bdd1243dSDimitry Andric 161bdd1243dSDimitry Andric /// A template-like entity which owns the whole pattern being substituted. 162bdd1243dSDimitry Andric /// This will usually own a set of template parameters, or in some 163bdd1243dSDimitry Andric /// cases might even be a template parameter itself. getAssociatedDecl(unsigned Depth)164bdd1243dSDimitry Andric std::pair<Decl *, bool> getAssociatedDecl(unsigned Depth) const { 165bdd1243dSDimitry Andric assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 166bdd1243dSDimitry Andric auto AD = TemplateArgumentLists[getNumLevels() - Depth - 1] 167bdd1243dSDimitry Andric .AssociatedDeclAndFinal; 168bdd1243dSDimitry Andric return {AD.getPointer(), AD.getInt()}; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric /// Determine whether there is a non-NULL template argument at the 1720b57cec5SDimitry Andric /// given depth and index. 1730b57cec5SDimitry Andric /// 1740b57cec5SDimitry Andric /// There must exist a template argument list at the given depth. hasTemplateArgument(unsigned Depth,unsigned Index)1750b57cec5SDimitry Andric bool hasTemplateArgument(unsigned Depth, unsigned Index) const { 1760b57cec5SDimitry Andric assert(Depth < getNumLevels()); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric if (Depth < NumRetainedOuterLevels) 1790b57cec5SDimitry Andric return false; 1800b57cec5SDimitry Andric 181bdd1243dSDimitry Andric if (Index >= 182bdd1243dSDimitry Andric TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()) 1830b57cec5SDimitry Andric return false; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric return !(*this)(Depth, Index).isNull(); 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric isAnyArgInstantiationDependent()188972a253aSDimitry Andric bool isAnyArgInstantiationDependent() const { 189bdd1243dSDimitry Andric for (ArgumentListLevel ListLevel : TemplateArgumentLists) 190bdd1243dSDimitry Andric for (const TemplateArgument &TA : ListLevel.Args) 191972a253aSDimitry Andric if (TA.isInstantiationDependent()) 192972a253aSDimitry Andric return true; 193972a253aSDimitry Andric return false; 194972a253aSDimitry Andric } 195972a253aSDimitry Andric 1960b57cec5SDimitry Andric /// Clear out a specific template argument. setArgument(unsigned Depth,unsigned Index,TemplateArgument Arg)1970b57cec5SDimitry Andric void setArgument(unsigned Depth, unsigned Index, 1980b57cec5SDimitry Andric TemplateArgument Arg) { 1990b57cec5SDimitry Andric assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 200bdd1243dSDimitry Andric assert(Index < 201bdd1243dSDimitry Andric TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()); 2020b57cec5SDimitry Andric const_cast<TemplateArgument &>( 203bdd1243dSDimitry Andric TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]) = Arg; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric /// Add a new outmost level to the multi-level template argument 2070b57cec5SDimitry Andric /// list. 208bdd1243dSDimitry Andric /// A 'Final' substitution means that Subst* nodes won't be built 209bdd1243dSDimitry Andric /// for the replacements. addOuterTemplateArguments(Decl * AssociatedDecl,ArgList Args,bool Final)210bdd1243dSDimitry Andric void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, 211bdd1243dSDimitry Andric bool Final) { 212bdd1243dSDimitry Andric assert(!NumRetainedOuterLevels && 213bdd1243dSDimitry Andric "substituted args outside retained args?"); 214bdd1243dSDimitry Andric assert(getKind() == TemplateSubstitutionKind::Specialization); 215bdd1243dSDimitry Andric TemplateArgumentLists.push_back( 2165f757f3fSDimitry Andric {{AssociatedDecl ? AssociatedDecl->getCanonicalDecl() : nullptr, 2175f757f3fSDimitry Andric Final}, 2185f757f3fSDimitry Andric Args}); 219bdd1243dSDimitry Andric } 220bdd1243dSDimitry Andric addOuterTemplateArguments(ArgList Args)2210b57cec5SDimitry Andric void addOuterTemplateArguments(ArgList Args) { 2220b57cec5SDimitry Andric assert(!NumRetainedOuterLevels && 2230b57cec5SDimitry Andric "substituted args outside retained args?"); 224bdd1243dSDimitry Andric assert(getKind() == TemplateSubstitutionKind::Rewrite); 225bdd1243dSDimitry Andric TemplateArgumentLists.push_back({{}, Args}); 226bdd1243dSDimitry Andric } 227bdd1243dSDimitry Andric addOuterTemplateArguments(std::nullopt_t)228bdd1243dSDimitry Andric void addOuterTemplateArguments(std::nullopt_t) { 229bdd1243dSDimitry Andric assert(!NumRetainedOuterLevels && 230bdd1243dSDimitry Andric "substituted args outside retained args?"); 231bdd1243dSDimitry Andric TemplateArgumentLists.push_back({}); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 234972a253aSDimitry Andric /// Replaces the current 'innermost' level with the provided argument list. 235972a253aSDimitry Andric /// This is useful for type deduction cases where we need to get the entire 236972a253aSDimitry Andric /// list from the AST, but then add the deduced innermost list. replaceInnermostTemplateArguments(Decl * AssociatedDecl,ArgList Args)23706c3fb27SDimitry Andric void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) { 23806c3fb27SDimitry Andric assert((!TemplateArgumentLists.empty() || NumRetainedOuterLevels) && 23906c3fb27SDimitry Andric "Replacing in an empty list?"); 24006c3fb27SDimitry Andric 24106c3fb27SDimitry Andric if (!TemplateArgumentLists.empty()) { 24206c3fb27SDimitry Andric assert((TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() || 24306c3fb27SDimitry Andric TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() == 24406c3fb27SDimitry Andric AssociatedDecl) && 24506c3fb27SDimitry Andric "Trying to change incorrect declaration?"); 246bdd1243dSDimitry Andric TemplateArgumentLists[0].Args = Args; 24706c3fb27SDimitry Andric } else { 24806c3fb27SDimitry Andric --NumRetainedOuterLevels; 24906c3fb27SDimitry Andric TemplateArgumentLists.push_back( 25006c3fb27SDimitry Andric {{AssociatedDecl, /*Final=*/false}, Args}); 25106c3fb27SDimitry Andric } 252972a253aSDimitry Andric } 253972a253aSDimitry Andric 2540b57cec5SDimitry Andric /// Add an outermost level that we are not substituting. We have no 2550b57cec5SDimitry Andric /// arguments at this level, and do not remove it from the depth of inner 2560b57cec5SDimitry Andric /// template parameters that we instantiate. addOuterRetainedLevel()2570b57cec5SDimitry Andric void addOuterRetainedLevel() { 2580b57cec5SDimitry Andric ++NumRetainedOuterLevels; 2590b57cec5SDimitry Andric } addOuterRetainedLevels(unsigned Num)2605ffd83dbSDimitry Andric void addOuterRetainedLevels(unsigned Num) { 2615ffd83dbSDimitry Andric NumRetainedOuterLevels += Num; 2625ffd83dbSDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric /// Retrieve the innermost template argument list. getInnermost()2650b57cec5SDimitry Andric const ArgList &getInnermost() const { 266bdd1243dSDimitry Andric return TemplateArgumentLists.front().Args; 2670b57cec5SDimitry Andric } 268972a253aSDimitry Andric /// Retrieve the outermost template argument list. getOutermost()269972a253aSDimitry Andric const ArgList &getOutermost() const { 270bdd1243dSDimitry Andric return TemplateArgumentLists.back().Args; 271972a253aSDimitry Andric } begin()272972a253aSDimitry Andric ArgListsIterator begin() { return TemplateArgumentLists.begin(); } begin()273972a253aSDimitry Andric ConstArgListsIterator begin() const { 274972a253aSDimitry Andric return TemplateArgumentLists.begin(); 275972a253aSDimitry Andric } end()276972a253aSDimitry Andric ArgListsIterator end() { return TemplateArgumentLists.end(); } end()277972a253aSDimitry Andric ConstArgListsIterator end() const { return TemplateArgumentLists.end(); } 27806c3fb27SDimitry Andric dump()27906c3fb27SDimitry Andric LLVM_DUMP_METHOD void dump() const { 28006c3fb27SDimitry Andric LangOptions LO; 28106c3fb27SDimitry Andric LO.CPlusPlus = true; 28206c3fb27SDimitry Andric LO.Bool = true; 28306c3fb27SDimitry Andric PrintingPolicy PP(LO); 28406c3fb27SDimitry Andric llvm::errs() << "NumRetainedOuterLevels: " << NumRetainedOuterLevels 28506c3fb27SDimitry Andric << "\n"; 28606c3fb27SDimitry Andric for (unsigned Depth = NumRetainedOuterLevels; Depth < getNumLevels(); 28706c3fb27SDimitry Andric ++Depth) { 28806c3fb27SDimitry Andric llvm::errs() << Depth << ": "; 28906c3fb27SDimitry Andric printTemplateArgumentList( 29006c3fb27SDimitry Andric llvm::errs(), 29106c3fb27SDimitry Andric TemplateArgumentLists[getNumLevels() - Depth - 1].Args, PP); 29206c3fb27SDimitry Andric llvm::errs() << "\n"; 29306c3fb27SDimitry Andric } 29406c3fb27SDimitry Andric } 2950b57cec5SDimitry Andric }; 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric /// The context in which partial ordering of function templates occurs. 2980b57cec5SDimitry Andric enum TPOC { 2990b57cec5SDimitry Andric /// Partial ordering of function templates for a function call. 3000b57cec5SDimitry Andric TPOC_Call, 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric /// Partial ordering of function templates for a call to a 3030b57cec5SDimitry Andric /// conversion function. 3040b57cec5SDimitry Andric TPOC_Conversion, 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric /// Partial ordering of function templates in other contexts, e.g., 3070b57cec5SDimitry Andric /// taking the address of a function template or matching a function 3080b57cec5SDimitry Andric /// template specialization to a function template. 3090b57cec5SDimitry Andric TPOC_Other 3100b57cec5SDimitry Andric }; 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric // This is lame but unavoidable in a world without forward 3130b57cec5SDimitry Andric // declarations of enums. The alternatives are to either pollute 3140b57cec5SDimitry Andric // Sema.h (by including this file) or sacrifice type safety (by 3150b57cec5SDimitry Andric // making Sema.h declare things as enums). 3160b57cec5SDimitry Andric class TemplatePartialOrderingContext { 3170b57cec5SDimitry Andric TPOC Value; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric public: TemplatePartialOrderingContext(TPOC Value)3200b57cec5SDimitry Andric TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} 3210b57cec5SDimitry Andric TPOC()3220b57cec5SDimitry Andric operator TPOC() const { return Value; } 3230b57cec5SDimitry Andric }; 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric /// Captures a template argument whose value has been deduced 3260b57cec5SDimitry Andric /// via c++ template argument deduction. 3270b57cec5SDimitry Andric class DeducedTemplateArgument : public TemplateArgument { 3280b57cec5SDimitry Andric /// For a non-type template argument, whether the value was 3290b57cec5SDimitry Andric /// deduced from an array bound. 3300b57cec5SDimitry Andric bool DeducedFromArrayBound = false; 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric public: 3330b57cec5SDimitry Andric DeducedTemplateArgument() = default; 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric DeducedTemplateArgument(const TemplateArgument &Arg, 3360b57cec5SDimitry Andric bool DeducedFromArrayBound = false) TemplateArgument(Arg)3370b57cec5SDimitry Andric : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {} 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric /// Construct an integral non-type template argument that 3400b57cec5SDimitry Andric /// has been deduced, possibly from an array bound. DeducedTemplateArgument(ASTContext & Ctx,const llvm::APSInt & Value,QualType ValueType,bool DeducedFromArrayBound)3410b57cec5SDimitry Andric DeducedTemplateArgument(ASTContext &Ctx, 3420b57cec5SDimitry Andric const llvm::APSInt &Value, 3430b57cec5SDimitry Andric QualType ValueType, 3440b57cec5SDimitry Andric bool DeducedFromArrayBound) 3450b57cec5SDimitry Andric : TemplateArgument(Ctx, Value, ValueType), 3460b57cec5SDimitry Andric DeducedFromArrayBound(DeducedFromArrayBound) {} 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric /// For a non-type template argument, determine whether the 3490b57cec5SDimitry Andric /// template argument was deduced from an array bound. wasDeducedFromArrayBound()3500b57cec5SDimitry Andric bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric /// Specify whether the given non-type template argument 3530b57cec5SDimitry Andric /// was deduced from an array bound. setDeducedFromArrayBound(bool Deduced)3540b57cec5SDimitry Andric void setDeducedFromArrayBound(bool Deduced) { 3550b57cec5SDimitry Andric DeducedFromArrayBound = Deduced; 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric }; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric /// A stack-allocated class that identifies which local 3600b57cec5SDimitry Andric /// variable declaration instantiations are present in this scope. 3610b57cec5SDimitry Andric /// 3620b57cec5SDimitry Andric /// A new instance of this class type will be created whenever we 3630b57cec5SDimitry Andric /// instantiate a new function declaration, which will have its own 3640b57cec5SDimitry Andric /// set of parameter declarations. 3650b57cec5SDimitry Andric class LocalInstantiationScope { 3660b57cec5SDimitry Andric public: 3670b57cec5SDimitry Andric /// A set of declarations. 3680b57cec5SDimitry Andric using DeclArgumentPack = SmallVector<VarDecl *, 4>; 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric private: 3710b57cec5SDimitry Andric /// Reference to the semantic analysis that is performing 3720b57cec5SDimitry Andric /// this template instantiation. 3730b57cec5SDimitry Andric Sema &SemaRef; 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric using LocalDeclsMap = 3760b57cec5SDimitry Andric llvm::SmallDenseMap<const Decl *, 3770b57cec5SDimitry Andric llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric /// A mapping from local declarations that occur 3800b57cec5SDimitry Andric /// within a template to their instantiations. 3810b57cec5SDimitry Andric /// 3820b57cec5SDimitry Andric /// This mapping is used during instantiation to keep track of, 3830b57cec5SDimitry Andric /// e.g., function parameter and variable declarations. For example, 3840b57cec5SDimitry Andric /// given: 3850b57cec5SDimitry Andric /// 3860b57cec5SDimitry Andric /// \code 3870b57cec5SDimitry Andric /// template<typename T> T add(T x, T y) { return x + y; } 3880b57cec5SDimitry Andric /// \endcode 3890b57cec5SDimitry Andric /// 3900b57cec5SDimitry Andric /// when we instantiate add<int>, we will introduce a mapping from 3910b57cec5SDimitry Andric /// the ParmVarDecl for 'x' that occurs in the template to the 3920b57cec5SDimitry Andric /// instantiated ParmVarDecl for 'x'. 3930b57cec5SDimitry Andric /// 3940b57cec5SDimitry Andric /// For a parameter pack, the local instantiation scope may contain a 3950b57cec5SDimitry Andric /// set of instantiated parameters. This is stored as a DeclArgumentPack 3960b57cec5SDimitry Andric /// pointer. 3970b57cec5SDimitry Andric LocalDeclsMap LocalDecls; 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric /// The set of argument packs we've allocated. 4000b57cec5SDimitry Andric SmallVector<DeclArgumentPack *, 1> ArgumentPacks; 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric /// The outer scope, which contains local variable 4030b57cec5SDimitry Andric /// definitions from some other instantiation (that may not be 4040b57cec5SDimitry Andric /// relevant to this particular scope). 4050b57cec5SDimitry Andric LocalInstantiationScope *Outer; 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric /// Whether we have already exited this scope. 4080b57cec5SDimitry Andric bool Exited = false; 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric /// Whether to combine this scope with the outer scope, such that 4110b57cec5SDimitry Andric /// lookup will search our outer scope. 4120b57cec5SDimitry Andric bool CombineWithOuterScope; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric /// If non-NULL, the template parameter pack that has been 4150b57cec5SDimitry Andric /// partially substituted per C++0x [temp.arg.explicit]p9. 4160b57cec5SDimitry Andric NamedDecl *PartiallySubstitutedPack = nullptr; 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric /// If \c PartiallySubstitutedPack is non-null, the set of 4190b57cec5SDimitry Andric /// explicitly-specified template arguments in that pack. 4200b57cec5SDimitry Andric const TemplateArgument *ArgsInPartiallySubstitutedPack; 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric /// If \c PartiallySubstitutedPack, the number of 4230b57cec5SDimitry Andric /// explicitly-specified template arguments in 4240b57cec5SDimitry Andric /// ArgsInPartiallySubstitutedPack. 4250b57cec5SDimitry Andric unsigned NumArgsInPartiallySubstitutedPack; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric public: 4280b57cec5SDimitry Andric LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) SemaRef(SemaRef)4290b57cec5SDimitry Andric : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 4300b57cec5SDimitry Andric CombineWithOuterScope(CombineWithOuterScope) { 4310b57cec5SDimitry Andric SemaRef.CurrentInstantiationScope = this; 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric LocalInstantiationScope(const LocalInstantiationScope &) = delete; 4350b57cec5SDimitry Andric LocalInstantiationScope & 4360b57cec5SDimitry Andric operator=(const LocalInstantiationScope &) = delete; 4370b57cec5SDimitry Andric ~LocalInstantiationScope()4380b57cec5SDimitry Andric ~LocalInstantiationScope() { 4390b57cec5SDimitry Andric Exit(); 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric getSema()4420b57cec5SDimitry Andric const Sema &getSema() const { return SemaRef; } 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric /// Exit this local instantiation scope early. Exit()4450b57cec5SDimitry Andric void Exit() { 4460b57cec5SDimitry Andric if (Exited) 4470b57cec5SDimitry Andric return; 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) 4500b57cec5SDimitry Andric delete ArgumentPacks[I]; 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric SemaRef.CurrentInstantiationScope = Outer; 4530b57cec5SDimitry Andric Exited = true; 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric /// Clone this scope, and all outer scopes, down to the given 4570b57cec5SDimitry Andric /// outermost scope. cloneScopes(LocalInstantiationScope * Outermost)4580b57cec5SDimitry Andric LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) { 4590b57cec5SDimitry Andric if (this == Outermost) return this; 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric // Save the current scope from SemaRef since the LocalInstantiationScope 4620b57cec5SDimitry Andric // will overwrite it on construction 4630b57cec5SDimitry Andric LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope; 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric LocalInstantiationScope *newScope = 4660b57cec5SDimitry Andric new LocalInstantiationScope(SemaRef, CombineWithOuterScope); 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric newScope->Outer = nullptr; 4690b57cec5SDimitry Andric if (Outer) 4700b57cec5SDimitry Andric newScope->Outer = Outer->cloneScopes(Outermost); 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric newScope->PartiallySubstitutedPack = PartiallySubstitutedPack; 4730b57cec5SDimitry Andric newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack; 4740b57cec5SDimitry Andric newScope->NumArgsInPartiallySubstitutedPack = 4750b57cec5SDimitry Andric NumArgsInPartiallySubstitutedPack; 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end(); 4780b57cec5SDimitry Andric I != E; ++I) { 4790b57cec5SDimitry Andric const Decl *D = I->first; 4800b57cec5SDimitry Andric llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = 4810b57cec5SDimitry Andric newScope->LocalDecls[D]; 4820b57cec5SDimitry Andric if (I->second.is<Decl *>()) { 4830b57cec5SDimitry Andric Stored = I->second.get<Decl *>(); 4840b57cec5SDimitry Andric } else { 4850b57cec5SDimitry Andric DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>(); 4860b57cec5SDimitry Andric DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); 4870b57cec5SDimitry Andric Stored = NewPack; 4880b57cec5SDimitry Andric newScope->ArgumentPacks.push_back(NewPack); 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric // Restore the saved scope to SemaRef 4920b57cec5SDimitry Andric SemaRef.CurrentInstantiationScope = oldScope; 4930b57cec5SDimitry Andric return newScope; 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric 49681ad6265SDimitry Andric /// deletes the given scope, and all outer scopes, down to the 4970b57cec5SDimitry Andric /// given outermost scope. deleteScopes(LocalInstantiationScope * Scope,LocalInstantiationScope * Outermost)4980b57cec5SDimitry Andric static void deleteScopes(LocalInstantiationScope *Scope, 4990b57cec5SDimitry Andric LocalInstantiationScope *Outermost) { 5000b57cec5SDimitry Andric while (Scope && Scope != Outermost) { 5010b57cec5SDimitry Andric LocalInstantiationScope *Out = Scope->Outer; 5020b57cec5SDimitry Andric delete Scope; 5030b57cec5SDimitry Andric Scope = Out; 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric /// Find the instantiation of the declaration D within the current 5080b57cec5SDimitry Andric /// instantiation scope. 5090b57cec5SDimitry Andric /// 5100b57cec5SDimitry Andric /// \param D The declaration whose instantiation we are searching for. 5110b57cec5SDimitry Andric /// 5120b57cec5SDimitry Andric /// \returns A pointer to the declaration or argument pack of declarations 5130b57cec5SDimitry Andric /// to which the declaration \c D is instantiated, if found. Otherwise, 5140b57cec5SDimitry Andric /// returns NULL. 5150b57cec5SDimitry Andric llvm::PointerUnion<Decl *, DeclArgumentPack *> * 5160b57cec5SDimitry Andric findInstantiationOf(const Decl *D); 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric void InstantiatedLocal(const Decl *D, Decl *Inst); 5190b57cec5SDimitry Andric void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst); 5200b57cec5SDimitry Andric void MakeInstantiatedLocalArgPack(const Decl *D); 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric /// Note that the given parameter pack has been partially substituted 5230b57cec5SDimitry Andric /// via explicit specification of template arguments 5240b57cec5SDimitry Andric /// (C++0x [temp.arg.explicit]p9). 5250b57cec5SDimitry Andric /// 5260b57cec5SDimitry Andric /// \param Pack The parameter pack, which will always be a template 5270b57cec5SDimitry Andric /// parameter pack. 5280b57cec5SDimitry Andric /// 5290b57cec5SDimitry Andric /// \param ExplicitArgs The explicitly-specified template arguments provided 5300b57cec5SDimitry Andric /// for this parameter pack. 5310b57cec5SDimitry Andric /// 5320b57cec5SDimitry Andric /// \param NumExplicitArgs The number of explicitly-specified template 5330b57cec5SDimitry Andric /// arguments provided for this parameter pack. 5340b57cec5SDimitry Andric void SetPartiallySubstitutedPack(NamedDecl *Pack, 5350b57cec5SDimitry Andric const TemplateArgument *ExplicitArgs, 5360b57cec5SDimitry Andric unsigned NumExplicitArgs); 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric /// Reset the partially-substituted pack when it is no longer of 5390b57cec5SDimitry Andric /// interest. ResetPartiallySubstitutedPack()5400b57cec5SDimitry Andric void ResetPartiallySubstitutedPack() { 5410b57cec5SDimitry Andric assert(PartiallySubstitutedPack && "No partially-substituted pack"); 5420b57cec5SDimitry Andric PartiallySubstitutedPack = nullptr; 5430b57cec5SDimitry Andric ArgsInPartiallySubstitutedPack = nullptr; 5440b57cec5SDimitry Andric NumArgsInPartiallySubstitutedPack = 0; 5450b57cec5SDimitry Andric } 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric /// Retrieve the partially-substitued template parameter pack. 5480b57cec5SDimitry Andric /// 5490b57cec5SDimitry Andric /// If there is no partially-substituted parameter pack, returns NULL. 5500b57cec5SDimitry Andric NamedDecl * 5510b57cec5SDimitry Andric getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, 5520b57cec5SDimitry Andric unsigned *NumExplicitArgs = nullptr) const; 5535ffd83dbSDimitry Andric 5545ffd83dbSDimitry Andric /// Determine whether D is a pack expansion created in this scope. 5555ffd83dbSDimitry Andric bool isLocalPackExpansion(const Decl *D); 5560b57cec5SDimitry Andric }; 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric class TemplateDeclInstantiator 5590b57cec5SDimitry Andric : public DeclVisitor<TemplateDeclInstantiator, Decl *> 5600b57cec5SDimitry Andric { 5610b57cec5SDimitry Andric Sema &SemaRef; 5620b57cec5SDimitry Andric Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; 5630b57cec5SDimitry Andric DeclContext *Owner; 5640b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs; 5650b57cec5SDimitry Andric Sema::LateInstantiatedAttrVec* LateAttrs = nullptr; 5660b57cec5SDimitry Andric LocalInstantiationScope *StartingScope = nullptr; 5671db9f3b2SDimitry Andric // Whether to evaluate the C++20 constraints or simply substitute into them. 568bdd1243dSDimitry Andric bool EvaluateConstraints = true; 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric /// A list of out-of-line class template partial 5710b57cec5SDimitry Andric /// specializations that will need to be instantiated after the 5720b57cec5SDimitry Andric /// enclosing class's instantiation is complete. 5730b57cec5SDimitry Andric SmallVector<std::pair<ClassTemplateDecl *, 5740b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *>, 4> 5750b57cec5SDimitry Andric OutOfLinePartialSpecs; 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric /// A list of out-of-line variable template partial 5780b57cec5SDimitry Andric /// specializations that will need to be instantiated after the 5790b57cec5SDimitry Andric /// enclosing variable's instantiation is complete. 5800b57cec5SDimitry Andric /// FIXME: Verify that this is needed. 5810b57cec5SDimitry Andric SmallVector< 5820b57cec5SDimitry Andric std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> 5830b57cec5SDimitry Andric OutOfLineVarPartialSpecs; 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric public: TemplateDeclInstantiator(Sema & SemaRef,DeclContext * Owner,const MultiLevelTemplateArgumentList & TemplateArgs)5860b57cec5SDimitry Andric TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, 5870b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs) 5880b57cec5SDimitry Andric : SemaRef(SemaRef), 5890b57cec5SDimitry Andric SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), 5900b57cec5SDimitry Andric Owner(Owner), TemplateArgs(TemplateArgs) {} 5910b57cec5SDimitry Andric setEvaluateConstraints(bool B)592bdd1243dSDimitry Andric void setEvaluateConstraints(bool B) { 593bdd1243dSDimitry Andric EvaluateConstraints = B; 594bdd1243dSDimitry Andric } getEvaluateConstraints()595bdd1243dSDimitry Andric bool getEvaluateConstraints() { 596bdd1243dSDimitry Andric return EvaluateConstraints; 597bdd1243dSDimitry Andric } 598bdd1243dSDimitry Andric 5990b57cec5SDimitry Andric // Define all the decl visitors using DeclNodes.inc 6000b57cec5SDimitry Andric #define DECL(DERIVED, BASE) \ 6010b57cec5SDimitry Andric Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); 6020b57cec5SDimitry Andric #define ABSTRACT_DECL(DECL) 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric // Decls which never appear inside a class or function. 6050b57cec5SDimitry Andric #define OBJCCONTAINER(DERIVED, BASE) 6060b57cec5SDimitry Andric #define FILESCOPEASM(DERIVED, BASE) 607bdd1243dSDimitry Andric #define TOPLEVELSTMT(DERIVED, BASE) 6080b57cec5SDimitry Andric #define IMPORT(DERIVED, BASE) 6090b57cec5SDimitry Andric #define EXPORT(DERIVED, BASE) 6100b57cec5SDimitry Andric #define LINKAGESPEC(DERIVED, BASE) 6110b57cec5SDimitry Andric #define OBJCCOMPATIBLEALIAS(DERIVED, BASE) 6120b57cec5SDimitry Andric #define OBJCMETHOD(DERIVED, BASE) 6130b57cec5SDimitry Andric #define OBJCTYPEPARAM(DERIVED, BASE) 6140b57cec5SDimitry Andric #define OBJCIVAR(DERIVED, BASE) 6150b57cec5SDimitry Andric #define OBJCPROPERTY(DERIVED, BASE) 6160b57cec5SDimitry Andric #define OBJCPROPERTYIMPL(DERIVED, BASE) 6170b57cec5SDimitry Andric #define EMPTY(DERIVED, BASE) 618480093f4SDimitry Andric #define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE) 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric // Decls which use special-case instantiation code. 6210b57cec5SDimitry Andric #define BLOCK(DERIVED, BASE) 6220b57cec5SDimitry Andric #define CAPTURED(DERIVED, BASE) 6230b57cec5SDimitry Andric #define IMPLICITPARAM(DERIVED, BASE) 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric #include "clang/AST/DeclNodes.inc" 6260b57cec5SDimitry Andric 627480093f4SDimitry Andric enum class RewriteKind { None, RewriteSpaceshipAsEqualEqual }; 628480093f4SDimitry Andric 629480093f4SDimitry Andric void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, 630480093f4SDimitry Andric TypeSourceInfo *&TInfo, 631480093f4SDimitry Andric DeclarationNameInfo &NameInfo); 632480093f4SDimitry Andric 6330b57cec5SDimitry Andric // A few supplemental visitor functions. 6340b57cec5SDimitry Andric Decl *VisitCXXMethodDecl(CXXMethodDecl *D, 6350b57cec5SDimitry Andric TemplateParameterList *TemplateParams, 636480093f4SDimitry Andric RewriteKind RK = RewriteKind::None); 6370b57cec5SDimitry Andric Decl *VisitFunctionDecl(FunctionDecl *D, 638480093f4SDimitry Andric TemplateParameterList *TemplateParams, 639480093f4SDimitry Andric RewriteKind RK = RewriteKind::None); 6400b57cec5SDimitry Andric Decl *VisitDecl(Decl *D); 6410b57cec5SDimitry Andric Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, 6420b57cec5SDimitry Andric ArrayRef<BindingDecl *> *Bindings = nullptr); 643fe6060f1SDimitry Andric Decl *VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, 644fe6060f1SDimitry Andric LookupResult *Lookup); 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric // Enable late instantiation of attributes. Late instantiated attributes 6470b57cec5SDimitry Andric // will be stored in LA. enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec * LA)6480b57cec5SDimitry Andric void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { 6490b57cec5SDimitry Andric LateAttrs = LA; 6500b57cec5SDimitry Andric StartingScope = SemaRef.CurrentInstantiationScope; 6510b57cec5SDimitry Andric } 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric // Disable late instantiation of attributes. disableLateAttributeInstantiation()6540b57cec5SDimitry Andric void disableLateAttributeInstantiation() { 6550b57cec5SDimitry Andric LateAttrs = nullptr; 6560b57cec5SDimitry Andric StartingScope = nullptr; 6570b57cec5SDimitry Andric } 6580b57cec5SDimitry Andric getStartingScope()6590b57cec5SDimitry Andric LocalInstantiationScope *getStartingScope() const { return StartingScope; } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric using delayed_partial_spec_iterator = SmallVectorImpl<std::pair< 6620b57cec5SDimitry Andric ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator; 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair< 6650b57cec5SDimitry Andric VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator; 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric /// Return an iterator to the beginning of the set of 6680b57cec5SDimitry Andric /// "delayed" partial specializations, which must be passed to 6690b57cec5SDimitry Andric /// InstantiateClassTemplatePartialSpecialization once the class 6700b57cec5SDimitry Andric /// definition has been completed. delayed_partial_spec_begin()6710b57cec5SDimitry Andric delayed_partial_spec_iterator delayed_partial_spec_begin() { 6720b57cec5SDimitry Andric return OutOfLinePartialSpecs.begin(); 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric delayed_var_partial_spec_begin()6750b57cec5SDimitry Andric delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { 6760b57cec5SDimitry Andric return OutOfLineVarPartialSpecs.begin(); 6770b57cec5SDimitry Andric } 6780b57cec5SDimitry Andric 6790b57cec5SDimitry Andric /// Return an iterator to the end of the set of 6800b57cec5SDimitry Andric /// "delayed" partial specializations, which must be passed to 6810b57cec5SDimitry Andric /// InstantiateClassTemplatePartialSpecialization once the class 6820b57cec5SDimitry Andric /// definition has been completed. delayed_partial_spec_end()6830b57cec5SDimitry Andric delayed_partial_spec_iterator delayed_partial_spec_end() { 6840b57cec5SDimitry Andric return OutOfLinePartialSpecs.end(); 6850b57cec5SDimitry Andric } 6860b57cec5SDimitry Andric delayed_var_partial_spec_end()6870b57cec5SDimitry Andric delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { 6880b57cec5SDimitry Andric return OutOfLineVarPartialSpecs.end(); 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric // Helper functions for instantiating methods. 6920b57cec5SDimitry Andric TypeSourceInfo *SubstFunctionType(FunctionDecl *D, 6930b57cec5SDimitry Andric SmallVectorImpl<ParmVarDecl *> &Params); 6940b57cec5SDimitry Andric bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); 6950b57cec5SDimitry Andric bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); 6960b57cec5SDimitry Andric 697480093f4SDimitry Andric bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl); 698480093f4SDimitry Andric 6990b57cec5SDimitry Andric TemplateParameterList * 7000b57cec5SDimitry Andric SubstTemplateParams(TemplateParameterList *List); 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric bool SubstQualifier(const DeclaratorDecl *OldDecl, 7030b57cec5SDimitry Andric DeclaratorDecl *NewDecl); 7040b57cec5SDimitry Andric bool SubstQualifier(const TagDecl *OldDecl, 7050b57cec5SDimitry Andric TagDecl *NewDecl); 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric Decl *VisitVarTemplateSpecializationDecl( 708e8d8bef9SDimitry Andric VarTemplateDecl *VarTemplate, VarDecl *FromVar, 7090b57cec5SDimitry Andric const TemplateArgumentListInfo &TemplateArgsInfo, 7100b57cec5SDimitry Andric ArrayRef<TemplateArgument> Converted, 7110b57cec5SDimitry Andric VarTemplateSpecializationDecl *PrevDecl = nullptr); 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); 7140b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl * 7150b57cec5SDimitry Andric InstantiateClassTemplatePartialSpecialization( 7160b57cec5SDimitry Andric ClassTemplateDecl *ClassTemplate, 7170b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *PartialSpec); 7180b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl * 7190b57cec5SDimitry Andric InstantiateVarTemplatePartialSpecialization( 7200b57cec5SDimitry Andric VarTemplateDecl *VarTemplate, 7210b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl *PartialSpec); 7220b57cec5SDimitry Andric void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric private: 7250b57cec5SDimitry Andric template<typename T> 7260b57cec5SDimitry Andric Decl *instantiateUnresolvedUsingDecl(T *D, 7270b57cec5SDimitry Andric bool InstantiatingPackElement = false); 7280b57cec5SDimitry Andric }; 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric } // namespace clang 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric #endif // LLVM_CLANG_SEMA_TEMPLATE_H 733