[cfe-commits] r90018 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h

Anders Carlsson andersca at mac.com
Fri Nov 27 14:05:05 PST 2009


Author: andersca
Date: Fri Nov 27 16:05:05 2009
New Revision: 90018

URL: http://llvm.org/viewvc/llvm-project?rev=90018&view=rev
Log:
Add a new PrimaryBaseInfo struct that combines the record decl of a primary base with whether it's virtual or not.

Modified:
    cfe/trunk/include/clang/AST/RecordLayout.h
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.h

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

==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Fri Nov 27 16:05:05 2009
@@ -47,6 +47,23 @@
   // FieldCount - Number of fields.
   unsigned FieldCount;
 
+public:
+  /// PrimaryBaseInfo - Contains info about a primary base.
+  struct PrimaryBaseInfo {
+    PrimaryBaseInfo() : Base(0), IsVirtual(false) {}
+
+    PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual)
+      : Base(Base), IsVirtual(IsVirtual) {}
+
+    /// Base - The primary base.
+    const CXXRecordDecl *Base;
+  
+    /// IsVirtual - Whether the primary base is virtual or not.
+    bool IsVirtual;
+  }; 
+  
+private:
+  /// CXXRecordLayoutInfo - Contains C++ specific layout information.
   struct CXXRecordLayoutInfo {
     /// NonVirtualSize - The non-virtual size (in bits) of an object, which is
     /// the size of the object without virtual bases.
@@ -56,11 +73,9 @@
     /// which is the alignment of the object without virtual bases.
     uint64_t NonVirtualAlign;
 
-    /// PrimaryBase - The primary base for our vtable.
-    const CXXRecordDecl *PrimaryBase;
-    /// PrimaryBase - Wether or not the primary base was a virtual base.
-    bool PrimaryBaseWasVirtual;
-
+    /// PrimaryBase - The primary base info for this record.
+    PrimaryBaseInfo PrimaryBase;
+    
     /// BaseOffsets - Contains a map from base classes to their offset.
     /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
     llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
@@ -92,7 +107,7 @@
   ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize,
                   const uint64_t *fieldoffsets, unsigned fieldcount,
                   uint64_t nonvirtualsize, unsigned nonvirtualalign,
-                  const CXXRecordDecl *PB, bool PBVirtual,
+                  const PrimaryBaseInfo &PrimaryBase,
                   const std::pair<const CXXRecordDecl *, uint64_t> *bases,
                   unsigned numbases,
                   const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
@@ -105,8 +120,7 @@
         FieldOffsets[i] = fieldoffsets[i];
     }
 
-    CXXInfo->PrimaryBase = PB;
-    CXXInfo->PrimaryBaseWasVirtual = PBVirtual;
+    CXXInfo->PrimaryBase = PrimaryBase;
     CXXInfo->NonVirtualSize = nonvirtualsize;
     CXXInfo->NonVirtualAlign = nonvirtualalign;
     for (unsigned i = 0; i != numbases; ++i)
@@ -162,17 +176,21 @@
     return CXXInfo->NonVirtualAlign;
   }
 
-  /// getPrimaryBase - Get the primary base.
-  const CXXRecordDecl *getPrimaryBase() const {
+  /// getPrimaryBaseInfo - Get the primary base info.
+  const PrimaryBaseInfo &getPrimaryBaseInfo() const {
     assert(CXXInfo && "Record layout does not have C++ specific info!");
 
     return CXXInfo->PrimaryBase;
   }
-  /// getPrimaryBaseWasVirtual - Indicates if the primary base was virtual.
-  bool getPrimaryBaseWasVirtual() const {
-    assert(CXXInfo && "Record layout does not have C++ specific info!");
 
-    return CXXInfo->PrimaryBaseWasVirtual;
+  // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+  const CXXRecordDecl *getPrimaryBase() const {
+    return getPrimaryBaseInfo().Base;
+  }
+
+  // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+  bool getPrimaryBaseWasVirtual() const {
+    return getPrimaryBaseInfo().IsVirtual;
   }
 
   /// getBaseClassOffset - Get the offset, in bits, for the given base class.

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

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Fri Nov 27 16:05:05 2009
@@ -14,7 +14,6 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/RecordLayout.h"
 #include "clang/Basic/TargetInfo.h"
 #include <llvm/ADT/SmallSet.h>
 #include <llvm/Support/MathExtras.h>
@@ -24,7 +23,7 @@
 ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx)
   : Ctx(Ctx), Size(0), Alignment(8), Packed(false), UnfilledBitsInLastByte(0),
   MaxFieldAlignment(0), DataSize(0), IsUnion(false), NonVirtualSize(0), 
-  NonVirtualAlignment(8), PrimaryBase(0), PrimaryBaseWasVirtual(false) {}
+  NonVirtualAlignment(8) { }
 
 /// LayoutVtable - Lay out the vtable and set PrimaryBase.
 void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
@@ -34,7 +33,7 @@
   }
 
   SelectPrimaryBase(RD);
-  if (PrimaryBase == 0) {
+  if (!PrimaryBase.Base) {
     int AS = 0;
     UpdateAlignment(Ctx.Target.getPointerAlign(AS));
     Size += Ctx.Target.getPointerWidth(AS);
@@ -52,7 +51,7 @@
       const CXXRecordDecl *Base =
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
       // Skip the PrimaryBase here, as it is laid down first.
-      if (Base != PrimaryBase || PrimaryBaseWasVirtual)
+      if (Base != PrimaryBase.Base || PrimaryBase.IsVirtual)
         LayoutBaseNonVirtually(Base, false);
     }
   }
