[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