================ @@ -0,0 +1,69 @@ +""" +Test the SBModule and SBTarget type lookup APIs to find multiple types. +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TypeFindFirstTestCase(TestBase): + def test_find_first_type(self): + """ + Test SBTarget::FindTypes() and SBModule::FindTypes() APIs. + + We had issues where our declaration context when finding types was + incorrectly calculated where a type in a namepace, and a type in a + function that was also in the same namespace would match a lookup. For + example: + + namespace a { + struct Foo { + int foo; + }; + + unsigned foo() { + typedef unsigned Foo; + Foo foo = 12; + return foo; + } + } // namespace a + + + Previously LLDB would calculate the declaration context of "a::Foo" + correctly, but incorrectly calculate the declaration context of "Foo" + from within the foo() function as "a::Foo". Adding tests to ensure this + works correctly. + """ + self.build() + target = self.createTestTarget() + exe_module = target.GetModuleAtIndex(0) + self.assertTrue(exe_module.IsValid()) + # Test the SBTarget and SBModule APIs for FindFirstType + for api in [target, exe_module]: + # We should find the "a::Foo" but not the "Foo" type in the function + types = api.FindTypes("a::Foo") + self.assertEqual(types.GetSize(), 1) + type_str0 = str(types.GetTypeAtIndex(0)) + self.assertIn('struct Foo', type_str0) + + # When we search by type basename, we should find any type whose + # basename matches "Foo", so "a::Foo" and the "Foo" type in the + # function. + types = api.FindTypes("Foo") + self.assertEqual(types.GetSize(), 2) + type_str0 = str(types.GetTypeAtIndex(0)) + type_str1 = str(types.GetTypeAtIndex(1)) + # We don't know which order the types will come back as, so + if 'struct Foo' in type_str0: + self.assertIn('typedef Foo', type_str1) + else: + self.assertIn('struct Foo', type_str1) + + # When we search by type basename with "::" prepended, we should + # only types in the root namespace which means only "Foo" type in ---------------- labath wrote:
> So I don't know of anyone that would use the function name when asking for a > type, even if that type was defined in a function. It's certainly not valid C++, if that's what you mean (c++ just doesn't give you the option of referring to a local type from outside of the function), but I don't think this kind of qualification is a revolutionary concept. For example if the aforementioned local struct had a constructor, it's mangled name would be `_ZZN1a3fooEvEN3FooC1Ev `, that is `a::foo()::Foo::Foo()`. Gdb (AFAICT) does not support these kinds of lookups, but it also does not return the type for query like `::Foo`. (instead gdb supports searching for a type in a specific block/function, which is kind of similar to this) > To make the expression parser work, we should be able to find all of the > types using a context like just "Foo", where we would find both `::Foo` and > the `Foo` from `a::foo()`, but sort the results based on the > CompilerDeclContext of each type that was returned. If we are evaluating an > expression in `a::foo()`, the `Foo` type from that function could tell us the > CompilerDeclContext it was defined in and we would find the closest match to > where the expression is being run. This approach has the problem that a type (or really, anything) defined with the same name at a class level would take precedence over a local declaration. For example with code like: ``` struct Foo { int one; } class Class { struct Foo { int two; } void Method() { struct Foo { int three; } } }; ``` if we were stopped in `Class::Method`, then the name `Foo` should refer to the third definition with that name, but I believe this will end up using the second one because clang will see the class-level declaration first and will not bother asking for other possible definitions. I think we used to use the same approach for local variables, but then we changed the implementation because of the same shadowing problem. https://github.com/llvm/llvm-project/pull/94846 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits