llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Bar Soloveychik (barsolo2000)

<details>
<summary>Changes</summary>

This patch introduces `RegisterTypeBuiltin`, an internal representation of GDB 
predefined types such as `uint32`, `bool`, `ieee_half`, and `data_ptr`.

- Store each builtin's encoding, display format, and optional fixed byte size.
- Use `std::nullopt` for target-dependent types such as pointers.
- Teach `RegisterTypeBuilderClang` to create the corresponding Clang 
`CompilerType`.
- Validate that the resulting type exactly matches the register size.
- Do not serialize builtins because GDB defines them implicitly by name.
- Add tests for fixed-size, named, pointer-sized, mismatched, and 
non-serialized builtins.

This provides the scalar element types needed to build register vectors in 
later patches. It does not parse or display vectors yet.

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


6 Files Affected:

- (modified) lldb/include/lldb/Utility/RegisterType.h (+36-2) 
- (modified) 
lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp (+36) 
- (modified) lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.h 
(+4) 
- (modified) lldb/source/Utility/RegisterType.cpp (+12) 
- (modified) lldb/unittests/Target/RegisterTypeBuilderClangTest.cpp (+65) 
- (modified) lldb/unittests/Utility/RegisterTypeTest.cpp (+32) 


``````````diff
diff --git a/lldb/include/lldb/Utility/RegisterType.h 
b/lldb/include/lldb/Utility/RegisterType.h
index 6734aca5a0b7c..bc403ae51c1db 100644
--- a/lldb/include/lldb/Utility/RegisterType.h
+++ b/lldb/include/lldb/Utility/RegisterType.h
@@ -9,9 +9,11 @@
 #ifndef LLDB_UTILITY_REGISTERTYPE_H
 #define LLDB_UTILITY_REGISTERTYPE_H
 
+#include "lldb/lldb-enumerations.h"
 #include "llvm/ADT/StringRef.h"
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <unordered_set>
 #include <vector>
