88
99#include " clang/AST/DeclCXX.h"
1010
11- #include " Plugins/TypeSystem/Clang/TypeSystemClang.h"
1211#include " RegisterTypeBuilderClang.h"
1312#include " lldb/Core/PluginManager.h"
14- #include " lldb/Utility/RegisterTypeFlags.h"
1513#include " lldb/lldb-enumerations.h"
1614
1715using namespace lldb_private ;
@@ -35,94 +33,122 @@ RegisterTypeBuilderClang::CreateInstance(Target &target) {
3533RegisterTypeBuilderClang::RegisterTypeBuilderClang (Target &target)
3634 : m_target(target) {}
3735
38- CompilerType RegisterTypeBuilderClang::GetRegisterType (
39- const std::string &name, const lldb_private::RegisterType &type_info,
40- uint32_t byte_size) {
36+ static std::string MakeTypeName (const RegisterType &type_info,
37+ uint32_t register_byte_size) {
38+ std::string type_name = " __lldb_register_" ;
39+ switch (type_info.getKind ()) {
40+ case RegisterType::eRegisterTypeKindFlags:
41+ type_name += " flags_" ;
42+ break ;
43+ case RegisterType::eRegisterTypeKindEnum:
44+ // Enums can be used by many registers and the size of each register
45+ // may be different. The register size is used as the underlying size
46+ // of the enumerators, so we must make one enum type per register size
47+ // it is used with.
48+ type_name += " enum_" + std::to_string (register_byte_size) + " _" ;
49+ break ;
50+ }
51+
52+ return type_name + type_info.GetID ();
53+ }
54+
55+ CompilerType
56+ RegisterTypeBuilderClang::BuildEnumType (const RegisterTypeEnum &enum_type_info,
57+ uint32_t register_byte_size,
58+ lldb::TypeSystemClangSP type_system) {
59+ std::string enum_type_name = MakeTypeName (enum_type_info, register_byte_size);
60+
61+ // Reuse existing type if we can.
62+ if (CompilerType enum_type =
63+ type_system->GetTypeForIdentifier <clang::EnumDecl>(
64+ type_system->getASTContext (), enum_type_name))
65+ return enum_type;
66+
67+ CompilerType register_uint_type =
68+ type_system->GetBuiltinTypeForEncodingAndBitSize (lldb::eEncodingUint,
69+ register_byte_size * 8 );
70+ CompilerType enum_type = type_system->CreateEnumerationType (
71+ enum_type_name, type_system->GetTranslationUnitDecl (),
72+ OptionalClangModuleID (), Declaration (), register_uint_type, false );
73+
74+ type_system->StartTagDeclarationDefinition (enum_type);
75+
76+ Declaration decl;
77+ for (const auto &enumerator : enum_type_info.GetEnumerators ()) {
78+ type_system->AddEnumerationValueToEnumerationType (
79+ enum_type, decl, enumerator.m_name .c_str (), enumerator.m_value ,
80+ register_byte_size * 8 );
81+ }
82+
83+ type_system->CompleteTagDeclarationDefinition (enum_type);
84+
85+ return enum_type;
86+ }
87+
88+ CompilerType RegisterTypeBuilderClang::BuildFlagsType (
89+ const lldb_private::RegisterTypeFlags &flags_info,
90+ uint32_t register_byte_size, lldb::TypeSystemClangSP type_system) {
91+ std::string register_type_name = MakeTypeName (flags_info, register_byte_size);
92+
93+ // Reuse existing type if we can.
94+ if (CompilerType flags_type =
95+ type_system->GetTypeForIdentifier <clang::CXXRecordDecl>(
96+ type_system->getASTContext (), register_type_name))
97+ return flags_type;
98+
99+ // In most ABI, a change of field type means a change in storage unit.
100+ // We want it all in one unit, so we use a field type the same as the
101+ // register's size.
102+ CompilerType field_uint_type =
103+ type_system->GetBuiltinTypeForEncodingAndBitSize (lldb::eEncodingUint,
104+ register_byte_size * 8 );
105+
106+ CompilerType flags_type = type_system->CreateRecordType (
107+ nullptr , OptionalClangModuleID (), register_type_name,
108+ llvm::to_underlying (clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
109+ type_system->StartTagDeclarationDefinition (flags_type);
110+
111+ for (auto field : flags_info.GetFields ()) {
112+ CompilerType field_type = field_uint_type;
113+
114+ if (const RegisterTypeEnum *enum_type_info = field.GetEnum ())
115+ if (!enum_type_info->GetEnumerators ().empty ())
116+ field_type =
117+ BuildEnumType (*enum_type_info, register_byte_size, type_system);
118+
119+ type_system->AddFieldToRecordType (flags_type, field.GetName (), field_type,
120+ field.GetSizeInBits ());
121+ }
122+
123+ type_system->CompleteTagDeclarationDefinition (flags_type);
124+ // So that the size of the type matches the size of the register.
125+ type_system->SetIsPacked (flags_type);
126+
127+ // This should be true if RegisterTypeFlags padded correctly.
128+ assert (
129+ llvm::expectedToOptional (flags_type.GetByteSize (nullptr )).value_or (0 ) ==
130+ flags_info.GetSize ());
131+
132+ return flags_type;
133+ }
134+
135+ CompilerType
136+ RegisterTypeBuilderClang::GetRegisterType (const RegisterInfo ®_info) {
41137 lldb::TypeSystemClangSP type_system =
42138 ScratchTypeSystemClang::GetForTarget (m_target);
43139 assert (type_system);
44140
45- std::string register_type_name = " __lldb_register_fields_" + name;
46- // For now we can only build sets of flags.
47- const RegisterTypeFlags *flags =
48- llvm::dyn_cast<RegisterTypeFlags>(&type_info);
49- if (!flags)
50- return {};
51-
52- // See if we have made this type before and can reuse it.
53- CompilerType fields_type =
54- type_system->GetTypeForIdentifier <clang::CXXRecordDecl>(
55- type_system->getASTContext (), register_type_name);
56-
57- if (!fields_type) {
58- // In most ABI, a change of field type means a change in storage unit.
59- // We want it all in one unit, so we use a field type the same as the
60- // register's size.
61- CompilerType field_uint_type =
62- type_system->GetBuiltinTypeForEncodingAndBitSize (lldb::eEncodingUint,
63- byte_size * 8 );
64-
65- fields_type = type_system->CreateRecordType (
66- nullptr , OptionalClangModuleID (), register_type_name,
67- llvm::to_underlying (clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
68- type_system->StartTagDeclarationDefinition (fields_type);
69-
70- // We assume that RegisterTypeFlags has padded and sorted the fields
71- // already.
72- for (const RegisterTypeFlags::Field &field : flags->GetFields ()) {
73- CompilerType field_type = field_uint_type;
74-
75- if (const RegisterTypeEnum *enum_type = field.GetEnum ()) {
76- const RegisterTypeEnum::Enumerators &enumerators =
77- enum_type->GetEnumerators ();
78- if (!enumerators.empty ()) {
79- // Enums can be used by many registers and the size of each register
80- // may be different. The register size is used as the underlying size
81- // of the enumerators, so we must make one enum type per register size
82- // it is used with.
83- std::string enum_type_name = " __lldb_register_fields_enum_" +
84- enum_type->GetID () + " _" +
85- std::to_string (byte_size);
86-
87- // Enums can be used by mutiple fields and multiple registers, so we
88- // may have built this one already.
89- CompilerType field_enum_type =
90- type_system->GetTypeForIdentifier <clang::EnumDecl>(
91- type_system->getASTContext (), enum_type_name);
92-
93- if (field_enum_type)
94- field_type = field_enum_type;
95- else {
96- field_type = type_system->CreateEnumerationType (
97- enum_type_name, type_system->GetTranslationUnitDecl (),
98- OptionalClangModuleID (), Declaration (), field_uint_type, false );
99-
100- type_system->StartTagDeclarationDefinition (field_type);
101-
102- Declaration decl;
103- for (auto enumerator : enumerators) {
104- type_system->AddEnumerationValueToEnumerationType (
105- field_type, decl, enumerator.m_name .c_str (),
106- enumerator.m_value , byte_size * 8 );
107- }
108-
109- type_system->CompleteTagDeclarationDefinition (field_type);
110- }
111- }
112- }
113-
114- type_system->AddFieldToRecordType (fields_type, field.GetName (),
115- field_type, field.GetSizeInBits ());
116- }
117-
118- type_system->CompleteTagDeclarationDefinition (fields_type);
119- // So that the size of the type matches the size of the register.
120- type_system->SetIsPacked (fields_type);
121-
122- // This should be true if RegisterTypeFlags padded correctly.
123- assert (llvm::expectedToOptional (fields_type.GetByteSize (nullptr ))
124- .value_or (0 ) == flags->GetSize ());
141+ if (!reg_info.register_type )
142+ return CompilerType ();
143+
144+ switch (reg_info.register_type ->getKind ()) {
145+ case RegisterType::eRegisterTypeKindFlags:
146+ return BuildFlagsType (
147+ *llvm::dyn_cast<RegisterTypeFlags>(reg_info.register_type ),
148+ reg_info.byte_size , type_system);
149+ case RegisterType::eRegisterTypeKindEnum:
150+ return BuildEnumType (
151+ *llvm::dyn_cast<RegisterTypeEnum>(reg_info.register_type ),
152+ reg_info.byte_size , type_system);
125153 }
126-
127- return fields_type;
128154}
0 commit comments