[cfe-commits] r76969 - in /cfe/trunk/lib/CodeGen: CGExprConstant.cpp CGRecordLayoutBuilder.cpp

Anders Carlsson andersca at mac.com
Fri Jul 24 08:21:09 PDT 2009


Author: andersca
Date: Fri Jul 24 10:20:52 2009
New Revision: 76969

URL: http://llvm.org/viewvc/llvm-project?rev=76969&view=rev
Log:
Check in a half finished new constant struct builder (Obviously not used yet).

Modified:
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=76969&r1=76968&r2=76969&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Fri Jul 24 10:20:52 2009
@@ -16,6 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/Builtins.h"
 #include "llvm/Constants.h"
@@ -27,6 +28,149 @@
 using namespace CodeGen;
 
 namespace  {
+
+class VISIBILITY_HIDDEN ConstStructBuilder {
+  CodeGenModule &CGM;
+  CodeGenFunction *CGF;
+
+  bool Packed;  
+  unsigned NextFieldOffsetInBytes;
+  
+  std::vector<llvm::Constant *> Elements;
+
+  ConstStructBuilder(CodeGenModule &CGM, CodeGenFunction *CGF)
+    : CGM(CGM), CGF(CGF), Packed(false), NextFieldOffsetInBytes(0) { }
+
+  bool AppendField(const FieldDecl *Field, uint64_t FieldOffset, 
+                   const Expr *InitExpr) {
+    uint64_t FieldOffsetInBytes = FieldOffset / 8;
+    
+    assert(NextFieldOffsetInBytes <= FieldOffsetInBytes 
+           && "Field offset mismatch!");
+    
+    // Emit the field.
+    llvm::Constant *C = CGM.EmitConstantExpr(InitExpr, Field->getType(), CGF);
+    if (!C)
+      return false;
+
+    unsigned FieldAlignment = getAlignment(C);
+    
+    // Round up the field offset to the alignment of the field type.
+    uint64_t AlignedNextFieldOffsetInBytes = 
+      llvm::RoundUpToAlignment(NextFieldOffsetInBytes, FieldAlignment);
+    
+    if (AlignedNextFieldOffsetInBytes > FieldOffsetInBytes) {
+      // FIXME: Must convert the struct to a packed struct.
+      return false;
+    }
+
+    if (AlignedNextFieldOffsetInBytes < FieldOffsetInBytes) {
+      // We need to append padding.
+      AppendPadding(FieldOffsetInBytes - AlignedNextFieldOffsetInBytes);
+      
+      assert(NextFieldOffsetInBytes == FieldOffsetInBytes &&
+             "Did not add enough padding!");
+      
+      AlignedNextFieldOffsetInBytes = NextFieldOffsetInBytes;
+    }
+    
+    // Add the field.
+    Elements.push_back(C);
+    NextFieldOffsetInBytes = AlignedNextFieldOffsetInBytes + getSizeInBytes(C);
+
+    return true;
+  }
+  
+  void AppendPadding(uint64_t NumBytes) {
+    if (!NumBytes)
+      return;
+
+    const llvm::Type *Ty = llvm::Type::Int8Ty;
+    if (NumBytes > 1) 
+      Ty = CGM.getLLVMContext().getArrayType(Ty, NumBytes);
+
+    llvm::Constant *C = CGM.getLLVMContext().getNullValue(Ty);
+    Elements.push_back(C);
+    assert(getAlignment(C) == 1 && "Padding must have 1 byte alignment!");
+    
+    NextFieldOffsetInBytes += getSizeInBytes(C);
+  }
+
+  void AppendTailPadding(uint64_t RecordSize) {
+    assert(RecordSize % 8 == 0 && "Invalid record size!");
+
+    uint64_t RecordSizeInBytes = RecordSize / 8;
+    assert(NextFieldOffsetInBytes <= RecordSizeInBytes && "Size mismatch!");
+    
+    unsigned NumPadBytes = RecordSizeInBytes - NextFieldOffsetInBytes;
+    AppendPadding(NumPadBytes);
+  }
+  
+  bool Build(const InitListExpr *ILE) {
+    RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
+    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+    
+    unsigned FieldNo = 0;
+    unsigned ElementNo = 0;
+    for (RecordDecl::field_iterator Field = RD->field_begin(), 
+         FieldEnd = RD->field_end(); 
+         ElementNo < ILE->getNumInits() && Field != FieldEnd;
+         ++Field, ++FieldNo) {
+      if (Field->isBitField()) {
+        if (!Field->getIdentifier())
+          continue;
+        
+        // FIXME: Bitfield support.
+        return false;
+      } else {
+        if (!AppendField(*Field, Layout.getFieldOffset(FieldNo),
+                         ILE->getInit(ElementNo)))
+          return false;
+      }
+      
+      ElementNo++;
+    }
+    
+    // Append tail padding if necessary.
+    AppendTailPadding(Layout.getSize());
+    
+    assert(Layout.getSize() / 8 == NextFieldOffsetInBytes && 
+           "Tail padding mismatch!");
+
+    return true;
+  }
+  
+  unsigned getAlignment(const llvm::Constant *C) const {
+    if (Packed)
+      return 1;
+    
+    return CGM.getTargetData().getABITypeAlignment(C->getType());
+  }
+  
+  uint64_t getSizeInBytes(const llvm::Constant *C) const {
+    return CGM.getTargetData().getTypeAllocSize(C->getType());
+  }
+  
+public:
+  static llvm::Constant *BuildStruct(CodeGenModule &CGM, CodeGenFunction *CGF,
+                                     const InitListExpr *ILE) {
+    ConstStructBuilder Builder(CGM, CGF);
+    
+    // FIXME: Use this when it works well enough.
+    return 0;
+    
+    if (!Builder.Build(ILE))
+      return 0;
+    
+    llvm::Constant *Result = 
+      CGM.getLLVMContext().getConstantStruct(Builder.Elements, Builder.Packed);
+
+    assert(Builder.NextFieldOffsetInBytes == Builder.getSizeInBytes(Result));
+
+    return 0;
+  }
+};
+  
 class VISIBILITY_HIDDEN ConstExprEmitter : 
   public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
   CodeGenModule &CGM;
@@ -186,6 +330,8 @@
   }
 
   llvm::Constant *EmitStructInitialization(InitListExpr *ILE) {
+    ConstStructBuilder::BuildStruct(CGM, CGF, ILE);
+    
     const llvm::StructType *SType =
         cast<llvm::StructType>(ConvertType(ILE->getType()));
     RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();

Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=76969&r1=76968&r2=76969&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Fri Jul 24 10:20:52 2009
@@ -208,7 +208,7 @@
 
   // Append tail padding if necessary.
   if (Layout.getSize() / 8 > getNextFieldOffsetInBytes())
-    AppendPadding(Layout.getSize() / 8, AlignmentAsLLVMStruct);
+    AppendPadding(getNextFieldOffsetInBytes(), AlignmentAsLLVMStruct);
   
   return true;
 }
@@ -290,7 +290,7 @@
   CGRecordLayoutBuilder Builder(Types);
   
   Builder.Layout(D);
-  
+
   // FIXME: Once this works well enough, enable it.
   return 0;
   





More information about the cfe-commits mailing list