| 23 | } |
| 24 | |
| 25 | static NamespaceAnnotations GetNamespaceAnnotations(clang::ASTContext& context, clang::CXXRecordDecl* decl) { |
| 26 | if (!decl->hasDefinition()) { |
| 27 | return {}; |
| 28 | } |
| 29 | |
| 30 | ErrorReporter report_error {context}; |
| 31 | NamespaceAnnotations ret; |
| 32 | |
| 33 | for (const clang::CXXBaseSpecifier& base : decl->bases()) { |
| 34 | auto annotation = base.getType().getAsString(); |
| 35 | if (annotation == "fexgen::generate_guest_symtable") { |
| 36 | ret.generate_guest_symtable = true; |
| 37 | } else if (annotation == "fexgen::indirect_guest_calls") { |
| 38 | ret.indirect_guest_calls = true; |
| 39 | } else { |
| 40 | throw report_error(base.getSourceRange().getBegin(), "Unknown namespace annotation"); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | for (const clang::FieldDecl* field : decl->fields()) { |
| 45 | auto name = field->getNameAsString(); |
| 46 | if (name == "load_host_endpoint_via") { |
| 47 | auto loader_function_expr = field->getInClassInitializer()->IgnoreCasts(); |
| 48 | auto loader_function_str = llvm::dyn_cast_or_null<clang::StringLiteral>(loader_function_expr); |
| 49 | if (loader_function_expr && !loader_function_str) { |
| 50 | throw report_error(loader_function_expr->getBeginLoc(), "Must initialize load_host_endpoint_via with a string"); |
| 51 | } |
| 52 | if (loader_function_str) { |
| 53 | ret.load_host_endpoint_via = loader_function_str->getString(); |
| 54 | } |
| 55 | } else if (name == "version") { |
| 56 | auto initializer = field->getInClassInitializer()->IgnoreCasts(); |
| 57 | auto version_literal = llvm::dyn_cast_or_null<clang::IntegerLiteral>(initializer); |
| 58 | if (!initializer || !version_literal) { |
| 59 | throw report_error(field->getBeginLoc(), "No version given (expected integral typed member, e.g. \"int version = 5;\")"); |
| 60 | } |
| 61 | ret.version = version_literal->getValue().getZExtValue(); |
| 62 | } else { |
| 63 | throw report_error(field->getBeginLoc(), "Unknown namespace annotation"); |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | return ret; |
| 68 | } |
| 69 | |
| 70 | enum class CallbackStrategy { |
| 71 | Default, |
no test coverage detected