diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-16 17:54:23 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-16 17:54:23 +0000 |
commit | ce58cd720b070c4481f32911d5d9c66411963ca6 (patch) | |
tree | 2084db2f1635d9e37aa2084e55ca82c268542d77 /lib/AST/Type.cpp | |
parent | 075094416be54004403f099d6671799c442bd6b6 (diff) |
P0012R1: Make exception specifications be part of the type system. This
implements the bulk of the change (modifying the type system to include
exception specifications), but not all the details just yet.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284337 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r-- | lib/AST/Type.cpp | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 113974c4b6..2601fa44cc 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -2717,8 +2717,9 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params, QualType *exnSlot = argSlot + NumParams; unsigned I = 0; for (QualType ExceptionType : epi.ExceptionSpec.Exceptions) { - // Note that a dependent exception specification does *not* make - // a type dependent; it's not even part of the C++ type system. + // Note that, before C++17, a dependent exception specification does + // *not* make a type dependent; it's not even part of the C++ type + // system. if (ExceptionType->isInstantiationDependentType()) setInstantiationDependent(); @@ -2757,6 +2758,19 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params, slot[0] = epi.ExceptionSpec.SourceDecl; } + // If this is a canonical type, and its exception specification is dependent, + // then it's a dependent type. This only happens in C++17 onwards. + if (isCanonicalUnqualified()) { + if (getExceptionSpecType() == EST_Dynamic || + getExceptionSpecType() == EST_ComputedNoexcept) { + assert(hasDependentExceptionSpec() && "type should not be canonical"); + setDependent(); + } + } else if (getCanonicalTypeInternal()->isDependentType()) { + // Ask our canonical type whether our exception specification was dependent. + setDependent(); + } + if (epi.ExtParameterInfos) { ExtParameterInfo *extParamInfos = const_cast<ExtParameterInfo *>(getExtParameterInfosBuffer()); @@ -2801,29 +2815,28 @@ FunctionProtoType::getNoexceptSpec(const ASTContext &ctx) const { return value.getBoolValue() ? NR_Nothrow : NR_Throw; } -bool FunctionProtoType::isNothrow(const ASTContext &Ctx, - bool ResultIfDependent) const { +CanThrowResult FunctionProtoType::canThrow(const ASTContext &Ctx) const { ExceptionSpecificationType EST = getExceptionSpecType(); assert(EST != EST_Unevaluated && EST != EST_Uninstantiated); if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) - return true; + return CT_Cannot; - if (EST == EST_Dynamic && ResultIfDependent) { + if (EST == EST_Dynamic) { // A dynamic exception specification is throwing unless every exception // type is an (unexpanded) pack expansion type. for (unsigned I = 0, N = NumExceptions; I != N; ++I) if (!getExceptionType(I)->getAs<PackExpansionType>()) - return false; - return ResultIfDependent; + return CT_Can; + return CT_Dependent; } if (EST != EST_ComputedNoexcept) - return false; + return CT_Can; NoexceptResult NR = getNoexceptSpec(Ctx); if (NR == NR_Dependent) - return ResultIfDependent; - return NR == NR_Nothrow; + return CT_Dependent; + return NR == NR_Nothrow ? CT_Cannot : CT_Can; } bool FunctionProtoType::isTemplateVariadic() const { |