[Lldb-commits] [PATCH] Fix demangling of names if required by language

Greg Clayton clayborg at gmail.com
Wed Jul 1 11:15:58 PDT 2015


I would prefer to see this patch done differently. There are new methods make on Mangled and on ConstString that probably don't need to be there. Can we have the mangled names be correct from the start by specifying the language when we create the Mangled string in the first place? We don't want to store a language with the Mangled object because that would make lldb_private::Symbol take up even more space since it has a Mangled object inside of it and lldb_private::Symbol objects are the biggest memory hogs in LLDB right now (we did memory profiling a while back). So I would prefer to see a solution that allows clients to specify the language when setting the mangled name. If this mangled name is eLanguageTypePascal83 or eLanguageTypeJava, then demangle right away and fix up the mangled string before it gets entered as the demangled counterpart.


REPOSITORY
  rL LLVM

================
Comment at: include/lldb/Core/ConstString.h:428-434
@@ -427,2 +427,9 @@
     //------------------------------------------------------------------
+    /// Clear the mangled or demangled counterpart for a mangled
+    /// or demangled ConstString.
+    //------------------------------------------------------------------
+    void
+    ClearMangledCounterpart ();
+
+    //------------------------------------------------------------------
     /// Set the C string value with length.
----------------
If my solution outlined in the request changes will work, the will go away.

================
Comment at: include/lldb/Core/Mangled.h:185
@@ -184,3 +184,3 @@
     const ConstString&
-    GetDemangledName () const;
+    GetDemangledName (lldb::LanguageType language = lldb::eLanguageTypeUnknown) const;
 
----------------
If my solution outlined in the request changes will work, the will go away.

================
Comment at: include/lldb/Core/Mangled.h:319-340
@@ -318,2 +318,24 @@
 
+    //----------------------------------------------------------------------
+    /// 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:
----------------
If my solution outlined in the request changes will work, the will go away.

================
Comment at: source/Core/Mangled.cpp:263-359
@@ -262,8 +262,10 @@
 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,5 +324,37 @@
             }
             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);
----------------
If my solution outlined in the request changes will work, the will go away. This code will become part of the code that sets the mangled name in a new version of Mangled::SetValue(...) that takes a language parameter:

```
    void
    SetValue (const ConstString &name, bool is_mangled, LanguageType language);
```

================
Comment at: source/Core/Mangled.cpp:474-512
@@ -440,2 +473,41 @@
 //----------------------------------------------------------------------
+// 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.
----------------
If my solution outlined in the request changes will work, the will go away.

================
Comment at: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp:883
@@ -882,2 +882,3 @@
                     {
+                        LanguageType cu_language = LanguageTypeFromDWARF(die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0));
                         Mangled mangled (ConstString(mangled_cstr), true);
----------------
You are accidentally taking the current DIE and thinking it is the compile unit DIE? This is wrong. You should calculate it once at the top using:

```
    const LanguageType cu_language = GetLanguageType();
```
Then use that everywhere. So remove this line of code.

================
Comment at: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp:906
@@ -904,2 +905,3 @@
                     {
+                        LanguageType cu_language = LanguageTypeFromDWARF(die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0));
                         Mangled mangled (ConstString(mangled_cstr), true);
----------------
Remove this and use the one that is calculated once at the top.

================
Comment at: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp:954
@@ -951,2 +953,3 @@
                 {
+                    LanguageType cu_language = LanguageTypeFromDWARF(die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0));
                     Mangled mangled (ConstString(mangled_cstr), true);
----------------
Remove this and use the one that is calculated once at the top.

================
Comment at: source/Symbol/Function.cpp:219
@@ -218,2 +218,3 @@
     assert(comp_unit != nullptr);
+    m_mangled.CheckLanguageForDemangling(comp_unit->GetLanguage());
 }
----------------
If my solution outlined in the request changes will work, the will go away.

================
Comment at: source/Symbol/Function.cpp:244
@@ -242,2 +243,3 @@
     assert(comp_unit != nullptr);
+    m_mangled.CheckLanguageForDemangling(comp_unit->GetLanguage());
 }
----------------
If my solution outlined in the request changes will work, the will go away.

http://reviews.llvm.org/D10744

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the lldb-commits mailing list