]> granicus.if.org Git - clang/commitdiff
Make -mms-bitfields behave consistently.
authorEli Friedman <eli.friedman@gmail.com>
Fri, 12 Oct 2012 23:29:20 +0000 (23:29 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Fri, 12 Oct 2012 23:29:20 +0000 (23:29 +0000)
Patch by Jeremiah Zanin.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165849 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/AST/Decl.cpp
lib/AST/RecordLayoutBuilder.cpp
lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGRecordLayoutBuilder.cpp
lib/Sema/SemaDeclAttr.cpp
test/Sema/mms-bitfields.c [new file with mode: 0644]
test/Sema/pragma-ms_struct.c

index 835961f798f63285f83bc49829f6e3e1fda4ad26..41f4d5cac2626b964a04663ac70bc6530e2cf1f9 100644 (file)
@@ -3015,6 +3015,11 @@ public:
     return K >= firstRecord && K <= lastRecord;
   }
 
+  /// isMsStrust - Get whether or not this is an ms_struct which can
+  /// be turned on with an attribute, pragma, or -mms-bitfields
+  /// commandline option.
+  bool isMsStruct(const ASTContext &C) const;
+
 private:
   /// \brief Deserialize just the fields.
   void LoadFieldsFromExternalStorage() const;
index fea81cf2c4516b94f52c7c3984469cb74ef2a262..442deca11be0c72a8de77307cc7d5afbfbf7483f 100644 (file)
@@ -2517,7 +2517,7 @@ unsigned FieldDecl::getFieldIndex() const {
   unsigned Index = 0;
   const RecordDecl *RD = getParent();
   const FieldDecl *LastFD = 0;
-  bool IsMsStruct = RD->hasAttr<MsStructAttr>();
+  bool IsMsStruct = RD->isMsStruct(getASTContext());
 
   for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
        I != E; ++I, ++Index) {
@@ -2765,6 +2765,13 @@ void RecordDecl::completeDefinition() {
   TagDecl::completeDefinition();
 }
 
+/// isMsStruct - Get whether or not this record uses ms_struct layout.
+/// This which can be turned on with an attribute, pragma, or the
+/// -mms-bitfields command-line option.
+bool RecordDecl::isMsStruct(const ASTContext &C) const {
+  return hasAttr<MsStructAttr>() || C.getLangOpts().MSBitfields == 1;
+}
+
 static bool isFieldOrIndirectField(Decl::Kind K) {
   return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K);
 }
index fc7586cffd681335df1ef3e01c1f92291a75e626..2bdc1e14e67bc5ff7c182757a05ba7d97c1a3881 100644 (file)
@@ -1574,12 +1574,12 @@ CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
 }
 
 void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
-  if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
+  if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
     IsUnion = RD->isUnion();
+    IsMsStruct = RD->isMsStruct(Context);
+  }
 
-  Packed = D->hasAttr<PackedAttr>();
-  
-  IsMsStruct = D->hasAttr<MsStructAttr>();
+  Packed = D->hasAttr<PackedAttr>();  
 
   // Honor the default struct packing maximum alignment flag.
   if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct) {
@@ -2085,7 +2085,7 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D) {
       ZeroLengthBitfield = 0;
     }
 
-    if (Context.getLangOpts().MSBitfields || IsMsStruct) {
+    if (IsMsStruct) {
       // If MS bitfield layout is required, figure out what type is being
       // laid out and align the field to the width of that type.
       
index e263a44f2df752b867fd2f188fba025536dbbd3c..402a945e4e1aa2fb38f99325039b4767f50a51e0 100644 (file)
@@ -824,7 +824,7 @@ CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit,
       }
     }
   } else {
-    bool IsMsStruct = record->hasAttr<MsStructAttr>();
+    bool IsMsStruct = record->isMsStruct(CGM.getContext());
     const FieldDecl *LastFD = 0;
     for (RecordDecl::field_iterator I = record->field_begin(),
            E = record->field_end();
index 0a20c08b15be51a69752b9d8ec9033f895995cb8..206f74a302580555f0e0406a6b08a2ca28acc5c4 100644 (file)
@@ -379,7 +379,7 @@ bool ConstStructBuilder::Build(InitListExpr *ILE) {
   unsigned FieldNo = 0;
   unsigned ElementNo = 0;
   const FieldDecl *LastFD = 0;
-  bool IsMsStruct = RD->hasAttr<MsStructAttr>();
+  bool IsMsStruct = RD->isMsStruct(CGM.getContext());
   
   for (RecordDecl::field_iterator Field = RD->field_begin(),
        FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
@@ -478,7 +478,7 @@ void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
 
   unsigned FieldNo = 0;
   const FieldDecl *LastFD = 0;
-  bool IsMsStruct = RD->hasAttr<MsStructAttr>();
+  bool IsMsStruct = RD->isMsStruct(CGM.getContext());
   uint64_t OffsetBits = CGM.getContext().toBits(Offset);
 
   for (RecordDecl::field_iterator Field = RD->field_begin(),
index 2f33ba93c282ebccb3693a090ff758b3e38ff0ba..26ef3efe73e6ad74d8085286476f9d0204dc34c8 100644 (file)
@@ -206,7 +206,7 @@ void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
   Alignment = Types.getContext().getASTRecordLayout(D).getAlignment();
   Packed = D->hasAttr<PackedAttr>();
   
-  IsMsStruct = D->hasAttr<MsStructAttr>();
+  IsMsStruct = D->isMsStruct(Types.getContext());
 
   if (D->isUnion()) {
     LayoutUnion(D);
@@ -1061,7 +1061,7 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,
   const ASTRecordLayout &AST_RL = getContext().getASTRecordLayout(D);
   RecordDecl::field_iterator it = D->field_begin();
   const FieldDecl *LastFD = 0;
-  bool IsMsStruct = D->hasAttr<MsStructAttr>();
+  bool IsMsStruct = D->isMsStruct(getContext());
   for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) {
     const FieldDecl *FD = *it;
 
index 5671a0fd217d0f9da8708c8beff44c02a3bf7c56..0b8dec314a189260b71628b00ae22c38e98561c2 100644 (file)
@@ -974,8 +974,8 @@ static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
 }
 
 static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (TagDecl *TD = dyn_cast<TagDecl>(D))
-    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
+    RD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
   else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
diff --git a/test/Sema/mms-bitfields.c b/test/Sema/mms-bitfields.c
new file mode 100644 (file)
index 0000000..9289b90
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -mms-bitfields -fsyntax-only -verify -triple x86_64-apple-darwin9 %s
+
+// The -mms-bitfields commandline parameter should behave the same
+// as the ms_struct attribute.
+struct
+{
+   int a : 1;
+   short b : 1;
+} t;
+
+// MS pads out bitfields between different types.
+static int arr[(sizeof(t) == 8) ? 1 : -1];
index d76ee8bab3eb1e214df36ccfcb4adb5590a0a95a..6533320e518d43509a57ba3ac7d693609071e9a5 100644 (file)
@@ -31,6 +31,12 @@ struct S {
                    unsigned long bf_2 : 12;
 } __attribute__((ms_struct)) t2;
 
+enum
+{
+  A = 0,
+  B,
+  C
+} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute ignored}}
 
 // rdar://10513599
 #pragma ms_struct on