forked from OSchip/llvm-project
Sema: Add initial support for '#pragma options align=mac68k'.
- Docs are fairly sketchy, if someone wants to pore through gcc to look for holes I'd appreciate any failing test cases! llvm-svn: 104809
This commit is contained in:
parent
439edd1aea
commit
6da1098b4b
|
@ -297,7 +297,11 @@ class RecordLayoutBuilder {
|
|||
llvm::SmallVector<uint64_t, 16> FieldOffsets;
|
||||
|
||||
/// Packed - Whether the record is packed or not.
|
||||
bool Packed;
|
||||
unsigned Packed : 1;
|
||||
|
||||
unsigned IsUnion : 1;
|
||||
|
||||
unsigned IsMac68kAlign : 1;
|
||||
|
||||
/// UnfilledBitsInLastByte - If the last field laid out was a bitfield,
|
||||
/// this contains the number of bits in the last byte that can be used for
|
||||
|
@ -311,8 +315,6 @@ class RecordLayoutBuilder {
|
|||
/// DataSize - The data size of the record being laid out.
|
||||
uint64_t DataSize;
|
||||
|
||||
bool IsUnion;
|
||||
|
||||
uint64_t NonVirtualSize;
|
||||
unsigned NonVirtualAlignment;
|
||||
|
||||
|
@ -350,9 +352,10 @@ class RecordLayoutBuilder {
|
|||
|
||||
RecordLayoutBuilder(ASTContext &Context, EmptySubobjectMap *EmptySubobjects)
|
||||
: Context(Context), EmptySubobjects(EmptySubobjects), Size(0), Alignment(8),
|
||||
Packed(false), UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0),
|
||||
IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8), PrimaryBase(0),
|
||||
PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { }
|
||||
Packed(false), IsUnion(false), IsMac68kAlign(false),
|
||||
UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0),
|
||||
NonVirtualSize(0), NonVirtualAlignment(8), PrimaryBase(0),
|
||||
PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { }
|
||||
|
||||
void Layout(const RecordDecl *D);
|
||||
void Layout(const CXXRecordDecl *D);
|
||||
|
@ -423,7 +426,7 @@ class RecordLayoutBuilder {
|
|||
void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset);
|
||||
|
||||
/// InitializeLayout - Initialize record layout for the given record decl.
|
||||
void InitializeLayout(const RecordDecl *D);
|
||||
void InitializeLayout(const Decl *D);
|
||||
|
||||
/// FinishLayout - Finalize record layout. Adjust record size based on the
|
||||
/// alignment.
|
||||
|
@ -942,16 +945,27 @@ RecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD,
|
|||
}
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::InitializeLayout(const RecordDecl *D) {
|
||||
IsUnion = D->isUnion();
|
||||
void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
|
||||
if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
|
||||
IsUnion = RD->isUnion();
|
||||
|
||||
Packed = D->hasAttr<PackedAttr>();
|
||||
|
||||
if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>())
|
||||
MaxFieldAlignment = MFAA->getAlignment();
|
||||
// mac68k alignment supersedes maximum field alignment and attribute aligned,
|
||||
// and forces all structures to have 2-byte alignment. The IBM docs on it
|
||||
// allude to additional (more complicated) semantics, especially with regard
|
||||
// to bit-fields, but gcc appears not to follow that.
|
||||
if (D->hasAttr<AlignMac68kAttr>()) {
|
||||
IsMac68kAlign = true;
|
||||
MaxFieldAlignment = 2 * 8;
|
||||
Alignment = 2 * 8;
|
||||
} else {
|
||||
if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>())
|
||||
MaxFieldAlignment = MFAA->getAlignment();
|
||||
|
||||
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
|
||||
UpdateAlignment(AA->getMaxAlignment());
|
||||
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
|
||||
UpdateAlignment(AA->getMaxAlignment());
|
||||
}
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::Layout(const RecordDecl *D) {
|
||||
|
@ -1020,13 +1034,7 @@ void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
|
|||
DataSize = Size;
|
||||
}
|
||||
|
||||
Packed = D->hasAttr<PackedAttr>();
|
||||
|
||||
if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>())
|
||||
MaxFieldAlignment = MFAA->getAlignment();
|
||||
|
||||
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
|
||||
UpdateAlignment(AA->getMaxAlignment());
|
||||
InitializeLayout(D);
|
||||
|
||||
// Layout each ivar sequentially.
|
||||
llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
|
||||
|
@ -1239,6 +1247,10 @@ void RecordLayoutBuilder::FinishLayout() {
|
|||
}
|
||||
|
||||
void RecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
|
||||
// The alignment is not modified when using 'mac68k' alignment.
|
||||
if (IsMac68kAlign)
|
||||
return;
|
||||
|
||||
if (NewAlignment <= Alignment)
|
||||
return;
|
||||
|
||||
|
|
|
@ -25,6 +25,10 @@ using namespace clang;
|
|||
|
||||
namespace {
|
||||
struct PackStackEntry {
|
||||
// We just use a sentinel to represent when the stack is set to mac68k
|
||||
// alignment.
|
||||
static const unsigned kMac68kAlignmentSentinel = ~0U;
|
||||
|
||||
unsigned Alignment;
|
||||
IdentifierInfo *Name;
|
||||
};
|
||||
|
@ -102,8 +106,12 @@ void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
|
|||
PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext);
|
||||
|
||||
// Otherwise, check to see if we need a max field alignment attribute.
|
||||
if (unsigned Alignment = Stack->getAlignment())
|
||||
RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8));
|
||||
if (unsigned Alignment = Stack->getAlignment()) {
|
||||
if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
|
||||
RD->addAttr(::new (Context) AlignMac68kAttr());
|
||||
else
|
||||
RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8));
|
||||
}
|
||||
}
|
||||
|
||||
void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
|
||||
|
@ -139,11 +147,9 @@ void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
|
|||
if (!PP.getTargetInfo().hasAlignMac68kSupport()) {
|
||||
Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
|
||||
return;
|
||||
} else {
|
||||
// Otherwise, just warn about it for now.
|
||||
Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option)
|
||||
<< KindLoc;
|
||||
}
|
||||
Context->push(0);
|
||||
Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -195,7 +201,10 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
|
|||
// FIXME: This should come from the target.
|
||||
if (AlignmentVal == 0)
|
||||
AlignmentVal = 8;
|
||||
Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
|
||||
if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel)
|
||||
Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
|
||||
else
|
||||
Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
|
||||
break;
|
||||
|
||||
case Action::PPK_Push: // pack(push [, id] [, [n])
|
||||
|
|
|
@ -8,5 +8,5 @@
|
|||
|
||||
#pragma options align=natural
|
||||
#pragma options align=reset
|
||||
/* expected-warning {{unsupported alignment option}} */ #pragma options align=mac68k
|
||||
#pragma options align=mac68k
|
||||
/* expected-warning {{unsupported alignment option}} */ #pragma options align=power
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
// RUN: %clang-cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#pragma options align=mac68k
|
||||
|
||||
typedef float __attribute__((vector_size (8))) v2f_t;
|
||||
typedef float __attribute__((vector_size (16))) v4f_t;
|
||||
|
||||
extern int a0_0[__alignof(v2f_t) == 8 ? 1 : -1];
|
||||
extern int a0_1[__alignof(v4f_t) == 16 ? 1 : -1];
|
||||
|
||||
struct s1 {
|
||||
char f0;
|
||||
int f1;
|
||||
};
|
||||
extern int a1_0[offsetof(struct s1, f0) == 0 ? 1 : -1];
|
||||
extern int a1_1[offsetof(struct s1, f1) == 2 ? 1 : -1];
|
||||
extern int a1_2[sizeof(struct s1) == 6 ? 1 : -1];
|
||||
extern int a1_3[__alignof(struct s1) == 2 ? 1 : -1];
|
||||
|
||||
struct s2 {
|
||||
char f0;
|
||||
double f1;
|
||||
};
|
||||
extern int a2_0[offsetof(struct s2, f0) == 0 ? 1 : -1];
|
||||
extern int a2_1[offsetof(struct s2, f1) == 2 ? 1 : -1];
|
||||
extern int a2_2[sizeof(struct s2) == 10 ? 1 : -1];
|
||||
extern int a2_3[__alignof(struct s2) == 2 ? 1 : -1];
|
||||
|
||||
struct s3 {
|
||||
char f0;
|
||||
v4f_t f1;
|
||||
};
|
||||
extern int a3_0[offsetof(struct s3, f0) == 0 ? 1 : -1];
|
||||
extern int a3_1[offsetof(struct s3, f1) == 2 ? 1 : -1];
|
||||
extern int a3_2[sizeof(struct s3) == 18 ? 1 : -1];
|
||||
extern int a3_3[__alignof(struct s3) == 2 ? 1 : -1];
|
||||
|
||||
struct s4 {
|
||||
char f0;
|
||||
char f1;
|
||||
};
|
||||
extern int a4_0[offsetof(struct s4, f0) == 0 ? 1 : -1];
|
||||
extern int a4_1[offsetof(struct s4, f1) == 1 ? 1 : -1];
|
||||
extern int a4_2[sizeof(struct s4) == 2 ? 1 : -1];
|
||||
extern int a4_3[__alignof(struct s4) == 2 ? 1 : -1];
|
||||
|
||||
struct s5 {
|
||||
unsigned f0 : 9;
|
||||
unsigned f1 : 9;
|
||||
};
|
||||
extern int a5_0[sizeof(struct s5) == 4 ? 1 : -1];
|
||||
extern int a5_1[__alignof(struct s5) == 2 ? 1 : -1];
|
||||
|
||||
struct s6 {
|
||||
unsigned : 0;
|
||||
unsigned : 0;
|
||||
};
|
||||
extern int a6_0[sizeof(struct s6) == 0 ? 1 : -1];
|
||||
extern int a6_1[__alignof(struct s6) == 2 ? 1 : -1];
|
||||
|
||||
struct s7 {
|
||||
char : 1;
|
||||
unsigned : 1;
|
||||
};
|
||||
extern int a7_0[sizeof(struct s7) == 2 ? 1 : -1];
|
||||
extern int a7_1[__alignof(struct s7) == 2 ? 1 : -1];
|
||||
|
||||
struct s8 {
|
||||
char f0;
|
||||
unsigned : 1;
|
||||
};
|
||||
extern int a8_0[sizeof(struct s8) == 2 ? 1 : -1];
|
||||
extern int a8_1[__alignof(struct s8) == 2 ? 1 : -1];
|
||||
|
||||
struct s9 {
|
||||
char f0[3];
|
||||
unsigned : 0;
|
||||
char f1;
|
||||
};
|
||||
extern int a9_0[sizeof(struct s9) == 6 ? 1 : -1];
|
||||
extern int a9_1[__alignof(struct s9) == 2 ? 1 : -1];
|
||||
|
||||
struct s10 {
|
||||
char f0;
|
||||
};
|
||||
extern int a10_0[sizeof(struct s10) == 2 ? 1 : -1];
|
||||
extern int a10_1[__alignof(struct s10) == 2 ? 1 : -1];
|
||||
|
||||
struct s11 {
|
||||
char f0;
|
||||
v2f_t f1;
|
||||
};
|
||||
extern int a11_0[offsetof(struct s11, f0) == 0 ? 1 : -1];
|
||||
extern int a11_1[offsetof(struct s11, f1) == 2 ? 1 : -1];
|
||||
extern int a11_2[sizeof(struct s11) == 10 ? 1 : -1];
|
||||
extern int a11_3[__alignof(struct s11) == 2 ? 1 : -1];
|
Loading…
Reference in New Issue