Index: include/lldb/Core/ConstString.h =================================================================== --- include/lldb/Core/ConstString.h +++ include/lldb/Core/ConstString.h @@ -425,6 +425,13 @@ GetMangledCounterpart (ConstString &counterpart) const; //------------------------------------------------------------------ + /// Clear the mangled or demangled counterpart for a mangled + /// or demangled ConstString. + //------------------------------------------------------------------ + void + ClearMangledCounterpart (); + + //------------------------------------------------------------------ /// Set the C string value with length. /// /// Set the string value in the object by uniquing \a cstr_len bytes Index: include/lldb/Core/Mangled.h =================================================================== --- include/lldb/Core/Mangled.h +++ include/lldb/Core/Mangled.h @@ -182,7 +182,7 @@ /// A const reference to the demangled name string object. //---------------------------------------------------------------------- const ConstString& - GetDemangledName () const; + GetDemangledName (lldb::LanguageType language = lldb::eLanguageTypeUnknown) const; void SetDemangledName (const ConstString &name) @@ -316,6 +316,28 @@ lldb::LanguageType GuessLanguage () const; + //---------------------------------------------------------------------- + /// Return true if the language will effect the demangling, false + /// otherwise. + /// + /// @param[in] language + /// The new enumeration value that describes the programming + /// language that a Mangled is associated with. + //------------------------------------------------------------------ + static bool + LanguageEffectsDemangling (lldb::LanguageType language); + + //---------------------------------------------------------------------- + /// If the language must be known in order to properly demangle, + /// force the object to be demangled in the known language. + /// + /// @param[in] language + /// The new enumeration value that describes the programming + /// language that a Mangled is associated with. + //------------------------------------------------------------------ + void + CheckLanguageForDemangling (lldb::LanguageType language); + private: //---------------------------------------------------------------------- /// Mangled member variables. Index: source/Core/ConstString.cpp =================================================================== --- source/Core/ConstString.cpp +++ source/Core/ConstString.cpp @@ -80,6 +80,17 @@ return false; } + bool + ClearMangledCounterpart (const char *key_ccstr) + { + if (key_ccstr) + { + GetStringMapEntryFromKeyData (key_ccstr).setValue(0); + return true; + } + return false; + } + const char * GetConstCString (const char *cstr) { @@ -319,6 +330,12 @@ } void +ConstString::ClearMangledCounterpart () +{ + StringPool().ClearMangledCounterpart(m_string); +} + +void ConstString::SetCStringWithLength (const char *cstr, size_t cstr_len) { m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len); Index: source/Core/Mangled.cpp =================================================================== --- source/Core/Mangled.cpp +++ source/Core/Mangled.cpp @@ -260,10 +260,12 @@ // object's lifetime. //---------------------------------------------------------------------- const ConstString& -Mangled::GetDemangledName () const +Mangled::GetDemangledName (lldb::LanguageType language) const { // Check to make sure we have a valid mangled name and that we - // haven't already decoded our mangled name. + // haven't already decoded our mangled name (note: the decoded name + // may have been cleared if the language changed since the object + // was created). if (m_mangled && !m_demangled) { // We need to generate and cache the demangled name. @@ -322,7 +324,39 @@ } if (demangled_name) { - m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); + // Fix up the demangled string if requred by the language, + // then store the demangling in the string pool as the + // mangled string's counter part. + switch (language) + { + case lldb::eLanguageTypePascal83: + case lldb::eLanguageTypeJava: + { + // Translate the C++-like demangled string into a + // Pascal-like string, replacing the namespace + // separators "::" with ".". + std::string temp_demangled_name; + const size_t n = strlen(demangled_name); + temp_demangled_name.reserve(n); + for (size_t i = 0; i != n; ++i) + { + auto c = demangled_name[i]; + if (c == ':' && i + 1 != n && demangled_name[i+1] == ':') + { + c = '.'; + ++i; + } + temp_demangled_name += c; + } + m_demangled.SetCStringWithMangledCounterpart(temp_demangled_name.c_str(), m_mangled); + break; + } + default: + // No fixups required - store as is. + assert(!LanguageEffectsDemangling(language)); + m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); + break; + } free(demangled_name); } } @@ -333,7 +367,6 @@ m_demangled.SetCString(""); } } - return m_demangled; } @@ -438,6 +471,45 @@ } //---------------------------------------------------------------------- +// Return true if the language will effect the demangling, false +// otherwise. +//---------------------------------------------------------------------- +bool +Mangled::LanguageEffectsDemangling (lldb::LanguageType language) +{ + return (language == lldb::eLanguageTypePascal83 || + language == lldb::eLanguageTypeJava); +} + +//---------------------------------------------------------------------- +// If the language effects how the string should be demangled, replace the +// old demangled string (if any) with a new demangled string using the +// given language. +//---------------------------------------------------------------------- +void +Mangled::CheckLanguageForDemangling (lldb::LanguageType language) +{ + if (LanguageEffectsDemangling(language) && m_mangled) + { + // If we already have a demangled string, clear it. + if (m_demangled) + m_demangled.Clear(); + + // If the mangled name already has a demangled counter part, clear it + // (the demangled string) from the string pool. + m_mangled.ClearMangledCounterpart(); + + // Call GetDemangledName to force a new demangling here. + // This is required because the mangled string in the string pool can + // be referenced by different Mangled objects (e.g. Function/Symbol), + // and who ever calls GetDemangledName first will set up the demangled + // counter part in the string pool using that language, so we need to + // make sure we're the first ones to do so. + GetDemangledName(language); + } +} + +//---------------------------------------------------------------------- // Dump OBJ to the supplied stream S. //---------------------------------------------------------------------- Stream& Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -880,10 +880,11 @@ // with duplicate entries if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (name && ::strcmp(name, mangled_cstr) != 0))) { + LanguageType cu_language = LanguageTypeFromDWARF(die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0)); Mangled mangled (ConstString(mangled_cstr), true); func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); + if (mangled.GetDemangledName(cu_language)) + func_fullnames.Insert (mangled.GetDemangledName(cu_language), die.GetOffset()); } } } @@ -902,10 +903,11 @@ // with duplicate entries if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { + LanguageType cu_language = LanguageTypeFromDWARF(die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0)); Mangled mangled (ConstString(mangled_cstr), true); func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); + if (mangled.GetDemangledName(cu_language)) + func_fullnames.Insert (mangled.GetDemangledName(cu_language), die.GetOffset()); } } else @@ -949,10 +951,11 @@ // with duplicate entries if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { + LanguageType cu_language = LanguageTypeFromDWARF(die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0)); Mangled mangled (ConstString(mangled_cstr), true); globals.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - globals.Insert (mangled.GetDemangledName(), die.GetOffset()); + if (mangled.GetDemangledName(cu_language)) + globals.Insert (mangled.GetDemangledName(cu_language), die.GetOffset()); } } break; Index: source/Symbol/Function.cpp =================================================================== --- source/Symbol/Function.cpp +++ source/Symbol/Function.cpp @@ -216,6 +216,7 @@ { m_block.SetParentScope(this); assert(comp_unit != nullptr); + m_mangled.CheckLanguageForDemangling(comp_unit->GetLanguage()); } Function::Function @@ -240,6 +241,7 @@ { m_block.SetParentScope(this); assert(comp_unit != nullptr); + m_mangled.CheckLanguageForDemangling(comp_unit->GetLanguage()); }