diff --git a/tools/rewriter/CAbi.h b/tools/rewriter/CAbi.h index 0027ee9c6..4edaec529 100644 --- a/tools/rewriter/CAbi.h +++ b/tools/rewriter/CAbi.h @@ -112,7 +112,20 @@ struct AbiSignature { std::vector ret; }; +struct Param { + std::string name; + std::string type_name; + std::string canonical_type_name; + uint32_t type_id; +}; + +struct ApiSignature { + std::vector args; + Param ret; +}; + struct FnSignature { AbiSignature abi; + ApiSignature api; bool variadic; }; diff --git a/tools/rewriter/DetermineAbi.cpp b/tools/rewriter/DetermineAbi.cpp index eb6d424fe..2a3de50f2 100644 --- a/tools/rewriter/DetermineAbi.cpp +++ b/tools/rewriter/DetermineAbi.cpp @@ -177,15 +177,7 @@ AbiSignature determineAbiSignature(const clang::CodeGen::CGFunctionInfo &info, return sig; } -FnSignature determineFnSignature(const clang::CodeGen::CGFunctionInfo &info, - const clang::ASTContext &astContext, Arch arch) { - return (FnSignature){ - .abi = determineAbiSignature(info, astContext, arch), - .variadic = info.isVariadic(), - }; -} - -FnSignature determineFnSignatureForDecl(const clang::FunctionDecl &fnDecl, Arch arch) { +AbiSignature determineAbiSignatureForDecl(const clang::FunctionDecl &fnDecl, Arch arch) { clang::ASTContext &astContext = fnDecl.getASTContext(); // set up context for codegen so we can ask about function ABI @@ -216,7 +208,7 @@ FnSignature determineFnSignatureForDecl(const clang::FunctionDecl &fnDecl, Arch auto name = fnDecl.getNameInfo().getAsString(); const auto &info = cgFunctionInfo(cgm, fnDecl); - DEBUG(llvm::dbgs() << "determineFnSignatureForDecl: " << name << "\n"); + DEBUG(llvm::dbgs() << "determineAbiSignatureForDecl: " << name << "\n"); const auto &convention = info.getEffectiveCallingConvention(); @@ -228,12 +220,12 @@ FnSignature determineFnSignatureForDecl(const clang::FunctionDecl &fnDecl, Arch info.getASTCallingConvention()); abort(); } - return determineFnSignature(info, astContext, arch); + return determineAbiSignature(info, astContext, arch); } -FnSignature determineFnSignatureForProtoType(const clang::FunctionProtoType &fpt, - clang::ASTContext &astContext, Arch arch) { - // FIXME: This is copied verbatim from determineFnSignatureForDecl and could be +AbiSignature determineAbiSignatureForProtoType(const clang::FunctionProtoType &fpt, + clang::ASTContext &astContext, Arch arch) { + // FIXME: This is copied verbatim from determineAbiSignatureForDecl and could be // factored out. This depends on what we do with PR #78 so I'm leaving it as // is for now. #if LLVM_VERSION_MAJOR >= 15 @@ -261,5 +253,73 @@ FnSignature determineFnSignatureForProtoType(const clang::FunctionProtoType &fpt cgm, fpt.getCanonicalTypeUnqualified().castAs()); - return determineFnSignature(info, astContext, arch); + return determineAbiSignature(info, astContext, arch); +} + +// Not thread safe. +std::unordered_map type_ids; + +uint32_t get_type_id(clang::QualType type) { + auto canonical_name = type.getCanonicalType().getAsString(); + // Constructs the default value, 0, if the key doesn't exist yet. + auto type_id = type_ids[canonical_name]; + if (type_id == 0) { + type_id = type_ids.size() + 1; + type_ids[canonical_name] = type_id; + } + return type_id; +} + +Param determineParam(std::string name, clang::QualType type) { + return (Param) { + .name = name, + .type_name = type.getAsString(), + .canonical_type_name = type.getCanonicalType().getAsString(), + .type_id = get_type_id(type), + }; +} + +ApiSignature determineApiSignatureForDecl(const clang::FunctionDecl &fn_decl) { + ApiSignature api; + + for (auto param_ptr : fn_decl.parameters()) { + auto ¶m = *param_ptr; + api.args.emplace_back(determineParam(param.getNameAsString(), param.getOriginalType())); + } + + auto ret = fn_decl.getReturnType(); + api.ret = determineParam("return", fn_decl.getReturnType()); + + return api; +} + +ApiSignature determineApiSignatureForProtoType(const clang::FunctionProtoType &fpt, + clang::ASTContext &astContext) { + ApiSignature api; + + auto i = 0; + for (auto param_type : fpt.param_types()) { + auto name = "arg_" + std::to_string(i++); + api.args.emplace_back(determineParam(name, param_type)); + } + api.ret = determineParam("return", fpt.getReturnType()); + + return api; +} + +FnSignature determineFnSignatureForDecl(const clang::FunctionDecl &fnDecl, Arch arch) { + return (FnSignature){ + .abi = determineAbiSignatureForDecl(fnDecl, arch), + .api = determineApiSignatureForDecl(fnDecl), + .variadic = fnDecl.isVariadic(), + }; +} + +FnSignature determineFnSignatureForProtoType(const clang::FunctionProtoType &fpt, + clang::ASTContext &astContext, Arch arch) { + return (FnSignature){ + .abi = determineAbiSignatureForProtoType(fpt, astContext, arch), + .api = determineApiSignatureForProtoType(fpt, astContext), + .variadic = fpt.isVariadic(), + }; }