Centralize the management of CXXRecordDecl::DefinitionData's Empty bit
in CXXRecordDecl itself. Yes, this is also part of <rdar://problem/8459981>.

This reinstates r114924, with one crucial bug fix: we were ignoring
the implicit fields created by anonymous structs/unions when updating
the bits in CXXRecordDecl, which means that a class/struct containing
only an anonymous class/struct would be considered "empty". Hilarity
follows. 


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114980 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 440eadd..0e37bc7 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -105,6 +105,11 @@
     //   A POD-struct is an aggregate class...
     data().PlainOldData = false;
     
+    // A class with a non-empty base class is not empty.
+    // FIXME: Standard ref?
+    if (!BaseClassDecl->isEmpty())
+      data().Empty = false;
+    
     // Now go through all virtual bases of this base and add them.
     for (CXXRecordDecl::base_class_iterator VBase =
           BaseClassDecl->vbases_begin(),
@@ -118,8 +123,12 @@
       // Add this base if it's not already in the list.
       if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)))
           VBases.push_back(Base);
+      
+      // C++0x [meta.unary.prop] is_empty:
+      //    T is a class type, but not a union type, with ... no virtual base
+      //    classes
+      data().Empty = false;
     }
-
   }
   
   if (VBases.empty())
@@ -285,6 +294,10 @@
       // C++ [class]p4:
       //   A POD-struct is an aggregate class...
       data().PlainOldData = false;
+      
+      // Virtual functions make the class non-empty.
+      // FIXME: Standard ref?
+      data().Empty = false;
     }
   }
   
@@ -298,18 +311,24 @@
       // declared it.
       else if (Constructor->isCopyConstructor())
         data().DeclaredCopyConstructor = true;
-    } else if (isa<CXXDestructorDecl>(D)) {
+      return;
+    } 
+
+    if (isa<CXXDestructorDecl>(D)) {
       data().DeclaredDestructor = true;
-    } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+      return;
+    } 
+
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
       // If this is the implicit copy constructor, note that we have now
       // declared it.
       // FIXME: Move constructors
       if (Method->getOverloadedOperator() == OO_Equal)
         data().DeclaredCopyAssignment = true;
+      return;
     }
-    
-    // Nothing else to do for implicitly-declared members.
-    return;
+
+    // Any other implicit declarations are handled like normal declarations.
   }
   
   // Handle (user-declared) constructors.
@@ -429,6 +448,19 @@
     QualType T = Context.getBaseElementType(Field->getType());
     if (!T->isPODType())
       data().PlainOldData = false;
+    
+    // If this is not a zero-length bit-field, then the class is not empty.
+    if (data().Empty) {
+      if (!Field->getBitWidth())
+        data().Empty = false;
+      else if (!Field->getBitWidth()->isTypeDependent() &&
+               !Field->getBitWidth()->isValueDependent()) {
+        llvm::APSInt Bits;
+        if (Field->getBitWidth()->isIntegerConstantExpr(Bits, Context))
+          if (!!Bits)
+            data().Empty = false;
+      } 
+    }
   }
 }
 
@@ -614,7 +646,6 @@
 
 void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {
   Method->setVirtualAsWritten(true);
-  setEmpty(false);
   setPolymorphic(true);
   setHasTrivialConstructor(false);
   setHasTrivialCopyConstructor(false);