зеркало из https://github.com/microsoft/clang-1.git
Add support for computing the exception specification for an inheriting
constructor. This isn't quite perfect (as usual, we don't handle default arguments correctly yet, and we don't deal with copy/move constructors for arguments correctly either, but this will be fixed when we implement core issue 1351. This completes our support for inheriting constructors. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179154 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
0baaabb717
Коммит
0b0ca4724d
|
@ -3542,7 +3542,7 @@ public:
|
|||
const QualType *data() const { return Exceptions.data(); }
|
||||
|
||||
/// \brief Integrate another called method into the collected data.
|
||||
void CalledDecl(SourceLocation CallLoc, CXXMethodDecl *Method);
|
||||
void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method);
|
||||
|
||||
/// \brief Integrate an invoked expression into the collected data.
|
||||
void CalledExpr(Expr *E);
|
||||
|
@ -3606,7 +3606,7 @@ public:
|
|||
/// \brief Determine what sort of exception specification an inheriting
|
||||
/// constructor of a class will have.
|
||||
ImplicitExceptionSpecification
|
||||
ComputeInheritingCtorExceptionSpec(CXXMethodDecl *MD);
|
||||
ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD);
|
||||
|
||||
/// \brief Evaluate the implicit exception specification for a defaulted
|
||||
/// special member function.
|
||||
|
|
|
@ -145,8 +145,9 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
void Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc,
|
||||
CXXMethodDecl *Method) {
|
||||
void
|
||||
Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc,
|
||||
const CXXMethodDecl *Method) {
|
||||
// If we have an MSAny spec already, don't bother.
|
||||
if (!Method || ComputedEST == EST_MSAny)
|
||||
return;
|
||||
|
@ -7522,9 +7523,73 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
|
|||
}
|
||||
|
||||
Sema::ImplicitExceptionSpecification
|
||||
Sema::ComputeInheritingCtorExceptionSpec(CXXMethodDecl *MD) {
|
||||
Sema::ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD) {
|
||||
CXXRecordDecl *ClassDecl = CD->getParent();
|
||||
|
||||
// C++ [except.spec]p14:
|
||||
// An inheriting constructor [...] shall have an exception-specification. [...]
|
||||
ImplicitExceptionSpecification ExceptSpec(*this);
|
||||
// FIXME: Compute the exception spec.
|
||||
if (ClassDecl->isInvalidDecl())
|
||||
return ExceptSpec;
|
||||
|
||||
// Inherited constructor.
|
||||
const CXXConstructorDecl *InheritedCD = CD->getInheritedConstructor();
|
||||
const CXXRecordDecl *InheritedDecl = InheritedCD->getParent();
|
||||
// FIXME: Copying or moving the parameters could add extra exceptions to the
|
||||
// set, as could the default arguments for the inherited constructor. This
|
||||
// will be addressed when we implement the resolution of core issue 1351.
|
||||
ExceptSpec.CalledDecl(CD->getLocStart(), InheritedCD);
|
||||
|
||||
// Direct base-class constructors.
|
||||
for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
|
||||
BEnd = ClassDecl->bases_end();
|
||||
B != BEnd; ++B) {
|
||||
if (B->isVirtual()) // Handled below.
|
||||
continue;
|
||||
|
||||
if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
|
||||
CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
|
||||
if (BaseClassDecl == InheritedDecl)
|
||||
continue;
|
||||
CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl);
|
||||
if (Constructor)
|
||||
ExceptSpec.CalledDecl(B->getLocStart(), Constructor);
|
||||
}
|
||||
}
|
||||
|
||||
// Virtual base-class constructors.
|
||||
for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
|
||||
BEnd = ClassDecl->vbases_end();
|
||||
B != BEnd; ++B) {
|
||||
if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
|
||||
CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
|
||||
if (BaseClassDecl == InheritedDecl)
|
||||
continue;
|
||||
CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl);
|
||||
if (Constructor)
|
||||
ExceptSpec.CalledDecl(B->getLocStart(), Constructor);
|
||||
}
|
||||
}
|
||||
|
||||
// Field constructors.
|
||||
for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
|
||||
FEnd = ClassDecl->field_end();
|
||||
F != FEnd; ++F) {
|
||||
if (F->hasInClassInitializer()) {
|
||||
if (Expr *E = F->getInClassInitializer())
|
||||
ExceptSpec.CalledExpr(E);
|
||||
else if (!F->isInvalidDecl())
|
||||
Diag(CD->getLocation(),
|
||||
diag::err_in_class_initializer_references_def_ctor) << CD;
|
||||
} else if (const RecordType *RecordTy
|
||||
= Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
|
||||
CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
|
||||
CXXConstructorDecl *Constructor = LookupDefaultConstructor(FieldRecDecl);
|
||||
if (Constructor)
|
||||
ExceptSpec.CalledDecl(F->getLocation(), Constructor);
|
||||
}
|
||||
}
|
||||
|
||||
return ExceptSpec;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,3 +112,26 @@ namespace rdar13017229 {
|
|||
Typo foo(); // expected-error{{unknown type name 'Typo'}}
|
||||
};
|
||||
}
|
||||
|
||||
namespace InhCtor {
|
||||
template<int> struct X {};
|
||||
struct Base {
|
||||
Base(X<0>) noexcept(true);
|
||||
Base(X<1>) noexcept(false);
|
||||
Base(X<2>) throw(X<2>);
|
||||
template<typename T> Base(T) throw(T);
|
||||
};
|
||||
template<typename T> struct Throw {
|
||||
Throw() throw(T);
|
||||
};
|
||||
struct Derived : Base, Throw<X<3>> {
|
||||
using Base::Base;
|
||||
Throw<X<4>> x;
|
||||
};
|
||||
struct Test {
|
||||
friend Derived::Derived(X<0>) throw(X<3>, X<4>);
|
||||
friend Derived::Derived(X<1>) noexcept(false);
|
||||
friend Derived::Derived(X<2>) throw(X<2>, X<3>, X<4>);
|
||||
};
|
||||
static_assert(!noexcept(Derived{X<5>{}}), "");
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ releases prior to version 3.2 in C++11 mode.</p>
|
|||
<tr>
|
||||
<td>Inheriting constructors</td>
|
||||
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm">N2540</a></td>
|
||||
<td class="none" align="center">No</td>
|
||||
<td class="svn" align="center">SVN</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Explicit conversion operators</td>
|
||||
|
|
Загрузка…
Ссылка в новой задаче