Skip to content

Commit

Permalink
Thunks/gen: Add support for compiling against clang 19
Browse files Browse the repository at this point in the history
  • Loading branch information
WhatAmISupposedToPutHere committed Dec 5, 2024
1 parent 20caf69 commit 426569d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
21 changes: 13 additions & 8 deletions ThunkLibs/Generator/analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "diagnostics.h"

#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Basic/Version.h>
#include <clang/Frontend/CompilerInstance.h>

#include <fmt/format.h>
Expand All @@ -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<clang::TemplateSpecializationTypeLoc>().getArgLoc(i).getLocation();
#endif
}

static NamespaceAnnotations GetNamespaceAnnotations(clang::ASTContext& context, clang::CXXRecordDecl* decl) {
if (!decl->hasDefinition()) {
return {};
Expand Down Expand Up @@ -245,17 +254,15 @@ void AnalysisAction::ParseInterface(clang::ASTContext& context) {
type = type->getLocallyUnqualifiedSingleStepDesugaredType();

if (param_idx >= function->getNumParams() || param_idx < -1) {
throw report_error(decl->getTypeAsWritten()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().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();

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<clang::TemplateSpecializationTypeLoc>().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"));
}

Expand Down Expand Up @@ -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<clang::TemplateSpecializationTypeLoc>().getArgLoc(0).getLocation();
const auto template_arg_loc = GetTemplateArgLocation(decl, 0);

if (auto emitted_function = llvm::dyn_cast<clang::FunctionDecl>(template_args[0].getAsDecl())) {
// Process later
Expand Down Expand Up @@ -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<clang::TemplateSpecializationTypeLoc>().getArgLoc(0).getLocation();
const auto template_arg_loc = GetTemplateArgLocation(decl, 0);

if (auto emitted_function = llvm::dyn_cast<clang::FunctionDecl>(template_args[0].getAsDecl())) {
auto return_type = emitted_function->getReturnType();
Expand Down
6 changes: 6 additions & 0 deletions unittests/ThunkLibs/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,15 @@ TEST_CASE_METHOD(Fixture, "UnknownAnnotation") {
TEST_CASE_METHOD(Fixture, "VersionedLibrary") {
const auto output = run_thunkgen_host("", "template<auto> 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") {
Expand Down

0 comments on commit 426569d

Please sign in to comment.