[cfe-commits] r76663 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Parse/Action.h lib/AST/DeclCXX.cpp lib/AST/DeclPrinter.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/Parser.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Jul 21 15:36:06 PDT 2009


Author: fjahanian
Date: Tue Jul 21 17:36:06 2009
New Revision: 76663

URL: http://llvm.org/viewvc/llvm-project?rev=76663&view=rev
Log:
Patch to accomodate Doug's comment on default
destruction of base/members for each destructor AST.


Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=76663&r1=76662&r2=76663&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Jul 21 17:36:06 2009
@@ -901,10 +901,7 @@
   /// Support for base and member destruction.
   /// BaseOrMemberDestructions - The arguments used to destruct the base 
   /// or member.
-  // FIXME. May want to use a new class as CXXBaseOrMemberInitializer has
-  // more info. than is needed. At the least, CXXBaseOrMemberInitializer need
-  // be renamed to something neutral.
-  CXXBaseOrMemberInitializer **BaseOrMemberDestructions;
+  uintptr_t *BaseOrMemberDestructions;
   unsigned NumBaseOrMemberDestructions;
   
   CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
@@ -915,7 +912,8 @@
       BaseOrMemberDestructions(0), NumBaseOrMemberDestructions(0) { 
     setImplicit(isImplicitlyDeclared);
   }
-
+  virtual void Destroy(ASTContext& C);
+  
 public:
   static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
                                    SourceLocation L, DeclarationName N,
@@ -941,32 +939,88 @@
   }
 
   /// destr_iterator - Iterates through the member/base destruction list.
-  typedef CXXBaseOrMemberInitializer **destr_iterator;
-  
+   
   /// destr_const_iterator - Iterates through the member/base destruction list.
-  typedef CXXBaseOrMemberInitializer * const * destr_const_iterator;
+  typedef uintptr_t const destr_const_iterator;
   
   /// destr_begin() - Retrieve an iterator to the first destructed member/base.
-  destr_iterator       destr_begin()       { return BaseOrMemberDestructions; }
+  uintptr_t* destr_begin() { 
+    return BaseOrMemberDestructions; 
+  }
   /// destr_begin() - Retrieve an iterator to the first destructed member/base.
-  destr_const_iterator destr_begin() const { return BaseOrMemberDestructions; }
+  uintptr_t* destr_begin() const { 
+    return BaseOrMemberDestructions; 
+  }
   
   /// destr_end() - Retrieve an iterator past the last destructed member/base.
-  destr_iterator       destr_end()       { 
+  uintptr_t* destr_end() { 
     return BaseOrMemberDestructions + NumBaseOrMemberDestructions; 
   }
   /// destr_end() - Retrieve an iterator past the last destructed member/base.
-  destr_const_iterator destr_end() const { 
+  uintptr_t* destr_end() const { 
     return BaseOrMemberDestructions + NumBaseOrMemberDestructions; 
   }
   
-  /// getNumArgs - Determine the number of arguments used to
-  /// destruct the member or base.
+  /// getNumBaseOrMemberDestructions - Number of base and non-static members
+  /// to destroy.
   unsigned getNumBaseOrMemberDestructions() const { 
     return NumBaseOrMemberDestructions; 
   }
   
-  void setBaseOrMemberDestructions(ASTContext &C);
+  /// getBaseOrMember - get the generic 'member' representing either the field
+  /// or a base class.
+  uintptr_t* getBaseOrMemberToDestroy() const {
+    return BaseOrMemberDestructions; 
+  }
+  
+  /// isVbaseToDestroy - returns true, if object is virtual base.
+  bool isVbaseToDestroy(uintptr_t Vbase) const {
+    return (Vbase & 0x1) != 0;
+  }
+  /// isDirectNonVBaseToDestroy - returns true, if object is direct non-virtual
+  /// base.
+  bool isDirectNonVBaseToDestroy(uintptr_t DrctNonVbase) const {
+    return (DrctNonVbase & 0x2) != 0;
+  }
+  /// isAnyBaseToDestroy - returns true, if object is any base (virtual or 
+  /// direct non-virtual)
+  bool isAnyBaseToDestroy(uintptr_t AnyBase) const {
+    return (AnyBase & 0x3) != 0;
+  }
+  /// isMemberToDestroy - returns true if object is a non-static data member.
+  bool isMemberToDestroy(uintptr_t Member) const {
+    return (Member & 0x3)  == 0;
+  }
+  /// getAnyBaseClassToDestroy - Get the type for the given base class object.
+  Type *getAnyBaseClassToDestroy(uintptr_t Base) const {
+    if (isAnyBaseToDestroy(Base))
+      return reinterpret_cast<Type*>(Base  & ~0x03);
+    return 0;
+  }
+  /// getMemberToDestroy - Get the member for the given object.
+  FieldDecl *getMemberToDestroy(uintptr_t Member) { 
+    if (isMemberToDestroy(Member))
+      return reinterpret_cast<FieldDecl *>(Member); 
+    return 0;
+  }
+  /// getVbaseClassToDestroy - Get the virtual base.
+  Type *getVbaseClassToDestroy(uintptr_t Vbase) const {
+    if (isVbaseToDestroy(Vbase))
+      return reinterpret_cast<Type*>(Vbase  & ~0x01);
+    return 0;
+  }
+  /// getDirectNonVBaseClassToDestroy - Get the virtual base.
+  Type *getDirectNonVBaseClassToDestroy(uintptr_t Base) const {
+    if (isDirectNonVBaseToDestroy(Base))
+      return reinterpret_cast<Type*>(Base  & ~0x02);
+    return 0;
+  }
+  
+  /// computeBaseOrMembersToDestroy - Compute information in current 
+  /// destructor decl's AST of bases and non-static data members which will be 
+  /// implicitly destroyed. We are storing the destruction in the order that
+  /// they should occur (which is the reverse of construction order).
+  void computeBaseOrMembersToDestroy(ASTContext &C);
                         
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { 

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=76663&r1=76662&r2=76663&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Jul 21 17:36:06 2009
@@ -1233,7 +1233,7 @@
                                     MemInitTy **MemInits, unsigned NumMemInits){
   }
  
- virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) {}
+ virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {}
 
   /// ActOnFinishCXXMemberSpecification - Invoked after all member declarators
   /// are parsed but *before* parsing of inline method definitions.

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=76663&r1=76662&r2=76663&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Jul 21 17:36:06 2009
@@ -480,13 +480,25 @@
 }
 
 void
-CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) {
+CXXDestructorDecl::Destroy(ASTContext& C) {
+  C.Deallocate(BaseOrMemberDestructions);
+  CXXMethodDecl::Destroy(C);
+}
+
+void
+CXXDestructorDecl::computeBaseOrMembersToDestroy(ASTContext &C) {
   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext());
-  llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToDestruct;
+  llvm::SmallVector<uintptr_t, 32> AllToDestruct;
+  
   for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),
        E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
-    CXXBaseOrMemberInitializer *Member = 
-      new CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,SourceLocation());
+    // Skip over virtual bases which have trivial destructors.
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(VBase->getType()->getAsRecordType()->getDecl());
+    if (BaseClassDecl->hasTrivialDestructor())
+      continue;
+    uintptr_t Member = 
+      reinterpret_cast<uintptr_t>(VBase->getType().getTypePtr()) | 0x1;
     AllToDestruct.push_back(Member);
   }
   for (CXXRecordDecl::base_class_iterator Base =
@@ -494,10 +506,17 @@
        E = ClassDecl->bases_end(); Base != E; ++Base) {
     if (Base->isVirtual())
       continue;
-    CXXBaseOrMemberInitializer *Member = 
-      new CXXBaseOrMemberInitializer(Base->getType(), 0, 0, SourceLocation());
+    // Skip over virtual bases which have trivial destructors.
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
+    if (BaseClassDecl->hasTrivialDestructor())
+      continue;
+    
+    uintptr_t Member = 
+      reinterpret_cast<uintptr_t>(Base->getType().getTypePtr()) | 0x2;
     AllToDestruct.push_back(Member);
   }
+  
   // non-static data members.
   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
        E = ClassDecl->field_end(); Field != E; ++Field) {
@@ -506,8 +525,12 @@
       FieldType = AT->getElementType();
     
     if (FieldType->getAsRecordType()) {
-      CXXBaseOrMemberInitializer *Member = 
-        new CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation());
+      // Skip over virtual bases which have trivial destructors.
+      CXXRecordDecl *BaseClassDecl
+        = cast<CXXRecordDecl>(FieldType->getAsRecordType()->getDecl());
+      if (BaseClassDecl->hasTrivialDestructor())
+        continue;
+      uintptr_t Member = reinterpret_cast<uintptr_t>(*Field);
       AllToDestruct.push_back(Member);
     }
   }
