diff --git a/ThunkLibs/Generator/analysis.cpp b/ThunkLibs/Generator/analysis.cpp index 3e2a6341cf..f0562a03e4 100644 --- a/ThunkLibs/Generator/analysis.cpp +++ b/ThunkLibs/Generator/analysis.cpp @@ -2,6 +2,7 @@ #include "diagnostics.h" #include +#include #include #include @@ -13,6 +14,14 @@ struct NamespaceAnnotations { bool indirect_guest_calls = false; }; +static clang::SourceLocation GetTemplateArgLocation(clang::ClassTemplateSpecializationDecl* decl, unsigned i) { +#if CLANG_VERSION_MAJOR >= 19 + return decl->getTemplateArgsAsWritten()->getTemplateArgs()[i].getLocation(); +#else + return decl->getTypeAsWritten()->getTypeLoc().getAs().getArgLoc(i).getLocation(); +#endif +} + static NamespaceAnnotations GetNamespaceAnnotations(clang::ASTContext& context, clang::CXXRecordDecl* decl) { if (!decl->hasDefinition()) { return {}; @@ -245,8 +254,7 @@ void AnalysisAction::ParseInterface(clang::ASTContext& context) { type = type->getLocallyUnqualifiedSingleStepDesugaredType(); if (param_idx >= function->getNumParams() || param_idx < -1) { - throw report_error(decl->getTypeAsWritten()->getTypeLoc().getAs().getArgLoc(1).getLocation(), - "Out-of-bounds parameter index passed to fex_gen_param"); + throw report_error(GetTemplateArgLocation(decl, 1), "Out-of-bounds parameter index passed to fex_gen_param"); } auto expected_type = param_idx == -1 ? function->getReturnType() : function->getParamDecl(param_idx)->getType(); @@ -254,8 +262,7 @@ void AnalysisAction::ParseInterface(clang::ASTContext& context) { if (!type->isVoidType() && !context.hasSameType(type, expected_type)) { auto loc = param_idx == -1 ? function->getReturnTypeSourceRange().getBegin() : function->getParamDecl(param_idx)->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); - throw report_error(decl->getTypeAsWritten()->getTypeLoc().getAs().getArgLoc(2).getLocation(), - "Type passed to fex_gen_param doesn't match the function signature") + throw report_error(GetTemplateArgLocation(decl, 2), "Type passed to fex_gen_param doesn't match the function signature") .addNote(report_error(loc, "Expected this type instead")); } @@ -296,8 +303,7 @@ void AnalysisAction::ParseInterface(clang::ASTContext& context) { const auto& template_args = decl->getTemplateArgs(); assert(template_args.size() == 1); - const auto template_arg_loc = - decl->getTypeAsWritten()->getTypeLoc().castAs().getArgLoc(0).getLocation(); + const auto template_arg_loc = GetTemplateArgLocation(decl, 0); if (auto emitted_function = llvm::dyn_cast(template_args[0].getAsDecl())) { // Process later @@ -333,8 +339,7 @@ void AnalysisAction::ParseInterface(clang::ASTContext& context) { const auto& template_args = decl->getTemplateArgs(); assert(template_args.size() == 1); - const auto template_arg_loc = - decl->getTypeAsWritten()->getTypeLoc().castAs().getArgLoc(0).getLocation(); + const auto template_arg_loc = GetTemplateArgLocation(decl, 0); if (auto emitted_function = llvm::dyn_cast(template_args[0].getAsDecl())) { auto return_type = emitted_function->getReturnType(); diff --git a/unittests/ThunkLibs/generator.cpp b/unittests/ThunkLibs/generator.cpp index d3fc9c7c0c..31a6234046 100644 --- a/unittests/ThunkLibs/generator.cpp +++ b/unittests/ThunkLibs/generator.cpp @@ -415,9 +415,15 @@ TEST_CASE_METHOD(Fixture, "UnknownAnnotation") { TEST_CASE_METHOD(Fixture, "VersionedLibrary") { const auto output = run_thunkgen_host("", "template struct fex_gen_config { int version = 123; };\n"); +#if CLANG_VERSION_MAJOR >= 17 + CHECK_THAT(output, matches(callExpr(callee(functionDecl(hasName("dlopen"))), hasArgument(0, stringLiteral().bind("libname")))) + .check_binding( + "libname", +[](const clang::StringLiteral* lit) { return lit->getString().ends_with(".so.123"); })); +#else CHECK_THAT(output, matches(callExpr(callee(functionDecl(hasName("dlopen"))), hasArgument(0, stringLiteral().bind("libname")))) .check_binding( "libname", +[](const clang::StringLiteral* lit) { return lit->getString().endswith(".so.123"); })); +#endif } TEST_CASE_METHOD(Fixture, "FunctionPointerViaType") {