]> granicus.if.org Git - clang/commitdiff
Check in CGRecordLayoutBuilder which is a reimplementation of the record layout...
authorAnders Carlsson <andersca@mac.com>
Thu, 23 Jul 2009 03:17:50 +0000 (03:17 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 23 Jul 2009 03:17:50 +0000 (03:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76845 91177308-0d34-0410-b5e6-96231b3b80d8

clang.xcodeproj/project.pbxproj
lib/CodeGen/CGRecordLayoutBuilder.cpp [new file with mode: 0644]
lib/CodeGen/CGRecordLayoutBuilder.h [new file with mode: 0644]
lib/CodeGen/CodeGenTypes.cpp
lib/CodeGen/CodeGenTypes.h

index 24f704aee3fa518df8c0f599863498b40564b18a..137f5e442348092f699afbd394795af76a7e59d1 100644 (file)
@@ -43,6 +43,7 @@
                1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
                1ADF47AF0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */; };
                1AFEF4070F8A6B2300476F2B /* clang-cc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFEF4050F8A6B2300476F2B /* clang-cc.cpp */; };
+               1AFF8AE31012BFC900D248DA /* CGRecordLayoutBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */; };
                3507E4C20E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */; };
                352246E70F5C6BE000D0D279 /* HTMLDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352246E10F5C6BE000D0D279 /* HTMLDiagnostics.cpp */; };
                352246E80F5C6BE000D0D279 /* InitHeaderSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352246E20F5C6BE000D0D279 /* InitHeaderSearch.cpp */; };
                1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = lib/CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; tabWidth = 2; };
                1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateInstantiateDecl.cpp; path = lib/Sema/SemaTemplateInstantiateDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
                1AFEF4050F8A6B2300476F2B /* clang-cc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = "clang-cc.cpp"; path = "tools/clang-cc/clang-cc.cpp"; sourceTree = "<group>"; tabWidth = 2; };
+               1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGRecordLayoutBuilder.cpp; path = lib/CodeGen/CGRecordLayoutBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
+               1AFF8AE21012BFC900D248DA /* CGRecordLayoutBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGRecordLayoutBuilder.h; path = lib/CodeGen/CGRecordLayoutBuilder.h; sourceTree = "<group>"; tabWidth = 2; };
                3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckObjCInstMethSignature.cpp; path = lib/Analysis/CheckObjCInstMethSignature.cpp; sourceTree = "<group>"; };
                352246E10F5C6BE000D0D279 /* HTMLDiagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLDiagnostics.cpp; path = lib/Frontend/HTMLDiagnostics.cpp; sourceTree = "<group>"; };
                352246E20F5C6BE000D0D279 /* InitHeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InitHeaderSearch.cpp; path = lib/Frontend/InitHeaderSearch.cpp; sourceTree = "<group>"; };
                                DE38CD4E0D794CF900A273B6 /* CGObjCRuntime.h */,
                                DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */,
                                3552E7580E520DD7003A8CA5 /* CGObjCMac.cpp */,
+                               1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */,
+                               1AFF8AE21012BFC900D248DA /* CGRecordLayoutBuilder.h */,
                                DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
                                35475B230E7997680000BFE4 /* CGValue.h */,
                                DE928B800C0A615B00231DA4 /* CodeGenFunction.h */,
                                1A14D3A70FD78A3F00DA2835 /* DeclPrinter.cpp in Sources */,
                                DE37252E0FE481AD00CF2CC2 /* Builtins.cpp in Sources */,
                                1AA1D91810125DE30078DEBC /* RecordLayoutBuilder.cpp in Sources */,
+                               1AFF8AE31012BFC900D248DA /* CGRecordLayoutBuilder.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
new file mode 100644 (file)
index 0000000..6a95566
--- /dev/null
@@ -0,0 +1,272 @@
+//===--- CGRecordLayoutBuilder.cpp - Record builder helper ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a helper class used to build CGRecordLayout objects and LLVM types.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGRecordLayoutBuilder.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/RecordLayout.h"
+#include "CodeGenTypes.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Target/TargetData.h"
+
+
+using namespace clang;
+using namespace CodeGen;
+
+void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
+  if (const PackedAttr* PA = D->getAttr<PackedAttr>())
+    StructPacking = PA->getAlignment();
+
+  if (LayoutFields(D))
+    return;
+  
+  assert(!StructPacking && 
+         "FIXME: Were not able to lay out a struct with #pragma pack!");
+  
+  // We weren't able to layout the struct. Try again with a packed struct
+  StructPacking = 1;
+  AlignmentAsLLVMStruct = 1;
+  FieldTypes.clear();
+  FieldInfos.clear();
+  LLVMFields.clear();
+  LLVMBitFields.clear();
+  
+  LayoutFields(D);
+}
+
+void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
+                                           uint64_t FieldOffset) {
+  uint64_t FieldSize = 
+    D->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
+  
+  if (FieldSize == 0)
+    return;
+
+  uint64_t NextFieldOffset = getNextFieldOffsetInBytes() * 8;
+  unsigned NumBytesToAppend;
+  
+  if (FieldOffset < NextFieldOffset) {
+    assert(BitsAvailableInLastField && "Bitfield size mismatch!");
+    assert(!FieldInfos.empty() && "Field infos can't be empty!");
+    
+    // The bitfield begins in the previous bit-field.
+    NumBytesToAppend = 
+      llvm::RoundUpToAlignment(FieldSize - BitsAvailableInLastField, 8) / 8;
+  } else {
+    assert(FieldOffset % 8 == 0 && "Field offset not aligned correctly");
+
+    // Append padding if necessary.
+    AppendBytes((FieldOffset - NextFieldOffset) / 8);
+    
+    NumBytesToAppend = 
+      llvm::RoundUpToAlignment(FieldSize, 8) / 8;
+    
+    assert(NumBytesToAppend && "No bytes to append!");
+  }
+
+  const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());
+  uint64_t TypeSizeInBits = getTypeSizeInBytes(Ty) * 8;
+  
+  LLVMFields.push_back(LLVMFieldInfo(D, FieldOffset / TypeSizeInBits));
+  LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset % TypeSizeInBits, 
+                                           FieldSize));
+  
+  AppendBytes(NumBytesToAppend);
+  
+  if (!NumBytesToAppend)
+    BitsAvailableInLastField -= FieldSize;
+  else
+    BitsAvailableInLastField = NumBytesToAppend * 8 - FieldSize;
+}
+
+bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
+                                        uint64_t FieldOffset) {
+  unsigned FieldPacking = StructPacking;
+  
+  // FIXME: Should this override struct packing? Probably we want to
+  // take the minimum?
+  if (const PackedAttr *PA = D->getAttr<PackedAttr>())
+    FieldPacking = PA->getAlignment();
+
+  // If the field is packed, then we need a packed struct.
+  if (!StructPacking && FieldPacking)
+    return false;
+
+  if (D->isBitField()) {
+    // We must use packed structs for unnamed bit fields since they
+    // don't affect the struct alignment.
+    if (!StructPacking && !D->getDeclName())
+      return false;
+    
+    LayoutBitField(D, FieldOffset);
+    return true;
+  }
+  
+  const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());
+
+  // Check if the field is aligned.
+  if (const AlignedAttr *PA = D->getAttr<AlignedAttr>()) {
+    unsigned FieldAlign = PA->getAlignment();
+   
+    if (!StructPacking && getTypeAlignment(Ty) > FieldAlign)
+      return false;
+  }
+   
+  assert(FieldOffset % 8 == 0 && "FieldOffset is not on a byte boundary!");
+  
+  uint64_t FieldOffsetInBytes = FieldOffset / 8;
+  
+  // Append padding if necessary.
+  AppendPadding(FieldOffsetInBytes, Ty);
+  
+  uint64_t FieldSizeInBytes = getTypeSizeInBytes(Ty);
+
+  // Now append the field.
+  LLVMFields.push_back(LLVMFieldInfo(D, FieldTypes.size()));
+  AppendField(FieldOffsetInBytes, FieldSizeInBytes, Ty);
+  
+  return true;
+}
+
+bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
+  assert(!D->isUnion() && "Can't call LayoutFields on a union!");
+  
+  const ASTRecordLayout &Layout = 
+    Types.getContext().getASTRecordLayout(D);
+  
+  unsigned FieldNo = 0;
+  for (RecordDecl::field_iterator Field = D->field_begin(), 
+       FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+    if (!LayoutField(*Field, Layout.getFieldOffset(FieldNo))) {
+      assert(!StructPacking && 
+             "Could not layout fields even with a packed LLVM struct!");
+      return false;
+    }
+  }
+
+  // Append tail padding if necessary.
+  if (Layout.getSize() / 8 > getNextFieldOffsetInBytes())
+    AppendPadding(Layout.getSize() / 8, AlignmentAsLLVMStruct);
+  
+  return true;
+}
+
+void CGRecordLayoutBuilder::AppendField(uint64_t FieldOffsetInBytes, 
+                                        uint64_t FieldSizeInBytes,
+                                        const llvm::Type *FieldTy) {
+  AlignmentAsLLVMStruct = std::max(AlignmentAsLLVMStruct,
+                                   getTypeAlignment(FieldTy));
+                                   
+  FieldTypes.push_back(FieldTy);
+  FieldInfos.push_back(FieldInfo(FieldOffsetInBytes, FieldSizeInBytes));
+
+  BitsAvailableInLastField = 0;
+}
+
+void 
+CGRecordLayoutBuilder::AppendPadding(uint64_t FieldOffsetInBytes,
+                                     const llvm::Type *FieldTy) {
+  AppendPadding(FieldOffsetInBytes, getTypeAlignment(FieldTy));
+}
+
+void CGRecordLayoutBuilder::AppendPadding(uint64_t FieldOffsetInBytes, 
+                                          unsigned FieldAlignment) {
+  uint64_t NextFieldOffsetInBytes = getNextFieldOffsetInBytes();
+  assert(NextFieldOffsetInBytes <= FieldOffsetInBytes &&
+         "Incorrect field layout!");
+  
+  // Round up the field offset to the alignment of the field type.
+  uint64_t AlignedNextFieldOffsetInBytes = 
+    llvm::RoundUpToAlignment(NextFieldOffsetInBytes, FieldAlignment);
+
+  if (AlignedNextFieldOffsetInBytes < FieldOffsetInBytes) {
+    // Even with alignment, the field offset is not at the right place,
+    // insert padding.
+    uint64_t PaddingInBytes = FieldOffsetInBytes - NextFieldOffsetInBytes;
+
+    AppendBytes(PaddingInBytes);
+  }
+}
+
+void CGRecordLayoutBuilder::AppendBytes(uint64_t NumBytes) {
+  if (NumBytes == 0)
+    return;
+  
+  const llvm::Type *Ty = llvm::Type::Int8Ty;
+  if (NumBytes > 1) {
+    // FIXME: Use a VMContext.
+    Ty = llvm::ArrayType::get(Ty, NumBytes);
+  }
+  
+  // Append the padding field
+  AppendField(getNextFieldOffsetInBytes(), NumBytes, Ty);
+}
+
+uint64_t CGRecordLayoutBuilder::getNextFieldOffsetInBytes() const {
+  if (FieldInfos.empty())
+    return 0;
+  
+  const FieldInfo &LastInfo = FieldInfos.back();
+  return LastInfo.OffsetInBytes + LastInfo.SizeInBytes;
+}
+
+unsigned CGRecordLayoutBuilder::getTypeAlignment(const llvm::Type *Ty) const {
+  if (StructPacking) {
+    assert(StructPacking == 1 && "FIXME: What if StructPacking is not 1 here");
+    return 1;
+  }
+  
+  return Types.getTargetData().getABITypeAlignment(Ty);
+}
+
+uint64_t CGRecordLayoutBuilder::getTypeSizeInBytes(const llvm::Type *Ty) const {
+  return Types.getTargetData().getTypeAllocSize(Ty);
+}
+
+CGRecordLayout *
+CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types,
+                                     const RecordDecl *D) {
+  CGRecordLayoutBuilder Builder(Types);
+  
+  if (D->isUnion())
+    return 0;
+
+  Builder.Layout(D);
+  
+  // FIXME: Once this works well enough, enable it.
+  return 0;
+  
+  // FIXME: Use a VMContext.
+  const llvm::Type *Ty = llvm::StructType::get(Builder.FieldTypes,
+                                               Builder.StructPacking);
+  
+  // Add all the field numbers.
+  for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i) {
+    const FieldDecl *FD = Builder.LLVMFields[i].first;
+    unsigned FieldNo = Builder.LLVMFields[i].second;
+
+    Types.addFieldInfo(FD, FieldNo);
+  }
+
+  // Add bitfield info.
+  for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i) {
+    const LLVMBitFieldInfo &Info = Builder.LLVMBitFields[i];
+    
+    Types.addBitFieldInfo(Info.FD, Info.Start, Info.Size);
+  }
+  
+  return new CGRecordLayout(Ty, llvm::SmallSet<unsigned, 8>());
+}
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.h b/lib/CodeGen/CGRecordLayoutBuilder.h
new file mode 100644 (file)
index 0000000..ac2f53c
--- /dev/null
@@ -0,0 +1,128 @@
+//===--- CGRecordLayoutBuilder.h - Record builder helper --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a helper class used to build CGRecordLayout objects and LLVM types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
+#define CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+  class Type;
+}
+
+namespace clang {
+  class FieldDecl;
+  class RecordDecl;
+  
+namespace CodeGen {
+  class CGRecordLayout;
+  class CodeGenTypes;
+
+class CGRecordLayoutBuilder {  
+  CodeGenTypes &Types;
+  
+  /// StructPacking - Will be 0 if this struct is not packed. If it is packed,
+  /// it will have the packing alignment in bits.
+  /// 
+  unsigned StructPacking;
+
+  /// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
+  /// LLVM types.
+  unsigned AlignmentAsLLVMStruct;
+  
+  /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
+  /// this will have the number of bits still available in the field.
+  char BitsAvailableInLastField;
+  
+  /// FieldTypes - Holds the LLVM types that the struct is created from.
+  std::vector<const llvm::Type *> FieldTypes;
+  
+  /// FieldInfo - Holds size and offset information about a field.
+  /// FIXME: I think we can get rid of this.
+  struct FieldInfo {
+    FieldInfo(uint64_t OffsetInBytes, uint64_t SizeInBytes)
+      : OffsetInBytes(OffsetInBytes), SizeInBytes(SizeInBytes) { }
+    
+    const uint64_t OffsetInBytes;
+    const uint64_t SizeInBytes;
+  };
+  llvm::SmallVector<FieldInfo, 16> FieldInfos;
+
+  /// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
+  typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
+  llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
+
+  /// LLVMBitFieldInfo - Holds location and size information about a bit field.
+  struct LLVMBitFieldInfo {
+    LLVMBitFieldInfo(const FieldDecl *FD, unsigned Start, unsigned Size)
+      : FD(FD), Start(Start), Size(Size) { }
+    
+    const FieldDecl *FD;
+    
+    unsigned Start;
+    unsigned Size;
+  };
+  llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
+  
+  CGRecordLayoutBuilder(CodeGenTypes &Types) 
+    : Types(Types), StructPacking(0), AlignmentAsLLVMStruct(1)
+    , BitsAvailableInLastField(0) { }
+
+  /// Layout - Will layout a RecordDecl.
+  void Layout(const RecordDecl *D);
+
+  /// LayoutField - try to layout all fields in the record decl.
+  /// Returns false if the operation failed because the struct is not packed.
+  bool LayoutFields(const RecordDecl *D);
+  
+  /// LayoutField - layout a single field. Returns false if the operation failed
+  /// because the current struct is not packed.
+  bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
+  
+  /// LayoutBitField - layout a single bit field.
+  void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
+
+  /// AppendField - Appends a field with the given offset size and type.
+  void AppendField(uint64_t FieldOffsetInBytes, uint64_t FieldSizeInBytes,
+                   const llvm::Type *FieldTy);
+
+  /// AppendPadding - Appends enough padding bytes so that the total struct
+  /// size matches the alignment of the passed in type.
+  void AppendPadding(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
+
+  /// AppendPadding - Appends enough padding bytes so that the total
+  /// struct size is a multiple of the field alignment.
+  void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
+  
+  /// AppendBytes - Append a given number of bytes to the record.
+  void AppendBytes(uint64_t NumBytes);
+
+  /// getNextFieldOffsetInBytes - returns where the next field offset is.
+  uint64_t getNextFieldOffsetInBytes() const;
+  
+  unsigned getTypeAlignment(const llvm::Type *Ty) const;
+  uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;
+
+public:
+  /// ComputeLayout - Return the right record layout for a given record decl.
+  static CGRecordLayout *ComputeLayout(CodeGenTypes &Types, 
+                                       const RecordDecl *D);
+};
+  
+} // end namespace CodeGen
+} // end namespace clang
+                                             
+
+#endif 
index 41d2ba24fe3ddc2a0b530abf930718b8e1fef28e..59463fa24ffe7a2f98b8109b45104544fd0b2ec8 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/Target/TargetData.h"
 
 #include "CGCall.h"
+#include "CGRecordLayoutBuilder.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -456,21 +457,30 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
     ResultType = llvm::StructType::get(std::vector<const llvm::Type*>());
   } else {
     // Layout fields.
-    RecordOrganizer RO(*this, *RD);
+    CGRecordLayout *Layout = 
+      CGRecordLayoutBuilder::ComputeLayout(*this, RD);
     
-    if (TD->isStruct() || TD->isClass())
-      RO.layoutStructFields(Context.getASTRecordLayout(RD));
-    else {
-      assert(TD->isUnion() && "unknown tag decl kind!");
-      RO.layoutUnionFields(Context.getASTRecordLayout(RD));
+    if (!Layout) {
+      // Layout fields.
+      RecordOrganizer RO(*this, *RD);
+
+      if (TD->isStruct() || TD->isClass())
+        RO.layoutStructFields(Context.getASTRecordLayout(RD));
+      else {
+        assert(TD->isUnion() && "unknown tag decl kind!");
+        RO.layoutUnionFields(Context.getASTRecordLayout(RD));
+      }
+      
+      Layout = new CGRecordLayout(RO.getLLVMType(), 
+                                  RO.getPaddingFields());
     }
     
     // Get llvm::StructType.
     const Type *Key = 
       Context.getTagDeclType(const_cast<TagDecl*>(TD)).getTypePtr();
-    CGRecordLayouts[Key] = new CGRecordLayout(RO.getLLVMType(), 
-                                              RO.getPaddingFields());
-    ResultType = RO.getLLVMType();
+    
+    CGRecordLayouts[Key] = Layout;
+    ResultType = Layout->getLLVMType();
   }
   
   // Refine our Opaque type to ResultType.  This can invalidate ResultType, so
index b72d8e92013aec8dc9c3ce6ab909324b63df2b06..925b933fca01c4e4e266c59b6830d2f7f9913b9b 100644 (file)
@@ -52,14 +52,15 @@ namespace CodeGen {
   class CGRecordLayout {
     CGRecordLayout(); // DO NOT IMPLEMENT
   public:
-    CGRecordLayout(llvm::Type *T, llvm::SmallSet<unsigned, 8> &PF) 
+    CGRecordLayout(const llvm::Type *T, 
+                   const llvm::SmallSet<unsigned, 8> &PF) 
       : STy(T), PaddingFields(PF) {
       // FIXME : Collect info about fields that requires adjustments 
       // (i.e. fields that do not directly map to llvm struct fields.)
     }
 
     /// getLLVMType - Return llvm type associated with this record.
-    llvm::Type *getLLVMType() const {
+    const llvm::Type *getLLVMType() const {
       return STy;
     }
 
@@ -72,7 +73,7 @@ namespace CodeGen {
     }
 
   private:
-    llvm::Type *STy;
+    const llvm::Type *STy;
     llvm::SmallSet<unsigned, 8> PaddingFields;
   };