[llvm] 7f85e98 - [ms] [llvm-ml] Fix MASM support for nested unnamed STRUCTs and UNIONs

Eric Astor via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 13 07:37:36 PDT 2020


Author: Eric Astor
Date: 2020-07-13T10:36:56-04:00
New Revision: 7f85e9808255f3f6c2dda81d834f9de1feb827c6

URL: https://github.com/llvm/llvm-project/commit/7f85e9808255f3f6c2dda81d834f9de1feb827c6
DIFF: https://github.com/llvm/llvm-project/commit/7f85e9808255f3f6c2dda81d834f9de1feb827c6.diff

LOG: [ms] [llvm-ml] Fix MASM support for nested unnamed STRUCTs and UNIONs

Summary: Fix MASM support for nested unnamed STRUCTs and UNIONs

Reviewed By: thakis

Differential Revision: https://reviews.llvm.org/D83345

Added: 
    

Modified: 
    llvm/lib/MC/MCParser/MasmParser.cpp
    llvm/test/tools/llvm-ml/struct.test

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp
index d7d0508cabff..58c22b2ccef2 100644
--- a/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -4084,11 +4084,8 @@ bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) {
     return Error(NameLoc, "mismatched name in ENDS directive; expected '" +
                               StructInProgress.back().Name + "'");
   StructInfo Structure = StructInProgress.pop_back_val();
-  if (Structure.Size % Structure.Alignment != 0) {
-    // Pad to make the structure's size divisible by its alignment.
-    Structure.Size +=
-        Structure.Alignment - (Structure.Size % Structure.Alignment);
-  }
+  // Pad to make the structure's size divisible by its alignment.
+  Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);
   Structs[Name.lower()] = Structure;
 
   if (parseToken(AsmToken::EndOfStatement))
@@ -4107,29 +4104,49 @@ bool MasmParser::parseDirectiveNestedEnds() {
     return addErrorSuffix(" in nested ENDS directive");
 
   StructInfo Structure = StructInProgress.pop_back_val();
-  if (Structure.Size % Structure.Alignment != 0) {
-    // Pad to make the structure's size divisible by its alignment.
-    Structure.Size +=
-        Structure.Alignment - (Structure.Size % Structure.Alignment);
-  }
-  StructInfo &ParentStruct = StructInProgress.back();
+  // Pad to make the structure's size divisible by its alignment.
+  Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);
 
-  FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT);
-  StructFieldInfo &StructInfo = Field.Contents.StructInfo;
-  Field.Type = Structure.Size;
-  Field.LengthOf = 1;
-  Field.SizeOf = Structure.Size;
+  StructInfo &ParentStruct = StructInProgress.back();
+  if (Structure.Name.empty()) {
+    const size_t OldFields = ParentStruct.Fields.size();
+    ParentStruct.Fields.insert(
+        ParentStruct.Fields.end(),
+        std::make_move_iterator(Structure.Fields.begin()),
+        std::make_move_iterator(Structure.Fields.end()));
+    for (const auto &FieldByName : Structure.FieldsByName) {
+      ParentStruct.FieldsByName[FieldByName.getKey()] =
+          FieldByName.getValue() + OldFields;
+    }
+    if (!ParentStruct.IsUnion) {
+      for (auto FieldIter = ParentStruct.Fields.begin() + OldFields;
+           FieldIter != ParentStruct.Fields.end(); ++FieldIter) {
+        FieldIter->Offset += ParentStruct.Size;
+      }
+    }
 
-  if (ParentStruct.IsUnion)
-    ParentStruct.Size = std::max(ParentStruct.Size, Field.SizeOf);
-  else
-    ParentStruct.Size += Field.SizeOf;
+    if (ParentStruct.IsUnion)
+      ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
+    else
+      ParentStruct.Size += Structure.Size;
+  } else {
+    FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT);
+    StructFieldInfo &StructInfo = Field.Contents.StructInfo;
+    Field.Type = Structure.Size;
+    Field.LengthOf = 1;
+    Field.SizeOf = Structure.Size;
+
+    if (ParentStruct.IsUnion)
+      ParentStruct.Size = std::max(ParentStruct.Size, Field.SizeOf);
+    else
+      ParentStruct.Size += Field.SizeOf;
 
-  StructInfo.Structure = Structure;
-  StructInfo.Initializers.emplace_back();
-  auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
-  for (const auto &SubField : Structure.Fields) {
-    FieldInitializers.push_back(SubField.Contents);
+    StructInfo.Structure = Structure;
+    StructInfo.Initializers.emplace_back();
+    auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
+    for (const auto &SubField : Structure.Fields) {
+      FieldInitializers.push_back(SubField.Contents);
+    }
   }
 
   return false;

diff  --git a/llvm/test/tools/llvm-ml/struct.test b/llvm/test/tools/llvm-ml/struct.test
index ecd89a140371..7bdbf51b7114 100644
--- a/llvm/test/tools/llvm-ml/struct.test
+++ b/llvm/test/tools/llvm-ml/struct.test
@@ -147,4 +147,33 @@ mov eax, [t2.FOOBAR.e.b]
 ; CHECK-NEXT: mov eax, dword ptr [rip + (t2+8)+1]
 ; CHECK-NEXT: mov eax, dword ptr [rip + t2+9]
 
+QUUX STRUCT
+  u DWORD ?
+  UNION
+    v WORD ?
+    w DWORD ?
+    STRUCT
+      x BYTE ?
+      y BYTE ?
+    ENDS
+  ENDS
+  z DWORD ?
+QUUX ENDS
+
+t9:
+mov eax, [ebx].QUUX.u
+mov eax, [ebx].QUUX.v
+mov eax, [ebx].QUUX.w
+mov eax, [ebx].QUUX.x
+mov eax, [ebx].QUUX.y
+mov eax, [ebx].QUUX.z
+
+; CHECK: t9:
+; CHECK-NEXT: mov eax, dword ptr [ebx]
+; CHECK-NEXT: mov eax, dword ptr [ebx + 4]
+; CHECK-NEXT: mov eax, dword ptr [ebx + 4]
+; CHECK-NEXT: mov eax, dword ptr [ebx + 4]
+; CHECK-NEXT: mov eax, dword ptr [ebx + 5]
+; CHECK-NEXT: mov eax, dword ptr [ebx + 8]
+
 END


        


More information about the llvm-commits mailing list