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
16
17using namespace lldb_private;
18
20
21void RegisterTypeBuilderClang::Initialize() {
22 static llvm::once_flag g_once_flag;
23 llvm::call_once(g_once_flag, []() {
24 PluginManager::RegisterPlugin(GetPluginNameStatic(),
25 GetPluginDescriptionStatic(), CreateInstance);
26 });
27}
28
30
33 return std::make_shared<RegisterTypeBuilderClang>(target);
34}
35
37 : m_target(target) {}
38
40 const std::string &name, const lldb_private::RegisterFlags &flags,
41 uint32_t byte_size) {
42 lldb::TypeSystemClangSP type_system =
44 assert(type_system);
45
46 std::string register_type_name = "__lldb_register_fields_" + name;
47 // See if we have made this type before and can reuse it.
48 CompilerType fields_type =
49 type_system->GetTypeForIdentifier<clang::CXXRecordDecl>(
50 register_type_name);
51
52 if (!fields_type) {
53 // In most ABI, a change of field type means a change in storage unit.
54 // We want it all in one unit, so we use a field type the same as the
55 // register's size.
56 CompilerType field_uint_type =
57 type_system->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint,
58 byte_size * 8);
59
60 fields_type = type_system->CreateRecordType(
62 register_type_name, llvm::to_underlying(clang::TagTypeKind::Struct),
64 type_system->StartTagDeclarationDefinition(fields_type);
65
66 // We assume that RegisterFlags has padded and sorted the fields
67 // already.
68 for (const RegisterFlags::Field &field : flags.GetFields()) {
69 CompilerType field_type = field_uint_type;
70
71 if (const FieldEnum *enum_type = field.GetEnum()) {
72 const FieldEnum::Enumerators &enumerators = enum_type->GetEnumerators();
73 if (!enumerators.empty()) {
74 // Enums can be used by many registers and the size of each register
75 // may be different. The register size is used as the underlying size
76 // of the enumerators, so we must make one enum type per register size
77 // it is used with.
78 std::string enum_type_name = "__lldb_register_fields_enum_" +
79 enum_type->GetID() + "_" +
80 std::to_string(byte_size);
81
82 // Enums can be used by mutiple fields and multiple registers, so we
83 // may have built this one already.
84 CompilerType field_enum_type =
85 type_system->GetTypeForIdentifier<clang::EnumDecl>(
86 enum_type_name);
87
88 if (field_enum_type)
89 field_type = field_enum_type;
90 else {
91 field_type = type_system->CreateEnumerationType(
92 enum_type_name, type_system->GetTranslationUnitDecl(),
93 OptionalClangModuleID(), Declaration(), field_uint_type, false);
94
95 type_system->StartTagDeclarationDefinition(field_type);
96
97 Declaration decl;
98 for (auto enumerator : enumerators) {
99 type_system->AddEnumerationValueToEnumerationType(
100 field_type, decl, enumerator.m_name.c_str(),
101 enumerator.m_value, byte_size * 8);
102 }
103
104 type_system->CompleteTagDeclarationDefinition(field_type);
105 }
106 }
107 }
108
109 type_system->AddFieldToRecordType(fields_type, field.GetName(),
110 field_type, lldb::eAccessPublic,
111 field.GetSizeInBits());
112 }
113
114 type_system->CompleteTagDeclarationDefinition(fields_type);
115 // So that the size of the type matches the size of the register.
116 type_system->SetIsPacked(fields_type);
117
118 // This should be true if RegisterFlags padded correctly.
119 assert(*fields_type.GetByteSize(nullptr) == flags.GetSize());
120 }
121
122 return fields_type;
123}
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:32
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
std::optional< 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
std::vector< Enumerator > Enumerators
Definition: RegisterFlags.h:39
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
const std::vector< Field > & GetFields() const
CompilerType GetRegisterType(const std::string &name, const lldb_private::RegisterFlags &flags, uint32_t byte_size) override
static lldb::RegisterTypeBuilderSP CreateInstance(Target &target)
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
Definition: lldb-forward.h:394
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eEncodingUint
unsigned integer
std::shared_ptr< lldb_private::TypeSystemClang > TypeSystemClangSP
Definition: lldb-forward.h:466