Index: include/lldb/Symbol/Variable.h =================================================================== --- include/lldb/Symbol/Variable.h +++ include/lldb/Symbol/Variable.h @@ -29,7 +29,7 @@ //------------------------------------------------------------------ Variable (lldb::user_id_t uid, const char *name, - const char *mangled, // The mangled variable name for variables in namespaces + const char *mangled, // The mangled or fully qualified name of the variable. const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope, SymbolContextScope *owner_scope, Index: include/lldb/Target/LanguageRuntime.h =================================================================== --- include/lldb/Target/LanguageRuntime.h +++ include/lldb/Target/LanguageRuntime.h @@ -90,6 +90,9 @@ static const char * GetNameForLanguageType (lldb::LanguageType language); + + static bool + LanguageIsCPlusPlus (lldb::LanguageType language); Process * GetProcess() Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -10,6 +10,7 @@ #ifndef SymbolFileDWARF_DWARFCompileUnit_h_ #define SymbolFileDWARF_DWARFCompileUnit_h_ +#include "lldb/lldb-enumerations.h" #include "DWARFDebugInfoEntry.h" #include "SymbolFileDWARF.h" @@ -186,6 +187,9 @@ uint32_t GetProducerVersionUpdate(); + lldb::LanguageType + GetLanguageType(); + bool IsDWARF64() const; @@ -204,6 +208,7 @@ uint32_t m_producer_version_major; uint32_t m_producer_version_minor; uint32_t m_producer_version_update; + lldb::LanguageType m_language_type; bool m_is_dwarf64; void Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -51,6 +51,7 @@ m_producer_version_major (0), m_producer_version_minor (0), m_producer_version_update (0), + m_language_type (eLanguageTypeUnknown), m_is_dwarf64 (false) { } @@ -68,6 +69,7 @@ m_func_aranges_ap.reset(); m_user_data = NULL; m_producer = eProducerInvalid; + m_language_type = eLanguageTypeUnknown; m_is_dwarf64 = false; } @@ -1042,6 +1044,19 @@ return m_producer_version_update; } +LanguageType +DWARFCompileUnit::GetLanguageType() +{ + if (m_language_type != eLanguageTypeUnknown) + return m_language_type; + + const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly(); + if (die) + m_language_type = static_cast( + die->GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, eLanguageTypeUnknown)); + return m_language_type; +} + bool DWARFCompileUnit::IsDWARF64() const { Index: source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -100,6 +100,14 @@ const char * GetQualifiedName () const; + // Same as GetQaulifiedName, but the life time of the returned string will + // be that of the LLDB session. + lldb_private::ConstString + GetQualifiedNameAsConstString () const + { + return lldb_private::ConstString (GetQualifiedName ()); + } + protected: typedef std::vector collection; collection m_entries; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -7402,6 +7402,24 @@ dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; SymbolContextScope * symbol_context_scope = NULL; + if (!mangled) + { + // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to + // generate fully qualified names of global variables with commands like "frame var j". + // For example, if j were an int variable holding a value 4 and declared in a namespace + // B which in turn is contained in a namespace A, the command "frame var j" returns + // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able + // to generate a fully qualified name from the declaration context. + if (die->GetParent()->Tag() == DW_TAG_compile_unit && + LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType())) + { + DWARFDeclContext decl_ctx; + + die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx); + mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString(); + } + } + // DWARF doesn't specify if a DW_TAG_variable is a local, global // or static variable, so we have to do a little digging by // looking at the location of a variable to see if it contains Index: source/Symbol/Variable.cpp =================================================================== --- source/Symbol/Variable.cpp +++ source/Symbol/Variable.cpp @@ -36,7 +36,7 @@ ( lldb::user_id_t uid, const char *name, - const char *mangled, // The mangled variable name for variables in namespaces + const char *mangled, // The mangled or fully qualified name of the variable. const lldb::SymbolFileTypeSP &symfile_type_sp, ValueType scope, SymbolContextScope *context, @@ -47,7 +47,7 @@ ) : UserID(uid), m_name(name), - m_mangled (ConstString(mangled), true), + m_mangled (ConstString(mangled)), m_symfile_type_sp(symfile_type_sp), m_scope(scope), m_owner_scope(context), @@ -69,8 +69,9 @@ const ConstString& Variable::GetName() const { - if (m_mangled) - return m_mangled.GetName(); + const ConstString &name = m_mangled.GetName(); + if (name) + return name; return m_name; } Index: source/Target/LanguageRuntime.cpp =================================================================== --- source/Target/LanguageRuntime.cpp +++ source/Target/LanguageRuntime.cpp @@ -367,6 +367,21 @@ return language_names[eLanguageTypeUnknown].name; } +bool +LanguageRuntime::LanguageIsCPlusPlus (LanguageType language) +{ + switch (language) + { + case eLanguageTypeC_plus_plus: + case eLanguageTypeC_plus_plus_03: + case eLanguageTypeC_plus_plus_11: + case eLanguageTypeC_plus_plus_14: + return true; + default: + return false; + } +} + lldb::SearchFilterSP LanguageRuntime::CreateExceptionSearchFilter () {