sivachandra updated this revision to Diff 49098.
sivachandra added a comment.

Fix a comment in file, fix formatting in another.


http://reviews.llvm.org/D17618

Files:
  include/lldb/Symbol/SymbolFile.h
  packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py
  packages/Python/lldbsuite/test/lang/cpp/stl/main.cpp
  source/Expression/IRExecutionUnit.cpp
  source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
  source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Symbol/SymbolFile.cpp
  unittests/CMakeLists.txt
  unittests/Language/CMakeLists.txt
  unittests/Language/CPlusPlus/CMakeLists.txt
  unittests/Language/CPlusPlus/TypeNamesEqualityTest.cpp

Index: unittests/Language/CPlusPlus/TypeNamesEqualityTest.cpp
===================================================================
--- /dev/null
+++ unittests/Language/CPlusPlus/TypeNamesEqualityTest.cpp
@@ -0,0 +1,32 @@
+//===-- ScalarTest.cpp ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+
+using namespace lldb_private;
+
+TEST(TypeNamesEqualTest, Equality)
+{
+    ASSERT_TRUE(CPlusPlusLanguage::TypeNamesEqual("int *", "int*"));
+    ASSERT_TRUE(CPlusPlusLanguage::TypeNamesEqual("unsigned int *", "unsigned int*"));
+    ASSERT_TRUE(CPlusPlusLanguage::TypeNamesEqual("const unsigned int", "unsigned int const"));
+    ASSERT_TRUE(CPlusPlusLanguage::TypeNamesEqual("const unsigned int *", "unsigned int const *"));
+    ASSERT_TRUE(CPlusPlusLanguage::TypeNamesEqual("unsigned int * const", "unsigned int * const"));
+}
+
+TEST(TypeNamesEqualTest, InEquality)
+{
+    ASSERT_FALSE(CPlusPlusLanguage::TypeNamesEqual("int *", "short int*"));
+    ASSERT_FALSE(CPlusPlusLanguage::TypeNamesEqual("unsigned int *", "unsigned int"));
+    ASSERT_FALSE(CPlusPlusLanguage::TypeNamesEqual("const unsigned int", "int const"));
+    ASSERT_FALSE(CPlusPlusLanguage::TypeNamesEqual("const unsigned int *", "unsigned int * const"));
+    ASSERT_FALSE(CPlusPlusLanguage::TypeNamesEqual("unsigned int const *", "unsigned int * const"));
+}
Index: unittests/Language/CPlusPlus/CMakeLists.txt
===================================================================
--- /dev/null
+++ unittests/Language/CPlusPlus/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_lldb_unittest(LLDBCPlusCPlusLanguageTests
+  TypeNamesEqualityTest.cpp
+  )
+
+  target_link_libraries(lldbPluginCPlusPlusLanguage)
Index: unittests/Language/CMakeLists.txt
===================================================================
--- /dev/null
+++ unittests/Language/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(CPlusPlus)
Index: unittests/CMakeLists.txt
===================================================================
--- unittests/CMakeLists.txt
+++ unittests/CMakeLists.txt
@@ -28,5 +28,6 @@
 add_subdirectory(Expression)
 add_subdirectory(Host)
 add_subdirectory(Interpreter)
+add_subdirectory(Language)
 add_subdirectory(ScriptInterpreter)
 add_subdirectory(Utility)
Index: source/Symbol/SymbolFile.cpp
===================================================================
--- source/Symbol/SymbolFile.cpp
+++ source/Symbol/SymbolFile.cpp
@@ -135,7 +135,10 @@
 }
 
 void
-SymbolFile::GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector<ConstString> &mangled_names)
+SymbolFile::GetMangledNamesForFunction(const SymbolContext &sc,
+                                       const std::string &scope_qualified_name,
+                                       const std::vector<std::string> &arguments,
+                                       std::vector<ConstString> &mangled_names)
 {
     return;
 }
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -209,7 +209,9 @@
                    lldb_private::SymbolContextList& sc_list) override;
 
     void
