Michael137 created this revision. Michael137 added reviewers: aprantl, martong. Herald added a subscriber: rnkovacs. Herald added a project: All. Michael137 requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
The problem here is that the ASTImporter adds the template base class member FieldDecl to the DeclContext twice. This happens because we don't construct a `LookupPtr` for decls that originate from modules and thus the ASTImporter never realizes that the FieldDecl has already been imported. These duplicate decls then break the assumption of the LayoutBuilder which expects only a single member decl to exist. The test will be fixed by a follow-up revision and is thus skipped for now. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D133944 Files: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/Makefile lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/TestBaseTemplateWithSameArg.py lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/base_module.cpp lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/base_module.h lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/main.cpp lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module.modulemap lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module1.cpp lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module1.h lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module2.cpp lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module2.h
Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module2.h =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module2.h @@ -0,0 +1,10 @@ +#ifndef MOD2_H_IN +#define MOD2_H_IN + +#include "base_module.h" + +struct ClassInMod2 { + ClassInMod3<int> VecInMod2; +}; + +#endif Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module2.cpp =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module2.cpp @@ -0,0 +1,3 @@ +#include "module2.h" + +namespace crash {} // namespace crash Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module1.h =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module1.h @@ -0,0 +1,10 @@ +#ifndef MOD1_H_IN +#define MOD1_H_IN + +#include "base_module.h" + +struct ClassInMod1 { + ClassInMod3<float> VecInMod1; +}; + +#endif // _H_IN Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module1.cpp =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module1.cpp @@ -0,0 +1,3 @@ +#include "module1.h" + +namespace crash {} // namespace crash Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module.modulemap =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/module.modulemap @@ -0,0 +1,14 @@ +module Module1 { + header "module1.h" + export * +} + +module Module2 { + header "module2.h" + export * +} + +module BaseModule { + header "base_module.h" + export * +} Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/main.cpp @@ -0,0 +1,15 @@ +#include "module1.h" +#include "module2.h" + +#include <cstdio> + +int main() { + ClassInMod1 FromMod1; + ClassInMod2 FromMod2; + + FromMod1.VecInMod1.BaseMember = 137; + FromMod2.VecInMod2.BaseMember = 42; + + std::puts("Break here"); + return 0; +} Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/base_module.h =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/base_module.h @@ -0,0 +1,8 @@ +#ifndef MOD3_H_IN +#define MOD3_H_IN + +template <typename SIZE_T> struct ClassInMod3Base { int BaseMember = 0; }; + +template <typename T> struct ClassInMod3 : public ClassInMod3Base<int> {}; + +#endif // _H_IN Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/base_module.cpp =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/base_module.cpp @@ -0,0 +1,3 @@ +#include "base_module.h" + +namespace crash {} // namespace crash Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/TestBaseTemplateWithSameArg.py =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/TestBaseTemplateWithSameArg.py @@ -0,0 +1,56 @@ +""" +Tests the scenario where we evaluate expressions +of two types in different modules that reference +a base class template instantiated with the same +template argument. + +Note that, +1. Since the decls originate from modules, LLDB + marks them as such and Clang doesn't create + a LookupPtr map on the corresponding DeclContext. + This prevents regular DeclContext::lookup from + succeeding. +2. Because we reference the same base template + from two different modules we get a redeclaration + chain for the base class's ClassTemplateSpecializationDecl. + The importer will import all FieldDecls into the + same DeclContext on the redeclaration chain. If + we don't do the bookkeeping correctly we end up + with duplicate decls on the same DeclContext leading + to crashes down the line. +""" + +import lldb +import os +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestBaseTemplateWithSameArg(TestBase): + + @add_test_categories(["gmodules"]) + @skipIf(bugnumber='rdar://96581048') + def test_same_base_template_arg(self): + self.build() + + self.main_source_file = lldb.SBFileSpec("main.cpp") + + (target, process, main_thread, _) = lldbutil.run_to_source_breakpoint(self, + "Break here", self.main_source_file) + + self.expect_expr("FromMod1", result_type="ClassInMod1", result_children=[ + ValueCheck(name="VecInMod1", children=[ + ValueCheck(name="ClassInMod3Base<int>", children=[ + ValueCheck(name="BaseMember", value="137") + ]) + ]) + ]) + + self.expect_expr("FromMod2", result_type="ClassInMod2", result_children=[ + ValueCheck(name="VecInMod2", children=[ + ValueCheck(name="ClassInMod3Base<int>", children=[ + ValueCheck(name="BaseMember", value="42") + ]) + ]) + ]) Index: lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/Makefile =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/gmodules/base-template-with-same-arg/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp module1.cpp module2.cpp base_module.cpp + +include Makefile.rules
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits