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