summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorBradley Smith <bradley.smith@arm.com>2015-04-28 11:24:54 +0000
committerBradley Smith <bradley.smith@arm.com>2015-04-28 11:24:54 +0000
commitba945626b094899c7a4cae587398a69097da560c (patch)
tree8999ff7481a090b491d669dc6bbcaeee21b32aeb /clang/lib/CodeGen/CodeGenModule.cpp
parent86e0249235f15fae19709e21b1ae250fd1f20ca0 (diff)
downloadbcm5719-llvm-ba945626b094899c7a4cae587398a69097da560c.tar.gz
bcm5719-llvm-ba945626b094899c7a4cae587398a69097da560c.zip
[ARM/AArch64] Enforce alignment for bitfielded structs
When creating a global variable with a type of a struct with bitfields, we must forcibly set the alignment of the global from the RecordDecl. We must do this so that the proper bitfield alignment makes its way down to LLVM, since clang will mangle the bitfields into one large type. llvm-svn: 235976
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c517d17666d..861a6ee164e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1799,6 +1799,23 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
D->getType().isConstant(Context) &&
isExternallyVisible(D->getLinkageAndVisibility().getLinkage()))
GV->setSection(".cp.rodata");
+
+ // The ARM/AArch64 ABI expects structs with bitfields to respect the proper
+ // container alignment, hence we have to enfore this in the IR so as to
+ // work around clang combining bitfields into one large type.
+ if (getContext().getTargetInfo().enforceBitfieldContainerAlignment()) {
+ if (const auto *RT = D->getType()->getAs<RecordType>()) {
+ const RecordDecl *RD = RT->getDecl();
+
+ for (auto I = RD->field_begin(), End = RD->field_end(); I != End; ++I) {
+ if ((*I)->isBitField()) {
+ const ASTRecordLayout &Info = getContext().getASTRecordLayout(RD);
+ GV->setAlignment(Info.getAlignment().getQuantity());
+ break;
+ }
+ }
+ }
+ }
}
if (AddrSpace != Ty->getAddressSpace())
OpenPOWER on IntegriCloud