[PATCH] D37409: [CodeView] Don't output nested typedefs that are scoped to classes.

Zachary Turner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 1 17:56:08 PDT 2017


zturner created this revision.
Herald added a subscriber: hiraditya.

S_UDT records are basically the "bridge" between the debugger's expression evaluator and the type information.  If you type `(Foo *)nullptr` into the watch window, the debugger looks for an S_UDT record named Foo.  If it can find one, it displays your type.  Otherwise you get an error.

We have always understood this to mean that if you have code like this:

  struct A {
    int X;
  };
  
  struct B {
    typedef A AT;
    AT Member;
  };

that you will get 3 S_UDT records.  "A", "B", and "B::AT".  Because if you were to type `(B::AT*)nullptr` into the debugger, it would need to find an S_UDT record named "B::AT".

But "B::AT" is actually the S_UDT record that would be generated if B were a namespace, not a struct.  So the debugger needs to be able to distinguish this case.  So what it does is:

1. Look for an S_UDT named "B::AT".  If it finds one, it knows that AT is in a namespace.
2. If it doesn't find one, split at the scope resolution operator, and look for an S_UDT named B.  If it finds one, look up the type for B, and then look for AT as one of its members.

With this algorithm, S_UDT records for nested typedefs are not just unnecessary, but actually wrong!

The results of implementing this in clang are dramatic.  It cuts our /DEBUG:FASTLINK PDB sizes by more than 50%, and we go from being ~20% //larger// than MSVC PDBs on average, to ~40% //smaller//.

It also slightly speeds up link time.  We get about 10% faster links than without this patch.


https://reviews.llvm.org/D37409

Files:
  llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp


Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1115,6 +1115,21 @@
 }
 
 static bool shouldEmitUdt(const DIType *T) {
+  if (!T)
+    return false;
+
+  // MSVC does not emit UDTs for typedefs that are scoped to classes.
+  if (T->getTag() == dwarf::DW_TAG_typedef) {
+    if (DIScope *Scope = T->getScope().resolve()) {
+      switch (Scope->getTag()) {
+      case dwarf::DW_TAG_structure_type:
+      case dwarf::DW_TAG_class_type:
+      case dwarf::DW_TAG_union_type:
+        return false;
+      }
+    }
+  }
+
   while (true) {
     if (!T || T->isForwardDecl())
       return false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37409.113631.patch
Type: text/x-patch
Size: 770 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170902/3b382822/attachment.bin>


More information about the llvm-commits mailing list