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 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" 16 17 using namespace lldb_private; 18 19 LLDB_PLUGIN_DEFINE(RegisterTypeBuilderClang) 20 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 }); 27 } 28 29 void RegisterTypeBuilderClang::Terminate() {} 30 31 lldb::RegisterTypeBuilderSP 32 RegisterTypeBuilderClang::CreateInstance(Target &target) { 33 return std::make_shared<RegisterTypeBuilderClang>(target); 34 } 35 36 RegisterTypeBuilderClang::RegisterTypeBuilderClang(Target &target) 37 : m_target(target) {} 38 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); 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( 62 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, 63 register_type_name, clang::TTK_Struct, lldb::eLanguageTypeC); 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 type_system->AddFieldToRecordType(fields_type, field.GetName(), 70 field_uint_type, lldb::eAccessPublic, 71 field.GetSizeInBits()); 72 } 73 74 type_system->CompleteTagDeclarationDefinition(fields_type); 75 // So that the size of the type matches the size of the register. 76 type_system->SetIsPacked(fields_type); 77 78 // This should be true if RegisterFlags padded correctly. 79 assert(*fields_type.GetByteSize(nullptr) == flags.GetSize()); 80 } 81 82 return fields_type; 83 } 84