diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2020,6 +2020,7 @@ CompilerType clang_type; uint64_t uval64 = 0; bool uval64_valid = false; + bool is_default_template_arg = false; if (num_attributes > 0) { DWARFFormValue form_value; for (size_t i = 0; i < num_attributes; ++i) { @@ -2050,6 +2051,11 @@ uval64 = form_value.Unsigned(); } break; + case DW_AT_default_value: + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + is_default_template_arg = form_value.Boolean(); + } + break; default: break; } @@ -2075,16 +2081,18 @@ template_param_infos.InsertArg( name, clang::TemplateArgument(ast, llvm::APSInt(apint, !is_signed), - ClangUtil::GetQualType(clang_type))); + ClangUtil::GetQualType(clang_type)), + is_default_template_arg); } else { template_param_infos.InsertArg( - name, - clang::TemplateArgument(ClangUtil::GetQualType(clang_type))); + name, clang::TemplateArgument(ClangUtil::GetQualType(clang_type)), + is_default_template_arg); } } else { auto *tplt_type = m_ast.CreateTemplateTemplateParmDecl(template_name); template_param_infos.InsertArg( - name, clang::TemplateArgument(clang::TemplateName(tplt_type))); + name, clang::TemplateArgument(clang::TemplateName(tplt_type)), + is_default_template_arg); } } } diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -377,7 +377,6 @@ size_t Size() const { return args.size(); } llvm::ArrayRef GetArgs() const { return args; } - llvm::ArrayRef GetNames() const { return names; } clang::TemplateArgument const &Front() const { @@ -385,9 +384,16 @@ return args.front(); } - void InsertArg(char const *name, clang::TemplateArgument arg) { + bool IsDefaultArg(size_t idx) const { + assert(defaulted_arg_check.size() > idx); + return defaulted_arg_check[idx]; + } + + void InsertArg(char const *name, clang::TemplateArgument arg, + bool is_defaulted = false) { args.emplace_back(std::move(arg)); names.push_back(name); + defaulted_arg_check.push_back(is_defaulted); } // Parameter pack related @@ -427,6 +433,11 @@ llvm::SmallVector names; llvm::SmallVector args; + /// Element 'i' is 'true' if 'args[i]' has a default + /// argument according to debug-info (indicated + /// via DW_AT_default_value). + llvm::SmallVector defaulted_arg_check; + const char * pack_name = nullptr; std::unique_ptr packed_args; }; diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -1392,14 +1392,40 @@ TemplateArgument const &targ = args[i]; if (IsValueParam(targ)) { QualType template_param_type = targ.getIntegralType(); - template_param_decls.push_back(NonTypeTemplateParmDecl::Create( + auto *decl = NonTypeTemplateParmDecl::Create( ast, decl_context, SourceLocation(), SourceLocation(), depth, i, identifier_info, template_param_type, parameter_pack, - ast.getTrivialTypeSourceInfo(template_param_type))); + ast.getTrivialTypeSourceInfo(template_param_type)); + + if (template_param_infos.IsDefaultArg(i)) { + if (targ.getKind() == TemplateArgument::Integral) { + Expr *LiteralExpr = nullptr; + if (template_param_type->isBooleanType()) { + LiteralExpr = CXXBoolLiteralExpr::Create( + ast, !targ.getAsIntegral().isZero(), template_param_type, {}); + } else { + LiteralExpr = IntegerLiteral::Create(ast, targ.getAsIntegral(), + template_param_type, {}); + } + + decl->setDefaultArgument(LiteralExpr); + } + } + + template_param_decls.push_back(decl); } else { - template_param_decls.push_back(TemplateTypeParmDecl::Create( + auto *decl = TemplateTypeParmDecl::Create( ast, decl_context, SourceLocation(), SourceLocation(), depth, i, - identifier_info, is_typename, parameter_pack)); + identifier_info, is_typename, parameter_pack); + + if (template_param_infos.IsDefaultArg(i)) { + if (targ.getKind() == TemplateArgument::Type) { + decl->setDefaultArgument( + ast.getTrivialTypeSourceInfo(targ.getAsType())); + } + } + + template_param_decls.push_back(decl); } } diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp --- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -9,6 +9,9 @@ #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" #include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h" +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "lldb/Core/Debugger.h" #include "TestingSupport/Symbol/ClangTestUtils.h" #include "TestingSupport/Symbol/YAMLModuleTester.h" #include "gmock/gmock.h" @@ -19,7 +22,23 @@ using namespace lldb_private::dwarf; namespace { -class DWARFASTParserClangTests : public testing::Test {}; +static std::once_flag debugger_initialize_flag; + +class DWARFASTParserClangTests : public testing::Test { + void SetUp() override { + HostInfo::Initialize(); + PlatformMacOSX::Initialize(); + std::call_once(debugger_initialize_flag, + []() { Debugger::Initialize(nullptr); }); + ArchSpec arch("x86_64-apple-macosx-"); + Platform::SetHostPlatform( + PlatformRemoteMacOSX::CreateInstance(true, &arch)); + } + void TearDown() override { + PlatformMacOSX::Terminate(); + HostInfo::Terminate(); + } +}; class DWARFASTParserClangStub : public DWARFASTParserClang { public: @@ -404,3 +423,378 @@ EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max + 2), llvm::Failed()); } + +TEST_F(DWARFASTParserClangTests, TestDefaultTemplateParamParsing) { + // Tests parsing DW_AT_default_value for template parameters. + + // template + // class foo {}; + // + // template