[IR] Allow fast math flags on fptrunc and fpext (#115894)
[llvm-project.git] / lldb / source / Plugins / RegisterTypeBuilder / RegisterTypeBuilderClang.cpp
blob1ecde7bee58209abac97376186fcc6f7ce13090d
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 //===----------------------------------------------------------------------===//
9 #include "clang/AST/DeclCXX.h"
11 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
12 #include "RegisterTypeBuilderClang.h"
13 #include "lldb/Core/PluginManager.h"
14 #include "lldb/Target/RegisterFlags.h"
15 #include "lldb/lldb-enumerations.h"
17 using namespace lldb_private;
19 LLDB_PLUGIN_DEFINE(RegisterTypeBuilderClang)
21 void 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 });
29 void RegisterTypeBuilderClang::Terminate() {}
31 lldb::RegisterTypeBuilderSP
32 RegisterTypeBuilderClang::CreateInstance(Target &target) {
33 return std::make_shared<RegisterTypeBuilderClang>(target);
36 RegisterTypeBuilderClang::RegisterTypeBuilderClang(Target &target)
37 : m_target(target) {}
39 CompilerType RegisterTypeBuilderClang::GetRegisterType(
40 const std::string &name, const lldb_private::RegisterFlags &flags,
41 uint32_t byte_size) {
42 lldb::TypeSystemClangSP type_system =
43 ScratchTypeSystemClang::GetForTarget(m_target);
44 assert(type_system);
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);
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);
60 fields_type = type_system->CreateRecordType(
61 nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
62 register_type_name, llvm::to_underlying(clang::TagTypeKind::Struct),
63 lldb::eLanguageTypeC);
64 type_system->StartTagDeclarationDefinition(fields_type);
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;
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);
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);
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);
95 type_system->StartTagDeclarationDefinition(field_type);
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);
104 type_system->CompleteTagDeclarationDefinition(field_type);
109 type_system->AddFieldToRecordType(fields_type, field.GetName(),
110 field_type, lldb::eAccessPublic,
111 field.GetSizeInBits());
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);
118 // This should be true if RegisterFlags padded correctly.
119 assert(*fields_type.GetByteSize(nullptr) == flags.GetSize());
122 return fields_type;