[PATCH] D43803: [RFC] Handle qualified unnamed types in CodeView printer

Shoaib Meenai via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 26 19:55:31 PST 2018


smeenai created this revision.
smeenai added reviewers: amccarth, compnerd, rnk, zturner.
Herald added a subscriber: aprantl.

When attempting to compile the following Objective-C++ code with
CodeView debug info:

  void (^b)(void) = []() {};

The generated debug metadata contains a structure like the following:

  !43 = !DICompositeType(tag: DW_TAG_structure_type, name: "__block_literal_1", scope: !6, file: !6, line: 1, size: 168, elements: !44)
  !44 = !{!45, !46, !47, !48, !49, !52}
  ...
  !52 = !DIDerivedType(tag: DW_TAG_member, scope: !6, file: !6, line: 1, baseType: !53, size: 8, offset: 160, flags: DIFlagPublic)
  !53 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !54)
  !54 = !DICompositeType(tag: DW_TAG_class_type, file: !6, line: 1, flags: DIFlagFwdDecl)

Note that the member node (!52) is unnamed, but rather than pointing to
a DICompositeType directly, it points to a DIDerivedType with tag
DW_TAG_const_type, which then points to the DICompositeType. However,
the CodeView assembly printer currently assumes that the base type for
an unnamed member will always be a DICompositeType, and attempts to
perform that cast, which triggers an assertion failure, since in this
case the base type is actually a DIDerivedType, not a DICompositeType
(and we would have to get the base type of the DIDerivedType to reach
the DICompositeType). I think the debug metadata being generated by the
frontend is correct (or at least plausible), and the CodeView printer
needs to handle this case.

This patch is a *very* rough attempt at handling this case. It's
definitely not ready as-is; I'm just putting it up to demonstrate the
problem and get advice on how best to handle it. In particular:

- Is there a simple C++ source construct which would generate the problematic debug metadata? Right now I'm tweaking debug metadata manually to construct a problematic case (the Objective-C++ source above generates a ton of IR, so it's not a great test case).
- Right now I'm just discarding the const/volatile qualifiers. I assume I should be applying the qualifiers to the nested members instead. I don't know how to do that, however: would I need to construct a new DIType based on the IndirectField.MemberTypeNode but with the additional qualifiers?


Repository:
  rL LLVM

https://reviews.llvm.org/D43803

Files:
  lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
  test/DebugInfo/COFF/const-unnamed-member.ll


Index: test/DebugInfo/COFF/const-unnamed-member.ll
===================================================================
--- /dev/null
+++ test/DebugInfo/COFF/const-unnamed-member.ll
@@ -0,0 +1,61 @@
+; RUN: llc -filetype=obj < %s | llvm-readobj -codeview - | FileCheck %s
+
+; Objective-C++ source demonstrating the issue:
+; void (^b)(void) = []() {};
+
+; C++ source derived and modified from:
+; struct S {
+;   struct {
+;     int a;
+;   };
+; } s;
+
+; CHECK: CodeViewTypes [
+; CHECK:  FieldList ([[S_fl:.*]]) {
+; CHECK:    TypeLeafKind: LF_FIELDLIST (0x1203)
+; CHECK:    DataMember {
+; CHECK:      Type: int (0x74)
+; CHECK:      FieldOffset: 0x0
+; CHECK:      Name: a
+; CHECK:    }
+; CHECK:  }
+; CHECK:  Struct ({{.*}}) {
+; CHECK:    TypeLeafKind: LF_STRUCTURE (0x1505)
+; CHECK:    MemberCount: 2
+; CHECK:    FieldList: <field list> ([[S_fl]])
+; CHECK:    SizeOf: 4
+; CHECK:    Name: S
+; CHECK:    LinkageName: .?AUS@@
+; CHECK:  }
+
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i686--windows-msvc19.11.0"
+
+%struct.S = type { %struct.anon }
+%struct.anon = type { i32 }
+
+@"\01?s@@3US@@A" = dso_local global %struct.S zeroinitializer, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!13, !14, !15, !16}
+!llvm.ident = !{!17}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "s", linkageName: "\01?s@@3US@@A", scope: !2, file: !3, line: 5, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 (trunk 325940) (llvm/trunk 325939)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "/tmp/ugh.cpp", directory: "/home/smeenai/llvm/build/llvm/Debug", checksumkind: CSK_MD5, checksum: "8256b51d95df0b5e42b848a3afe9cbda")
+!4 = !{}
+!5 = !{!0}
+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !3, line: 1, size: 32, flags: DIFlagTypePassByValue, elements: !7, identifier: ".?AUS@@")
+!7 = !{!8, !12}
+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !6, file: !3, line: 2, size: 32, flags: DIFlagTypePassByValue, elements: !9, identifier: ".?AU<unnamed-type-$S1>@S@@")
+!9 = !{!10}
+!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !3, line: 3, baseType: !11, size: 32)
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !DIDerivedType(tag: DW_TAG_member, scope: !6, file: !3, line: 2, baseType: !18, size: 32) ; !8 changed to !18
+!13 = !{i32 1, !"NumRegisterParameters", i32 0}
+!14 = !{i32 2, !"CodeView", i32 1}
+!15 = !{i32 2, !"Debug Info Version", i32 3}
+!16 = !{i32 1, !"wchar_size", i32 2}
+!17 = !{!"clang version 7.0.0 (trunk 325940) (llvm/trunk 325939)"}
+!18 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !8) ; added manually
Index: lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1819,6 +1819,19 @@
   assert((DDTy->getOffsetInBits() % 8) == 0 && "Unnamed bitfield member!");
   uint64_t Offset = DDTy->getOffsetInBits();
   const DIType *Ty = DDTy->getBaseType().resolve();
+  bool FullyResolved = false;
+  while (!FullyResolved) {
+    switch (Ty->getTag()) {
+    case dwarf::DW_TAG_const_type:
+    case dwarf::DW_TAG_volatile_type:
+      Ty = cast<DIDerivedType>(Ty)->getBaseType().resolve();
+      break;
+    default:
+      FullyResolved = true;
+      break;
+    }
+  }
+
   const DICompositeType *DCTy = cast<DICompositeType>(Ty);
   ClassInfo NestedInfo = collectClassInfo(DCTy);
   for (const ClassInfo::MemberInfo &IndirectField : NestedInfo.Members)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43803.136031.patch
Type: text/x-patch
Size: 3824 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180227/1341deff/attachment.bin>


More information about the llvm-commits mailing list