shafik updated this revision to Diff 250644.
shafik marked 2 inline comments as done.
shafik added a comment.

Addressing minor comments


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,66 @@
         return int(t1);
 }
 
+// Some cases to cover ADL, we have two cases:
+//
+// - f which will have a overload in the global namespace if unqualified lookup
+// find f(int) and f(T) is found via ADL.
+//
+// - g which does not have an overload in the global namespace.
+namespace A {
+struct C {};
+
+template <typename T> int f(T) { return 4; }
+
+template <typename T> int g(T) { return 4; }
+} // namespace A
+
+// Meant to overload A::f(T) which may be found via ADL
+int f(int) { return 1; }
+
+// Regular overloaded functions case h(T) and h(double).
+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 D {};
+
+// Make sure we cover more straight forward cases as well.
+bool operator<(const D &, const D &) { return true; }
+bool operator>(const D &, const D &) { return true; }
+bool operator>>(const D &, const D &) { return true; }
+bool operator<<(const D &, const D &) { return true; }
+bool operator==(const D &, const D &) { return true; }
+
 int main() {
-        return foo(42);
+  A::B b1;
+  A::B b2;
+  D d1;
+  D d2;
+
+  bool result_b = b1 < b2 && b1 << b2 && b1 == b2 && b1 > b2 && b1 >> b2;
+  bool result_c = d1 < d2 && d1 << d2 && d1 == d2 && d1 > d2 && d1 >> d2;
+
+  return foo(42) + result_b + result_c + f(A::C{}) + g(A::C{}) + h(10) + h(1.) +
+         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,40 @@
 
     def do_test_template_function(self, add_cast):
         self.build()
-        (_, _, thread, _) = lldbutil.run_to_name_breakpoint(self, "main")
-        frame = thread.GetSelectedFrame()
-        expr = "foo(42)"
+        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)", result_type="int", result_value="42")
+        else:
+          self.expect("expr b1 <=> b2",  error=True, substrs=["warning: <user expression 0>:1:4: '<=>' is a single token in C++20; add a space to avoid a change in behavior"])
+
+          self.expect_expr("foo(42)", result_type="int", result_value="42")
+
+          # overload with template case
+          self.expect_expr("h(10)", result_type="int", result_value="10")
+
+          # ADL lookup case
+          self.expect_expr("f(A::C{})", result_type="int", result_value="4")
+
+          # ADL lookup but no overload
+          self.expect_expr("g(A::C{})", result_type="int", result_value="4")
+
+          # variadic function cases
+          self.expect_expr("var(1)", result_type="int", result_value="10")
+          self.expect_expr("var(1, 2)", result_type="int", result_value="10")
+
+          # Overloaded templated operator case
+          self.expect_expr("b1 > b2", result_type="bool", result_value="true")
+          self.expect_expr("b1 >> b2", result_type="bool", result_value="true")
+          self.expect_expr("b1 << b2", result_type="bool", result_value="true")
+          self.expect_expr("b1 == b2", result_type="bool", result_value="true")
+
+          # Overloaded operator case
+          self.expect_expr("d1 > d2", result_type="bool", result_value="true")
+          self.expect_expr("d1 >> d2", result_type="bool", result_value="true")
+          self.expect_expr("d1 << d2", result_type="bool", result_value="true")
+          self.expect_expr("d1 == d2", result_type="bool", result_value="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,22 @@
       }
 
       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;
+          if (!D.partialDemangle(attrs.mangled_name))
+            name = D.getFunctionBaseName(nullptr, nullptr);
+        }
+
         // 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 +1192,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