diff options
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 9c1ffb0c654..a9aae009401 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -791,11 +791,17 @@ namespace { ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E); QualType TransformFunctionProtoType(TypeLocBuilder &TLB, - FunctionProtoTypeLoc TL); + FunctionProtoTypeLoc TL) { + // Call the base version; it will forward to our overridden version below. + return inherited::TransformFunctionProtoType(TLB, TL); + } + + template<typename Fn> QualType TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals); + unsigned ThisTypeQuals, + Fn TransformExceptionSpec); ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment, @@ -1327,21 +1333,16 @@ ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr( E->getParam()); } -QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, - FunctionProtoTypeLoc TL) { - // We need a local instantiation scope for this function prototype. - LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); - return inherited::TransformFunctionProtoType(TLB, TL); -} - +template<typename Fn> QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals) { + unsigned ThisTypeQuals, + Fn TransformExceptionSpec) { // We need a local instantiation scope for this function prototype. LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); - return inherited::TransformFunctionProtoType(TLB, TL, ThisContext, - ThisTypeQuals); + return inherited::TransformFunctionProtoType( + TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec); } ParmVarDecl * @@ -1576,7 +1577,8 @@ static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) { /// A form of SubstType intended specifically for instantiating the /// type of a FunctionDecl. Its purpose is solely to force the -/// instantiation of default-argument expressions. +/// instantiation of default-argument expressions and to avoid +/// instantiating an exception-specification. TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &Args, SourceLocation Loc, @@ -1599,9 +1601,17 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T, QualType Result; - if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) { - Result = Instantiator.TransformFunctionProtoType(TLB, Proto, ThisContext, - ThisTypeQuals); + if (FunctionProtoTypeLoc Proto = + TL.IgnoreParens().getAs<FunctionProtoTypeLoc>()) { + // Instantiate the type, other than its exception specification. The + // exception specification is instantiated in InitFunctionInstantiation + // once we've built the FunctionDecl. + // FIXME: Set the exception specification to EST_Uninstantiated here, + // instead of rebuilding the function type again later. + Result = Instantiator.TransformFunctionProtoType( + TLB, Proto, ThisContext, ThisTypeQuals, + [](FunctionProtoType::ExceptionSpecInfo &ESI, + bool &Changed) { return false; }); } else { Result = Instantiator.TransformType(TLB, TL); } @@ -1611,6 +1621,26 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T, return TLB.getTypeSourceInfo(Context, Result); } +void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, + const MultiLevelTemplateArgumentList &Args) { + FunctionProtoType::ExceptionSpecInfo ESI = + Proto->getExtProtoInfo().ExceptionSpec; + assert(ESI.Type != EST_Uninstantiated); + + TemplateInstantiator Instantiator(*this, Args, New->getLocation(), + New->getDeclName()); + + SmallVector<QualType, 4> ExceptionStorage; + bool Changed = false; + if (Instantiator.TransformExceptionSpec( + New->getTypeSourceInfo()->getTypeLoc().getLocEnd(), ESI, + ExceptionStorage, Changed)) + // On error, recover by dropping the exception specification. + ESI.Type = EST_None; + + UpdateExceptionSpec(New, ESI); +} + ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, |