diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 48e3451f25770b041226c6f2dfc34e1fe75cded2..b6f8c735cc83429384fb102a1c619a4524dc7732 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -1691,6 +1691,10 @@ public: /// beneficial for performance to overalign a data type. unsigned getPreferredTypeAlign(const Type *T) const; + /// \brief Return the default alignment for __attribute__((aligned)) on + /// this target, to be used if no alignment value is specified. + unsigned getTargetDefaultAlignForAttributeAligned(void) const; + /// \brief Return the alignment in bits that should be given to a /// global variable with type \p T. unsigned getAlignOfGlobalVar(QualType T) const; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 1d6485a56e9340f2e4382ce6a50132963792ff1b..8406205c7fd9ddc4422c3aee0b8c0f35476414ee 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -66,6 +66,7 @@ protected: unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; unsigned char SuitableAlign; + unsigned char DefaultAlignForAttributeAligned; unsigned char MinGlobalAlign; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short MaxVectorAlign; @@ -314,6 +315,12 @@ public: /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } + /// \brief Return the default alignment for __attribute__((aligned)) on + /// this target, to be used if no alignment value is specified. + unsigned getDefaultAlignForAttributeAligned() const { + return DefaultAlignForAttributeAligned; + } + /// getMinGlobalAlign - Return the minimum alignment of a global variable, /// unless its alignment is explicitly reduced via attributes. unsigned getMinGlobalAlign() const { return MinGlobalAlign; } diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c54a006d26a765bd30ccdffc47a811361c4d47b0..4d6a51bf1924196a7d189aaf6ff137c66bd8ee87 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1817,6 +1817,13 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { return ABIAlign; } +/// getTargetDefaultAlignForAttributeAligned - Return the default alignment +/// for __attribute__((aligned)) on this target, to be used if no alignment +/// value is specified. +unsigned ASTContext::getTargetDefaultAlignForAttributeAligned(void) const { + return getTargetInfo().getDefaultAlignForAttributeAligned(); +} + /// getAlignOfGlobalVar - Return the alignment in bits that should be given /// to a global variable of the specified type. unsigned ASTContext::getAlignOfGlobalVar(QualType T) const { diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 871bbd5ef43f9e13bda6af5b93037bfe5b8ffc8a..330258b025b5f5c9d11cda6ad45c523378dc4f79 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -36,6 +36,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { LongWidth = LongAlign = 32; LongLongWidth = LongLongAlign = 64; SuitableAlign = 64; + DefaultAlignForAttributeAligned = 128; MinGlobalAlign = 0; HalfWidth = 16; HalfAlign = 16; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 1f81bcd46d4fd0a9c16c8bde06a111becfe2fbaa..047cf0d5b5c04686940bfd8c4bb53a2ebb01d200 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -5521,6 +5521,7 @@ public: LongDoubleWidth = 128; LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEquad; + DefaultAlignForAttributeAligned = 64; MinGlobalAlign = 16; DescriptionString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; diff --git a/test/Sema/struct-packed-align.c b/test/Sema/struct-packed-align.c index 291de6762cd18354152c518b5b8d25de2afba121..417c30308ca3b0d6f268518d4c9f5a5d079c2458 100644 --- a/test/Sema/struct-packed-align.c +++ b/test/Sema/struct-packed-align.c @@ -55,13 +55,16 @@ struct __attribute__((aligned(8))) as1 { extern int e1[sizeof(struct as1) == 8 ? 1 : -1]; extern int e2[__alignof(struct as1) == 8 ? 1 : -1]; -// FIXME: Will need to force arch once max usable alignment isn't hard -// coded. struct __attribute__((aligned)) as1_2 { char c; }; +#ifdef __s390x__ +extern int e1_2[sizeof(struct as1_2) == 8 ? 1 : -1]; +extern int e2_2[__alignof(struct as1_2) == 8 ? 1 : -1]; +#else extern int e1_2[sizeof(struct as1_2) == 16 ? 1 : -1]; extern int e2_2[__alignof(struct as1_2) == 16 ? 1 : -1]; +#endif struct as2 { char c; diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index c1d1a1dbe6d40ba328fd092c46ddf5b760634305..58857b91a9aa7de71a9bec8b65e0e274654cd1cc 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -413,15 +413,14 @@ namespace { // FIXME: Do not do the calculation here // FIXME: Handle types correctly // A null pointer means maximum alignment - // FIXME: Load the platform-specific maximum alignment, rather than - // 16, the x86 max. OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName() << "(ASTContext &Ctx) const {\n"; OS << " assert(!is" << getUpperName() << "Dependent());\n"; OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " return (" << getLowerName() << "Expr ? " << getLowerName() - << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)" - << "* Ctx.getCharWidth();\n"; + OS << " return " << getLowerName() << "Expr ? " << getLowerName() + << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue()" + << " * Ctx.getCharWidth() : " + << "Ctx.getTargetDefaultAlignForAttributeAligned();\n"; OS << " else\n"; OS << " return 0; // FIXME\n"; OS << "}\n";