diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 2 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 31 |
4 files changed, 19 insertions, 22 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 65ddc059fa..cb4d336de1 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2195,7 +2195,7 @@ ASTContext::getFunctionType(QualType ResultTy, else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { Size += sizeof(Expr*); } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { - Size += sizeof(FunctionDecl*); + Size += 2 * sizeof(FunctionDecl*); } if (EPI.ConsumedArguments) Size += NumArgs * sizeof(bool); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 10c1adc875..3f6a09457d 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1550,7 +1550,8 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, // Store the function decl from which we will resolve our // exception specification. FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + numArgs); - *slot = epi.ExceptionSpecDecl; + slot[0] = epi.ExceptionSpecDecl; + slot[1] = epi.ExceptionSpecTemplate; // This exception specification doesn't make the type dependent, because // it's not instantiated as part of instantiating the type. } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 669ba3ad37..d2e0e6b63b 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9776,9 +9776,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { // Instantiate the exception specification for any function which is // used: CodeGen will need it. - if (Func->getTemplateInstantiationPattern() && - Func->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() - == EST_Uninstantiated) + const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>(); + if (FPT && FPT->getExceptionSpecType() == EST_Uninstantiated) InstantiateExceptionSpec(Loc, Func); // Implicit instantiation of function templates and member functions of diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 4d312f855f..c7bd99c1ca 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2251,6 +2251,8 @@ static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function, static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, const FunctionProtoType *Proto, const MultiLevelTemplateArgumentList &TemplateArgs) { + assert(Proto->getExceptionSpecType() != EST_Uninstantiated); + // C++11 [expr.prim.general]p3: // If a declaration declares a member function or member function // template of a class X, the expression this is a prvalue of type @@ -2377,20 +2379,8 @@ static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Decl) { - // Find the template declaration which contains the exception specification. - // Per [except.spec]p4, prefer the exception spec on the primary template - // if this is an explicit instantiation. - FunctionDecl *Tmpl = 0; - if (Decl->getPrimaryTemplate()) - Tmpl = Decl->getPrimaryTemplate()->getTemplatedDecl(); - else if (FunctionDecl *MemTmpl = Decl->getInstantiatedFromMemberFunction()) - Tmpl = MemTmpl; - else - Tmpl = Decl->getTemplateInstantiationPattern(); - assert(Tmpl && "can't instantiate non-template"); - - if (Decl->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() - != EST_Uninstantiated) + const FunctionProtoType *Proto = Decl->getType()->castAs<FunctionProtoType>(); + if (Proto->getExceptionSpecType() != EST_Uninstantiated) return; InstantiatingTemplate Inst(*this, PointOfInstantiation, Decl, @@ -2406,10 +2396,12 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(Decl, 0, /*RelativeToPrimary*/true); - addInstantiatedParametersToScope(*this, Decl, Tmpl, Scope, TemplateArgs); + FunctionDecl *Template = Proto->getExceptionSpecTemplate(); + addInstantiatedParametersToScope(*this, Decl, Template, Scope, TemplateArgs); - const FunctionProtoType *Proto = Tmpl->getType()->castAs<FunctionProtoType>(); - ::InstantiateExceptionSpec(*this, Decl, Proto, TemplateArgs); + ::InstantiateExceptionSpec(*this, Decl, + Template->getType()->castAs<FunctionProtoType>(), + TemplateArgs); } /// \brief Initializes the common fields of an instantiation function @@ -2457,6 +2449,10 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI.ExceptionSpecType != EST_None && EPI.ExceptionSpecType != EST_DynamicNone && EPI.ExceptionSpecType != EST_BasicNoexcept) { + FunctionDecl *ExceptionSpecTemplate = Tmpl; + if (EPI.ExceptionSpecType == EST_Uninstantiated) + ExceptionSpecTemplate = EPI.ExceptionSpecTemplate; + // Mark the function has having an uninstantiated exception specification. const FunctionProtoType *NewProto = New->getType()->getAs<FunctionProtoType>(); @@ -2464,6 +2460,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI = NewProto->getExtProtoInfo(); EPI.ExceptionSpecType = EST_Uninstantiated; EPI.ExceptionSpecDecl = New; + EPI.ExceptionSpecTemplate = ExceptionSpecTemplate; New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), NewProto->arg_type_begin(), NewProto->getNumArgs(), |