Skip to content

[lldb][SBType] GetBasicType to unwrap canonical type #149112

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Michael137
Copy link
Member

SBType::GetBasicType fails on typedefs to primitive types. The docs for GetBasicType state:

Returns the BasicType value that is most appropriate to this type

But, e.g., for uint64_t this would currently return eBasicTypeInvalid.

TypeSystemClang::GetBasicTypeEnumeration (which is what SBType::GetBasicType uses) doesn't see through typedefs. Inside LLDB we almost always call GetBasicTypeEnumeration on the canonical type. In the cases we don't I suspect those were just subtle bugs. This patch gets the canonical type inside of GetBasicTypeEnumeration instead.

rdar://155829208

`SBType::GetBasicType` fails on typedefs to primitive types. The docs for `GetBasicType` state:
```
Returns the BasicType value that is most appropriate to this type
```
But, e.g., for `uint64_t` this would currently return `eBasicTypeInvalid`.

`TypeSystemClang::GetBasicTypeEnumeration` (which is what
`SBType::GetBasicType` uses) doesn't see through typedefs.
Inside LLDB we almost always call `GetBasicTypeEnumeration`
on the canonical type. In the cases we don't I suspect those were just
subtle bugs. This patch gets the canonical type inside of
`GetBasicTypeEnumeration` instead.

rdar://155829208
@Michael137 Michael137 requested a review from labath July 16, 2025 15:07
@Michael137 Michael137 requested a review from JDevlieghere as a code owner July 16, 2025 15:07
@llvmbot llvmbot added the lldb label Jul 16, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 16, 2025

@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)

Changes

SBType::GetBasicType fails on typedefs to primitive types. The docs for GetBasicType state:

Returns the BasicType value that is most appropriate to this type

But, e.g., for uint64_t this would currently return eBasicTypeInvalid.

TypeSystemClang::GetBasicTypeEnumeration (which is what SBType::GetBasicType uses) doesn't see through typedefs. Inside LLDB we almost always call GetBasicTypeEnumeration on the canonical type. In the cases we don't I suspect those were just subtle bugs. This patch gets the canonical type inside of GetBasicTypeEnumeration instead.

rdar://155829208


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