-    GetMangledNamesForFunction (const std::string &scope_qualified_name,
+    GetMangledNamesForFunction (const lldb_private::SymbolContext& sc,
+                                const std::string &scope_qualified_name,
+                                const std::vector<std::string> &arguments,
                                 std::vector<lldb_private::ConstString> &mangled_names) override;
 
     uint32_t
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2966,7 +2966,9 @@
 }
 
 void
-SymbolFileDWARF::GetMangledNamesForFunction (const std::string &scope_qualified_name,
+SymbolFileDWARF::GetMangledNamesForFunction (const SymbolContext& sc,
+                                             const std::string &scope_qualified_name,
+                                             const std::vector<std::string> &arguments,
                                              std::vector<ConstString> &mangled_names)
 {
     DWARFDebugInfo* info = DebugInfo();
@@ -2982,18 +2984,42 @@
 
         SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
         if (dwo)
-            dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
+            dwo->GetMangledNamesForFunction(sc, scope_qualified_name, arguments, mangled_names);
     }
 
     NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name);
     if (iter == m_function_scope_qualified_name_map.end())
         return;
 
+    size_t arg_count = arguments.size();
     DIERefSetSP set_sp = (*iter).second;
     std::set<DIERef>::iterator set_iter;
     for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++)
     {
         DWARFDIE die = DebugInfo()->GetDIE (*set_iter);
+
+        Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+        TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+        DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+        TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, NULL);
+        CompilerType compiler_type = type_sp->GetFullCompilerType();
+
+        if (compiler_type.GetNumberOfFunctionArguments() != arg_count)
+            continue;
+
+        size_t match_count = 0;
+        for (size_t i = 0; i < compiler_type.GetNumberOfFunctionArguments(); i++)
+        {
+            std::string arg_type = compiler_type.GetFunctionArgumentAtIndex(i).GetTypeName().AsCString();
+            if (CPlusPlusLanguage::TypeNamesEqual(llvm::StringRef(arguments[i]), llvm::StringRef(arg_type)))
+                match_count++;
+            else
+                break;
+        }
+
+        if (match_count != arg_count)
+            continue;
+
         mangled_names.push_back(ConstString(die.GetMangledName()));
     }
 }
Index: source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
===================================================================
--- source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -99,20 +99,23 @@
         llvm::StringRef
         GetContext ();
         
-        llvm::StringRef
+        const std::vector<std::string> &
         GetArguments ();
         
         llvm::StringRef
         GetQualifiers ();
 
     protected:
         void
         Parse();
+    
+        void
+        SetArguments(const llvm::StringRef &arg_string);
 
         ConstString     m_full;         // Full name:    "lldb::SBTarget::GetBreakpointAtIndex(unsigned int) const"
         llvm::StringRef m_basename;     // Basename:     "GetBreakpointAtIndex"
         llvm::StringRef m_context;      // Decl context: "lldb::SBTarget"
-        llvm::StringRef m_arguments;    // Arguments:    "(unsigned int)"
+        std::vector<std::string> m_arguments;    // Arguments:    ["unsigned int"]
         llvm::StringRef m_qualifiers;   // Qualifiers:   "const"
         Type m_type;
         bool m_parsed;
@@ -137,7 +140,7 @@
     
     HardcodedFormatters::HardcodedSyntheticFinder
     GetHardcodedSynthetics () override;
-    
+
     //------------------------------------------------------------------
     // Static Functions
     //------------------------------------------------------------------
@@ -165,6 +168,9 @@
 
     static bool
     ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier);
+
+    static bool
+    TypeNamesEqual(const llvm::StringRef &t1, const llvm::StringRef &t2);
     
     // in some cases, compilers will output different names for one same type. when that happens, it might be impossible
     // to construct SBType objects for a valid type, because the name that is available is not the same as the name that
Index: source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
===================================================================
--- source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -89,7 +89,7 @@
     m_full.Clear();
     m_basename = llvm::StringRef();
     m_context = llvm::StringRef();
