LLDB mainline
RegisterTypeBuilderClang.cpp
Go to the documentation of this file.
1//===-- RegisterTypeBuilderClang.cpp ---------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "clang/AST/DeclCXX.h"
10
14
15using namespace lldb_private;
16
18
23
27
30 return std::make_shared<RegisterTypeBuilderClang>(target);
31}
32
35
38 uint32_t register_byte_size,
39 lldb::TypeSystemClangSP type_system) {
40 if (auto maybe_compiler_type =
41 GetExistingCompilerType(enum_type_info, register_byte_size))
42 return *maybe_compiler_type;
43
44 CompilerType register_uint_type =
45 type_system->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint,
46 register_byte_size * 8);
47 CompilerType enum_type = type_system->CreateEnumerationType(
48 "", type_system->GetTranslationUnitDecl(), OptionalClangModuleID(),
49 Declaration(), register_uint_type, false);
50
51 type_system->StartTagDeclarationDefinition(enum_type);
52
53 Declaration decl;
54 for (const auto &enumerator : enum_type_info->GetEnumerators()) {
55 type_system->AddEnumerationValueToEnumerationType(
56 enum_type, decl, enumerator.m_name.c_str(), enumerator.m_value,
57 register_byte_size * 8);
58 }
59
60 type_system->CompleteTagDeclarationDefinition(enum_type);
61
62 m_type_cache.try_emplace(
63 std::make_pair(enum_type_info->GetUID(), register_byte_size), enum_type);
64 return enum_type;
65}
66
68 const lldb_private::RegisterTypeFlags *flags_info,
69 uint32_t register_byte_size, lldb::TypeSystemClangSP type_system) {
70 if (auto maybe_compiler_type =
71 GetExistingCompilerType(flags_info, register_byte_size))
72 return *maybe_compiler_type;
73
74 // In most ABI, a change of field type means a change in storage unit.
75 // We want it all in one unit, so we use a field type the same as the
76 // register's size.
77 CompilerType field_uint_type =
78 type_system->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint,
79 register_byte_size * 8);
80
81 CompilerType flags_type = type_system->CreateRecordType(
82 nullptr, OptionalClangModuleID(), "",
83 llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
84 type_system->StartTagDeclarationDefinition(flags_type);
85
86 for (auto field : flags_info->GetFields()) {
87 CompilerType field_type = field_uint_type;
88
89 if (const RegisterTypeEnum *enum_type_info = field.GetEnum())
90 if (!enum_type_info->GetEnumerators().empty())
91 field_type =
92 BuildEnumType(enum_type_info, register_byte_size, type_system);
93
94 type_system->AddFieldToRecordType(flags_type, field.GetName(), field_type,
95 field.GetSizeInBits());
96 }
97
98 type_system->CompleteTagDeclarationDefinition(flags_type);
99 // So that the size of the type matches the size of the register.
100 type_system->SetIsPacked(flags_type);
101
102 // This should be true if RegisterTypeFlags padded correctly.
103 assert(
104 llvm::expectedToOptional(flags_type.GetByteSize(nullptr)).value_or(0) ==
105 flags_info->GetSize());
106
107 m_type_cache.try_emplace(
108 std::make_pair(flags_info->GetUID(), register_byte_size), flags_type);
109 return flags_type;
110}
111
114 lldb::TypeSystemClangSP type_system =
116 assert(type_system);
117
118 if (m_cached_type_system.lock() != type_system) {
119 m_type_cache.clear();
120 m_cached_type_system = type_system;
121 }
122
123 if (!reg_info.register_type)
124 return CompilerType();
125
126 // Note that we do not check the type cache here because types can be nested.
127 // There is a cache check in each of the Build<subtype> methods, and those
128 // methods may call each other (Flags may use Enums for example).
129
130 switch (reg_info.register_type->getKind()) {
132 return BuildFlagsType(
133 llvm::dyn_cast<RegisterTypeFlags>(reg_info.register_type),
134 reg_info.byte_size, type_system);
136 return BuildEnumType(
137 llvm::dyn_cast<RegisterTypeEnum>(reg_info.register_type),
138 reg_info.byte_size, type_system);
139 }
140}
141
143 const RegisterType *register_type, uint32_t register_byte_size) {
144 auto cached =
145 m_type_cache.find({register_type->GetUID(), register_byte_size});
146 if (cached != m_type_cache.end())
147 return cached->second;
148
149 return {};
150}
#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.
Definition Declaration.h:24
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
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)
std::weak_ptr< TypeSystemClang > m_cached_type_system
CompilerType GetRegisterType(const RegisterInfo &reg_info) override
Do not cache the returned CompilerType.
llvm::SmallDenseMap< std::pair< uint64_t, uint32_t >, CompilerType, 8 > m_type_cache
static lldb::RegisterTypeBuilderSP CreateInstance(Target &target)
const Enumerators & GetEnumerators() const
const std::vector< Field > & GetFields() const
RegisterTypeKind getKind() const
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.