]> granicus.if.org Git - clang/commitdiff
Add a new PrimaryBaseInfo struct that combines the record decl of a primary base...
authorAnders Carlsson <andersca@mac.com>
Fri, 27 Nov 2009 22:05:05 +0000 (22:05 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 27 Nov 2009 22:05:05 +0000 (22:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90018 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/RecordLayout.h
lib/AST/RecordLayoutBuilder.cpp
lib/AST/RecordLayoutBuilder.h

index 9b1c640a40b244321ced0f503698d37f5879b700..c34a27e18f52c8ad6e2b1c9e3538b7257c1eafde 100644 (file)
@@ -47,6 +47,23 @@ class ASTRecordLayout {
   // 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 @@ class ASTRecordLayout {
     /// 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 @@ class ASTRecordLayout {
   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 @@ class ASTRecordLayout {
         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 @@ public:
     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.
index 5bc27b9d06f576829091e3d2550404bc89339d2b..af270577bc6c1a1e335568e159ba19776f4c47f5 100644 (file)
@@ -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 @@ using namespace clang;
 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 @@ void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
   }
 
   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 @@ ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
       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 @@ bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
 }
 
 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 @@ ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
       cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
     if (!i->isVirtual()) {
       SelectPrimaryVBase(Base, FirstPrimary);
-      if (PrimaryBase)
+      if (PrimaryBase.Base)
         return;
       continue;
     }
@@ -115,7 +115,7 @@ ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
       if (FirstPrimary==0)
         FirstPrimary = Base;
       if (!IndirectPrimaryBases.count(Base)) {
-        setPrimaryBase(Base, true);
+        setPrimaryBase(Base, /*IsVirtual=*/true);
         return;
       }
     }
@@ -141,14 +141,17 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
   // 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 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
 
   // 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 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
     }
     
     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 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
   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 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
 
   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 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
                              NonVirtualSize,
                              Builder.NonVirtualAlignment,
                              Builder.PrimaryBase,
-                             Builder.PrimaryBaseWasVirtual,
                              Builder.Bases.data(),
                              Builder.Bases.size(),
                              Builder.VBases.data(),
index fe02d882cec8d372deae9b4cbf41366e86c514cf..69e0498917c7696651742c3c7d14d1781ef96495 100644 (file)
@@ -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 @@ class ASTRecordLayoutBuilder {
 
   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 @@ class ASTRecordLayoutBuilder {
   /// 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;