summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprConstant.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-07-25 01:40:29 +0000
committerAnders Carlsson <andersca@mac.com>2009-07-25 01:40:29 +0000
commit3b484b928daea1b80ad8f79dd7bef2445cf883e4 (patch)
tree486fa566ab47c37e91b20585a19caafd5dc29643 /clang/lib/CodeGen/CGExprConstant.cpp
parentc1a5cfa9a024ed14f418e1d7c660ba96fd34d6b5 (diff)
downloadbcm5719-llvm-3b484b928daea1b80ad8f79dd7bef2445cf883e4.tar.gz
bcm5719-llvm-3b484b928daea1b80ad8f79dd7bef2445cf883e4.zip
More work on the constant struct builder. We can now convert the struct to a packed struct when necessary.
llvm-svn: 77038
Diffstat (limited to 'clang/lib/CodeGen/CGExprConstant.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp43
1 files changed, 40 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 84e9283cadb..db34fdee0c3 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -61,13 +61,50 @@ class VISIBILITY_HIDDEN ConstStructBuilder {
llvm::RoundUpToAlignment(NextFieldOffsetInBytes, FieldAlignment);
if (AlignedNextFieldOffsetInBytes > FieldOffsetInBytes) {
- // FIXME: Must convert the struct to a packed struct.
- return false;
+ std::vector<llvm::Constant *> PackedElements;
+
+ assert(!Packed && "Alignment is wrong even with a packed struct!");
+
+ // Convert the struct to a packed struct.
+ uint64_t ElementOffsetInBytes = 0;
+
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+ llvm::Constant *C = Elements[i];
+
+ unsigned ElementAlign =
+ CGM.getTargetData().getABITypeAlignment(C->getType());
+ uint64_t AlignedElementOffsetInBytes =
+ llvm::RoundUpToAlignment(ElementOffsetInBytes, ElementAlign);
+
+ if (AlignedElementOffsetInBytes > ElementOffsetInBytes) {
+ // We need some padding.
+ uint64_t NumBytes =
+ AlignedElementOffsetInBytes - ElementOffsetInBytes;
+
+ const llvm::Type *Ty = llvm::Type::Int8Ty;
+ if (NumBytes > 1)
+ Ty = CGM.getLLVMContext().getArrayType(Ty, NumBytes);
+
+ llvm::Constant *Padding = CGM.getLLVMContext().getNullValue(Ty);
+ PackedElements.push_back(Padding);
+ ElementOffsetInBytes += getSizeInBytes(Padding);
+ }
+
+ PackedElements.push_back(C);
+ ElementOffsetInBytes += getSizeInBytes(C);
+ }
+
+ assert(ElementOffsetInBytes == NextFieldOffsetInBytes &&
+ "Packing the struct changed its size!");
+
+ Elements = PackedElements;
+ Packed = true;
+ AlignedNextFieldOffsetInBytes = NextFieldOffsetInBytes;
}
if (AlignedNextFieldOffsetInBytes < FieldOffsetInBytes) {
// We need to append padding.
- AppendPadding(FieldOffsetInBytes - AlignedNextFieldOffsetInBytes);
+ AppendPadding(FieldOffsetInBytes - NextFieldOffsetInBytes);
assert(NextFieldOffsetInBytes == FieldOffsetInBytes &&
"Did not add enough padding!");
OpenPOWER on IntegriCloud