diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/TargetInfo.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 17 |
3 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 330258b025b..cb6449f9741 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -75,6 +75,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { RegParmMax = 0; SSERegParmMax = 0; HasAlignMac68kSupport = false; + EnforceBitfieldContainerAlignment = false; // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 047cf0d5b5c..3d6f4f95944 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -3983,6 +3983,9 @@ class ARMTargetInfo : public TargetInfo { ZeroLengthBitfieldBoundary = 0; + // Enforce the alignment of bitfield structs + EnforceBitfieldContainerAlignment = true; + // Thumb1 add sp, #imm requires the immediate value be multiple of 4, // so set preferred for small types to 32. if (T.isOSBinFormatMachO()) { @@ -4825,6 +4828,9 @@ public: UseBitFieldTypeAlignment = true; UseZeroLengthBitfieldAlignment = true; + // Enforce the alignment of bitfield structs + EnforceBitfieldContainerAlignment = true; + // AArch64 targets default to using the ARM C++ ABI. TheCXXABI.set(TargetCXXABI::GenericAArch64); } 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()) |