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

Method ParseInterface

ThunkLibs/Generator/analysis.cpp:209–528  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

207}
208
209void AnalysisAction::ParseInterface(clang::ASTContext& context) {
210 ErrorReporter report_error {context};
211
212 const std::unordered_map<unsigned, ParameterAnnotations> no_param_annotations {};
213
214 // TODO: Assert fex_gen_type is not declared at non-global namespaces
215 if (auto template_decl = FindClassTemplateDeclByName(*context.getTranslationUnitDecl(), "fex_gen_type")) {
216 for (auto* decl : template_decl->specializations()) {
217 const auto& template_args = decl->getTemplateArgs();
218 assert(template_args.size() == 1);
219
220 // NOTE: Function types that are equivalent but use differently
221 // named types (e.g. GLuint/GLenum) are represented by
222 // different Type instances. The canonical type they refer
223 // to is unique, however.
224 clang::QualType type = context.getCanonicalType(template_args[0].getAsType());
225 type = type->getLocallyUnqualifiedSingleStepDesugaredType();
226
227 const auto annotations = GetTypeAnnotations(context, decl);
228 if (type->isFunctionPointerType() || type->isFunctionType()) {
229 if (decl->getNumBases()) {
230 throw report_error(decl->getBeginLoc(), "Function pointer types cannot be annotated");
231 }
232 thunked_funcptrs[type.getAsString()] = std::pair {type.getTypePtr(), no_param_annotations};
233 } else {
234 RepackedType repack_info = {.assumed_compatible = annotations.is_opaque || annotations.assumed_compatible,
235 .pointers_only = annotations.is_opaque && !annotations.assumed_compatible,
236 .emit_layout_wrappers = annotations.emit_layout_wrappers};
237 [[maybe_unused]] auto [it, inserted] = types.emplace(context.getCanonicalType(type.getTypePtr()), repack_info);
238 assert(inserted);
239 }
240 }
241 }
242
243 // Process function parameter annotations
244 std::unordered_map<const clang::FunctionDecl*, std::unordered_map<unsigned, ParameterAnnotations>> param_annotations;
245 for (auto& decl_context : decl_contexts) {
246 if (auto template_decl = FindClassTemplateDeclByName(*decl_context, "fex_gen_param")) {
247 for (auto* decl : template_decl->specializations()) {
248 const auto& template_args = decl->getTemplateArgs();
249 assert(template_args.size() == 3);
250
251 auto function = llvm::dyn_cast<clang::FunctionDecl>(template_args[0].getAsDecl());
252 auto param_idx = template_args[1].getAsIntegral().getSExtValue();
253 clang::QualType type = context.getCanonicalType(template_args[2].getAsType());
254 type = type->getLocallyUnqualifiedSingleStepDesugaredType();
255
256 if (param_idx >= function->getNumParams() || param_idx < -1) {
257 throw report_error(GetTemplateArgLocation(decl, 1), "Out-of-bounds parameter index passed to fex_gen_param");
258 }
259
260 auto expected_type = param_idx == -1 ? function->getReturnType() : function->getParamDecl(param_idx)->getType();
261
262 if (!type->isVoidType() && !context.hasSameType(type, expected_type)) {
263 auto loc = param_idx == -1 ? function->getReturnTypeSourceRange().getBegin() :
264 function->getParamDecl(param_idx)->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
265 throw report_error(GetTemplateArgLocation(decl, 2), "Type passed to fex_gen_param doesn't match the function signature")
266 .addNote(report_error(loc, "Expected this type instead"));

Callers

nothing calls this directly

Calls 11

GetTypeAnnotationsFunction · 0.85
GetTemplateArgLocationFunction · 0.85
GetParameterAnnotationsFunction · 0.85
GetNamespaceAnnotationsFunction · 0.85
GetAnnotationsFunction · 0.85
to_stringFunction · 0.85
emplaceMethod · 0.80
UsesCustomRepackForMethod · 0.80
sizeMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected