Index: packages/Python/lldbsuite/test/lang/cpp/template-function/Makefile =================================================================== --- packages/Python/lldbsuite/test/lang/cpp/template-function/Makefile +++ packages/Python/lldbsuite/test/lang/cpp/template-function/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Index: packages/Python/lldbsuite/test/lang/cpp/template-function/TestTemplateFunctions.py =================================================================== --- packages/Python/lldbsuite/test/lang/cpp/template-function/TestTemplateFunctions.py +++ packages/Python/lldbsuite/test/lang/cpp/template-function/TestTemplateFunctions.py @@ -0,0 +1,30 @@ +""" +Test that we can call C++ template fucntions. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TemplateFunctionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def do_test_template_function(self, add_cast): + self.build() + (_, _, thread, _) = lldbutil.run_to_name_breakpoint(self, "main") + frame = thread.GetSelectedFrame() + expr = "foo(42)" + if add_cast: + expr = "(int)" + expr + expr_result = frame.EvaluateExpression(expr) + self.assertTrue(expr_result.IsValid()) + self.assertEqual(expr_result.GetValue(), "42") + + def test_template_function_with_cast(self): + self.do_test_template_function(True) + + @expectedFailureAll(debug_info=["dwarf", "gmodules"]) + def test_template_function_without_cast(self): + self.do_test_template_function(False) Index: packages/Python/lldbsuite/test/lang/cpp/template-function/main.cpp =================================================================== --- packages/Python/lldbsuite/test/lang/cpp/template-function/main.cpp +++ packages/Python/lldbsuite/test/lang/cpp/template-function/main.cpp @@ -0,0 +1,16 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +template +int foo(T t1) { + return int(t1); +} + +int main() { + return foo(42); +} Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1590,6 +1590,7 @@ if (!type_handled) { clang::FunctionDecl *function_decl = nullptr; + clang::FunctionDecl *template_function_decl = nullptr; if (abstract_origin_die_form.IsValid()) { DWARFDIE abs_die = @@ -1617,10 +1618,14 @@ if (has_template_params) { ClangASTContext::TemplateParameterInfos template_param_infos; ParseTemplateParameterInfos(die, template_param_infos); + template_function_decl = m_ast.CreateFunctionDeclaration( + ignore_containing_context ? m_ast.GetTranslationUnitDecl() + : containing_decl_ctx, + type_name_cstr, clang_type, storage, is_inline); clang::FunctionTemplateDecl *func_template_decl = m_ast.CreateFunctionTemplateDecl( - containing_decl_ctx, function_decl, type_name_cstr, - template_param_infos); + containing_decl_ctx, template_function_decl, + type_name_cstr, template_param_infos); m_ast.CreateFunctionTemplateSpecializationInfo( function_decl, func_template_decl, template_param_infos); } @@ -1630,10 +1635,15 @@ if (function_decl) { LinkDeclContextToDIE(function_decl, die); - if (!function_param_decls.empty()) + if (!function_param_decls.empty()) { m_ast.SetFunctionParameters(function_decl, &function_param_decls.front(), function_param_decls.size()); + if (template_function_decl) + m_ast.SetFunctionParameters(template_function_decl, + &function_param_decls.front(), + function_param_decls.size()); + } ClangASTMetadata metadata; metadata.SetUserID(die.GetID());