@@ -515,8 +538,7 @@
   unsigned NumDestructions = AllToDestruct.size();
   if (NumDestructions > 0) {
     NumBaseOrMemberDestructions = NumDestructions;
-    BaseOrMemberDestructions = 
-      new (C) CXXBaseOrMemberInitializer*[NumDestructions];
+    BaseOrMemberDestructions = new (C) uintptr_t [NumDestructions];
     // Insert in reverse order.
     for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx)
       BaseOrMemberDestructions[i++] = AllToDestruct[Idx];

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=76663&r1=76662&r2=76663&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Tue Jul 21 17:36:06 2009
@@ -376,25 +376,25 @@
     }
     else if (CXXDestructorDecl *DDecl = dyn_cast<CXXDestructorDecl>(D)) {
       if (DDecl->getNumBaseOrMemberDestructions() > 0) {
-        // FIXME. This is strictly for visualization of destructor's AST for
-        // how base/members are destructed. It has no other validity.
+        // List order of base/member destruction for visualization purposes.
         assert (D->isThisDeclarationADefinition() && "Destructor with dtor-list");
-        Proto += " : ";
-        for (CXXDestructorDecl::destr_const_iterator B = DDecl->destr_begin(), 
-             E = DDecl->destr_end();
+        Proto += "/* : ";
+        for (CXXDestructorDecl::destr_const_iterator *B = DDecl->destr_begin(), 
+             *E = DDecl->destr_end();
              B != E; ++B) {
-          CXXBaseOrMemberInitializer * BMInitializer = (*B);
+          uintptr_t BaseOrMember = (*B);
           if (B != DDecl->destr_begin())
             Proto += ", ";
 
-          if (BMInitializer->isMemberInitializer()) {
-            FieldDecl *FD = BMInitializer->getMember();
+          if (DDecl->isMemberToDestroy(BaseOrMember)) {
+            FieldDecl *FD = DDecl->getMemberToDestroy(BaseOrMember);
             Proto += "~";
             Proto += FD->getNameAsString();
           }
           else // FIXME. skip dependent types for now.
             if (const RecordType *RT = 
-                BMInitializer->getBaseClass()->getAsRecordType()) {
+                  DDecl->getAnyBaseClassToDestroy(BaseOrMember)
+                    ->getAsRecordType()) {
               const CXXRecordDecl *BaseDecl = 
                 cast<CXXRecordDecl>(RT->getDecl());
               Proto += "~";
@@ -402,6 +402,7 @@
             }
           Proto += "()";
         }
+        Proto += " */";
       }
     }
     else

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=76663&r1=76662&r2=76663&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Tue Jul 21 17:36:06 2009
@@ -172,7 +172,7 @@
     if (Tok.is(tok::colon))
       ParseConstructorInitializer(LM.D);
     else
-      Actions.ActOnDefaultCDtorInitializers(LM.D);
+      Actions.ActOnDefaultCtorInitializers(LM.D);
 
     // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'??
     ParseFunctionStatementBody(LM.D);

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=76663&r1=76662&r2=76663&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Jul 21 17:36:06 2009
@@ -666,7 +666,7 @@
   if (Tok.is(tok::colon))
     ParseConstructorInitializer(Res);
   else
-    Actions.ActOnDefaultCDtorInitializers(Res);
+    Actions.ActOnDefaultCtorInitializers(Res);
 
   return ParseFunctionStatementBody(Res);
 }

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jul 21 17:36:06 2009
@@ -1463,7 +1463,7 @@
                                                     SourceLocation MemberLoc,
                                                     IdentifierInfo &Member,
                                                     DeclPtrTy ImplDecl);
-  virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl);
+  virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl);
   bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
                                FunctionDecl *FDecl,
                                const FunctionProtoType *Proto,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jul 21 17:36:06 2009
@@ -3282,12 +3282,15 @@
   // Verify that that gotos and switch cases don't jump into scopes illegally.
   if (CurFunctionNeedsScopeChecking)
     DiagnoseInvalidJumps(Body);
-
-  // C++ constructors that have function-try-blocks can't have return statements
-  // in the handlers of that block. (C++ [except.handle]p14) Verify this.
+  
+  // C++ constructors that have function-try-blocks can't have return 
+  // statements in the handlers of that block. (C++ [except.handle]p14) 
+  // Verify this.
   if (isa<CXXConstructorDecl>(dcl) && isa<CXXTryStmt>(Body))
     DiagnoseReturnInConstructorExceptionHandler(cast<CXXTryStmt>(Body));
-
+  
+  if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl))
+    Destructor->computeBaseOrMembersToDestroy(Context);
   return D;
 }
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jul 21 17:36:06 2009
@@ -918,7 +918,7 @@
   }
 }
 
-void Sema::ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) {
+void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {
   if (!CDtorDecl)
     return;
   
@@ -926,10 +926,6 @@
       = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))
     Constructor->setBaseOrMemberInitializers(Context, 
                                            (CXXBaseOrMemberInitializer **)0, 0);
-  else 
-    if (CXXDestructorDecl *Destructor 
-        = dyn_cast<CXXDestructorDecl>(CDtorDecl.getAs<Decl>()))
-      Destructor->setBaseOrMemberDestructions(Context);
 }
 
 namespace {





More information about the cfe-commits mailing list