diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-07 00:20:55 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-07 00:20:55 +0000 |
commit | a009b59fc2c550a229b9146aabda8e33fe3a7771 (patch) | |
tree | ac66230ec39ba2f487397b32f07d3bdf3a3999a1 /lib | |
parent | 666b3e9858d1c4a72e2c228588fbabf1a5a629ff (diff) |
Factor out the template transformation of a sequence of function
parameters into parameter types, so that substitution of
explicitly-specified function template arguments uses the same
path. This enables the use of explicitly-specified function template
arguments with variadic templates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122986 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 56 |
3 files changed, 57 insertions, 34 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index fcc73b8974..644ff35c3e 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1889,19 +1889,11 @@ Sema::SubstituteExplicitTemplateArguments( // Instantiate the types of each of the function parameters given the // explicitly-specified template arguments. - for (FunctionDecl::param_iterator P = Function->param_begin(), - PEnd = Function->param_end(); - P != PEnd; - ++P) { - QualType ParamType - = SubstType((*P)->getType(), - MultiLevelTemplateArgumentList(*ExplicitArgumentList), - (*P)->getLocation(), (*P)->getDeclName()); - if (ParamType.isNull() || Trap.hasErrorOccurred()) - return TDK_SubstitutionFailure; - - ParamTypes.push_back(ParamType); - } + if (SubstParmTypes(Function->getLocation(), + Function->param_begin(), Function->getNumParams(), + MultiLevelTemplateArgumentList(*ExplicitArgumentList), + ParamTypes)) + return TDK_SubstitutionFailure; // If the caller wants a full function type back, instantiate the return // type and form that function type. diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 7deb7cad3b..c4f91f9ff6 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1221,6 +1221,23 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, return NewParm; } +/// \brief Substitute the given template arguments into the given set of +/// parameters, producing the set of parameter types that would be generated +/// from such a substitution. +bool Sema::SubstParmTypes(SourceLocation Loc, + ParmVarDecl **Params, unsigned NumParams, + const MultiLevelTemplateArgumentList &TemplateArgs, + llvm::SmallVectorImpl<QualType> &ParamTypes) { + assert(!ActiveTemplateInstantiations.empty() && + "Cannot perform an instantiation without some context on the " + "instantiation stack"); + + TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, + DeclarationName()); + return Instantiator.TransformFunctionTypeParams(Loc, Params, NumParams, 0, + ParamTypes, 0); +} + /// \brief Perform substitution on the base class specifiers of the /// given class template specialization. /// diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 25ead7bba5..60ec950c12 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -439,9 +439,11 @@ public: /// variables vector are acceptable. /// /// Return true on error. - bool TransformFunctionTypeParams(FunctionProtoTypeLoc TL, + bool TransformFunctionTypeParams(SourceLocation Loc, + ParmVarDecl **Params, unsigned NumParams, + const QualType *ParamTypes, llvm::SmallVectorImpl<QualType> &PTypes, - llvm::SmallVectorImpl<ParmVarDecl*> &PVars); + llvm::SmallVectorImpl<ParmVarDecl*> *PVars); /// \brief Transforms a single function-type parameter. Return null /// on error. @@ -3390,13 +3392,13 @@ TreeTransform<Derived>::TransformFunctionTypeParam(ParmVarDecl *OldParm) { template<typename Derived> bool TreeTransform<Derived>:: - TransformFunctionTypeParams(FunctionProtoTypeLoc TL, - llvm::SmallVectorImpl<QualType> &PTypes, - llvm::SmallVectorImpl<ParmVarDecl*> &PVars) { - FunctionProtoType *T = TL.getTypePtr(); - - for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) { - if (ParmVarDecl *OldParm = TL.getArg(i)) { + TransformFunctionTypeParams(SourceLocation Loc, + ParmVarDecl **Params, unsigned NumParams, + const QualType *ParamTypes, + llvm::SmallVectorImpl<QualType> &OutParamTypes, + llvm::SmallVectorImpl<ParmVarDecl*> *PVars) { + for (unsigned i = 0; i != NumParams; ++i) { + if (ParmVarDecl *OldParm = Params[i]) { if (OldParm->isParameterPack()) { // We have a function parameter pack that may need to be expanded. llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; @@ -3428,8 +3430,9 @@ bool TreeTransform<Derived>:: if (!NewParm) return true; - PTypes.push_back(NewParm->getType()); - PVars.push_back(NewParm); + OutParamTypes.push_back(NewParm->getType()); + if (PVars) + PVars->push_back(NewParm); } // We're done with the pack expansion. @@ -3445,14 +3448,15 @@ bool TreeTransform<Derived>:: if (!NewParm) return true; - PTypes.push_back(NewParm->getType()); - PVars.push_back(NewParm); + OutParamTypes.push_back(NewParm->getType()); + if (PVars) + PVars->push_back(NewParm); continue; } // Deal with the possibility that we don't have a parameter // declaration for this parameter. - QualType OldType = T->getArgType(i); + QualType OldType = ParamTypes[i]; bool IsPackExpansion = false; if (const PackExpansionType *Expansion = dyn_cast<PackExpansionType>(OldType)) { @@ -3464,7 +3468,7 @@ bool TreeTransform<Derived>:: // Determine whether we should expand the parameter packs. bool ShouldExpand = false; unsigned NumExpansions = 0; - if (getDerived().TryExpandParameterPacks(TL.getBeginLoc(), SourceRange(), + if (getDerived().TryExpandParameterPacks(Loc, SourceRange(), Unexpanded.data(), Unexpanded.size(), ShouldExpand, NumExpansions)) { @@ -3480,8 +3484,9 @@ bool TreeTransform<Derived>:: if (NewType.isNull()) return true; - PTypes.push_back(NewType); - PVars.push_back(0); + OutParamTypes.push_back(NewType); + if (PVars) + PVars->push_back(0); } // We're done with the pack expansion. @@ -3502,8 +3507,9 @@ bool TreeTransform<Derived>:: if (IsPackExpansion) NewType = getSema().Context.getPackExpansionType(NewType); - PTypes.push_back(NewType); - PVars.push_back(0); + OutParamTypes.push_back(NewType); + if (PVars) + PVars->push_back(0); } return false; @@ -3530,7 +3536,11 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, QualType ResultType; if (TL.getTrailingReturn()) { - if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls)) + if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(), + TL.getParmArray(), + TL.getNumArgs(), + TL.getTypePtr()->arg_type_begin(), + ParamTypes, &ParamDecls)) return QualType(); ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); @@ -3542,7 +3552,11 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, if (ResultType.isNull()) return QualType(); - if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls)) + if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(), + TL.getParmArray(), + TL.getNumArgs(), + TL.getTypePtr()->arg_type_begin(), + ParamTypes, &ParamDecls)) return QualType(); } |