]> granicus.if.org Git - clang/commitdiff
More layout builder work.
authorAnders Carlsson <andersca@mac.com>
Sat, 18 Jul 2009 20:50:59 +0000 (20:50 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 18 Jul 2009 20:50:59 +0000 (20:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76333 91177308-0d34-0410-b5e6-96231b3b80d8

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

index fcf81f88bcb4e620d278bcbaccf287b78ad558ce..2350275d56ee0d84767a651694fce4e3645d7cf5 100644 (file)
@@ -44,8 +44,10 @@ class ASTRecordLayout {
   }
 
   ASTRecordLayout(uint64_t Size, unsigned Alignment,
+                  unsigned nextoffset,
                   const uint64_t *fieldoffsets, unsigned fieldcount) 
-  : Size(Size), FieldOffsets(0), Alignment(Alignment), FieldCount(fieldcount) {
+  : Size(Size), NextOffset(nextoffset), FieldOffsets(0), Alignment(Alignment), 
+    FieldCount(fieldcount) {
     if (FieldCount > 0)  {
       FieldOffsets = new uint64_t[FieldCount];
       for (unsigned i = 0; i < FieldCount; ++i)
index b72e588ca7a445a386f640a101f6f60316be3997..5230ba95d1db2babb3ff20cf3a9ebd79596e2e7f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/TargetInfo.h"
@@ -42,6 +43,36 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
   FinishLayout();
 }
 
+void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
+                                    const ObjCImplementationDecl *Impl) {
+  if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
+    const ASTRecordLayout &SL = Ctx.getASTObjCInterfaceLayout(SD);
+
+    UpdateAlignment(SL.getAlignment());
+    
+    // We start laying out ivars not at the end of the superclass
+    // structure, but at the next byte following the last field.
+    Size = llvm::RoundUpToAlignment(SL.NextOffset, 8);
+    NextOffset = Size;
+  }
+  
+  if (const PackedAttr *PA = D->getAttr<PackedAttr>())
+    StructPacking = PA->getAlignment();
+  
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+    UpdateAlignment(AA->getAlignment());
+  
+  // Layout each ivar sequentially.
+  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
+  Ctx.ShallowCollectObjCIvars(D, Ivars, Impl);
+  for (unsigned i = 0, e = Ivars.size(); i != e; ++i)
+    LayoutField(Ivars[i]);
+  
+  // Finally, round the size of the total struct up to the alignment of the
+  // struct itself.
+  FinishLayout();
+}
+
 void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
   unsigned FieldPacking = StructPacking;
   uint64_t FieldOffset = IsUnion ? 0 : Size;
@@ -157,6 +188,21 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
   Builder.Layout(D);
 
   return new ASTRecordLayout(Builder.Size, Builder.Alignment,
+                             Builder.NextOffset,
+                             Builder.FieldOffsets.data(), 
+                             Builder.FieldOffsets.size());
+}
+
+const ASTRecordLayout *
+ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
+                                      const ObjCInterfaceDecl *D,
+                                      const ObjCImplementationDecl *Impl) {
+  ASTRecordLayoutBuilder Builder(Ctx);
+  
+  Builder.Layout(D, Impl);
+  
+  return new ASTRecordLayout(Builder.Size, Builder.Alignment,
+                             Builder.NextOffset,
                              Builder.FieldOffsets.data(), 
                              Builder.FieldOffsets.size());
 }
index a51c626e14c10773969baa42700cbcf77fa67f9e..473cb85659daf3f487723210784c55488317a5cf 100644 (file)
@@ -16,6 +16,8 @@ namespace clang {
   class ASTContext;
   class ASTRecordLayout;
   class FieldDecl;
+  class ObjCImplementationDecl;
+  class ObjCInterfaceDecl;
   class RecordDecl;
   
 class ASTRecordLayoutBuilder {
@@ -32,6 +34,9 @@ class ASTRecordLayoutBuilder {
   ASTRecordLayoutBuilder(ASTContext &Ctx);
   
   void Layout(const RecordDecl *D);
+  void Layout(const ObjCInterfaceDecl *D,
+              const ObjCImplementationDecl *Impl);
+
   void LayoutField(const FieldDecl *D);
   void FinishLayout();
   
@@ -42,7 +47,9 @@ class ASTRecordLayoutBuilder {
 public:
   static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx, 
                                               const RecordDecl *RD);
-  
+  static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
+                                              const ObjCInterfaceDecl *D,
+                                            const ObjCImplementationDecl *Impl);
 };
   
 } // end namespace clang