From 8453ddb5fed2d04e12824e92a0bd2cc66091bb4c Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 1 Jul 2010 20:59:04 +0000 Subject: Provide exception specifications for implicitly-declared copy constructors. llvm-svn: 107429 --- clang/lib/Sema/SemaDeclCXX.cpp | 49 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) (limited to 'clang/lib/Sema/SemaDeclCXX.cpp') diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index cb454581d1a..56e965f81fe 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4988,6 +4988,49 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(Scope *S, ArgType = ArgType.withConst(); ArgType = Context.getLValueReferenceType(ArgType); + // C++ [except.spec]p14: + // An implicitly declared special member function (Clause 12) shall have an + // exception-specification. [...] + ImplicitExceptionSpecification ExceptSpec(Context); + unsigned Quals = HasConstCopyConstructor? Qualifiers::Const : 0; + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), + BaseEnd = ClassDecl->bases_end(); + Base != BaseEnd; + ++Base) { + // Virtual bases are handled below. + if (Base->isVirtual()) + continue; + + const CXXRecordDecl *BaseClassDecl + = cast(Base->getType()->getAs()->getDecl()); + if (CXXConstructorDecl *CopyConstructor + = BaseClassDecl->getCopyConstructor(Context, Quals)) + ExceptSpec.CalledDecl(CopyConstructor); + } + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), + BaseEnd = ClassDecl->vbases_end(); + Base != BaseEnd; + ++Base) { + const CXXRecordDecl *BaseClassDecl + = cast(Base->getType()->getAs()->getDecl()); + if (CXXConstructorDecl *CopyConstructor + = BaseClassDecl->getCopyConstructor(Context, Quals)) + ExceptSpec.CalledDecl(CopyConstructor); + } + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), + FieldEnd = ClassDecl->field_end(); + Field != FieldEnd; + ++Field) { + QualType FieldType = Context.getBaseElementType((*Field)->getType()); + if (const RecordType *FieldClassType = FieldType->getAs()) { + const CXXRecordDecl *FieldClassDecl + = cast(FieldClassType->getDecl()); + if (CXXConstructorDecl *CopyConstructor + = FieldClassDecl->getCopyConstructor(Context, Quals)) + ExceptSpec.CalledDecl(CopyConstructor); + } + } + // An implicitly-declared copy constructor is an inline public // member of its class. DeclarationName Name @@ -4999,8 +5042,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(Scope *S, Context.getFunctionType(Context.VoidTy, &ArgType, 1, false, 0, - /*FIXME: hasExceptionSpec*/false, - false, 0, 0, + ExceptSpec.hasExceptionSpecification(), + ExceptSpec.hasAnyExceptionSpecification(), + ExceptSpec.size(), + ExceptSpec.data(), FunctionType::ExtInfo()), /*TInfo=*/0, /*isExplicit=*/false, -- cgit v1.2.3