6 Files Affected:

  • (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+1-1)
  • (modified) lldb/source/Symbol/CompilerType.cpp (+4-6)
  • (modified) lldb/source/ValueObject/ValueObject.cpp (+4-4)
  • (added) lldb/test/API/python_api/sbtype_basic_type/Makefile (+3)
  • (added) lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py (+32)
  • (added) lldb/test/API/python_api/sbtype_basic_type/main.cpp (+11)
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 82e07bb8e0ffb..216d5a9f4745f 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -5467,7 +5467,7 @@ CompilerType TypeSystemClang::GetBuiltinTypeByName(ConstString name) {
 lldb::BasicType
 TypeSystemClang::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
   if (type) {
-    clang::QualType qual_type(GetQualType(type));
+    clang::QualType qual_type(GetCanonicalQualType(type));
     const clang::Type::TypeClass type_class = qual_type->getTypeClass();
     if (type_class == clang::Type::Builtin) {
       switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index dd81fc2361f88..62c0ddf51c012 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -354,12 +354,11 @@ bool CompilerType::IsSigned() const {
 }
 
 bool CompilerType::IsNullPtrType() const {
-  return GetCanonicalType().GetBasicTypeEnumeration() ==
-         lldb::eBasicTypeNullPtr;
+  return GetBasicTypeEnumeration() == lldb::eBasicTypeNullPtr;
 }
 
 bool CompilerType::IsBoolean() const {
-  return GetCanonicalType().GetBasicTypeEnumeration() == lldb::eBasicTypeBool;
+  return GetBasicTypeEnumeration() == lldb::eBasicTypeBool;
 }
 
 bool CompilerType::IsEnumerationIntegerTypeSigned() const {
@@ -379,7 +378,7 @@ bool CompilerType::IsPromotableIntegerType() const {
   if (IsUnscopedEnumerationType())
     return true;
 
-  switch (GetCanonicalType().GetBasicTypeEnumeration()) {
+  switch (GetBasicTypeEnumeration()) {
   case lldb::eBasicTypeBool:
   case lldb::eBasicTypeChar:
   case lldb::eBasicTypeSignedChar:
@@ -455,8 +454,7 @@ bool CompilerType::IsContextuallyConvertibleToBool() const {
 }
 
 bool CompilerType::IsBasicType() const {
-  return GetCanonicalType().GetBasicTypeEnumeration() !=
-         lldb::eBasicTypeInvalid;
+  return GetBasicTypeEnumeration() != lldb::eBasicTypeInvalid;
 }
 
 std::string CompilerType::TypeDescription() {
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index a6fb3fad65251..84ad130299221 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -3228,8 +3228,8 @@ lldb::ValueObjectSP ValueObject::CastToBasicType(CompilerType type) {
         llvm::APSInt ext =
             int_value_or_err->extOrTrunc(type_byte_size * CHAR_BIT);
         Scalar scalar_int(ext);
-        llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
-            type.GetCanonicalType().GetBasicTypeEnumeration());
+        llvm::APFloat f =
+            scalar_int.CreateAPFloatFromAPSInt(type.GetBasicTypeEnumeration());
         return ValueObject::CreateValueObjectFromAPFloat(target, f, type,
                                                          "result");
       } else {
@@ -3245,7 +3245,7 @@ lldb::ValueObjectSP ValueObject::CastToBasicType(CompilerType type) {
         if (int_value_or_err) {
           Scalar scalar_int(*int_value_or_err);
           llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(
-              type.GetCanonicalType().GetBasicTypeEnumeration());
+              type.GetBasicTypeEnumeration());
           return ValueObject::CreateValueObjectFromAPFloat(target, f, type,
                                                            "result");
         } else {
@@ -3261,7 +3261,7 @@ lldb::ValueObjectSP ValueObject::CastToBasicType(CompilerType type) {
         if (float_value_or_err) {
           Scalar scalar_float(*float_value_or_err);
           llvm::APFloat f = scalar_float.CreateAPFloatFromAPFloat(
-              type.GetCanonicalType().GetBasicTypeEnumeration());
+              type.GetBasicTypeEnumeration());
           return ValueObject::CreateValueObjectFromAPFloat(target, f, type,
                                                            "result");
         } else {
diff --git a/lldb/test/API/python_api/sbtype_basic_type/Makefile b/lldb/test/API/python_api/sbtype_basic_type/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/python_api/sbtype_basic_type/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py b/lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py
new file mode 100644
index 0000000000000..ba74341324039
--- /dev/null
+++ b/lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py
@@ -0,0 +1,32 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+    def test(self):
+        """Test that SBType.GetBasicType unwraps typedefs."""
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "return", lldb.SBFileSpec("main.cpp")
+        )
+
+        a = self.frame().FindVariable("a")
+        self.assertTrue(a)
+
+        int_basic_type = a.GetType().GetBasicType()
+        self.assertEqual(int_basic_type, 13)
+
+        b = self.frame().FindVariable("b")
+        self.assertTrue(b)
+
+        c = self.frame().FindVariable("c")
+        self.assertTrue(c)
+
+        d = self.frame().FindVariable("d")
+        self.assertTrue(d)
+
+        self.assertEqual(a.GetType().GetBasicType(), int_basic_type)
+        self.assertEqual(b.GetType().GetBasicType(), int_basic_type)
+        self.assertEqual(c.GetType().GetBasicType(), int_basic_type)
diff --git a/lldb/test/API/python_api/sbtype_basic_type/main.cpp b/lldb/test/API/python_api/sbtype_basic_type/main.cpp
new file mode 100644
index 0000000000000..7ded37186edaf
--- /dev/null
+++ b/lldb/test/API/python_api/sbtype_basic_type/main.cpp
@@ -0,0 +1,11 @@
+using T1 = int;
+using T2 = T1;
+using T3 = T2;
+
+int main() {
+  int a;
+  T1 b;
+  T2 c;
+  T3 d;
+  return 0;
+}

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.

2 participants