[cfe-commits] r74359 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp

Fariborz Jahanian fjahanian at apple.com
Fri Jun 26 16:49:17 PDT 2009


Author: fjahanian
Date: Fri Jun 26 18:49:16 2009
New Revision: 74359

URL: http://llvm.org/viewvc/llvm-project?rev=74359&view=rev
Log:
Patch to mark destructors when they are used.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=74359&r1=74358&r2=74359&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 26 18:49:16 2009
@@ -593,7 +593,7 @@
   "%2 does not have any default constructor">;
 def note_previous_class_decl : Note<
   "%0 declared here">;
-def err_unintialized_member_for_assign : Error<
+def err_uninitialized_member_for_assign : Error<
   "cannot define the implicit default assignment operator for %0, because "
   "non-static %select{reference|const}1 member %2 can't use default "
   "assignment operator">;

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=74359&r1=74358&r2=74359&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Jun 26 18:49:16 2009
@@ -1592,12 +1592,21 @@
                                     CXXConstructorDecl *Constructor,
                                     QualType DeclInitType, 
                                     Expr **Exprs, unsigned NumExprs);
+
+  /// MarcDestructorReferenced - Prepare for calling destructor on the
+  /// constructed decl.
+  void MarcDestructorReferenced(SourceLocation Loc, QualType DeclInitType);
   
   /// DefineImplicitDefaultConstructor - Checks for feasibility of 
   /// defining this constructor as the default constructor.
   void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
                                         CXXConstructorDecl *Constructor);
   
+  /// DefineImplicitDestructor - Checks for feasibility of 
+  /// defining this destructor as the default destructor.
+  void DefineImplicitDestructor(SourceLocation CurrentLocation,
+                                        CXXDestructorDecl *Destructor);
+  
   /// DefineImplicitCopyConstructor - Checks for feasibility of 
   /// defining this constructor as the copy constructor.
   void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=74359&r1=74358&r2=74359&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jun 26 18:49:16 2009
@@ -2792,9 +2792,13 @@
                                                  IK_Default);
         if (!Constructor)
           Var->setInvalidDecl();
-        else 
+        else { 
           if (!RD->hasTrivialConstructor())
             InitializeVarWithConstructor(Var, Constructor, InitType, 0, 0);
+          // FIXME. Must do all that is needed to destroy the object
+          // on scope exit. For now, just mark the destructor as used.
+          MarcDestructorReferenced(Var->getLocation(), InitType);
+        }
       }
     }
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=74359&r1=74358&r2=74359&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Jun 26 18:49:16 2009
@@ -1945,6 +1945,56 @@
     Constructor->setInvalidDecl();
 }
 
