9#include "clang/AST/DeclCXX.h"
15#include "llvm/ADT/bit.h"
16#include "llvm/Support/ErrorHandling.h"
35 return std::make_shared<RegisterTypeBuilderClang>(target);
48 clang::ASTContext &ast = type_system->getASTContext();
50 if (builtin_type->
GetID() ==
"data_ptr" ||
51 builtin_type->
GetID() ==
"code_ptr")
52 compiler_type = type_system->GetType(ast.VoidPtrTy);
53 else if (builtin_type->
GetID() ==
"bool")
54 compiler_type = type_system->GetType(ast.BoolTy);
55 else if (builtin_type->
GetID() ==
"bfloat16")
56 compiler_type = type_system->GetType(ast.BFloat16Ty);
57 else if (std::optional<uint64_t> byte_size = builtin_type->
GetByteSize())
58 compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
62 llvm::expectedToOptional(compiler_type.
GetByteSize(
nullptr)) !=
67 std::make_pair(builtin_type->
GetUID(), expected_byte_size),
74 uint32_t register_byte_size,
76 if (
auto maybe_compiler_type =
78 return *maybe_compiler_type;
82 register_byte_size * 8);
83 CompilerType enum_type = type_system->CreateEnumerationType(
87 type_system->StartTagDeclarationDefinition(enum_type);
91 type_system->AddEnumerationValueToEnumerationType(
92 enum_type, decl, enumerator.m_name.c_str(), enumerator.m_value,
93 register_byte_size * 8);
96 type_system->CompleteTagDeclarationDefinition(enum_type);
99 std::make_pair(enum_type_info->
GetUID(), register_byte_size), enum_type);
106 if (
auto maybe_compiler_type =
108 return *maybe_compiler_type;
115 register_byte_size * 8);
117 CompilerType flags_type = type_system->CreateRecordType(
120 type_system->StartTagDeclarationDefinition(flags_type);
122 for (
auto field : flags_info->
GetFields()) {
126 if (!enum_type_info->GetEnumerators().empty())
128 BuildEnumType(enum_type_info, register_byte_size, type_system);
130 type_system->AddFieldToRecordType(flags_type, field.GetName(), field_type,
131 field.GetSizeInBits());
134 type_system->CompleteTagDeclarationDefinition(flags_type);
136 type_system->SetIsPacked(flags_type);
140 llvm::expectedToOptional(flags_type.
GetByteSize(
nullptr)).value_or(0) ==
144 std::make_pair(flags_info->
GetUID(), register_byte_size), flags_type);
150 uint32_t expected_byte_size,
152 if (!expected_byte_size)
157 std::optional<uint32_t> element_size =
160 *element_size * vector_type->
GetCount() != expected_byte_size)
165 BuildType(element_register_type, *element_size, type_system);
169 const auto *builtin_element =
170 llvm::dyn_cast<RegisterTypeBuiltin>(element_register_type);
171 bool pointer_element =
172 builtin_element && (builtin_element->GetID() ==
"data_ptr" ||
173 builtin_element->GetID() ==
"code_ptr");
177 bool use_vector = builtin_element && !pointer_element &&
178 builtin_element->GetID() !=
"bool" &&
179 llvm::has_single_bit(vector_type->
GetCount());
180 CompilerType compiler_type = type_system->CreateArrayType(
181 element_type, vector_type->
GetCount(), use_vector);
184 llvm::expectedToOptional(compiler_type.
GetByteSize(
nullptr));
187 if (use_vector && compiler_size != expected_byte_size) {
188 compiler_type = type_system->CreateArrayType(
189 element_type, vector_type->
GetCount(),
false);
191 llvm::expectedToOptional(compiler_type.
GetByteSize(
nullptr));
193 if (compiler_size != expected_byte_size)
197 std::make_pair(vector_type->
GetUID(), expected_byte_size), compiler_type);
198 return compiler_type;
203 uint32_t available_byte_size,
205 std::optional<uint32_t> byte_size =
207 if (!byte_size || *byte_size > available_byte_size)
209 uint32_t expected_byte_size = *byte_size;
210 if (!expected_byte_size)
215 std::vector<std::pair<llvm::StringRef, CompilerType>> fields;
216 fields.reserve(union_type->
GetFields().size());
220 std::optional<uint32_t> field_size =
222 if (!field_size || *field_size > expected_byte_size)
226 BuildType(field.GetType(), *field_size, type_system);
229 fields.emplace_back(field.GetName(), field_type);
235 std::string type_name =
"__lldb_register_union_" +
236 std::to_string(union_type->
GetUID()) +
"_" +
237 std::to_string(expected_byte_size);
238 CompilerType compiler_type = type_system->CreateRecordType(
241 type_system->StartTagDeclarationDefinition(compiler_type);
242 for (
const auto &[field_name, field_type] : fields)
243 type_system->AddFieldToRecordType(compiler_type, field_name, field_type,
245 type_system->CompleteTagDeclarationDefinition(compiler_type);
246 type_system->SetIsPacked(compiler_type);
248 if (llvm::expectedToOptional(compiler_type.
GetByteSize(
nullptr)) !=
253 std::make_pair(union_type->
GetUID(), expected_byte_size), compiler_type);
254 return compiler_type;
259 uint32_t expected_byte_size,
261 switch (register_type->
getKind()) {
264 expected_byte_size, type_system);
267 expected_byte_size, type_system);
269 return BuildUnionType(llvm::cast<RegisterTypeUnion>(register_type),
270 expected_byte_size, type_system);
279 if (std::optional<uint64_t> fixed_size = register_type->
GetByteSize()) {
281 return static_cast<uint32_t
>(*fixed_size);
285 switch (register_type->
getKind()) {
287 const auto *builtin_type = llvm::cast<RegisterTypeBuiltin>(register_type);
288 if (builtin_type->GetID() !=
"data_ptr" &&
289 builtin_type->GetID() !=
"code_ptr")
291 std::optional<uint64_t> pointer_size = llvm::expectedToOptional(
292 type_system->GetType(type_system->getASTContext().VoidPtrTy)
293 .GetByteSize(
nullptr));
294 if (!pointer_size || *pointer_size >
UINT32_MAX)
296 return static_cast<uint32_t
>(*pointer_size);
299 const auto *vector_type = llvm::cast<RegisterTypeVector>(register_type);
300 std::optional<uint32_t> element_size =
302 if (!element_size || *element_size >
UINT32_MAX / vector_type->GetCount())
304 return *element_size * vector_type->GetCount();
307 uint32_t byte_size = 0;
309 llvm::cast<RegisterTypeUnion>(register_type)->GetFields()) {
310 std::optional<uint32_t> field_size =
314 byte_size = std::max(byte_size, *field_size);
360 llvm_unreachable(
"Unhandled RegisterType kind");
364 const RegisterType *register_type, uint32_t register_byte_size) {
368 return cached->second;
#define LLDB_PLUGIN_DEFINE(PluginName)
Generic representation of a type in a programming language.
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
A class that describes the declaration location of a lldb object.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
CompilerType BuildVectorType(const RegisterTypeVector *vector_type, uint32_t expected_byte_size, lldb::TypeSystemClangSP type_system)
std::optional< CompilerType > GetExistingCompilerType(const RegisterType *register_type, uint32_t register_byte_size)
CompilerType BuildEnumType(const RegisterTypeEnum *enum_type_info, uint32_t register_byte_size, lldb::TypeSystemClangSP type_system)
CompilerType BuildFlagsType(const RegisterTypeFlags *flags_info, uint32_t register_byte_size, lldb::TypeSystemClangSP type_system)
CompilerType BuildType(const RegisterType *register_type, uint32_t expected_byte_size, lldb::TypeSystemClangSP type_system)
std::weak_ptr< TypeSystemClang > m_cached_type_system
CompilerType GetRegisterType(const RegisterInfo ®_info) override
Do not cache the returned CompilerType.
llvm::SmallDenseMap< std::pair< uint64_t, uint32_t >, CompilerType, 8 > m_type_cache
CompilerType BuildBuiltinType(const RegisterTypeBuiltin *builtin_type, uint32_t expected_byte_size, lldb::TypeSystemClangSP type_system)
CompilerType BuildUnionType(const RegisterTypeUnion *union_type, uint32_t available_byte_size, lldb::TypeSystemClangSP type_system)
std::optional< uint32_t > GetExpectedByteSize(const RegisterType *register_type, lldb::TypeSystemClangSP type_system)
Return the target-resolved byte size of register_type.
static llvm::StringRef GetPluginNameStatic()
RegisterTypeBuilderClang(Target &target)
static llvm::StringRef GetPluginDescriptionStatic()
static lldb::RegisterTypeBuilderSP CreateInstance(Target &target)
A predefined GDB target-description type.
lldb::Encoding GetEncoding() const
std::optional< uint64_t > GetByteSize() const override
Return this type's fixed size in bytes, if it has one.
const Enumerators & GetEnumerators() const
const std::vector< Field > & GetFields() const
A GDB target-description union type.
const std::vector< Field > & GetFields() const
A GDB target-description vector type. The element type must outlive it.
const RegisterType * GetElementType() const
uint32_t GetCount() const
RegisterTypeKind getKind() const
virtual std::optional< uint64_t > GetByteSize() const
Return this type's fixed size in bytes, if it has one.
const std::string & GetID() const
@ eRegisterTypeKindBuiltin
@ eRegisterTypeKindVector
uint64_t GetUID() const
Return an identifier unique among all RegisterType instances constructed during the lifetime of the L...
static lldb::TypeSystemClangSP GetForTarget(Target &target, std::optional< IsolatedASTKind > ast_kind=DefaultAST, bool create_on_demand=true)
Returns the scratch TypeSystemClang for the given target.
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::RegisterTypeBuilder > RegisterTypeBuilderSP
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eEncodingUint
unsigned integer
std::shared_ptr< lldb_private::TypeSystemClang > TypeSystemClangSP
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_size
Size in bytes of the register.
const RegisterType * register_type
If not nullptr, a type defined by XML descriptions.