MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / EmitLayoutWrappers

Method EmitLayoutWrappers

ThunkLibs/Generator/gen.cpp:138–330  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

136};
137
138void GenerateThunkLibsAction::EmitLayoutWrappers(clang::ASTContext& context, std::ofstream& file,
139 std::unordered_map<const clang::Type*, TypeCompatibility>& type_compat) {
140 // Sort struct types by dependency so that repacking code is emitted in an order that compiles fine
141 std::vector<std::pair<const clang::Type*, RepackedType>> types {this->types.begin(), this->types.end()};
142 BubbleSort(types.begin(), types.end(), compare_by_struct_dependency {context});
143
144 for (const auto& [type, type_repack_info] : types) {
145 auto struct_name = get_type_name(context, type);
146
147 // Opaque types don't need layout definitions
148 if (type_repack_info.assumed_compatible && type_repack_info.pointers_only && struct_name != "void") {
149 if (guest_abi.pointer_size != 4) {
150 fmt::print(file, "template<> inline constexpr bool has_compatible_data_layout<{}*> = true;\n", struct_name);
151 }
152 continue;
153 } else if (type_repack_info.assumed_compatible) {
154 // TODO: Handle more cleanly
155 type_compat[type] = TypeCompatibility::Full;
156 }
157
158 // These must be handled later since they are not canonicalized and hence must be de-duplicated first
159 if (type->isBuiltinType()) {
160 continue;
161 }
162
163 // TODO: Instead, map these names back to *some* type that's named?
164 if (struct_name.starts_with("unnamed_")) {
165 continue;
166 }
167
168 if (type->isEnumeralType()) {
169 fmt::print(file, "template<>\nstruct __attribute__((packed)) guest_layout<{}> {{\n", struct_name);
170 fmt::print(file, " using type = {}int{}_t;\n", type->isUnsignedIntegerOrEnumerationType() ? "u" : "",
171 guest_abi.at(struct_name).get_if_simple_or_struct()->size_bits);
172 fmt::print(file, " type data;\n");
173 fmt::print(file, "}};\n");
174 continue;
175 }
176
177 if (type_compat.at(type) == TypeCompatibility::None && !type_repack_info.emit_layout_wrappers) {
178 // Disallow use of layout wrappers for this type by specializing without a definition
179 fmt::print(file, "template<>\nstruct guest_layout<{}>;\n", struct_name);
180 fmt::print(file, "template<>\nstruct host_layout<{}>;\n", struct_name);
181 fmt::print(file, "guest_layout<{}>& to_guest(const host_layout<{}>&) = delete;\n", struct_name, struct_name);
182 continue;
183 }
184
185 // Guest layout definition
186 // NOTE: uint64_t has lower alignment requirements on 32-bit than on 64-bit, so we require tightly packed structs
187 // TODO: Now we must emit padding bytes explicitly, though!
188 fmt::print(file, "template<>\nstruct __attribute__((packed)) guest_layout<{}> {{\n", struct_name);
189 if (type_compat.at(type) == TypeCompatibility::Full) {
190 fmt::print(file, " using type = {};\n", struct_name);
191 } else {
192 fmt::print(file, " struct type {{\n");
193 for (auto& member : guest_abi.at(struct_name).get_if_struct()->members) {
194 fmt::print(file, " guest_layout<{}{}> {};\n", member.type_name,
195 member.array_size ? fmt::format("[{}]", member.array_size.value()) : "", member.member_name);

Callers

nothing calls this directly

Calls 10

BubbleSortFunction · 0.85
get_type_nameFunction · 0.85
printFunction · 0.85
formatFunction · 0.85
atMethod · 0.80
get_if_structMethod · 0.80
UsesCustomRepackForMethod · 0.80
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected