[cfe-commits] r130451 - in /cfe/trunk: lib/AST/Decl.cpp lib/CodeGen/CGExprConstant.cpp test/CodeGen/ms_struct-bitfield-init.c
Fariborz Jahanian
fjahanian at apple.com
Thu Apr 28 15:49:46 PDT 2011
Author: fjahanian
Date: Thu Apr 28 17:49:46 2011
New Revision: 130451
URL: http://llvm.org/viewvc/llvm-project?rev=130451&view=rev
Log:
ms_struct patch for initialization and field access irgen.
// rdar://8823265 - wip.
Added:
cfe/trunk/test/CodeGen/ms_struct-bitfield-init.c
Modified:
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=130451&r1=130450&r2=130451&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu Apr 28 17:49:46 2011
@@ -2047,13 +2047,24 @@
if (CachedFieldIndex) return CachedFieldIndex - 1;
unsigned index = 0;
- RecordDecl::field_iterator
- i = getParent()->field_begin(), e = getParent()->field_end();
+ const RecordDecl *RD = getParent();
+ const FieldDecl *LastFD = 0;
+ bool IsMsStruct = RD->hasAttr<MsStructAttr>();
+
+ RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
while (true) {
assert(i != e && "failed to find field in parent!");
if (*i == this)
break;
+ if (IsMsStruct) {
+ // Zero-length bitfields following non-bitfield members are ignored.
+ if (getASTContext().ZeroBitfieldFollowsNonBitfield((*i), LastFD)) {
+ ++i;
+ continue;
+ }
+ LastFD = (*i);
+ }
++i;
++index;
}
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=130451&r1=130450&r2=130451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Thu Apr 28 17:49:46 2011
@@ -344,16 +344,30 @@
unsigned FieldNo = 0;
unsigned ElementNo = 0;
+ const FieldDecl *LastFD = 0;
+ bool IsMsStruct = RD->hasAttr<MsStructAttr>();
+
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+ if (IsMsStruct) {
+ // Zero-length bitfields following non-bitfield members are
+ // ignored:
+ if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((*Field), LastFD)) {
+ --FieldNo;
+ continue;
+ }
+ LastFD = (*Field);
+ }
// If this is a union, skip all the fields that aren't being initialized.
if (RD->isUnion() && ILE->getInitializedFieldInUnion() != *Field)
continue;
// Don't emit anonymous bitfields, they just affect layout.
- if (Field->isBitField() && !Field->getIdentifier())
+ if (Field->isBitField() && !Field->getIdentifier()) {
+ LastFD = (*Field);
continue;
+ }
// Get the initializer. A struct can include fields without initializers,
// we just use explicit null values for them.
Added: cfe/trunk/test/CodeGen/ms_struct-bitfield-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms_struct-bitfield-init.c?rev=130451&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/ms_struct-bitfield-init.c (added)
+++ cfe/trunk/test/CodeGen/ms_struct-bitfield-init.c Thu Apr 28 17:49:46 2011
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-darwin9 %s
+// rdar://8823265
+
+extern void abort(void);
+#define ATTR __attribute__((__ms_struct__))
+
+struct
+{
+ char foo;
+ long : 0;
+ char : 0;
+ int : 0;
+ char bar;
+} ATTR t1 = {'a', 'b'};
+
+struct
+{
+ char bar0;
+ long : 0;
+ int : 0;
+ char bar1;
+ char bar2;
+ long : 0;
+ char bar3;
+ char bar4;
+ char : 0;
+ char bar5;
+ char bar6;
+ char : 0;
+ char bar7;
+ char bar8;
+} ATTR t2 = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'};
+
+struct {
+ int : 0;
+ int i1;
+ int : 0;
+ int i2;
+ int : 0;
+ int i3;
+ int : 0;
+ int i4;
+} t3 = {1,2,3,4};
+
+int main() {
+ if (sizeof(t1) != 2)
+ abort();
+ if (t1.foo != 'a')
+ abort();
+ if (t1.bar != 'b')
+ abort();
+ t1.foo = 'c';
+ t1.bar = 'd';
+ if (t1.foo != 'c')
+ abort();
+ if (t1.bar != 'd')
+ abort();
+ if (sizeof(t2) != 9)
+ abort();
+ if (t2.bar0 != 'a' || t2.bar8 != 'i')
+ abort();
+ if (sizeof(t3) != 16)
+ abort();
+ if (t3.i1 != 1 || t3.i4 != 4)
+ abort();
+ return 0;
+}
+
More information about the cfe-commits
mailing list