shafik updated this revision to Diff 249247.
shafik marked 11 inline comments as done.
shafik added a comment.

Moving to using `ItaniumPartialDemangler` for now.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75761/new/

https://reviews.llvm.org/D75761

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/test/API/lang/cpp/template-function/TestTemplateFunctions.py
  lldb/test/API/lang/cpp/template-function/main.cpp

Index: lldb/test/API/lang/cpp/template-function/main.cpp
===================================================================
--- lldb/test/API/lang/cpp/template-function/main.cpp
+++ lldb/test/API/lang/cpp/template-function/main.cpp
@@ -3,6 +3,67 @@
         return int(t1);
 }
 
+// Some cases to cover ADL
+namespace A {
+struct C {};
+
+template <typename T> int f(T) { return 4; }
+
+template <typename T> int g(T) { return 4; }
+} // namespace A
+
+int f(int) { return 1; }
+
+template <class T> int h(T x) { return x; }
+
+int h(double d) { return 5; }
+
+template <class... Us> int var(Us... pargs) { return 10; }
+
+// Having the templated overloaded operators in a namespace effects the
+// mangled name generated in the IR e.g. _ZltRK1BS1_ Vs _ZN1AltERKNS_1BES2_
+// One will be in the symbol table but the other won't. This results in a
+// different code path that will result in CPlusPlusNameParser being used.
+// This allows us to cover that code as well.
+namespace A {
+template <typename T> bool operator<(const T &, const T &) { return true; }
+
+template <typename T> bool operator>(const T &, const T &) { return true; }
+
+template <typename T> bool operator<<(const T &, const T &) { return true; }
+
+template <typename T> bool operator>>(const T &, const T &) { return true; }
+
+template <typename T> bool operator==(const T &, const T &) { return true; }
+
+struct B {};
+} // namespace A
+
+struct C {};
+
+// Make sure we cover more straight forward cases as well.
+bool operator<(const C &, const C &) { return true; }
+bool operator>(const C &, const C &) { return true; }
+bool operator>>(const C &, const C &) { return true; }
+bool operator<<(const C &, const C &) { return true; }
+bool operator==(const C &, const C &) { return true; }
+
 int main() {
-        return foo(42);
+  A::B b1;
+  A::B b2;
+  C c1;
+  C c2;
+
+  bool result_b = b1 < b2 && b1 << b2 && b1 == b2 && b1 > b2 && b1 >> b2;
+  bool result_c = c1 < c2 && c1 << c2 && c1 == c2 && c1 > c2 && c1 >> c2;
+
+  return foo(42) + result_b + result_c +
+         // ADL lookup case,
+         f(A::C{}) +
+         // ADL lookup but no overload
+         g(A::C{}) +
+         // overload with template
+         h(10) + h(1.) +
+         // variadic function
+         var(1) + var(1, 2); // break here
 }
Index: lldb/test/API/lang/cpp/template-function/TestTemplateFunctions.py
===================================================================
--- lldb/test/API/lang/cpp/template-function/TestTemplateFunctions.py
+++ lldb/test/API/lang/cpp/template-function/TestTemplateFunctions.py
@@ -13,14 +13,54 @@
 
     def do_test_template_function(self, add_cast):
         self.build()
-        (_, _, thread, _) = lldbutil.run_to_name_breakpoint(self, "main")
-        frame = thread.GetSelectedFrame()
-        expr = "foo(42)"
+        (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
+                lldb.SBFileSpec("main.cpp", False))
+
         if add_cast:
-            expr = "(int)" + expr
-        expr_result = frame.EvaluateExpression(expr)
-        self.assertTrue(expr_result.IsValid())
-        self.assertEqual(expr_result.GetValue(), "42")
+          self.expect("expr (int) foo(42)",
+                substrs=['(int)', '= 42'])
+        else:
+          self.expect("expr foo(42)",
+                substrs=['(int)', '= 42'])
+
+          self.expect("expr h(10)",
+                substrs=['(int)', '= 10'])
+
+          self.expect("expr f(A::C{})",
+           substrs=['(int)', '= 4'])
+
+          self.expect("expr g(A::C{})",
+           substrs=['(int)', '= 4'])
+
+          self.expect("expr var(1)",
+           substrs=['(int)', '= 10'])
+
+          self.expect("expr var(1,2)",
+           substrs=['(int)', '= 10'])
+
+          self.expect("expr b1 > b2",
+           substrs=['(bool)', '= true'])
+
+          self.expect("expr b1 >> b2",
+           substrs=['(bool)', '= true'])
+
+          self.expect("expr b1 << b2",
+           substrs=['(bool)', '= true'])
+
+          self.expect("expr b1 == b2",
+           substrs=['(bool)', '= true'])
+
+          self.expect("expr c1 > c2",
+           substrs=['(bool)', '= true'])
+
+          self.expect("expr c1 >> c2",
+           substrs=['(bool)', '= true'])
+
+          self.expect("expr c1 << c2",
+           substrs=['(bool)', '= true'])
+
+          self.expect("expr c1 == c2",
+           substrs=['(bool)', '= true'])
 
     @skipIfWindows
     def test_template_function_with_cast(self):
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -35,6 +35,8 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/StreamString.h"
 
+#include "llvm/Demangle/Demangle.h"
+
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
@@ -1167,12 +1169,24 @@
       }
 
       if (!function_decl) {
+        const char *name = attrs.name.GetCString();
+
+        // We currently generate function templates with template parameters in
+        // their name. In order to get closer to the AST that clang generates
+        // we want to strip these from the name when creating the AST.
+        if (attrs.mangled_name) {
+          llvm::ItaniumPartialDemangler D;
+          D.partialDemangle(attrs.mangled_name);
+          size_t Size = 1;
+
+          name = D.getFunctionBaseName(nullptr, &Size);
+        }
+
         // We just have a function that isn't part of a class
         function_decl = m_ast.CreateFunctionDeclaration(
             ignore_containing_context ? m_ast.GetTranslationUnitDecl()
                                       : containing_decl_ctx,
-            attrs.name.GetCString(), clang_type, attrs.storage,
-            attrs.is_inline);
+            name, clang_type, attrs.storage, attrs.is_inline);
 
         if (has_template_params) {
           TypeSystemClang::TemplateParameterInfos template_param_infos;
@@ -1180,14 +1194,14 @@
           template_function_decl = m_ast.CreateFunctionDeclaration(
               ignore_containing_context ? m_ast.GetTranslationUnitDecl()
                                         : containing_decl_ctx,
-              attrs.name.GetCString(), clang_type, attrs.storage,
-              attrs.is_inline);
+              name, clang_type, attrs.storage, attrs.is_inline);
+
           clang::FunctionTemplateDecl *func_template_decl =
-              m_ast.CreateFunctionTemplateDecl(
-                  containing_decl_ctx, template_function_decl,
-                  attrs.name.GetCString(), template_param_infos);
+              m_ast.CreateFunctionTemplateDecl(containing_decl_ctx,
+                                               template_function_decl, name,
+                                               template_param_infos);
           m_ast.CreateFunctionTemplateSpecializationInfo(
-              function_decl, func_template_decl, template_param_infos);
+              template_function_decl, func_template_decl, template_param_infos);
         }
 
         lldbassert(function_decl);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to