emrekultursay updated this revision to Diff 339694. emrekultursay added a comment.
Add test Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D100977/new/ https://reviews.llvm.org/D100977 Files: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/test/API/functionalities/lazy-loading/TestLazyLoading.py lldb/test/API/functionalities/lazy-loading/main.cpp lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/Makefile lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/TestPointerToMemberTypeDependingOnParentSize.py lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/main.cpp
Index: lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/main.cpp @@ -0,0 +1,35 @@ +// This class just serves as an indirection between LLDB and Clang. LLDB might +// be tempted to check the member type of DependsOnParam2 for whether it's +// in some 'currently-loading' state before trying to produce the record layout. +// By inheriting from ToLayout this will make LLDB just check if +// DependsOnParam1 is currently being loaded (which it's not) but it won't +// check if all the types DependsOnParam2 is depending on for its layout are +// currently parsed. +template <typename ToLayoutParam> struct DependsOnParam1 : ToLayoutParam {}; +// This class forces the memory layout of it's type parameter to be created. +template <typename ToLayoutParam> struct DependsOnParam2 { + DependsOnParam1<ToLayoutParam> m; +}; + +// This is the class that LLDB has to generate the record layout for. +struct ToLayout { + // The class part of this pointer-to-member type has a memory layout that + // depends on the surrounding class. If LLDB eagerly tries to layout the + // class part of a pointer-to-member type while parsing, then layouting this + // type should cause a test failure (as we aren't done parsing ToLayout + // at this point). + int DependsOnParam2<ToLayout>::* pointer_to_member_member; + // Some dummy member variable. This is only there so that Clang can detect + // that the record layout is inconsistent (i.e., the number of fields in the + // layout doesn't fit to the fields in the declaration). + int some_member; +}; + +// Emit the definition of DependsOnParam2<ToLayout>. It seems Clang won't +// emit the definition of a class template if it's only used in the class part +// of a pointer-to-member type. +DependsOnParam2<ToLayout> x; + +ToLayout test_var; + +int main() { return test_var.some_member; } Index: lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/TestPointerToMemberTypeDependingOnParentSize.py =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/TestPointerToMemberTypeDependingOnParentSize.py @@ -0,0 +1,24 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @no_debug_info_test + def test(self): + """ + This tests a pointer-to-member member which class part is the + surrounding class. LLDB should *not* try to generate the record layout + of the class when parsing pointer-to-member types while parsing debug + info (as the references class might not be complete when the type is + parsed). + """ + self.build() + self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + + # Force the record layout for 'ToLayout' to be generated by printing + # a value of it's type. + self.expect("target variable test_var") Index: lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/Makefile =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/pointer_to_member_type_depending_on_parent_size/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules Index: lldb/test/API/functionalities/lazy-loading/main.cpp =================================================================== --- lldb/test/API/functionalities/lazy-loading/main.cpp +++ lldb/test/API/functionalities/lazy-loading/main.cpp @@ -26,6 +26,7 @@ struct StaticClassMember { int i; }; struct UnusedClassMember { int i; }; struct UnusedClassMemberPtr { int i; }; +struct PointerToMember { int i; }; namespace NS { class ClassInNamespace { @@ -36,6 +37,7 @@ int dummy; // Prevent bug where LLDB always completes first member. ClassMember member; static StaticClassMember static_member; + int (PointerToMember::*ptr_to_member); UnusedClassMember unused_member; UnusedClassMemberPtr *unused_member_ptr; int enteredFunction() { Index: lldb/test/API/functionalities/lazy-loading/TestLazyLoading.py =================================================================== --- lldb/test/API/functionalities/lazy-loading/TestLazyLoading.py +++ lldb/test/API/functionalities/lazy-loading/TestLazyLoading.py @@ -41,6 +41,7 @@ class_we_enter_decl = [class_decl_kind, "ClassWeEnter"] class_member_decl = [struct_decl_kind, "ClassMember"] class_static_member_decl = [struct_decl_kind, "StaticClassMember"] + class_pointer_to_member_decl = [struct_decl_kind, "PointerToMember"] unused_class_member_decl = [struct_decl_kind, "UnusedClassMember"] unused_class_member_ptr_decl = [struct_decl_kind, "UnusedClassMemberPtr"] @@ -58,6 +59,7 @@ self.assert_decl_not_loaded(self.class_in_namespace_decl) self.assert_decl_not_loaded(self.class_member_decl) self.assert_decl_not_loaded(self.class_static_member_decl) + self.assert_decl_not_loaded(self.class_pointer_to_member_decl) self.assert_decl_not_loaded(self.unused_class_member_decl) def get_ast_dump(self): @@ -232,6 +234,8 @@ self.assert_decl_loaded(self.class_member_decl) # We didn't load the type of the unused static member. self.assert_decl_not_completed(self.class_static_member_decl) + # We didn't load the type of the unused pointer-to-member member. + self.assert_decl_not_completed(self.class_pointer_to_member_decl) # This should not have loaded anything else. self.assert_decl_not_loaded(self.other_struct_decl) Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1357,7 +1357,7 @@ dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true); CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType(); - CompilerType class_clang_type = class_type->GetLayoutCompilerType(); + CompilerType class_clang_type = class_type->GetForwardCompilerType(); CompilerType clang_type = TypeSystemClang::CreateMemberPointerType( class_clang_type, pointee_clang_type);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits