Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Implement [[msvc::no_unique_address]] (#65675)" #67198

Merged
merged 1 commit into from
Sep 22, 2023

Conversation

amykhuang
Copy link
Collaborator

This reverts commit 4a55d42.

Reverting because this breaks sphinx documentation, and even with it
fixed the format of the attribute makes the no_unique_address
documentation show up twice.

This reverts commit 4a55d42.

Reverting because this breaks sphinx documentation, and even with it
fixed the format of the attribute makes the no_unique_address
documentation show up twice.
@amykhuang amykhuang merged commit 71f9e76 into llvm:main Sep 22, 2023
1 of 3 checks passed
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Sep 22, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Sep 22, 2023

@llvm/pr-subscribers-clang

Changes

This reverts commit 4a55d42.

Reverting because this breaks sphinx documentation, and even with it
fixed the format of the attribute makes the no_unique_address
documentation show up twice.


Patch is 25.26 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/67198.diff

9 Files Affected:

  • (modified) clang/include/clang/Basic/Attr.td (+3-16)
  • (modified) clang/include/clang/Basic/AttrDocs.td (-4)
  • (modified) clang/lib/AST/Decl.cpp (+3-8)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+8-45)
  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (+1-2)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (-10)
  • (removed) clang/test/Layout/ms-no-unique-address.cpp (-381)
  • (modified) clang/test/Preprocessor/has_attribute.cpp (+1-4)
  • (removed) clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp (-19)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index bb8d204f33dc531..21a3b5226623cf2 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1798,24 +1798,11 @@ def ArmMveStrictPolymorphism : TypeAttr, TargetSpecificAttr<TargetARM> {
   let Documentation = [ArmMveStrictPolymorphismDocs];
 }
 
-def NoUniqueAddress : InheritableAttr {
-  let Subjects = SubjectList<[NonBitField], ErrorDiag>;
-  // No spellings because instances of this attribute are created by
-  // MSNoUniqueAddress and ItaniumNoUniqueAddress
-  let Spellings = [];
-  let Documentation = [NoUniqueAddressDocs];
-}
-
-def MSNoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
-  let Subjects = SubjectList<[NonBitField], ErrorDiag>;
-  let Spellings = [CXX11<"msvc", "no_unique_address", 201803>];
-  let Documentation = [NoUniqueAddressDocs];
-}
-
-def ItaniumNoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> {
-  let Subjects = SubjectList<[NonBitField], ErrorDiag>;
+def NoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> {
   let Spellings = [CXX11<"", "no_unique_address", 201803>];
+  let Subjects = SubjectList<[NonBitField], ErrorDiag>;
   let Documentation = [NoUniqueAddressDocs];
+  let SimpleHandler = 1;
 }
 
 def ReturnsTwice : InheritableAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 18428d26b5dc8f2..b13baa46754cfd4 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1405,10 +1405,6 @@ Example usage:
 
 ``[[no_unique_address]]`` is a standard C++20 attribute. Clang supports its use
 in C++11 onwards.
-
-On MSVC targets, ``[[no_unique_address]]`` is ignored; use
-``[[msvc::no_unique_address]]`` instead. Currently there is no guarantee of ABI
-compatibility or stability.
   }];
 }
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 07aee0d87c835a8..08ae2087cfe70eb 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4507,14 +4507,9 @@ bool FieldDecl::isZeroSize(const ASTContext &Ctx) const {
 
   // Otherwise, [...] the circumstances under which the object has zero size
   // are implementation-defined.
-  if (!Ctx.getTargetInfo().getCXXABI().isMicrosoft())
-    return true;
-
-  // MS ABI: has nonzero size if it is a class type with class type fields,
-  // whether or not they have nonzero size
-  return !llvm::any_of(CXXRD->fields(), [](const FieldDecl *Field) {
-    return Field->getType()->getAs<RecordType>();
-  });
+  // FIXME: This might be Itanium ABI specific; we don't yet know what the MS
+  // ABI will do.
+  return true;
 }
 
 bool FieldDecl::isPotentiallyOverlapping() const {
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index f1f2275da44dcad..8afd88ae7be27b3 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2545,10 +2545,7 @@ struct MicrosoftRecordLayoutBuilder {
     CharUnits Alignment;
   };
   typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
-  MicrosoftRecordLayoutBuilder(const ASTContext &Context,
-                               EmptySubobjectMap *EmptySubobjects)
-      : Context(Context), EmptySubobjects(EmptySubobjects) {}
-
+  MicrosoftRecordLayoutBuilder(const ASTContext &Context) : Context(Context) {}
 private:
   MicrosoftRecordLayoutBuilder(const MicrosoftRecordLayoutBuilder &) = delete;
   void operator=(const MicrosoftRecordLayoutBuilder &) = delete;
@@ -2598,8 +2595,6 @@ struct MicrosoftRecordLayoutBuilder {
       llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtorDispSet,
       const CXXRecordDecl *RD) const;
   const ASTContext &Context;
-  EmptySubobjectMap *EmptySubobjects;
-
   /// The size of the record being laid out.
   CharUnits Size;
   /// The non-virtual size of the record layout.
@@ -2913,7 +2908,8 @@ static bool recordUsesEBO(const RecordDecl *RD) {
 }
 
 void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
-    const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl,
+    const CXXRecordDecl *RD,
+    const CXXRecordDecl *BaseDecl,
     const ASTRecordLayout &BaseLayout,
     const ASTRecordLayout *&PreviousBaseLayout) {
   // Insert padding between two bases if the left first one is zero sized or
@@ -2946,7 +2942,6 @@ void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
   }
   Bases.insert(std::make_pair(BaseDecl, BaseOffset));
   Size += BaseLayout.getNonVirtualSize();
-  DataSize = Size;
   PreviousBaseLayout = &BaseLayout;
 }
 
@@ -2964,43 +2959,15 @@ void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) {
   LastFieldIsNonZeroWidthBitfield = false;
   ElementInfo Info = getAdjustedElementInfo(FD);
   Alignment = std::max(Alignment, Info.Alignment);
-
-  const CXXRecordDecl *FieldClass = FD->getType()->getAsCXXRecordDecl();
-  bool IsOverlappingEmptyField = FD->isPotentiallyOverlapping() &&
-                                 FieldClass->isEmpty() &&
-                                 FieldClass->fields().empty();
-  CharUnits FieldOffset = CharUnits::Zero();
-
-  if (UseExternalLayout) {
+  CharUnits FieldOffset;
+  if (UseExternalLayout)
     FieldOffset =
         Context.toCharUnitsFromBits(External.getExternalFieldOffset(FD));
-  } else if (IsUnion) {
+  else if (IsUnion)
     FieldOffset = CharUnits::Zero();
-  } else if (EmptySubobjects) {
-    if (!IsOverlappingEmptyField)
-      FieldOffset = DataSize.alignTo(Info.Alignment);
-
-    while (!EmptySubobjects->CanPlaceFieldAtOffset(FD, FieldOffset)) {
-      const CXXRecordDecl *ParentClass = cast<CXXRecordDecl>(FD->getParent());
-      bool HasBases = ParentClass && (!ParentClass->bases().empty() ||
-                                      !ParentClass->vbases().empty());
-      if (FieldOffset == CharUnits::Zero() && DataSize != CharUnits::Zero() &&
-          HasBases) {
-        // MSVC appears to only do this when there are base classes;
-        // otherwise it overlaps no_unique_address fields in non-zero offsets.
-        FieldOffset = DataSize.alignTo(Info.Alignment);
-      } else {
-        FieldOffset += Info.Alignment;
-      }
-    }
-  } else {
+  else
     FieldOffset = Size.alignTo(Info.Alignment);
-  }
   placeFieldAtOffset(FieldOffset);
-
-  if (!IsOverlappingEmptyField)
-    DataSize = std::max(DataSize, FieldOffset + Info.Size);
-
   Size = std::max(Size, FieldOffset + Info.Size);
 }
 
@@ -3046,7 +3013,6 @@ void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) {
     Alignment = std::max(Alignment, Info.Alignment);
     RemainingBitsInField = Context.toBits(Info.Size) - Width;
   }
-  DataSize = Size;
 }
 
 void
@@ -3072,7 +3038,6 @@ MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(const FieldDecl *FD) {
     Size = FieldOffset;
     Alignment = std::max(Alignment, Info.Alignment);
   }