-    m_arguments = llvm::StringRef();
+    m_arguments = std::vector<std::string>();
     m_qualifiers = llvm::StringRef();
     m_type = eTypeInvalid;
     m_parsed = false;
@@ -195,7 +195,7 @@
         llvm::StringRef parens("()", 2);
         if (ReverseFindMatchingChars (full, parens, arg_start, arg_end))
         {
-            m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
+            SetArguments(full.substr(arg_start, arg_end - arg_start + 1));
             if (arg_end + 1 < full.size())
                 m_qualifiers = full.substr(arg_end + 1);
             if (arg_start > 0)
@@ -253,7 +253,7 @@
                 // be a valid C++ method, clear everything out and indicate an error
                 m_context = llvm::StringRef();
                 m_basename = llvm::StringRef();
-                m_arguments = llvm::StringRef();
+                m_arguments = std::vector<std::string>();
                 m_qualifiers = llvm::StringRef();
                 m_parse_error = true;
             }
@@ -281,14 +281,61 @@
     return m_context;
 }
 
-llvm::StringRef
+const std::vector<std::string> &
 CPlusPlusLanguage::MethodName::GetArguments ()
 {
     if (!m_parsed)
         Parse();
     return m_arguments;
 }
 
+void
+CPlusPlusLanguage::MethodName::SetArguments(const llvm::StringRef &arg_str)
+{
+    // Remove the open and close parenthesis.
+    llvm::StringRef input = arg_str.substr(1, arg_str.size() - 2);
+    int paren_count = 0;
+    int angle_count = 0;
+
+    std::string arg;
+    for (size_t i = 0; i < input.size(); i++)
+    {
+        char c = input[i];
+        switch (c)
+        {
+        case ',':
+            if (paren_count == 0 && angle_count == 0)
+            {
+                m_arguments.push_back(arg.substr());
+                arg.erase();
+                continue;
+            }
+        case '(':
+            paren_count++;
+            break;
+        case '<':
+            angle_count++;
+            break;
+        case ')':
+            paren_count--;
+            break;
+        case '>':
+            angle_count--;
+            break;
+        case ' ':
+            if (arg.size() == 0)
+                continue;
+        default:
+            break;
+        }
+
+        arg.push_back(c);
+    }
+
+    if (arg.size() > 0)
+        m_arguments.push_back(arg);
+}
+
 llvm::StringRef
 CPlusPlusLanguage::MethodName::GetQualifiers ()
 {
@@ -313,6 +360,54 @@
     return res;
 }
 
