[cfe-commits] r107437 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/except/except.spec/p14-ir.cpp

Douglas Gregor dgregor at apple.com
Thu Jul 1 15:31:05 PDT 2010


Author: dgregor
Date: Thu Jul  1 17:31:05 2010
New Revision: 107437

URL: http://llvm.org/viewvc/llvm-project?rev=107437&view=rev
Log:
Provide exception specifications for implicitly-declared default constructors.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CXX/except/except.spec/p14-ir.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=107437&r1=107436&r2=107437&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Jul  1 17:31:05 2010
@@ -785,7 +785,7 @@
   void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
   
   /// getDefaultConstructor - Returns the default constructor for this class
-  CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
+  CXXConstructorDecl *getDefaultConstructor();
 
   /// getDestructor - Returns the destructor decl for this class.
   CXXDestructorDecl *getDestructor() const;

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=107437&r1=107436&r2=107437&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Jul  1 17:31:05 2010
@@ -624,7 +624,8 @@
 }
 
 CXXConstructorDecl *
-CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
+CXXRecordDecl::getDefaultConstructor() {
+  ASTContext &Context = getASTContext();
   QualType ClassType = Context.getTypeDeclType(this);
   DeclarationName ConstructorName
     = Context.DeclarationNames.getCXXConstructorName(

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=107437&r1=107436&r2=107437&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jul  1 17:31:05 2010
@@ -2656,9 +2656,6 @@
 /// The scope, if provided, is the class scope.
 void Sema::AddImplicitlyDeclaredMembersToClass(Scope *S, 
                                                CXXRecordDecl *ClassDecl) {
-  // FIXME: Implicit declarations have exception specifications, which are
-  // the union of the specifications of the implicitly called functions.
-
   if (!ClassDecl->hasUserDeclaredConstructor())
     DeclareImplicitDefaultConstructor(S, ClassDecl);
 
@@ -4146,6 +4143,48 @@
   //   user-declared constructor for class X, a default constructor is
   //   implicitly declared. An implicitly-declared default constructor
   //   is an inline public member of its class.
+  
+  // C++ [except.spec]p14:
+  //   An implicitly declared special member function (Clause 12) shall have an 
+  //   exception-specification. [...]
+  ImplicitExceptionSpecification ExceptSpec(Context);
+
+  // Direct base-class destructors.
+  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>())
+      if (CXXConstructorDecl *Constructor
+            = cast<CXXRecordDecl>(BaseType->getDecl())->getDefaultConstructor())
+        ExceptSpec.CalledDecl(Constructor);
+  }
+  
+  // Virtual base-class destructors.
+  for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
+                                       BEnd = ClassDecl->vbases_end();
+       B != BEnd; ++B) {
+    if (const RecordType *BaseType = B->getType()->getAs<RecordType>())
+      if (CXXConstructorDecl *Constructor
+            = cast<CXXRecordDecl>(BaseType->getDecl())->getDefaultConstructor())
+        ExceptSpec.CalledDecl(Constructor);
+  }
+  
+  // Field destructors.
+  for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
+                               FEnd = ClassDecl->field_end();
+       F != FEnd; ++F) {
+    if (const RecordType *RecordTy
+                = Context.getBaseElementType(F->getType())->getAs<RecordType>())
+      if (CXXConstructorDecl *Constructor
+            = cast<CXXRecordDecl>(RecordTy->getDecl())->getDefaultConstructor())
+        ExceptSpec.CalledDecl(Constructor);
+  }
+  
+  
+  // Create the actual constructor declaration.
   CanQualType ClassType
     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   DeclarationName Name
@@ -4155,8 +4194,10 @@
                                  ClassDecl->getLocation(), Name,
                                  Context.getFunctionType(Context.VoidTy,
                                                          0, 0, false, 0,
-                                                         /*FIXME*/false, false,
-                                                         0, 0,
+                                       ExceptSpec.hasExceptionSpecification(),
+                                     ExceptSpec.hasAnyExceptionSpecification(),
+                                                         ExceptSpec.size(),
+                                                         ExceptSpec.data(),
                                                        FunctionType::ExtInfo()),
                                  /*TInfo=*/0,
                                  /*isExplicit=*/false,

Modified: cfe/trunk/test/CXX/except/except.spec/p14-ir.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/except/except.spec/p14-ir.cpp?rev=107437&r1=107436&r2=107437&view=diff
==============================================================================
--- cfe/trunk/test/CXX/except/except.spec/p14-ir.cpp (original)
+++ cfe/trunk/test/CXX/except/except.spec/p14-ir.cpp Thu Jul  1 17:31:05 2010
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -o - %s | FileCheck %s
 
+// Copy constructor
 struct X0 {
   X0();
   X0(const X0 &) throw();
@@ -42,3 +43,28 @@
   // CHECK: ret void
   X5 x5a(x5);
 }
+
+// Default constructor
+struct X6 {
+  X6() throw();
+};
+
+struct X7 { 
+  X7();
+};
+
+struct X8 : X6 { };
+struct X9 : X6, X7 { };
+
+void test() {
+  // CHECK: define linkonce_odr void @_ZN2X8C1Ev
+  // CHECK-NOT: define
+  // CHECK: call void @__cxa_call_unexpected
+  // CHECK-NOT: define
+  // CHECK: ret void
+  X8();
+  // CHECK: define linkonce_odr void @_ZN2X9C1Ev
+  // CHECK-NOT: call void @__cxa_call_unexpected
+  // CHECK: ret void
+  X9();
+}





More information about the cfe-commits mailing list