summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2015-02-28 00:13:13 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2015-02-28 00:13:13 +0000
commitcd187f033e9cc5b4904be20a47041763fbbc95e8 (patch)
tree195f1b0bf38f412fe5778511afb2930773bef02a
parentb2e16973df700ed1f18c9ab38bd5f8c113801832 (diff)
downloadbcm5719-llvm-cd187f033e9cc5b4904be20a47041763fbbc95e8.tar.gz
bcm5719-llvm-cd187f033e9cc5b4904be20a47041763fbbc95e8.zip
DebugInfo: hoist definition into global context when needed
When generating debug info for a static inline member which is initialized for the DLLExport storage class, hoist the definition into a non-composite type context. Otherwise, we would trigger an assertion when generating the DIE for the associated global value as the debug context has a type association. This addresses PR22669. Thanks to David Blakie for help in coming up with a solution to this! llvm-svn: 230816
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp15
-rw-r--r--clang/test/CodeGenCXX/inline-dllexport-member.cpp10
2 files changed, 22 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 6d78ee87540..42d5c3613be 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2376,9 +2376,17 @@ void CGDebugInfo::collectVarDeclProps(const VarDecl *VD, llvm::DIFile &Unit,
// FIXME: Generalize this for even non-member global variables where the
// declaration and definition may have different lexical decl contexts, once
// we have support for emitting declarations of (non-member) global variables.
- VDContext = getContextDescriptor(
- dyn_cast<Decl>(VD->isStaticDataMember() ? VD->getLexicalDeclContext()
- : VD->getDeclContext()));
+ const DeclContext *DC = VD->isStaticDataMember() ? VD->getLexicalDeclContext()
+ : VD->getDeclContext();
+ // When a record type contains an in-line initialization of a static data
+ // member, and the record type is marked as __declspec(dllexport), an implicit
+ // definition of the member will be created in the record context. DWARF
+ // doesn't seem to have a nice way to describe this in a form that consumers
+ // are likely to understand, so fake the "normal" situation of a definition
+ // outside the class by putting it in the global scope.
+ if (DC->isRecord())
+ DC = CGM.getContext().getTranslationUnitDecl();
+ VDContext = getContextDescriptor(dyn_cast<Decl>(DC));
}
llvm::DISubprogram
@@ -3171,6 +3179,7 @@ llvm::DIDerivedType
CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) {
if (!D->isStaticDataMember())
return llvm::DIDerivedType();
+
auto MI = StaticDataMemberCache.find(D->getCanonicalDecl());
if (MI != StaticDataMemberCache.end()) {
assert(MI->second && "Static data member declaration should still exist");
diff --git a/clang/test/CodeGenCXX/inline-dllexport-member.cpp b/clang/test/CodeGenCXX/inline-dllexport-member.cpp
new file mode 100644
index 00000000000..14634bd5a96
--- /dev/null
+++ b/clang/test/CodeGenCXX/inline-dllexport-member.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple i686-windows-gnu -fms-compatibility -g -emit-llvm %s -o - \
+// RUN: | FileCheck %s
+
+struct __declspec(dllexport) s {
+ static const unsigned int ui = 0;
+};
+
+// CHECK: , [[SCOPE:![^,]*]], {{.*}}, i32* @_ZN1s2uiE, {{.*}}} ; [ DW_TAG_variable ] [ui] [line 5] [def]
+// CHECK: [[SCOPE]] = {{.*}} ; [ DW_TAG_file_type ]
+
OpenPOWER on IntegriCloud