Improved MSVC __interface support by adding first class support for it, instead of aliasing to "struct" which had some incorrect behaviour. Patch by David Robins.

llvm-svn: 163013
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index d5df63f..043e46e 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2260,12 +2260,28 @@
   }
   
   // Use the externally-supplied field offset.
-  return ExternalFieldOffset;
-}
-
-void RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset,
-                                            uint64_t UnpaddedOffset,
-                                            uint64_t UnpackedOffset,
+  return ExternalFieldOffset;

+}

+

+/// \brief Get diagnostic %select index for tag kind for

+/// field padding diagnostic message.

+/// WARNING: Indexes apply to particular diagnostics only!

+///

+/// \returns diagnostic %select index.

+static unsigned getPaddingDiagFromTagKind(TagTypeKind Tag)

+{

+  switch (Tag) {

+    case TTK_Struct: return 0;

+    case TTK_Interface: return 1;

+    case TTK_Class:  return 2;

+    default: assert("Invalid tag kind for field padding diagnostic!");

+  }

+  return -1;

+}

+

+void RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset,

+                                            uint64_t UnpaddedOffset,

+                                            uint64_t UnpackedOffset,

                                             unsigned UnpackedAlign,
                                             bool isPacked,
                                             const FieldDecl *D) {
@@ -2288,20 +2304,20 @@
     if (PadSize % CharBitNum == 0) {
       PadSize = PadSize / CharBitNum;
       InBits = false;
-    }
-    if (D->getIdentifier())
-      Diag(D->getLocation(), diag::warn_padded_struct_field)
-          << (D->getParent()->isStruct() ? 0 : 1) // struct|class
-          << Context.getTypeDeclType(D->getParent())
-          << PadSize
-          << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1) // plural or not
-          << D->getIdentifier();
-    else
-      Diag(D->getLocation(), diag::warn_padded_struct_anon_field)
-          << (D->getParent()->isStruct() ? 0 : 1) // struct|class
-          << Context.getTypeDeclType(D->getParent())
-          << PadSize
-          << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not
+    }

+    if (D->getIdentifier())

+      Diag(D->getLocation(), diag::warn_padded_struct_field)

+          << getPaddingDiagFromTagKind(D->getParent()->getTagKind())

+          << Context.getTypeDeclType(D->getParent())

+          << PadSize

+          << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1) // plural or not

+          << D->getIdentifier();

+    else

+      Diag(D->getLocation(), diag::warn_padded_struct_anon_field)

+          << getPaddingDiagFromTagKind(D->getParent()->getTagKind())

+          << Context.getTypeDeclType(D->getParent())

+          << PadSize

+          << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not

   }
 
   // Warn if we packed it unnecessarily. If the alignment is 1 byte don't