-  DataSize = Size;
 }
 
 void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) {
@@ -3339,9 +3304,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
   const ASTRecordLayout *NewEntry = nullptr;
 
   if (isMsLayout(*this)) {
+    MicrosoftRecordLayoutBuilder Builder(*this);
     if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
-      EmptySubobjectMap EmptySubobjects(*this, RD);
-      MicrosoftRecordLayoutBuilder Builder(*this, &EmptySubobjects);
       Builder.cxxLayout(RD);
       NewEntry = new (*this) ASTRecordLayout(
           *this, Builder.Size, Builder.Alignment, Builder.Alignment,
@@ -3353,7 +3317,6 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
           Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
           Builder.Bases, Builder.VBases);
     } else {
-      MicrosoftRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
       Builder.layout(D);
       NewEntry = new (*this) ASTRecordLayout(
           *this, Builder.Size, Builder.Alignment, Builder.Alignment,
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index cc93fe7d5461967..5a6b5efbf6c1223 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4374,8 +4374,7 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
   case ParsedAttr::AT_Deprecated:
   case ParsedAttr::AT_FallThrough:
   case ParsedAttr::AT_CXX11NoReturn:
-  case ParsedAttr::AT_MSNoUniqueAddress:
-  case ParsedAttr::AT_ItaniumNoUniqueAddress:
+  case ParsedAttr::AT_NoUniqueAddress:
   case ParsedAttr::AT_Likely:
   case ParsedAttr::AT_Unlikely:
     return true;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index f3839b2c59e0dcf..090a54eedaa07d0 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -8372,10 +8372,6 @@ static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   D->addAttr(NoMergeAttr::Create(S.Context, AL));
 }
 
-static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  D->addAttr(NoUniqueAddressAttr::Create(S.Context, AL));
-}
-
 static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   // The 'sycl_kernel' attribute applies only to function templates.
   const auto *FD = cast<FunctionDecl>(D);
@@ -9281,12 +9277,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
   case ParsedAttr::AT_NoMerge:
     handleNoMergeAttr(S, D, AL);
     break;
-  case ParsedAttr::AT_MSNoUniqueAddress:
-    handleNoUniqueAddressAttr(S, D, AL);
-    break;
-  case ParsedAttr::AT_ItaniumNoUniqueAddress:
-    handleNoUniqueAddressAttr(S, D, AL);
-    break;
 
   case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
     handleAvailableOnlyInDefaultEvalMethod(S, D, AL);
diff --git a/clang/test/Layout/ms-no-unique-address.cpp b/clang/test/Layout/ms-no-unique-address.cpp
deleted file mode 100644
index 51cfd9a6ae3b77f..000000000000000
--- a/clang/test/Layout/ms-no-unique-address.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only -triple x86_64-windows-msvc -fms-compatibility -fdump-record-layouts %s | FileCheck %s
-
-namespace Empty {
-  struct A {};
-  struct A2 {};
-  struct A3 { [[msvc::no_unique_address]] A a; };
-  struct alignas(8) A4 {};
-
-  struct B {
-    [[msvc::no_unique_address]] A a;
-    char b;
-  };
-  static_assert(sizeof(B) == 1);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::B
-  // CHECK-NEXT:     0 |   struct Empty::A a (empty)
-  // CHECK-NEXT:     0 |   char b
-  // CHECK-NEXT:       | [sizeof=1, align=1,
-  // CHECK-NEXT:       |  nvsize=1, nvalign=1]
-
-  struct C {
-    [[msvc::no_unique_address]] A a;
-    [[msvc::no_unique_address]] A2 a2;
-    char c;
-  };
-  static_assert(sizeof(C) == 1);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::C
-  // CHECK-NEXT:     0 |   struct Empty::A a (empty)
-  // CHECK-NEXT:     0 |   struct Empty::A2 a2 (empty)
-  // CHECK-NEXT:     0 |   char c
-  // CHECK-NEXT:       | [sizeof=1, align=1,
-  // CHECK-NEXT:       |  nvsize=1, nvalign=1]
-
-  struct D {
-    [[msvc::no_unique_address]] A3 a;
-    int i;
-  };
-  static_assert(sizeof(D) == 8);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::D
-  // CHECK-NEXT:     0 |   struct Empty::A3 a (empty)
-  // CHECK-NEXT:     0 |     struct Empty::A a (empty)
-  // CHECK-NEXT:     4 |   int i
-  // CHECK-NEXT:       | [sizeof=8, align=4,
-  // CHECK-NEXT:       |  nvsize=8, nvalign=4]
-
-  struct E {
-    [[msvc::no_unique_address]] A a1;
-    [[msvc::no_unique_address]] A a2;
-    char e;
-  };
-  static_assert(sizeof(E) == 2);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::E
-  // CHECK-NEXT:     0 |   struct Empty::A a1 (empty)
-  // CHECK-NEXT:     1 |   struct Empty::A a2 (empty)
-  // CHECK-NEXT:     0 |   char e
-  // CHECK-NEXT:       | [sizeof=2, align=1,
-  // CHECK-NEXT:       |  nvsize=2, nvalign=1]
-
-  struct F {
-    ~F();
-    [[msvc::no_unique_address]] A a1;
-    [[msvc::no_unique_address]] A a2;
-    char f;
-  };
-  static_assert(sizeof(F) == 2);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::F
-  // CHECK-NEXT:     0 |   struct Empty::A a1 (empty)
-  // CHECK-NEXT:     1 |   struct Empty::A a2 (empty)
-  // CHECK-NEXT:     0 |   char f
-  // CHECK-NEXT:       | [sizeof=2, align=1,
-  // CHECK-NEXT:       |  nvsize=2, nvalign=1]
-
-  struct G { [[msvc::no_unique_address]] A a; ~G(); };
-  static_assert(sizeof(G) == 1);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::G
-  // CHECK-NEXT:     0 |   struct Empty::A a (empty)
-  // CHECK-NEXT:       | [sizeof=1, align=1,
-  // CHECK-NEXT:       |  nvsize=1, nvalign=1]
-
-  struct H {
-    [[msvc::no_unique_address]] A a;
-    [[msvc::no_unique_address]] A b;
-    ~H();
-  };
-  static_assert(sizeof(H) == 2);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::H
-  // CHECK-NEXT:     0 |   struct Empty::A a (empty)
-  // CHECK-NEXT:     1 |   struct Empty::A b (empty)
-  // CHECK-NEXT:       | [sizeof=2, align=1,
-  // CHECK-NEXT:       |  nvsize=2, nvalign=1]
-
-  struct I {
-    [[msvc::no_unique_address]] A4 a;
-    [[msvc::no_unique_address]] A4 b;
-  };
-  static_assert(sizeof(I) == 16);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::I
-  // CHECK-NEXT:     0 |   struct Empty::A4 a (empty)
-  // CHECK-NEXT:     8 |   struct Empty::A4 b (empty)
-  // CHECK-NEXT:       | [sizeof=16, align=8,
-  // CHECK-NEXT:       |  nvsize=16, nvalign=8]
-
-  struct J {
-    [[msvc::no_unique_address]] A4 a;
-    A4 b;
-  };
-  static_assert(sizeof(J) == 16);
-
-  // MSVC puts a and b at the same offset.
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::J
-  // CHECK-NEXT:     0 |   struct Empty::A4 a (empty)
-  // CHECK-NEXT:     8 |   struct Empty::A4 b (empty)
-  // CHECK-NEXT:       | [sizeof=16, align=8,
-  // CHECK-NEXT:       |  nvsize=16, nvalign=8]
-
-  struct K {
-    [[msvc::no_unique_address]] A4 a;
-    [[msvc::no_unique_address]] char c;
-    [[msvc::no_unique_address]] A4 b;
-  };
-  static_assert(sizeof(K) == 16);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::K
-  // CHECK-NEXT:     0 |   struct Empty::A4 a (empty)
-  // CHECK-NEXT:     0 |   char c
-  // CHECK-NEXT:     8 |   struct Empty::A4 b (empty)
-  // CHECK-NEXT:       | [sizeof=16, align=8,
-  // CHECK-NEXT:       |  nvsize=16, nvalign=8]
-
-  struct OversizedEmpty : A {
-    ~OversizedEmpty();
-    [[msvc::no_unique_address]] A a;
-  };
-  static_assert(sizeof(OversizedEmpty) == 1);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::OversizedEmpty
-  // CHECK-NEXT:     0 |   struct Empty::A (base) (empty)
-  // CHECK-NEXT:     0 |   struct Empty::A a (empty)
-  // CHECK-NEXT:       | [sizeof=1, align=1,
-  // CHECK-NEXT:       |  nvsize=1, nvalign=1]
-
-  struct HasOversizedEmpty {
-    [[msvc::no_unique_address]] OversizedEmpty m;
-  };
-  static_assert(sizeof(HasOversizedEmpty) == 1);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::HasOversizedEmpty
-  // CHECK-NEXT:     0 |   struct Empty::OversizedEmpty m (empty)
-  // CHECK-NEXT:     0 |     struct Empty::A (base) (empty)
-  // CHECK-NEXT:     0 |     struct Empty::A a (empty)
-  // CHECK-NEXT:       | [sizeof=1, align=1,
-  // CHECK-NEXT:       |  nvsize=1, nvalign=1]
-
-  struct EmptyWithNonzeroDSize {
-    [[msvc::no_unique_address]] A a;
-    int x;
-    [[msvc::no_unique_address]] A b;
-    int y;
-    [[msvc::no_unique_address]] A c;
-  };
-  static_assert(sizeof(EmptyWithNonzeroDSize) == 8);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::EmptyWithNonzeroDSize
-  // CHECK-NEXT:     0 |   struct Empty::A a (empty)
-  // CHECK-NEXT:     0 |   int x
-  // CHECK-NEXT:     1 |   struct Empty::A b (empty)
-  // CHECK-NEXT:     4 |   int y
-  // CHECK-NEXT:     2 |   struct Empty::A c (empty)
-  // CHECK-NEXT:       | [sizeof=8,  align=4,
-  // CHECK-NEXT:       |  nvsize=8, nvalign=4]
-
-  struct EmptyWithNonzeroDSizeNonPOD {
-    ~EmptyWithNonzeroDSizeNonPOD();
-    [[msvc::no_unique_address]] A a;
-    int x;
-    [[msvc::no_unique_address]] A b;
-    int y;
-    [[msvc::no_unique_address]] A c;
-  };
-  static_assert(sizeof(EmptyWithNonzeroDSizeNonPOD) == 8);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct Empty::EmptyWithNonzeroDSizeNonPOD
-  // CHECK-NEXT:     0 |   struct Empty::A a (empty)
-  // CHECK-NEXT:     0 |   int x
-  // CHECK-NEXT:     1 |   struct Empty::A b (empty)
-  // CHECK-NEXT:     4 |   int y
-  // CHECK-NEXT:     2 |   struct Empty::A c (empty)
-  // CHECK-NEXT:       | [sizeof=8, align=4,
-  // CHECK-NEXT:       |  nvsize=8, nvalign=4]
-}
-
-namespace POD {
-  struct A { int n; char c[3]; };
-  struct B { [[msvc::no_unique_address]] A a; char d; };
-  static_assert(sizeof(B) == 12);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct POD::B
-  // CHECK-NEXT:     0 |   struct POD::A a
-  // CHECK-NEXT:     0 |     int n
-  // CHECK-NEXT:     4 |     char[3] c
-  // CHECK-NEXT:     8 |   char d
-  // CHECK-NEXT:       | [sizeof=12,  align=4,
-  // CHECK-NEXT:       |  nvsize=12, nvalign=4]
-}
-
-namespace NonPOD {
-  struct A { int n; char c[3]; ~A(); };
-  struct B { [[msvc::no_unique_address]] A a; char d; };
-  static_assert(sizeof(B) == 12);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct NonPOD::B
-  // CHECK-NEXT:     0 |   struct NonPOD::A a
-  // CHECK-NEXT:     0 |     int n
-  // CHECK-NEXT:     4 |     char[3] c
-  // CHECK-NEXT:     8 |   char d
-  // CHECK-NEXT:       | [sizeof=12, align=4,
-  // CHECK-NEXT:       |  nvsize=12, nvalign=4]
-}
-
-namespace VBases {
-  // The nvsize of an object includes the complete size of its empty subobjects
-  // (although it's unclear why). Ensure this corner case is handled properly.
-  struct Empty {};
-  struct alignas(8) A {}; // dsize 0, nvsize 0, size 8
-  struct B : A { char c; }; // dsize 1, nvsize 8, size 8
-  static_assert(sizeof(B) == 8);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct VBases::B
-  // CHECK-NEXT:     0 |   struct VBases::A (base) (empty)
-  // CHECK-NEXT:     0 |   char c
-  // CHECK-NEXT:       | [sizeof=8, align=8,
-  // CHECK-NEXT:       |  nvsize=8, nvalign=8]
-
-  struct V { int n; };
-
-  struct C : B, virtual V {};
-  static_assert(sizeof(C) == 24);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct VBases::C
-  // CHECK-NEXT:     0 |   struct VBases::B (base)
-  // CHECK-NEXT:     0 |     struct VBases::A (base) (empty)
-  // CHECK-NEXT:     0 |     char c
-  // CHECK-NEXT:     8 |   (C vbtable pointer)
-  // CHECK-NEXT:    16 |   struct VBases::V (virtual base)
-  // CHECK-NEXT:    16 |     int n
-  // CHECK-NEXT:       | [sizeof=24, align=8,
-  // CHECK-NEXT:       |  nvsize=16, nvalign=8]
-
-  struct D : virtual Empty {
-    [[msvc::no_unique_address]] Empty a;
-  };
-  static_assert(sizeof(D) == 16);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct VBases::D
-  // CHECK-NEXT:     0 |   (D vbtable pointer)
-  // CHECK-NEXT:     8 |   struct VBases::Empty a
-  // CHECK-NEXT:    16 |   struct VBases::Empty (virtual base) (empty)
-  // CHECK-NEXT:       | [sizeof=16, align=8,
-  // CHECK-NEXT:       |  nvsize=16, nvalign=8]
-
-  struct E : virtual V {
-    [[msvc::no_unique_address]] B b;
-  };
-  static_assert(sizeof(E) == 24);
-
-  // CHECK:*** Dumping AST Record Layout
-  // CHECK:          0 | struct VBases::E
-  // CHECK-NEXT:     0 |   (E vbtable pointer)
-  // CHECK-NEXT:     8 |   struct VBases::B b
-  // CHECK-NEXT:     8 |     struct VBases::A (base) (empty)
-  // CHECK-NEXT:     8 |     char c
-  // CHECK-NEXT:    16 |   struct VBases::V (virtual base)
-  // CHECK-NEXT:    16 |     int n
-  // CHECK-NEXT:       | [sizeof=24, align=8,
-  // CHECK-NEXT:       |  nvsize=16, nvalign=8]
-
-  struct X : virtual A { [[msvc::no_unique_address]] A a; };
-  struct F : virtual A {
-    [[msvc::no_unique_address]] A a;
-    [[msvc::no_unique_address]] X x;
-  };
-  static_assert(sizeof(F...
[truncated]

@amykhuang amykhuang deleted the revert-no-unique branch September 22, 2023 21:39
@github-actions
Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 9779a731a65fd8daee4d0a4b6945e882263b062e 159cc6b5d3cea0c4b51bd5dac7728a3cfa379f28 -- clang/lib/AST/Decl.cpp clang/lib/AST/RecordLayoutBuilder.cpp clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/test/Preprocessor/has_attribute.cpp
View the diff from clang-format here.
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 8afd88ae7..30c94b0de 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2546,6 +2546,7 @@ struct MicrosoftRecordLayoutBuilder {
   };
   typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
   MicrosoftRecordLayoutBuilder(const ASTContext &Context) : Context(Context) {}
+
 private:
   MicrosoftRecordLayoutBuilder(const MicrosoftRecordLayoutBuilder &) = delete;
   void operator=(const MicrosoftRecordLayoutBuilder &) = delete;
@@ -2908,8 +2909,7 @@ static bool recordUsesEBO(const RecordDecl *RD) {
 }
 
 void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
-    const CXXRecordDecl *RD,
-    const CXXRecordDecl *BaseDecl,
+    const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl,
     const ASTRecordLayout &BaseLayout,
     const ASTRecordLayout *&PreviousBaseLayout) {
   // Insert padding between two bases if the left first one is zero sized or

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants