<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 24, 2015 at 3:12 PM, Saleem Abdulrasool <span dir="ltr"><<a href="mailto:abdulras@fb.com" target="_blank">abdulras@fb.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi dblaikie,<br>
<br>
When generating debug info for a static inline member which is initialized for<br>
the DLLExport storage class, hoist the definition into a non-composite type<br>
context.  Otherwise, we would trigger an assertion when generating the DIE for<br>
the associated global value as the debug context has a type association.  This<br>
addresses PR22669.<br>
<br>
Thanks to David Blakie for help in coming up with a solution to this!<br>
<br>
REPOSITORY<br>
  rL LLVM<br>
<br>
<a href="http://reviews.llvm.org/D7872" target="_blank">http://reviews.llvm.org/D7872</a><br>
<br>
Files:<br>
  lib/CodeGen/CGDebugInfo.cpp<br>
  test/CodeGenCXX/inline-dllexport-member.cpp<br>
<br>
Index: lib/CodeGen/CGDebugInfo.cpp<br>
===================================================================<br>
--- lib/CodeGen/CGDebugInfo.cpp<br>
+++ lib/CodeGen/CGDebugInfo.cpp<br>
@@ -2376,9 +2376,11 @@<br>
   // FIXME: Generalize this for even non-member global variables where the<br>
   // declaration and definition may have different lexical decl contexts, once<br>
   // we have support for emitting declarations of (non-member) global variables.<br>
-  VDContext = getContextDescriptor(<br>
-      dyn_cast<Decl>(VD->isStaticDataMember() ? VD->getLexicalDeclContext()<br>
-                                              : VD->getDeclContext()));<br>
+  const DeclContext *DC = VD->isStaticDataMember() ? VD->getLexicalDeclContext()<br>
+                                                   : VD->getDeclContext();<br>
+  while (DC->isRecord())<br>
+    DC = DC->getParent();<br></blockquote><div><br>I'd be OK with just putting this straight in the global decl context, rather than the nearest enclosing namespace - but if you're going to do it this way, it might be worth a test (eg: a namespace with a class with another class inside the first class, and the static variable inside the inner class) that demonstrates that this loop walks out to the right place.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  VDContext = getContextDescriptor(dyn_cast<Decl>(DC));<br>
 }<br>
<br>
 llvm::DISubprogram<br>
@@ -3171,6 +3173,7 @@<br>
 CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) {<br>
   if (!D->isStaticDataMember())<br>
     return llvm::DIDerivedType();<br>
+<br>
   auto MI = StaticDataMemberCache.find(D->getCanonicalDecl());<br>
   if (MI != StaticDataMemberCache.end()) {<br>
     assert(MI->second && "Static data member declaration should still exist");<br>
Index: test/CodeGenCXX/inline-dllexport-member.cpp<br>
===================================================================<br>
--- /dev/null<br>
+++ test/CodeGenCXX/inline-dllexport-member.cpp<br>
@@ -0,0 +1,12 @@<br>
+// RUN: %clang_cc1 -triple i686-windows-gnu -fms-compatibility -g -emit-llvm %s -o - \<br>
+// RUN:    | FileCheck %s<br>
+<br>
+struct __declspec(dllexport) s {<br>
+  static const unsigned int ui = 0;<br>
+};<br>
+<br>
+// CHECK: ; [ DW_TAG_variable ] [ui] [line 5] [def]<br></blockquote><div><br>We should check that the variable is scoped to the right place (either null or the CU or the nearest non-class (namespace) scope, etc).<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+// CHECK: ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from unsigned int]<br>
+// CHECK: ; [ DW_TAG_base_type ] [unsigned int] [line 0, size 32, align 32, offset 0, enc DW_ATE_unsigned]<br></blockquote><div><br>We don't need to test the const/base type - we haven't changed the code for that in this change.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+// CHECH: ; [ DW_TAG_member ] [ui] [line 5, size 0, align 0, offset 0] [static] [from ]<br></blockquote><div><br>& then we probably don't need to check the member at all (again, we haven't really touched that code) - but if you want to we could test that the variable references the member as its declaration.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
<br>
EMAIL PREFERENCES<br>
  <a href="http://reviews.llvm.org/settings/panel/emailpreferences/" target="_blank">http://reviews.llvm.org/settings/panel/emailpreferences/</a><br>
</blockquote></div><br></div></div>