[cfe-commits] r104809 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp lib/Sema/SemaAttr.cpp test/Parser/pragma-options.c test/Sema/pragma-align-mac68k.c
Daniel Dunbar
daniel at zuster.org
Wed May 26 22:45:51 PDT 2010
Author: ddunbar
Date: Thu May 27 00:45:51 2010
New Revision: 104809
URL: http://llvm.org/viewvc/llvm-project?rev=104809&view=rev
Log:
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!
Added:
cfe/trunk/test/Sema/pragma-align-mac68k.c
Modified:
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/test/Parser/pragma-options.c
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=104809&r1=104808&r2=104809&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Thu May 27 00:45:51 2010
@@ -297,7 +297,11 @@
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 @@
/// DataSize - The data size of the record being laid out.
uint64_t DataSize;
- bool IsUnion;
-
uint64_t NonVirtualSize;
unsigned NonVirtualAlignment;
@@ -350,9 +352,10 @@
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 @@
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 @@
}
}
-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 @@
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::UpdateAlignment(unsigned NewAlignment) {
+ // The alignment is not modified when using 'mac68k' alignment.
+ if (IsMac68kAlign)
+ return;
+
if (NewAlignment <= Alignment)
return;
Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=104809&r1=104808&r2=104809&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Thu May 27 00:45:51 2010
@@ -25,6 +25,10 @@
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 @@
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 @@
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 @@
// 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])
Modified: cfe/trunk/test/Parser/pragma-options.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-options.c?rev=104809&r1=104808&r2=104809&view=diff
==============================================================================
--- cfe/trunk/test/Parser/pragma-options.c (original)
+++ cfe/trunk/test/Parser/pragma-options.c Thu May 27 00:45:51 2010
@@ -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
Added: cfe/trunk/test/Sema/pragma-align-mac68k.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/pragma-align-mac68k.c?rev=104809&view=auto
==============================================================================
--- cfe/trunk/test/Sema/pragma-align-mac68k.c (added)
+++ cfe/trunk/test/Sema/pragma-align-mac68k.c Thu May 27 00:45:51 2010
@@ -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];
More information about the cfe-commits
mailing list