summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-07-01 20:59:04 +0000
committerDouglas Gregor <dgregor@apple.com>2010-07-01 20:59:04 +0000
commit8453ddb5fed2d04e12824e92a0bd2cc66091bb4c (patch)
tree7b3a15f8e49f2994f9bf2372593e6c1c1a3fa79a /clang/lib/Sema/SemaDeclCXX.cpp
parent0e980755d332cb14b9d6a9d4c11a7879510927a6 (diff)
downloadbcm5719-llvm-8453ddb5fed2d04e12824e92a0bd2cc66091bb4c.tar.gz
bcm5719-llvm-8453ddb5fed2d04e12824e92a0bd2cc66091bb4c.zip
Provide exception specifications for implicitly-declared copy constructors.
llvm-svn: 107429
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp49
1 files changed, 47 insertions, 2 deletions
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<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->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<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->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<RecordType>()) {
+ const CXXRecordDecl *FieldClassDecl
+ = cast<CXXRecordDecl>(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,
OpenPOWER on IntegriCloud