|
1 | 1 | #include "objc.h"
|
2 | 2 | #include "inttypes.h"
|
3 | 3 | #include <optional>
|
| 4 | +#include <string> |
| 5 | +#include <type_traits> |
4 | 6 |
|
5 | 7 | #define RELEASE_ASSERT(condition) ((condition) ? (void)0 : (std::abort(), (void)0))
|
6 | 8 |
|
@@ -1098,37 +1100,51 @@ void ObjCProcessor::ReadIvarList(ObjCReader* reader, ClassBase& cls, std::string
|
1098 | 1100 | }
|
1099 | 1101 | }
|
1100 | 1102 |
|
| 1103 | +// Returns the type named `name`, creating it via `factory()` and |
| 1104 | +// defining it on the view if it does not already exist. |
| 1105 | +template <typename F> |
| 1106 | + requires (std::is_same_v<std::invoke_result_t<F>, Ref<Type>>) |
| 1107 | +std::pair<QualifiedName, Ref<Type>> DefineNamedType( |
| 1108 | + Ref<BinaryView> view, const QualifiedName& name, F&& factory) |
| 1109 | +{ |
| 1110 | + auto typeID = Type::GenerateAutoTypeId("objc", name); |
| 1111 | + if (auto type = view->GetTypeById(typeID)) |
| 1112 | + return {name, type}; |
| 1113 | + |
| 1114 | + auto type = factory(); |
| 1115 | + auto definedName = view->DefineType(typeID, name, type); |
| 1116 | + return {definedName, type}; |
| 1117 | +} |
1101 | 1118 |
|
1102 | 1119 | std::pair<QualifiedName, Ref<Type>> finalizeStructureBuilder(
|
1103 |
| - Ref<BinaryView> m_data, StructureBuilder sb, std::string name) |
| 1120 | + Ref<BinaryView> m_data, StructureBuilder sb, const QualifiedName& name) |
1104 | 1121 | {
|
1105 |
| - auto classTypeStruct = sb.Finalize(); |
1106 |
| - |
1107 |
| - QualifiedName classTypeName(name); |
1108 |
| - auto classTypeId = Type::GenerateAutoTypeId("objc", classTypeName); |
1109 |
| - auto classType = Type::StructureType(classTypeStruct); |
1110 |
| - auto classQualName = m_data->DefineType(classTypeId, classTypeName, classType); |
| 1122 | + return DefineNamedType(m_data, name, [&]() { |
| 1123 | + auto classTypeStruct = sb.Finalize(); |
| 1124 | + return Type::StructureType(classTypeStruct); |
| 1125 | + }); |
| 1126 | +} |
1111 | 1127 |
|
1112 |
| - return {classQualName, classType}; |
| 1128 | +std::pair<QualifiedName, Ref<Type>> finalizeStructureBuilder( |
| 1129 | + Ref<BinaryView> m_data, StructureBuilder sb, const std::string& name) |
| 1130 | +{ |
| 1131 | + return finalizeStructureBuilder(m_data, std::move(sb), QualifiedName(name)); |
1113 | 1132 | }
|
1114 | 1133 |
|
1115 | 1134 | std::pair<QualifiedName, Ref<Type>> finalizeEnumerationBuilder(
|
1116 |
| - Ref<BinaryView> m_data, EnumerationBuilder eb, uint64_t size, QualifiedName name) |
| 1135 | + Ref<BinaryView> m_data, EnumerationBuilder eb, uint64_t size, const QualifiedName& name) |
1117 | 1136 | {
|
1118 |
| - auto enumTypeStruct = eb.Finalize(); |
1119 |
| - |
1120 |
| - auto enumTypeId = Type::GenerateAutoTypeId("objc", name); |
1121 |
| - auto enumType = Type::EnumerationType(enumTypeStruct, size); |
1122 |
| - auto enumQualName = m_data->DefineType(enumTypeId, name, enumType); |
1123 |
| - |
1124 |
| - return {enumQualName, enumType}; |
| 1137 | + return DefineNamedType(m_data, name, [&]() { |
| 1138 | + auto enumTypeStruct = eb.Finalize(); |
| 1139 | + return Type::EnumerationType(enumTypeStruct, size); |
| 1140 | + }); |
1125 | 1141 | }
|
1126 | 1142 |
|
1127 |
| -inline QualifiedName defineTypedef(Ref<BinaryView> m_data, const QualifiedName name, Ref<Type> type) |
| 1143 | +inline QualifiedName defineTypedef(Ref<BinaryView> m_data, const QualifiedName& name, Ref<Type> type) |
1128 | 1144 | {
|
1129 |
| - auto typeID = Type::GenerateAutoTypeId("objc", name); |
1130 |
| - m_data->DefineType(typeID, name, type); |
1131 |
| - return m_data->GetTypeNameById(typeID); |
| 1145 | + return DefineNamedType(m_data, name, [&]() { |
| 1146 | + return type; |
| 1147 | + }).first; |
1132 | 1148 | }
|
1133 | 1149 |
|
1134 | 1150 | void ObjCProcessor::GenerateClassTypes()
|
@@ -1528,11 +1544,8 @@ void ObjCProcessor::ProcessObjCData()
|
1528 | 1544 | classBuilder.AddMember(Type::PointerType(addrSize, Type::VoidType()), "vtable");
|
1529 | 1545 | classBuilder.AddMember(Type::PointerType(addrSize, Type::NamedType(m_data, m_typeNames.classRO)), "data");
|
1530 | 1546 |
|
1531 |
| - auto classTypeStruct = classBuilder.Finalize(); |
1532 |
| - auto classType = Type::StructureType(classTypeStruct); |
1533 |
| - auto classQualName = m_data->DefineType(classTypeId, classTypeName, classType); |
1534 |
| - |
1535 |
| - m_typeNames.cls = classQualName; |
| 1547 | + type = finalizeStructureBuilder(m_data, classBuilder, classTypeName); |
| 1548 | + m_typeNames.cls = type.first; |
1536 | 1549 |
|
1537 | 1550 | StructureBuilder categoryBuilder;
|
1538 | 1551 | categoryBuilder.AddMember(Type::PointerType(addrSize, Type::IntegerType(1, true)), "category_name");
|
|
0 commit comments