Skip to content

[lldb] Fix FindDirectNestedType not working with class templates #81666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 16, 2024

Conversation

Endilll
Copy link
Contributor

@Endilll Endilll commented Feb 13, 2024

This patch attempts to fix lookup in class template specialization.

The first fixed problem is that during type lookup DeclContextGetName have been dropping template arguments. So when such a name was compared against a name in DW_AT_name, which contains template arguments, false mismatches have been occurring.

The second fixed problem is that LLDB's printing policy hasn't been matching Clang's printing policy when it comes to integral non-type template arguments. This again caused some false mismatches during type lookup, because Clang puts e.g. 3U in debug info for class specializations, but LLDB has been expecting just 3. This patch brings printing policy in line with what Clang does.

This patch attempts to fix lookup in class template specialization that have an integral non-type template parameter of non-int type. unsigned 3 might be printed as `3` or `3U` depending on PrintingPolicy. This patch bring it in line with what Clang does (which addes the suffix).
@Endilll Endilll added the lldb label Feb 13, 2024
@Endilll Endilll requested a review from Michael137 February 13, 2024 21:29
@llvmbot
Copy link
Member

llvmbot commented Feb 13, 2024

@llvm/pr-subscribers-lldb

Author: Vlad Serebrennikov (Endilll)

Changes

This patch attempts to fix lookup in class template specialization that have an integral non-type template parameter of non-int type. unsigned 3 might be printed as 3 or 3U depending on PrintingPolicy. This patch bring it in line with what Clang does (which addes the suffix).


Full diff: https://github.com/llvm/llvm-project/pull/81666.diff

3 Files Affected:

  • (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+7-2)
  • (modified) lldb/test/API/python_api/type/TestTypeList.py (+17)
  • (modified) lldb/test/API/python_api/type/main.cpp (+13)
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index a41e2c690853d2..e6a9d3f4f02836 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2165,6 +2165,7 @@ PrintingPolicy TypeSystemClang::GetTypePrintingPolicy() {
   // (and we then would have suppressed them from the type name) and also setups
   // where LLDB wasn't able to reconstruct the default arguments.
   printing_policy.SuppressDefaultTemplateArgs = false;
+  printing_policy.AlwaysIncludeTypeForTemplateArgument = true;
   return printing_policy;
 }
 
@@ -9265,8 +9266,12 @@ ConstString TypeSystemClang::DeclContextGetName(void *opaque_decl_ctx) {
   if (opaque_decl_ctx) {
     clang::NamedDecl *named_decl =
         llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
-    if (named_decl)
-      return ConstString(named_decl->getName());
+    if (named_decl) {
+      std::string name;
+      llvm::raw_string_ostream stream{name};
+      named_decl->getNameForDiagnostic(stream, GetTypePrintingPolicy(), /*qualified=*/ false);
+      return ConstString(name);
+    }
   }
   return ConstString();
 }
diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py
index c267defb58edf9..f874e87771c624 100644
--- a/lldb/test/API/python_api/type/TestTypeList.py
+++ b/lldb/test/API/python_api/type/TestTypeList.py
@@ -150,6 +150,23 @@ def test(self):
         invalid_type = task_type.FindDirectNestedType(None)
         self.assertFalse(invalid_type)
 
+        # Check that FindDirectNestedType works with types from AST
+        pointer = frame0.FindVariable("pointer")
+        pointer_type = pointer.GetType()
+        self.assertTrue(pointer_type)
+        self.DebugSBType(pointer_type)
+        pointer_info_type = pointer_type.template_args[0]
+        self.assertTrue(pointer_info_type)
+        self.DebugSBType(pointer_info_type)
+
+        pointer_masks1_type = pointer_info_type.FindDirectNestedType("Masks1")
+        self.assertTrue(pointer_masks1_type)
+        self.DebugSBType(pointer_masks1_type)
+
+        pointer_masks2_type = pointer_info_type.FindDirectNestedType("Masks2")
+        self.assertTrue(pointer_masks2_type)
+        self.DebugSBType(pointer_masks2_type)
+
         # We'll now get the child member 'id' from 'task_head'.
         id = task_head.GetChildMemberWithName("id")
         self.DebugSBValue(id)
diff --git a/lldb/test/API/python_api/type/main.cpp b/lldb/test/API/python_api/type/main.cpp
index 98de9707d88654..b587acdd96c590 100644
--- a/lldb/test/API/python_api/type/main.cpp
+++ b/lldb/test/API/python_api/type/main.cpp
@@ -34,6 +34,15 @@ class Task {
     {}
 };
 
