Check in  CGRecordLayoutBuilder which is a reimplementation of the record layout code. (Yay, no more packed structs unless absolutely necessary). We currently don't use the layouts being built but that will change when the new code is mature enough :)

llvm-svn: 76845
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.h b/clang/lib/CodeGen/CGRecordLayoutBuilder.h
new file mode 100644
index 0000000..ac2f53c
--- /dev/null
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.h
@@ -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