diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-11-13 20:01:57 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-11-13 20:01:57 +0000 |
commit | 0b3a46247edbb6a058288234fb105f3607262603 (patch) | |
tree | 7683beb767d0846ecd0b2a84058e5afc9cb1fce2 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | cc8d3b877400742377b09b6346b3e2fe6b27b4b4 (diff) | |
download | bcm5719-llvm-0b3a46247edbb6a058288234fb105f3607262603.tar.gz bcm5719-llvm-0b3a46247edbb6a058288234fb105f3607262603.zip |
PR21437, final part of DR1330: delay-parsing of exception-specifications. This
is a re-commit of Doug's r154844 (modernized and updated to fit into current
Clang).
llvm-svn: 221918
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d4cb2fe3504..925bd99051e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5286,6 +5286,12 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { /// C++11 [dcl.fct.def.default]p2. void Sema::CheckExplicitlyDefaultedMemberExceptionSpec( CXXMethodDecl *MD, const FunctionProtoType *SpecifiedType) { + // If the exception specification was explicitly specified but hadn't been + // parsed when the method was defaulted, grab it now. + if (SpecifiedType->getExceptionSpecType() == EST_Unparsed) + SpecifiedType = + MD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>(); + // Compute the implicit exception specification. CallingConv CC = Context.getDefaultCallingConvention(/*IsVariadic=*/false, /*IsCXXMethod=*/true); @@ -13245,6 +13251,7 @@ bool Sema::checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method) { FindCXXThisExpr Finder(*this); switch (Proto->getExceptionSpecType()) { + case EST_Unparsed: case EST_Uninstantiated: case EST_Unevaluated: case EST_BasicNoexcept: @@ -13372,6 +13379,45 @@ void Sema::checkExceptionSpecification( } } +void Sema::actOnDelayedExceptionSpecification(Decl *MethodD, + ExceptionSpecificationType EST, + SourceRange SpecificationRange, + ArrayRef<ParsedType> DynamicExceptions, + ArrayRef<SourceRange> DynamicExceptionRanges, + Expr *NoexceptExpr) { + if (!MethodD) + return; + + // Dig out the method we're referring to. + if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(MethodD)) + MethodD = FunTmpl->getTemplatedDecl(); + + CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(MethodD); + if (!Method) + return; + + // Check the exception specification. + llvm::SmallVector<QualType, 4> Exceptions; + FunctionProtoType::ExceptionSpecInfo ESI; + checkExceptionSpecification(/*IsTopLevel*/true, EST, DynamicExceptions, + DynamicExceptionRanges, NoexceptExpr, Exceptions, + ESI); + + // Update the exception specification on the function type. + Context.adjustExceptionSpec(Method, ESI, /*AsWritten*/true); + + if (Method->isStatic()) + checkThisInStaticMemberFunctionExceptionSpec(Method); + + if (Method->isVirtual()) { + // Check overrides, which we previously had to delay. + for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(), + OEnd = Method->end_overridden_methods(); + O != OEnd; ++O) + CheckOverridingFunctionExceptionSpec(Method, *O); + } +} + /// HandleMSProperty - Analyze a __delcspec(property) field of a C++ class. /// MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record, |