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

Function ComputeDataLayout

ThunkLibs/Generator/data_layout.cpp:24–154  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

22 : type_abi(abi_) {}
23
24std::unordered_map<const clang::Type*, TypeInfo>
25ComputeDataLayout(const clang::ASTContext& context, const std::unordered_map<const clang::Type*, AnalysisAction::RepackedType>& types) {
26 std::unordered_map<const clang::Type*, TypeInfo> layout;
27
28 // First, add all types directly used in function signatures of the library API to the meta set
29 for (const auto& [type, type_repack_info] : types) {
30 if (type_repack_info.assumed_compatible) {
31 auto [_, inserted] = layout.insert(std::pair {context.getCanonicalType(type), TypeInfo {}});
32 if (!inserted) {
33 throw std::runtime_error(
34 "Failed to gather type metadata: Opaque type \"" + clang::QualType {type, 0}.getAsString() + "\" already registered");
35 }
36 continue;
37 }
38
39 if (type->isIncompleteType()) {
40 throw std::runtime_error(
41 "Cannot compute data layout of incomplete type \"" + clang::QualType {type, 0}.getAsString() + "\". Did you forget any annotations?");
42 }
43
44 if (type->isStructureType()) {
45 StructInfo info;
46 info.size_bits = context.getTypeSize(type);
47 info.alignment_bits = context.getTypeAlign(type);
48
49 auto [_, inserted] = layout.insert(std::pair {context.getCanonicalType(type), info});
50 if (!inserted) {
51 throw std::runtime_error("Failed to gather type metadata: Type \"" + clang::QualType {type, 0}.getAsString() + "\" already registered");
52 }
53 } else if (type->isBuiltinType() || type->isEnumeralType()) {
54 SimpleTypeInfo info;
55 info.size_bits = context.getTypeSize(type);
56 info.alignment_bits = context.getTypeAlign(type);
57
58 // NOTE: Non-enum types are intentionally not canonicalized since that would turn e.g. size_t into platform-specific types
59 auto [_, inserted] = layout.insert(std::pair {type->isEnumeralType() ? context.getCanonicalType(type) : type, info});
60 if (!inserted) {
61 throw std::runtime_error("Failed to gather type metadata: Type \"" + clang::QualType {type, 0}.getAsString() + "\" already registered");
62 }
63 }
64 }
65
66 // Then, add information about members
67 for (const auto& [type, type_repack_info] : types) {
68 if (!type->isStructureType() || type_repack_info.assumed_compatible) {
69 continue;
70 }
71
72 auto& info = *layout.at(context.getCanonicalType(type)).get_if_struct();
73
74 for (auto* field : type->getAsStructureType()->getDecl()->fields()) {
75 auto field_type = field->getType().getTypePtr();
76 std::optional<uint64_t> array_size;
77 if (auto array_type = llvm::dyn_cast<clang::ConstantArrayType>(field->getType())) {
78 array_size = array_type->getSize().getZExtValue();
79 field_type = array_type->getElementType().getTypePtr();
80 if (llvm::isa<clang::ConstantArrayType>(field_type)) {
81 throw std::runtime_error("Unsupported multi-dimensional array member \"" + field->getNameAsString() + "\" in type \"" +

Callers 3

ExecuteActionMethod · 0.85
OnAnalysisCompleteMethod · 0.85
OnAnalysisCompleteMethod · 0.85

Calls 6

get_type_nameFunction · 0.85
fprintfFunction · 0.85
formatFunction · 0.85
get_if_structMethod · 0.80
atMethod · 0.80

Tested by

no test coverage detected