+void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
+                                            CXXDestructorDecl *Destructor) {
+  assert((Destructor->isImplicit() && !Destructor->isUsed()) &&
+         "DefineImplicitDestructor - call it for implicit default dtor");
+  
+  CXXRecordDecl *ClassDecl
+  = cast<CXXRecordDecl>(Destructor->getDeclContext());
+  assert(ClassDecl && "DefineImplicitDestructor - invalid destructor");
+  // C++ [class.dtor] p5
+  // Before the implicitly-declared default destructor for a class is 
+  // implicitly defined, all the implicitly-declared default destructors
+  // for its base class and its non-static data members shall have been
+  // implicitly defined.
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
+       Base != ClassDecl->bases_end(); ++Base) {
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
+    if (!BaseClassDecl->hasTrivialDestructor()) {
+      if (CXXDestructorDecl *BaseDtor = 
+          const_cast<CXXDestructorDecl*>(BaseClassDecl->getDestructor(Context)))
+        MarkDeclarationReferenced(CurrentLocation, BaseDtor);
+      else
+        assert(false && 
+               "DefineImplicitDestructor - missing dtor in a base class");
+    }
+  }
+  
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
+       Field != ClassDecl->field_end(Context);
+       ++Field) {
+    QualType FieldType = Context.getCanonicalType((*Field)->getType());
+    if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+      FieldType = Array->getElementType();
+    if (const RecordType *FieldClassType = FieldType->getAsRecordType()) {
+      CXXRecordDecl *FieldClassDecl
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      if (!FieldClassDecl->hasTrivialDestructor()) {
+        if (CXXDestructorDecl *FieldDtor = 
+            const_cast<CXXDestructorDecl*>(
+                                        FieldClassDecl->getDestructor(Context)))
+          MarkDeclarationReferenced(CurrentLocation, FieldDtor);
+        else
+          assert(false && 
+          "DefineImplicitDestructor - missing dtor in class of a data member");
+      }
+    }
+  }
+  Destructor->setUsed();
+}
+
 void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
                                           CXXMethodDecl *MethodDecl) {
   assert((MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&
@@ -1984,14 +2034,14 @@
         MarkDeclarationReferenced(CurrentLocation, FieldAssignOpMethod);
     }
     else if (FieldType->isReferenceType()) {
-      Diag(ClassDecl->getLocation(), diag::err_unintialized_member_for_assign) 
+      Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign) 
       << Context.getTagDeclType(ClassDecl) << 0 << (*Field)->getNameAsCString();
       Diag((*Field)->getLocation(), diag::note_declared_at);
       Diag(CurrentLocation, diag::note_first_required_here);
       err = true;
     }
     else if (FieldType.isConstQualified()) {
-      Diag(ClassDecl->getLocation(), diag::err_unintialized_member_for_assign) 
+      Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign) 
       << Context.getTagDeclType(ClassDecl) << 1 << (*Field)->getNameAsCString();
       Diag((*Field)->getLocation(), diag::note_declared_at);
       Diag(CurrentLocation, diag::note_first_required_here);
@@ -2084,6 +2134,16 @@
   VD->setInit(Context, Temp);
 }
 
+void Sema::MarcDestructorReferenced(SourceLocation Loc, QualType DeclInitType)
+{
+  CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(
+                                  DeclInitType->getAsRecordType()->getDecl());
+  if (!ClassDecl->hasTrivialDestructor())
+    if (CXXDestructorDecl *Destructor = 
+        const_cast<CXXDestructorDecl*>(ClassDecl->getDestructor(Context)))
+      MarkDeclarationReferenced(Loc, Destructor);
+}
+
 /// AddCXXDirectInitializerToDecl - This action is called immediately after 
 /// ActOnDeclarator, when a C++ direct initializer is present.
 /// e.g: "int x(1);"
@@ -2150,6 +2210,9 @@
       VDecl->setCXXDirectInitializer(true);
       InitializeVarWithConstructor(VDecl, Constructor, DeclInitType, 
                                    (Expr**)Exprs.release(), NumExprs);
+      // FIXME. Must do all that is needed to destroy the object
+      // on scope exit. For now, just mark the destructor as used.
+      MarcDestructorReferenced(VDecl->getLocation(), DeclInitType);
     }
     return;
   }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=74359&r1=74358&r2=74359&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jun 26 18:49:16 2009
@@ -5593,9 +5593,10 @@
       if (!Constructor->isUsed())
         DefineImplicitCopyConstructor(Loc, Constructor, TypeQuals);
     }
-    // FIXME: more checking for other implicits go here.
-    else
-      Constructor->setUsed(true);
+  } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
+    if (Destructor->isImplicit() && !Destructor->isUsed())
+      DefineImplicitDestructor(Loc, Destructor);
+    
   } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
     if (MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&
         MethodDecl->getOverloadedOperator() == OO_Equal) {

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=74359&r1=74358&r2=74359&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Jun 26 18:49:16 2009
@@ -1567,7 +1567,7 @@
   CXXTemporary *Temp = CXXTemporary::Create(Context, 
                                             RD->getDestructor(Context));
   ExprTemporaries.push_back(Temp);
-  
+  MarcDestructorReferenced(E->getExprLoc(), E->getType());
   // FIXME: Add the temporary to the temporaries vector.
   return Owned(CXXBindTemporaryExpr::Create(Context, Temp, E));
 }





More information about the cfe-commits mailing list