@@ -26,6 +28,7 @@ class RegisterType {
   enum RegisterTypeKind {
     eRegisterTypeKindFlags,
     eRegisterTypeKindEnum,
+    eRegisterTypeKindBuiltin,
   };
 
   RegisterTypeKind getKind() const { return m_kind; }
@@ -39,8 +42,9 @@ class RegisterType {
   /// Output XML that describes this type, to be inserted into a target XML
   /// file. Reserved characters like "<" are replaced with their XML safe
   /// equivalents like "&lt;".
-  void ToXML(Stream &strm, std::unordered_set<std::string> &previously_emitted,
-             const RegisterType *user = nullptr) const;
+  virtual void ToXML(Stream &strm,
+                     std::unordered_set<std::string> &previously_emitted,
+                     const RegisterType *user = nullptr) const;
 
   /// Print a string escaped for use as an XML attribute value.
   static void PrintXMLAttributeValue(Stream &strm, llvm::StringRef value);
@@ -60,6 +64,9 @@ class RegisterType {
   /// reused after this instance is destroyed.
   uint64_t GetUID() const { return m_uid; }
 
+  /// Return this type's fixed size in bytes, if it has one.
+  virtual std::optional<uint64_t> GetByteSize() const { return std::nullopt; }
+
   void SetDependencies(std::vector<const RegisterType *> dependencies) {
     m_dependencies = dependencies;
   }
@@ -71,6 +78,33 @@ class RegisterType {
   std::vector<const RegisterType *> m_dependencies;
 };
 
+/// A predefined GDB target-description type. Builtin types are referenced by
+/// name and are not emitted as XML definitions.
+class RegisterTypeBuiltin : public RegisterType {
+public:
+  /// A missing byte size means the size depends on the target.
+  RegisterTypeBuiltin(std::string id, lldb::Encoding encoding,
+                      lldb::Format format, std::optional<uint64_t> byte_size);
+
+  lldb::Encoding GetEncoding() const { return m_encoding; }
+  lldb::Format GetFormat() const { return m_format; }
+  std::optional<uint64_t> GetByteSize() const override { return m_byte_size; }
+
+  void ToXML(Stream &strm, std::unordered_set<std::string> &previously_emitted,
+             const RegisterType *user = nullptr) const override;
+  void ToXMLElement(Stream &strm,
+                    const RegisterType *user = nullptr) const override;
+
+  static bool classof(const RegisterType *type) {
+    return type->getKind() == eRegisterTypeKindBuiltin;
+  }
+
+private:
+  const lldb::Encoding m_encoding;
+  const lldb::Format m_format;
+  const std::optional<uint64_t> m_byte_size;
+};
+
 } // namespace lldb_private
 
 #endif // LLDB_UTILITY_REGISTERTYPE_H
diff --git 
a/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp 
b/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
index 7a49c75f181bd..e06e92e3ba8a9 100644
--- a/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
+++ b/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
@@ -10,6 +10,7 @@
 
 #include "RegisterTypeBuilderClang.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Utility/RegisterType.h"
 #include "lldb/lldb-enumerations.h"
 
 using namespace lldb_private;
@@ -33,6 +34,37 @@ RegisterTypeBuilderClang::CreateInstance(Target &target) {
 RegisterTypeBuilderClang::RegisterTypeBuilderClang(Target &target)
     : m_target(target) {}
 
+CompilerType RegisterTypeBuilderClang::BuildBuiltinType(
+    const RegisterTypeBuiltin *builtin_type, uint32_t expected_byte_size,
+    lldb::TypeSystemClangSP type_system) {
+  if (auto type = GetExistingCompilerType(builtin_type, expected_byte_size))
+    return *type;
+
+  CompilerType compiler_type;
+  clang::ASTContext &ast = type_system->getASTContext();
+  // These GDB types have semantics that encoding and byte size cannot express.
+  if (builtin_type->GetID() == "data_ptr" ||
+      builtin_type->GetID() == "code_ptr")
+    compiler_type = type_system->GetType(ast.VoidPtrTy);
+  else if (builtin_type->GetID() == "bool")
+    compiler_type = type_system->GetType(ast.BoolTy);
+  else if (builtin_type->GetID() == "bfloat16")
+    compiler_type = type_system->GetType(ast.BFloat16Ty);
+  else if (std::optional<uint64_t> byte_size = builtin_type->GetByteSize())
+    compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
+        builtin_type->GetEncoding(), *byte_size * 8);
+
+  if (!compiler_type.IsValid() ||
+      llvm::expectedToOptional(compiler_type.GetByteSize(nullptr)) !=
+          expected_byte_size)
+    return {};
+
+  m_type_cache.try_emplace(
+      std::make_pair(builtin_type->GetUID(), expected_byte_size),
+      compiler_type);
+  return compiler_type;
+}
+
 CompilerType
 RegisterTypeBuilderClang::BuildEnumType(const RegisterTypeEnum *enum_type_info,
                                         uint32_t register_byte_size,
@@ -128,6 +160,10 @@ RegisterTypeBuilderClang::GetRegisterType(const 
RegisterInfo &reg_info) {
   // methods may call each other (Flags may use Enums for example).
 
   switch (reg_info.register_type->getKind()) {
+  case RegisterType::eRegisterTypeKindBuiltin:
+    return BuildBuiltinType(
+        llvm::cast<RegisterTypeBuiltin>(reg_info.register_type),
+        reg_info.byte_size, type_system);
   case RegisterType::eRegisterTypeKindFlags:
     return BuildFlagsType(
         llvm::dyn_cast<RegisterTypeFlags>(reg_info.register_type),
diff --git a/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.h 
b/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.h
index 8d970367a15b2..e4734a85269d4 100644
--- a/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.h
+++ b/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.h
@@ -33,6 +33,10 @@ class RegisterTypeBuilderClang : public RegisterTypeBuilder {
   CompilerType GetRegisterType(const RegisterInfo &reg_info) override;
 
 private:
+  CompilerType BuildBuiltinType(const RegisterTypeBuiltin *builtin_type,
+                                uint32_t expected_byte_size,
+                                lldb::TypeSystemClangSP type_system);
+
   CompilerType BuildEnumType(const RegisterTypeEnum *enum_type_info,
                              uint32_t register_byte_size,
                              lldb::TypeSystemClangSP type_system);
diff --git a/lldb/source/Utility/RegisterType.cpp 
b/lldb/source/Utility/RegisterType.cpp
index 4734b939ffdaf..583930915f3b9 100644
--- a/lldb/source/Utility/RegisterType.cpp
+++ b/lldb/source/Utility/RegisterType.cpp
@@ -43,3 +43,15 @@ void RegisterType::PrintXMLAttributeValue(Stream &strm, 
llvm::StringRef value) {
   llvm::printHTMLEscaped(value, escape_strm);
   strm << escaped;
 }
+
+RegisterTypeBuiltin::RegisterTypeBuiltin(std::string id,
+                                         lldb::Encoding encoding,
+                                         lldb::Format format,
+                                         std::optional<uint64_t> byte_size)
+    : RegisterType(eRegisterTypeKindBuiltin, std::move(id)),
+      m_encoding(encoding), m_format(format), m_byte_size(byte_size) {}
+
+void RegisterTypeBuiltin::ToXML(Stream &, std::unordered_set<std::string> &,
+                                const RegisterType *) const {}
+
+void RegisterTypeBuiltin::ToXMLElement(Stream &, const RegisterType *) const {}
diff --git a/lldb/unittests/Target/RegisterTypeBuilderClangTest.cpp 
b/lldb/unittests/Target/RegisterTypeBuilderClangTest.cpp
index c24c3e35957f9..33c014e92fc02 100644
--- a/lldb/unittests/Target/RegisterTypeBuilderClangTest.cpp
+++ b/lldb/unittests/Target/RegisterTypeBuilderClangTest.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/RegisterInfo.h"
+#include "lldb/Utility/RegisterType.h"
 #include "lldb/Utility/RegisterTypeFlags.h"
 #include "gtest/gtest.h"
 
@@ -160,4 +161,68 @@ TEST_F(RegisterTypeBuilderClangTest, 
CacheFollowsScratchTypeSystem) {
   EXPECT_NE(first, second);
 }
 
+TEST_F(RegisterTypeBuilderClangTest, BuildsFixedSizeBuiltin) {
+  Target &target = m_debugger_sp->GetDummyTarget();
+  RegisterTypeBuiltin builtin("uint32", eEncodingUint, eFormatHex, 4);
+  RegisterTypeBuilderClang builder(target);
+
+  CompilerType type = builder.GetRegisterType(MakeRegisterInfo(builtin, 4));
+  lldb::TypeSystemClangSP type_system =
+      ScratchTypeSystemClang::GetForTarget(target);
+
+  ASSERT_TRUE(type);
+  ASSERT_TRUE(type_system);
+  EXPECT_EQ(type,
+            type_system->GetType(type_system->getASTContext().UnsignedIntTy));
+}
+
+TEST_F(RegisterTypeBuilderClangTest, BuildsNamedBuiltins) {
+  Target &target = m_debugger_sp->GetDummyTarget();
+  RegisterTypeBuiltin boolean("bool", eEncodingUint, eFormatBoolean, 1);
+  RegisterTypeBuiltin ieee_half("ieee_half", eEncodingIEEE754, eFormatFloat, 
2);
+  RegisterTypeBuiltin bfloat16("bfloat16", eEncodingIEEE754, eFormatFloat, 2);
+  RegisterTypeBuilderClang builder(target);
+
+  CompilerType bool_type =
+      builder.GetRegisterType(MakeRegisterInfo(boolean, 1));
+  CompilerType half_type =
+      builder.GetRegisterType(MakeRegisterInfo(ieee_half, 2));
+  CompilerType bfloat_type =
+      builder.GetRegisterType(MakeRegisterInfo(bfloat16, 2));
+  lldb::TypeSystemClangSP type_system =
+      ScratchTypeSystemClang::GetForTarget(target);
+
+  ASSERT_TRUE(type_system);
+  clang::ASTContext &ast = type_system->getASTContext();
+  EXPECT_EQ(bool_type, type_system->GetType(ast.BoolTy));
+  EXPECT_EQ(half_type, type_system->GetType(ast.HalfTy));
+  EXPECT_EQ(bfloat_type, type_system->GetType(ast.BFloat16Ty));
+}
+
+TEST_F(RegisterTypeBuilderClangTest, BuildsTargetSizedPointer) {
+  Target &target = m_debugger_sp->GetDummyTarget();
+  RegisterTypeBuiltin builtin("data_ptr", eEncodingUint, eFormatAddressInfo,
+                              std::nullopt);
+  RegisterTypeBuilderClang builder(target);
+
+  CompilerType type = builder.GetRegisterType(MakeRegisterInfo(builtin, 8));
+  lldb::TypeSystemClangSP type_system =
+      ScratchTypeSystemClang::GetForTarget(target);
+
+  ASSERT_TRUE(type);
+  ASSERT_TRUE(type_system);
+  EXPECT_EQ(type, 
type_system->GetType(type_system->getASTContext().VoidPtrTy));
+}
+
+TEST_F(RegisterTypeBuilderClangTest, RejectsSizeMismatch) {
+  Target &target = m_debugger_sp->GetDummyTarget();
+  RegisterTypeBuiltin uint32("uint32", eEncodingUint, eFormatHex, 4);
+  RegisterTypeBuiltin pointer("data_ptr", eEncodingUint, eFormatAddressInfo,
+                              std::nullopt);
+  RegisterTypeBuilderClang builder(target);
+
+  EXPECT_FALSE(builder.GetRegisterType(MakeRegisterInfo(uint32, 8)));
+  EXPECT_FALSE(builder.GetRegisterType(MakeRegisterInfo(pointer, 4)));
+}
+
 } // namespace
diff --git a/lldb/unittests/Utility/RegisterTypeTest.cpp 
b/lldb/unittests/Utility/RegisterTypeTest.cpp
index 6fd2d546dabc4..34de8c15b69c6 100644
--- a/lldb/unittests/Utility/RegisterTypeTest.cpp
+++ b/lldb/unittests/Utility/RegisterTypeTest.cpp
@@ -6,6 +6,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "lldb/Utility/RegisterType.h"
 #include "lldb/Utility/RegisterTypeFlags.h"
 #include "lldb/Utility/StreamString.h"
 #include "gmock/gmock.h"
@@ -597,3 +598,34 @@ TEST(RegisterTypeTest, XMLDefinitionsAreDeduplicatedByID) {
                               "  <evalue name=\"first\" value=\"0\"/>\n"
                               "</enum>\n");
 }
+
+TEST(RegisterTypeBuiltinTest, Construction) {
+  RegisterTypeBuiltin type("uint32", eEncodingUint, eFormatHex, 4);
+
+  EXPECT_EQ(type.GetID(), "uint32");
+  EXPECT_EQ(type.GetEncoding(), eEncodingUint);
+  EXPECT_EQ(type.GetFormat(), eFormatHex);
+  ASSERT_TRUE(type.GetByteSize());
+  EXPECT_EQ(*type.GetByteSize(), 4u);
+}
+
+TEST(RegisterTypeBuiltinTest, TargetDependentByteSize) {
+  RegisterTypeBuiltin type("data_ptr", eEncodingUint, eFormatAddressInfo,
+                           std::nullopt);
+
+  EXPECT_FALSE(type.GetByteSize());
+}
+
+TEST(RegisterTypeBuiltinTest, DoesNotSerialize) {
+  RegisterTypeBuiltin builtin("uint8", eEncodingUint, eFormatHex, 1);
+  const RegisterType &type = builtin;
+  StreamString strm;
+  std::unordered_set<std::string> previously_emitted;
+
+  type.ToXML(strm, previously_emitted);
+  EXPECT_TRUE(strm.GetString().empty());
+  EXPECT_TRUE(previously_emitted.empty());
+
+  type.ToXMLElement(strm);
+  EXPECT_TRUE(strm.GetString().empty());
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/218725
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to