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_";
47 register_type_name += name;
48 // See if we have made this type before and can reuse it.
49 CompilerType fields_type =
50 type_system->GetTypeForIdentifier<clang::CXXRecordDecl>(
51 register_type_name);
52
53 if (!fields_type) {
54 // In most ABI, a change of field type means a change in storage unit.
55 // We want it all in one unit, so we use a field type the same as the
56 // register's size.
57 CompilerType field_uint_type =
58 type_system->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint,
59 byte_size * 8);
60
61 fields_type = type_system->CreateRecordType(
63 register_type_name, llvm::to_underlying(clang::TagTypeKind::Struct),
65 type_system->StartTagDeclarationDefinition(fields_type);
66
67 // We assume that RegisterFlags has padded and sorted the fields
68 // already.
69 for (const RegisterFlags::Field &field : flags.GetFields()) {
70 type_system->AddFieldToRecordType(fields_type, field.GetName(),
71 field_uint_type, lldb::eAccessPublic,
72 field.GetSizeInBits());
73 }
74
75 type_system->CompleteTagDeclarationDefinition(fields_type);
76 // So that the size of the type matches the size of the register.
77 type_system->SetIsPacked(fields_type);
78
79 // This should be true if RegisterFlags padded correctly.
80 assert(*fields_type.GetByteSize(nullptr) == flags.GetSize());
81 }
82
83 return fields_type;
84}
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
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.
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.
Definition: SBAttachInfo.h:14
std::shared_ptr< lldb_private::RegisterTypeBuilder > RegisterTypeBuilderSP
Definition: lldb-forward.h:388
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eEncodingUint
unsigned integer
std::shared_ptr< lldb_private::TypeSystemClang > TypeSystemClangSP
Definition: lldb-forward.h:458