[Lldb-commits] [lldb] 5dd7c16 - [lldb] Don't create Clang AST nodes in GetDIEClassTemplateParams
Arthur Eubanks via lldb-commits
lldb-commits at lists.llvm.org
Tue Jan 24 19:13:59 PST 2023
Author: Arthur Eubanks
Date: 2023-01-24T19:13:19-08:00
New Revision: 5dd7c16c3dcfd3154a53ee59e0e092c1e0092197
URL: https://github.com/llvm/llvm-project/commit/5dd7c16c3dcfd3154a53ee59e0e092c1e0092197
DIFF: https://github.com/llvm/llvm-project/commit/5dd7c16c3dcfd3154a53ee59e0e092c1e0092197.diff
LOG: [lldb] Don't create Clang AST nodes in GetDIEClassTemplateParams
Otherwise we may be inserting a decl into a DeclContext that's not fully defined yet.
This simplifies/removes some clang AST node creation code. Instead, use
clang::printTemplateArgumentList().
Reviewed By: Michael137
Differential Revision: https://reviews.llvm.org/D142413
Added:
lldb/test/API/lang/cpp/nested-template/Makefile
lldb/test/API/lang/cpp/nested-template/TestNestedTemplate.py
lldb/test/API/lang/cpp/nested-template/main.cpp
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 9ebc49417138b..56bd089b86a1e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -745,28 +745,9 @@ DWARFASTParserClang::GetDIEClassTemplateParams(const DWARFDIE &die) {
if (llvm::StringRef(die.GetName()).contains("<"))
return ConstString();
- clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE(die, nullptr);
TypeSystemClang::TemplateParameterInfos template_param_infos;
if (ParseTemplateParameterInfos(die, template_param_infos)) {
- // Most of the parameters here don't matter, but we make sure the base name
- // is empty so when we print the name we only get the template parameters.
- clang::ClassTemplateDecl *class_template_decl =
- m_ast.ParseClassTemplateDecl(decl_ctx, GetOwningClangModule(die),
- eAccessPublic, "", clang::TTK_Struct,
- template_param_infos);
- if (!class_template_decl)
- return ConstString();
-
- clang::ClassTemplateSpecializationDecl *class_specialization_decl =
- m_ast.CreateClassTemplateSpecializationDecl(
- decl_ctx, GetOwningClangModule(die), class_template_decl,
- clang::TTK_Struct, template_param_infos);
- if (!class_specialization_decl)
- return ConstString();
- CompilerType clang_type =
- m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
- ConstString name = clang_type.GetTypeName(/*BaseOnly*/ true);
- return name;
+ return ConstString(m_ast.PrintTemplateParams(template_param_infos));
}
return ConstString();
}
@@ -1541,9 +1522,9 @@ DWARFASTParserClang::GetCPlusPlusQualifiedName(const DWARFDIE &die) {
DWARFDIE parent_decl_ctx_die = die.GetParentDeclContextDIE();
// TODO: change this to get the correct decl context parent....
while (parent_decl_ctx_die) {
- // The name may not contain template parameters due to simplified template
- // names; we must reconstruct the full name from child template parameter
- // dies via GetTemplateParametersString().
+ // The name may not contain template parameters due to
+ // -gsimple-template-names; we must reconstruct the full name from child
+ // template parameter dies via GetDIEClassTemplateParams().
const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
switch (parent_tag) {
case DW_TAG_namespace: {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index c078d997df9f3..0733d22a0069b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -95,11 +95,6 @@ class DWARFASTParserClang : public DWARFASTParser {
/// parameters from the DIE name and instead always adds template parameter
/// children DIEs.
///
- /// Currently this is only called in two places, when uniquing C++ classes and
- /// when looking up the definition for a declaration (which is then cached).
- /// If this is ever called more than twice per DIE, we need to start caching
- /// the results to prevent unbounded growth of the created clang AST nodes.
- ///
/// \param die The struct/class DWARFDIE containing template parameters.
/// \return A string, including surrounding '<>', of the template parameters.
/// If the DIE's name already has '<>', returns an empty ConstString because
@@ -146,10 +141,6 @@ class DWARFASTParserClang : public DWARFASTParser {
lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
- /// Get the template parameters of a die as a string if the die name does not
- /// already contain them. This happens with -gsimple-template-names.
- std::string GetTemplateParametersString(const DWARFDIE &die);
-
std::string GetCPlusPlusQualifiedName(const DWARFDIE &die);
bool ParseChildMembers(
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index d1745d970c441..e3c61b0f00bb4 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1431,6 +1431,24 @@ static TemplateParameterList *CreateTemplateParameterList(
return template_param_list;
}
+std::string TypeSystemClang::PrintTemplateParams(
+ const TemplateParameterInfos &template_param_infos) {
+ llvm::SmallVector<NamedDecl *, 8> ignore;
+ clang::TemplateParameterList *template_param_list =
+ CreateTemplateParameterList(getASTContext(), template_param_infos,
+ ignore);
+ llvm::SmallVector<clang::TemplateArgument, 2> args =
+ template_param_infos.args;
+ if (template_param_infos.hasParameterPack()) {
+ args.append(template_param_infos.packed_args->args);
+ }
+ std::string str;
+ llvm::raw_string_ostream os(str);
+ clang::printTemplateArgumentList(os, args, GetTypePrintingPolicy(),
+ template_param_list);
+ return str;
+}
+
clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
clang::FunctionDecl *func_decl,
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 8307fa5556088..f94a055cb9ada 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -1067,6 +1067,10 @@ class TypeSystemClang : public TypeSystem {
bool SetDeclIsForcefullyCompleted(const clang::TagDecl *td);
+ /// Return the template parameters (including surrounding <>) in string form.
+ std::string
+ PrintTemplateParams(const TemplateParameterInfos &template_param_infos);
+
private:
/// Returns the PrintingPolicy used when generating the internal type names.
/// These type names are mostly used for the formatter selection.
diff --git a/lldb/test/API/lang/cpp/nested-template/Makefile b/lldb/test/API/lang/cpp/nested-template/Makefile
new file mode 100644
index 0000000000000..e49374fb0b1eb
--- /dev/null
+++ b/lldb/test/API/lang/cpp/nested-template/Makefile
@@ -0,0 +1,5 @@
+CXX_SOURCES := main.cpp
+
+CFLAGS_EXTRAS = $(TEST_CFLAGS_EXTRAS) $(LIMIT_DEBUG_INFO_FLAGS)
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/cpp/nested-template/TestNestedTemplate.py b/lldb/test/API/lang/cpp/nested-template/TestNestedTemplate.py
new file mode 100644
index 0000000000000..e44ce7ec61a0d
--- /dev/null
+++ b/lldb/test/API/lang/cpp/nested-template/TestNestedTemplate.py
@@ -0,0 +1,24 @@
+"""
+Test that a nested template parameter works with simple template names.
+"""
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+class NestedTemplateTestCase(TestBase):
+ def do_test(self, debug_flags):
+ self.build(dictionary=debug_flags)
+ self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
+ self.expect("image lookup -A -t 'Inner<int>'", DATA_TYPES_DISPLAYED_CORRECTLY, substrs=["1 match found"])
+
+ @skipIf(compiler=no_match("clang"))
+ @skipIf(compiler_version=["<", "15.0"])
+ def test_simple_template_names(self):
+ self.do_test(dict(TEST_CFLAGS_EXTRAS="-gsimple-template-names"))
+
+ @skipIf(compiler=no_match("clang"))
+ @skipIf(compiler_version=["<", "15.0"])
+ def test_no_simple_template_names(self):
+ self.do_test(dict(TEST_CFLAGS_EXTRAS="-gno-simple-template-names"))
diff --git a/lldb/test/API/lang/cpp/nested-template/main.cpp b/lldb/test/API/lang/cpp/nested-template/main.cpp
new file mode 100644
index 0000000000000..06d1094880964
--- /dev/null
+++ b/lldb/test/API/lang/cpp/nested-template/main.cpp
@@ -0,0 +1,10 @@
+struct Outer {
+ Outer() {}
+
+ template <class T>
+ struct Inner {};
+};
+
+int main() {
+ Outer::Inner<int> oi;
+}
More information about the lldb-commits
mailing list