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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits