diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-07-01 20:59:04 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-07-01 20:59:04 +0000 | 
| commit | 8453ddb5fed2d04e12824e92a0bd2cc66091bb4c (patch) | |
| tree | 7b3a15f8e49f2994f9bf2372593e6c1c1a3fa79a /clang/lib/Sema/SemaDeclCXX.cpp | |
| parent | 0e980755d332cb14b9d6a9d4c11a7879510927a6 (diff) | |
| download | bcm5719-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.cpp | 49 | 
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, | 