+template <unsigned Value>
+struct PointerInfo {
+  enum Masks1 { pointer_mask };
+  enum class Masks2 { pointer_mask };
+};
+
+template <unsigned Value, typename InfoType = PointerInfo<Value>>
+struct Pointer {};
+
 enum EnumType {};
 enum class ScopedEnumType {};
 enum class EnumUChar : unsigned char {};
@@ -71,5 +80,9 @@ int main (int argc, char const *argv[])
     ScopedEnumType scoped_enum_type;
     EnumUChar scoped_enum_type_uchar;
 
+    Pointer<3> pointer;
+    PointerInfo<3>::Masks1 mask1 = PointerInfo<3>::Masks1::pointer_mask;
+    PointerInfo<3>::Masks2 mask2 = PointerInfo<3>::Masks2::pointer_mask;
+
     return 0; // Break at this line
 }

Copy link

github-actions bot commented Feb 13, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@Endilll
Copy link
Contributor Author

Endilll commented Feb 13, 2024

This PR is a draft because the new test, which is simplified llvm::PointerIntPair and llvm::PointerIntPairInfo, doesn't pass even with the proposed fix.

@Endilll Endilll marked this pull request as ready for review February 14, 2024 08:38
Copy link
Member

@Michael137 Michael137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Can you add a bit more detail into the commit message and PR description about what the underlying problem was? I.e., DeclContextGetName used to return type names without template parameters which FindTypes would then compare against the DW_AT_names from DWARF. But the names in DWARF do contain template parameters, causing the lookups to fail.

@Endilll Endilll merged commit 7b7d411 into llvm:main Feb 16, 2024
@Endilll Endilll deleted the lldb-fix-type-lookup branch February 16, 2024 16:40
@JDevlieghere
Copy link
Member

@Endilll
Copy link
Contributor Author

Endilll commented Feb 16, 2024

Trying to take a look, but https://green.lab.llvm.org is extraordinary slow for me.

@JDevlieghere
Copy link
Member

This is what the failure looks like:

======================================================================
FAIL: test_with_run_command_dsym (TestDataFormatterLibcxxChrono.LibcxxChronoDataFormatterTestCase)
   Test that that file and class static variables display correctly.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/jonas/llvm/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1676, in test_method
    return attrvalue(self)
  File "/Users/jonas/llvm/llvm-project/lldb/packages/Python/lldbsuite/test/decorators.py", line 150, in wrapper
    return func(*args, **kwargs)
  File "/Users/jonas/llvm/llvm-project/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/TestDataFormatterLibcxxChrono.py", line 35, in test_with_run_command
    self.expect(
  File "/Users/jonas/llvm/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 2447, in expect
    self.fail(log_msg)
AssertionError: Ran command:
"frame variable ss_tp"

Got output:
(std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long long> >) ss_tp = {
  __d_ = (__rep_ = 0)
}

Expecting sub string: "ss_tp = date/time=1970-01-01T00:00:00Z timestamp=0 s" (was not found)

@Endilll
Copy link
Contributor Author

Endilll commented Feb 16, 2024

@JDevlieghere I have an idea what have caused this failure, but I guess I have to enable libcxx to replicate it locally.

@JDevlieghere
Copy link
Member

Great. Let me know if you need help reproducing stuff on macOS.

@rastogishubham
Copy link
Contributor

I am going to revert this patch for now, to make sure that green dragon is up and running again

rastogishubham added a commit that referenced this pull request Feb 16, 2024
@rastogishubham
Copy link
Contributor

Hi @Endilll this patch has been reverted with 831ba95 to make sure the lldb bots are green.

@Endilll
Copy link
Contributor Author

Endilll commented Feb 16, 2024

I'd appreciate if you gave me a slightly bit more time, because I've been testing the fix locally in the meantime.

Endilll added a commit that referenced this pull request Feb 16, 2024
…plates (#81666)"

This patch attempts to fix lookup in class template specialization.

The first fixed problem is that during type lookup `DeclContextGetName`
have been dropping template arguments. So when such a name was compared
against a name in `DW_AT_name`, which contains template arguments, false
mismatches have been occurring.

The second fixed problem is that LLDB's printing policy hasn't been
matching Clang's printing policy when it comes to integral non-type
template arguments. This again caused some false mismatches during type
lookup, because Clang puts e.g. `3U` in debug info for class
specializations, but LLDB has been expecting just `3`. This patch brings
printing policy in line with what Clang does.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants