]> granicus.if.org Git - clang/commitdiff
Emit debug info for dynamic classes if they are imported from a DLL.
authorAdrian McCarthy <amccarth@google.com>
Tue, 16 Aug 2016 22:11:18 +0000 (22:11 +0000)
committerAdrian McCarthy <amccarth@google.com>
Tue, 16 Aug 2016 22:11:18 +0000 (22:11 +0000)
With -debug-info-kind=limited, we omit debug info for dynamic classes that live in other TUs. This reduces duplicate type information. When statically linked, the type information comes together. But if your binary has a class derived from a base in a DLL, the base class info is not available to the debugger.

The decision is made in shouldOmitDefinition (CGDebugInfo.cpp). Per a suggestion from rnk, I've tweaked the decision so that we do include definitions for classes marked as DLL imports. This should be a relatively small number of classes, so we don't pay a large price for duplication of the type info, yet it should cover most cases on Windows.

Essentially this makes debug info for DLLs independent, but we still assume that all TUs within the same DLL will be consistently built with (or without) debug info and the debugger will be able to search across the debug info within that scope to resolve any declarations into definitions, etc.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@278861 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDebugInfo.cpp
test/CodeGenCXX/debug-info-dllimport-base-class.cpp [new file with mode: 0644]

index 8722e5ae260e815816007cdb70ae85661d8d3755..ee2e21bdd4881229403e27a51301070264ad609c 100644 (file)
@@ -1685,7 +1685,12 @@ static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
   if (!CXXDecl)
     return false;
 
-  if (CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())
+  // Only emit complete debug info for a dynamic class when its vtable is
+  // emitted.  However, Microsoft debuggers don't resolve type information
+  // across DLL boundaries, so skip this optimization if the class is marked
+  // dllimport.
+  if (CXXDecl->hasDefinition() && CXXDecl->isDynamicClass() &&
+      !CXXDecl->hasAttr<DLLImportAttr>())
     return true;
 
   TemplateSpecializationKind Spec = TSK_Undeclared;
diff --git a/test/CodeGenCXX/debug-info-dllimport-base-class.cpp b/test/CodeGenCXX/debug-info-dllimport-base-class.cpp
new file mode 100644 (file)
index 0000000..8b440e1
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i386-pc-windows -emit-llvm -gcodeview -debug-info-kind=limited -fms-compatibility %s -x c++ -o - | FileCheck %s
+
+// Ensure we emit debug info for the full definition of base classes that will
+// be imported from a DLL.  Otherwise, the debugger wouldn't be able to show the
+// members.
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedBase",
+// CHECK-NOT:              DIFlagFwdDecl
+// CHECK-SAME:             ){{$}}
+
+struct __declspec(dllimport) ImportedBase {
+  ImportedBase();
+  virtual void Foo();
+};
+
+struct DerivedFromImported : public ImportedBase {};
+
+int main() {
+  DerivedFromImported d;
+}