Index: packages/Python/lldbsuite/test/expression_command/radar_47565290/Makefile =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/expression_command/radar_47565290/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Index: packages/Python/lldbsuite/test/expression_command/radar_47565290/TestClassTemplateSpecializationParametersHandling.py =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/expression_command/radar_47565290/TestClassTemplateSpecializationParametersHandling.py @@ -0,0 +1,26 @@ +""" +Test Expression Parser code gen for ClassTemplateSpecializationDecl. This is a fix for rdar://problem/47564499 +""" + +from __future__ import print_function + + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestClassTemplateSpecializationParametersHandling(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_with_run_command(self): + """Test that that file and class static variables display correctly.""" + self.build() + + (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here', + lldb.SBFileSpec("main.cpp", False)) + + self.expect("expr -u 0 -- b.foo()", substrs=['$0 = 1']) Index: packages/Python/lldbsuite/test/expression_command/radar_47565290/main.cpp =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/expression_command/radar_47565290/main.cpp @@ -0,0 +1,26 @@ +template +class A { + +}; + +class BB; + +template <> +class A { + +}; + +class Value{}; + +class BB final : public Value, + public A { +public: + int foo() { return 1;} +}; + + +int main() { + BB b; + + return b.foo() - 1; // break here +} Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -1549,25 +1549,31 @@ } } - if (template_param_infos.packed_args && - template_param_infos.packed_args->args.size()) { + if (template_param_infos.packed_args) { IdentifierInfo *identifier_info = nullptr; if (template_param_infos.pack_name && template_param_infos.pack_name[0]) identifier_info = &ast->Idents.get(template_param_infos.pack_name); const bool parameter_pack_true = true; - if (IsValueParam(template_param_infos.packed_args->args[0])) { - template_param_decls.push_back(NonTypeTemplateParmDecl::Create( - *ast, decl_context, - SourceLocation(), SourceLocation(), depth, num_template_params, - identifier_info, - template_param_infos.packed_args->args[0].getIntegralType(), - parameter_pack_true, nullptr)); - } else { + + if (template_param_infos.packed_args->args.size()) { + + if (IsValueParam(template_param_infos.packed_args->args[0])) { + template_param_decls.push_back(NonTypeTemplateParmDecl::Create( + *ast, decl_context, SourceLocation(), SourceLocation(), depth, + num_template_params, identifier_info, + template_param_infos.packed_args->args[0].getIntegralType(), + parameter_pack_true, nullptr)); + } else { + template_param_decls.push_back(TemplateTypeParmDecl::Create( + *ast, decl_context, SourceLocation(), SourceLocation(), depth, + num_template_params, identifier_info, is_typename, + parameter_pack_true)); + } + } else if (identifier_info) { template_param_decls.push_back(TemplateTypeParmDecl::Create( - *ast, decl_context, - SourceLocation(), SourceLocation(), depth, num_template_params, - identifier_info, - is_typename, parameter_pack_true)); + *ast, decl_context, SourceLocation(), SourceLocation(), depth, + num_template_params, identifier_info, is_typename, + parameter_pack_true)); } } clang::Expr *const requires_clause = nullptr; // TODO: Concepts