@@ -74,12 +73,13 @@
 }
 
 void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
-  const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+  const ASTRecordLayout::PrimaryBaseInfo &BaseInfo = 
+    Ctx.getASTRecordLayout(RD).getPrimaryBaseInfo();
   
   // If the record has a primary base class that is virtual, add it to the set
   // of primary bases.
-  if (Layout.getPrimaryBaseWasVirtual())
-    IndirectPrimaryBases.insert(Layout.getPrimaryBase());
+  if (BaseInfo.IsVirtual)
+    IndirectPrimaryBases.insert(BaseInfo.Base);
   
   // Now traverse all bases and find primary bases for them.
   for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
@@ -107,7 +107,7 @@
       cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
     if (!i->isVirtual()) {
       SelectPrimaryVBase(Base, FirstPrimary);
-      if (PrimaryBase)
+      if (PrimaryBase.Base)
         return;
       continue;
     }
@@ -115,7 +115,7 @@
       if (FirstPrimary==0)
         FirstPrimary = Base;
       if (!IndirectPrimaryBases.count(Base)) {
-        setPrimaryBase(Base, true);
+        setPrimaryBase(Base, /*IsVirtual=*/true);
         return;
       }
     }
@@ -141,14 +141,17 @@
   // base class, if one exists.
   for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
        e = RD->bases_end(); i != e; ++i) {
-    if (!i->isVirtual()) {
-      const CXXRecordDecl *Base =
-        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-      if (Base->isDynamicClass()) {
-        // We found it.
-        setPrimaryBase(Base, false);
-        return;
-      }
+    // Ignore virtual bases.
+    if (i->isVirtual())
+      continue;
+    
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+
+    if (Base->isDynamicClass()) {
+      // We found it.
+      PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false);
+      return;
     }
   }
 
@@ -166,8 +169,8 @@
 
   // Otherwise if is the first nearly empty virtual base, if one exists,
   // otherwise there is no primary base class.
-  if (!PrimaryBase)
-    setPrimaryBase(FirstPrimary, true);
+  if (!PrimaryBase.Base)
+    setPrimaryBase(FirstPrimary, /*IsVirtual=*/true);
 }
 
 void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
@@ -232,9 +235,10 @@
     }
     
     if (Base->getNumVBases()) {
-      const ASTRecordLayout &L = Ctx.getASTRecordLayout(Base);
-      const CXXRecordDecl *PB = L.getPrimaryBase();
-      LayoutVirtualBases(Class, Base, PB, BaseOffset, mark, IndirectPrimary);
+      const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Base);
+      const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBaseInfo().Base;
+      LayoutVirtualBases(Class, Base, PrimaryBase, BaseOffset, mark, 
+                         IndirectPrimary);
     }
   }
 }
@@ -455,10 +459,10 @@
   if (RD) {
     LayoutVtable(RD);
     // PrimaryBase goes first.
-    if (PrimaryBase) {
-      if (PrimaryBaseWasVirtual)
-        IndirectPrimaryBases.insert(PrimaryBase);
-      LayoutBaseNonVirtually(PrimaryBase, PrimaryBaseWasVirtual);
+    if (PrimaryBase.Base) {
+      if (PrimaryBase.IsVirtual)
+        IndirectPrimaryBases.insert(PrimaryBase.Base);
+      LayoutBaseNonVirtually(PrimaryBase.Base, PrimaryBase.IsVirtual);
     }
     LayoutNonVirtualBases(RD);
   }
@@ -470,7 +474,7 @@
 
   if (RD) {
     llvm::SmallSet<const CXXRecordDecl*, 32> mark;
-    LayoutVirtualBases(RD, RD, PrimaryBase, 0, mark, IndirectPrimaryBases);
+    LayoutVirtualBases(RD, RD, PrimaryBase.Base, 0, mark, IndirectPrimaryBases);
   }
 
   // Finally, round the size of the total struct up to the alignment of the
@@ -687,7 +691,6 @@
                              NonVirtualSize,
                              Builder.NonVirtualAlignment,
                              Builder.PrimaryBase,
-                             Builder.PrimaryBaseWasVirtual,
                              Builder.Bases.data(),
                              Builder.Bases.size(),
                              Builder.VBases.data(),

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=90018&r1=90017&r2=90018&view=diff

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Fri Nov 27 16:05:05 2009
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
 #define LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
 
+#include "clang/AST/RecordLayout.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/System/DataTypes.h"
@@ -54,8 +55,8 @@
 
   uint64_t NonVirtualSize;
   unsigned NonVirtualAlignment;
-  const CXXRecordDecl *PrimaryBase;
-  bool PrimaryBaseWasVirtual;
+  
+  ASTRecordLayout::PrimaryBaseInfo PrimaryBase;
 
   typedef llvm::SmallVector<std::pair<const CXXRecordDecl *, 
                                       uint64_t>, 4> BaseOffsetsTy;
@@ -94,9 +95,8 @@
   /// base class.
   void IdentifyPrimaryBases(const CXXRecordDecl *RD);
   
-  void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) {
-    PrimaryBase = PB;
-    PrimaryBaseWasVirtual = Virtual;
+  void setPrimaryBase(const CXXRecordDecl *Base, bool IsVirtual) {
+    PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, IsVirtual);
   }
   
   bool IsNearlyEmpty(const CXXRecordDecl *RD) const;





More information about the cfe-commits mailing list