diff options
| author | Saleem Abdulrasool <compnerd@compnerd.org> | 2015-02-28 00:13:13 +0000 |
|---|---|---|
| committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2015-02-28 00:13:13 +0000 |
| commit | cd187f033e9cc5b4904be20a47041763fbbc95e8 (patch) | |
| tree | 195f1b0bf38f412fe5778511afb2930773bef02a | |
| parent | b2e16973df700ed1f18c9ab38bd5f8c113801832 (diff) | |
| download | bcm5719-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.cpp | 15 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/inline-dllexport-member.cpp | 10 |
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 ] + |