+bool CPlusPlusLanguage::TypeNamesEqual (const llvm::StringRef &t1, const llvm::StringRef &t2)
+{
+    llvm::StringRef r1 = t1.trim();
+    llvm::StringRef r2 = t2.trim();
+
+    if (r1 == r2)
+        return true;
+
+    char last = r1.back();
+    if (last == '&' || last == '*')
+    {
+        if (r2.back() != last)
+            return false;
+
+        return CPlusPlusLanguage::TypeNamesEqual(r1.drop_back(), r2.drop_back());
+    }
+
+    if (r1.endswith("const"))
+    {
+        // If both end with "const", drop strlen("const") from the back and compare.
+        if (r2.endswith("const"))
+            return CPlusPlusLanguage::TypeNamesEqual(r1.drop_back(5), r2.drop_back(5));
+
+        // If r2 starts with "const", then drop strlen("const") from its front and
+        // compare with r1 after dropping strlen("const") from its back.
+        if (r2.startswith("const"))
+            return CPlusPlusLanguage::TypeNamesEqual(r1.drop_back(5), r2.drop_front(5));
+
+        return false;
+    }
+
+    if (r1.startswith("const"))
+    {
+        // If both start with "const", drop strlen("const") from the front and compare.
+        if (r2.startswith("const"))
+            return CPlusPlusLanguage::TypeNamesEqual(r1.drop_front(5), r2.drop_front(5));
+
+        // If r2 ends with "const", then drop strlen("const") from its back and
+        // compare with r1 after dropping strlen("const") from its front.
+        if (r2.endswith("const"))
+            return CPlusPlusLanguage::TypeNamesEqual(r1.drop_front(5), r2.drop_back(5));
+
+        return false;
+    }
+
+    return false;
+}
+
 bool
 CPlusPlusLanguage::IsCPPMangledName (const char *name)
 {
Index: source/Expression/IRExecutionUnit.cpp
===================================================================
--- source/Expression/IRExecutionUnit.cpp
+++ source/Expression/IRExecutionUnit.cpp
@@ -653,6 +653,7 @@
 {
     CPlusPlusLanguage::MethodName cpp_name(demangled);
     std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
+    const std::vector<std::string> &arguments = cpp_name.GetArguments();
 
     if (!scope_qualified_name.size())
         return ConstString();
@@ -669,7 +670,7 @@
         return ConstString();
 
     std::vector<ConstString> alternates;
-    sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
+    sym_file->GetMangledNamesForFunction(sym_ctx, scope_qualified_name, arguments, alternates);
 
     std::vector<ConstString> param_and_qual_matches;
     std::vector<ConstString> param_matches;
@@ -683,13 +684,10 @@
         if (!cpp_name.IsValid())
             continue;
 
-        if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments())
-        {
-            if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
-                param_and_qual_matches.push_back(alternate_mangled_name);
-            else
-                param_matches.push_back(alternate_mangled_name);
-        }
+        if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
+            param_and_qual_matches.push_back(alternate_mangled_name);
+        else
+            param_matches.push_back(alternate_mangled_name);
     }
 
     if (param_and_qual_matches.size())
Index: packages/Python/lldbsuite/test/lang/cpp/stl/main.cpp
===================================================================
--- packages/Python/lldbsuite/test/lang/cpp/stl/main.cpp
+++ packages/Python/lldbsuite/test/lang/cpp/stl/main.cpp
@@ -13,11 +13,14 @@
 int main (int argc, char const *argv[])
 {
     std::string hello_world ("Hello World!");
+    std::string str("a_string");
     std::cout << hello_world << std::endl;
     std::cout << hello_world.length() << std::endl;
     std::cout << hello_world[11] << std::endl;
 
     std::map<std::string, int> associative_array;
+    std::map<std::string, std::string> ssmap;
+    ssmap[str] = hello_world;
     std::cout << "size of upon construction associative_array: " << associative_array.size() << std::endl;
     associative_array[hello_world] = 1;
     associative_array["hello"] = 2;
Index: packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py
===================================================================
--- packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py
+++ packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py
@@ -24,6 +24,23 @@
         self.source = 'main.cpp'
         self.line = line_number(self.source, '// Set break point at this line.')
 
+    def test_string_maps(self):
+        self.build()
+        exe = os.path.join(os.getcwd(), "a.out")
+
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+        self.runCmd("run", RUN_SUCCEEDED)
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['main.cpp:%d' % self.line,
+                       'stop reason = breakpoint'])
+
+        self.expect('expr associative_array[hello_world]',
+            substrs = [' = 1'])
+        self.expect('expr ssmap[str]',
+            substrs = [' = "Hello World!"'])
+
     # rdar://problem/10400981
     @unittest2.expectedFailure
     def test(self):
Index: include/lldb/Symbol/SymbolFile.h
===================================================================
--- include/lldb/Symbol/SymbolFile.h
+++ include/lldb/Symbol/SymbolFile.h
@@ -146,7 +146,7 @@
     virtual uint32_t        FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types);
     virtual size_t          FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types);
 
-    virtual void            GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector<ConstString> &mangled_names);
+    virtual void            GetMangledNamesForFunction(const SymbolContext& sc, const std::string &scope_qualified_name, const std::vector<std::string> &arguments, std::vector<ConstString> &mangled_names);
 //  virtual uint32_t        FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0;
     virtual TypeList *      GetTypeList ();
     virtual size_t          GetTypes (lldb_private::SymbolContextScope *sc_scope,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to