diff options
| author | rajdakin <rajdakin@gmail.com> | 2023-03-31 17:33:40 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-31 17:33:40 +0200 |
| commit | 4334a1985b49fcff714c7a023197d1594abeb200 (patch) | |
| tree | ac28fefe938dd237e28728b498bf3a789768fc40 | |
| parent | ba03124720ef0c6a52b4b63ab8745a78dc5f7f74 (diff) | |
| download | box64-4334a1985b49fcff714c7a023197d1594abeb200.tar.gz box64-4334a1985b49fcff714c7a023197d1594abeb200.zip | |
[WRAPPER HELPER] First pass toward a better wrapper helper (#658)
| -rw-r--r-- | wrapperhelper/README.md | 108 | ||||
| -rw-r--r-- | wrapperhelper/ast.h | 70 | ||||
| -rw-r--r-- | wrapperhelper/gen.cpp | 681 | ||||
| -rw-r--r-- | wrapperhelper/gen.h | 25 | ||||
| -rw-r--r-- | wrapperhelper/main.cpp | 48 | ||||
| -rw-r--r-- | wrapperhelper/utils.h | 154 |
6 files changed, 533 insertions, 553 deletions
diff --git a/wrapperhelper/README.md b/wrapperhelper/README.md index 1fb2a7e5..cedce959 100644 --- a/wrapperhelper/README.md +++ b/wrapperhelper/README.md @@ -1,41 +1,87 @@ -This tool is based on liblcangtooling, by parsing the AST of the library header files, generating the required structures of the wrapping library, including structure definitions, export function signatures, callback function wrapping, etc. Of course, this cannot completely automate, only as a reference. At the same time, this tool is also quite rough, and may even have errors. +# Wrapper helper + +This tool is based on libclangtooling. + +It parses the AST of the library header files, generating the required structures of the wrapping library, including: +- structure definitions, +- export function signatures, +- callback function wrapping, +etc. Of course, this cannot completely automate everything, it can only be used as a reference. + +At the same time, this tool is also quite rough, and may even have errors. + +## Usage: -Usage: helper <filename> <libname> [guest_triple] [host_triple] -- <clang_flags> - <filename> : set the header file to be parsed - <libname> : set libname required for wrapping func - [guest_triple]: set guest triple arm32/arm64/x86/x64, default is x64 - [host_triple]: set host tripe arm32/arm64/x86/x64, default is arm64 - -- : is necessary + <filename> : set the header file to be parsed + <libname> : set libname required for wrapping func + [guest_triple]: set guest triple: can be arm32/arm64/x86/x64, default is x64 + [host_triple] : set host triple: can be arm32/arm64/x86/x64, default is arm64 + -- : mandatory + <clang_flags> : extra compiler flags + +### Usage example: + +`./helper /usr/include/jpeglib.h libjpeg x64 arm64 -- -I /usr/lib/gcc/x86_*/12.2.0/include --include /usr/lib/gcc/x86_*/12.2.0/include/stddef.h --include /usr/include/stdio.h` -Usage example: +You would see an output similar to the files `src/wrapped/wrappedlibjpeg.c` and `src/wrapped/wrappedlibjpeg_private.h`, should they exist. -./helper /usr/include/jpeglib.h libjpeg x64 arm64 -- +If there are multiple header files to process, write them into a custom header file as input. -You will see output similar to wrappedlibjpeg.c file and libjpeg_private.h file. If there are multiple header files to process, write them into a custom header file as input. +### Output sample -The output may like this: +Using the command above, we get the following (trimmed) files: + +In `wrappedlibjpeg_private.h`: ```c -// libjpeg_private.h -GOM(jpeg_read_coefficients, pFEp) -GOM(jpeg_write_coefficients, vFEpp) -GOM(jpeg_copy_critical_parameters, vFEpp) -GOM(jpeg_read_icc_profile, uFEppp) -... -// wrappedlibjpeg.c -typedef void (*vFp_t)(struct jpeg_common_struct * a0); -typedef void (*vFpu_t)(struct jpeg_common_struct * a0, int a1); -... -typedef struct jpeg_error_mgr { - vFp_t error_exit; - vFpu_t emit_message; - vFp_t output_messag -... -EXPORT void my_jpeg_set_marker_processor(void* emu, struct jpeg_decompress_struct * cinfo, int marker_code, void * routine) { - // WARN: This function's arg has structure ptr which is special, may be need wrap it for host - libjpeg62_my_tmy = (libjpeg62_my_t)my_lib->priv.w.p2; - my->jpeg_set_marker_processor(cinfo, marker_code, findjpeg_marker_parser_methodFct(routine)) -} +... +GO(jpeg_quality_scaling, iFi) +... +GOM(jpeg_destroy, vFEp) ... ``` +In `wrappedlibjpeg.c`: +```c +... +typedef struct jpeg_source_mgr { + void *next_input_byte; + unsigned long bytes_in_buffer; + vFp_t init_source; + iFp_t fill_input_buffer; + vFpI_t skip_input_data; + iFpi_t resync_to_restart; + vFp_t term_source; +} jpeg_source_mgr, *jpeg_source_mgr_ptr; +... +#define GO(A) \ +static uintptr_t my_term_source_fct_##A = 0; \ +void my_term_source_##A(struct jpeg_decompress_struct * a0) { \ + return RunFunction(my_context, my_term_source_fct_##A, 1, a0); \ +} +SUPER() +#undef GO +static void* findterm_sourceFct(void* fct) { + if(!fct) return fct; + if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct); + #define GO(A) if(my_term_source_fct_##A == (uintptr_t)fct) return my_term_source_##A;} + SUPER() + #undef GO + #define GO(A) if(my_term_source_fct_##A == 0) {my_term_source_fct_##A = (uintptr_t)fct;return my_term_source_##A;} + SUPER() + #undef GO + return NULL; +} +... +EXPORT int my_jpeg_quality_scaling(void *emu, int quality) { + libjpeg_my_t *my = (libjpeg_my_t*)my_lib->priv.w.p2; + my->jpeg_quality_scaling(quality); +} +... +EXPORT void my_jpeg_destroy(void *emu, struct jpeg_common_struct * cinfo) { + // WARN: This function's arg has a structure ptr which is special, may need to wrap it for the host + libjpeg_my_t *my = (libjpeg_my_t*)my_lib->priv.w.p2; + my->jpeg_destroy(cinfo); +} +... +``` diff --git a/wrapperhelper/ast.h b/wrapperhelper/ast.h index 0055089f..65e48ffd 100644 --- a/wrapperhelper/ast.h +++ b/wrapperhelper/ast.h @@ -25,10 +25,9 @@ #include "gen.h" #include "utils.h" -using namespace clang; -using namespace clang::tooling; - -static void ParseParameter(ASTContext* AST, WrapperGenerator* Gen, ParmVarDecl* Decl, FuncInfo* Func) { +static void ParseParameter(clang::ASTContext* AST, WrapperGenerator* Gen, clang::ParmVarDecl* Decl, FuncInfo* Func) { + using namespace clang; + (void)AST; (void)Func; auto ParmType = Decl->getType(); if (ParmType->isPointerType()) { auto PointeeType = ParmType->getPointeeType(); @@ -40,7 +39,7 @@ static void ParseParameter(ASTContext* AST, WrapperGenerator* Gen, ParmVarDecl* } Record->type = StripTypedef(PointeeType); Record->decl = PointeeType->getAs<RecordType>()->getDecl(); - Record->type_name = Record->decl->getIdentifier()->getName().str(); + Record->type_name = Record->decl->getIdentifier() ? Record->decl->getIdentifier()->getName().str() : "<null identifier>"; } } else if (PointeeType->isPointerType()) { PointeeType = PointeeType->getPointeeType(); @@ -53,7 +52,7 @@ static void ParseParameter(ASTContext* AST, WrapperGenerator* Gen, ParmVarDecl* Record->type = StripTypedef(PointeeType); Record->decl = PointeeType->getAs<RecordType>()->getDecl(); - Record->type_name = Record->decl->getIdentifier()->getName().str(); + Record->type_name = Record->decl->getIdentifier() ? Record->decl->getIdentifier()->getName().str() : "<null identifier>"; } } } @@ -65,25 +64,26 @@ static void ParseParameter(ASTContext* AST, WrapperGenerator* Gen, ParmVarDecl* } Record->type = StripTypedef(ParmType); Record->decl = ParmType->getAs<RecordType>()->getDecl(); - Record->type_name = Record->decl->getIdentifier()->getName().str(); + Record->type_name = Record->decl->getIdentifier() ? Record->decl->getIdentifier()->getName().str() : "<null identifier>"; } } } -static void ParseFunction(ASTContext* AST, WrapperGenerator* Gen, FunctionDecl* Decl) { +static void ParseFunction(clang::ASTContext* AST, WrapperGenerator* Gen, clang::FunctionDecl* Decl) { + using namespace clang; auto Type = Decl->getType().getTypePtr(); auto FuncInfo = &Gen->funcs[Type]; FuncInfo->type = Type; FuncInfo->func_name = Decl->getNameAsString(); FuncInfo->decl = Decl; FuncInfo->callback_args.resize(Decl->getNumParams()); - if (Decl->getAttr<clang::WeakRefAttr>()) { + if (Decl->getAttr<WeakRefAttr>()) { FuncInfo->is_weak = true; } if (Decl->isVariadic()) { FuncInfo->is_variadaic = true; } - for (int i = 0; i < Decl->getNumParams(); i++) { + for (unsigned i = 0; i < Decl->getNumParams(); i++) { auto ParmDecl = Decl->getParamDecl(i); if (ParmDecl->getType()->isFunctionPointerType()) { FuncInfo->callback_args[i] = ParmDecl->getType().getTypePtr(); @@ -97,21 +97,21 @@ static void ParseFunction(ASTContext* AST, WrapperGenerator* Gen, FunctionDecl* class MyASTVisitor : public clang::RecursiveASTVisitor<MyASTVisitor> { public: - MyASTVisitor(ASTContext* ctx) : Ctx(ctx) {} - MyASTVisitor(ASTContext* ctx, WrapperGenerator* gen) : Ctx(ctx), Gen(gen) {} + MyASTVisitor(clang::ASTContext* ctx) : Ctx(ctx) {} + MyASTVisitor(clang::ASTContext* ctx, WrapperGenerator* gen) : Ctx(ctx), Gen(gen) {} - bool VisitFunctionDecl(FunctionDecl* Decl) { + bool VisitFunctionDecl(clang::FunctionDecl* Decl) { ParseFunction(Ctx, Gen, Decl); return true; } private: - ASTContext* Ctx; + clang::ASTContext* Ctx; WrapperGenerator* Gen; }; class MyASTConsumer : public clang::ASTConsumer { public: - MyASTConsumer(ASTContext* Context, const std::string& libname, const std::string& host_triple, const std::string& guest_triple) + MyASTConsumer(clang::ASTContext* Context, const std::string& libname, const std::string& host_triple, const std::string& guest_triple) : Visitor(Context, &Generator) { Generator.Init(libname, host_triple, guest_triple); } @@ -120,16 +120,35 @@ public: std::cout << "--------------- Libclangtooling parse complete -----------------\n"; Generator.Prepare(&Ctx); std::cout << "--------------- Generator prepare complete -----------------\n"; - std::ofstream FuncDeclFile(Generator.libname + "_private.h", std::ios::out); - FuncDeclFile << Generator.GenFuncDeclare(&Ctx) << std::endl; + std::ofstream FuncDeclFile("wrapped" + Generator.libname + "_private.h", std::ios::out); + FuncDeclFile << Generator.GenFuncDeclare(&Ctx); FuncDeclFile.close(); - std::ofstream FuncDefinelFile("wrapped" + Generator.libname + ".c", std::ios::out); - FuncDefinelFile << Generator.GenCallbackTypeDefs(&Ctx) << std::endl; - FuncDefinelFile << Generator.GenRecordDeclare(&Ctx) << std::endl; - FuncDefinelFile << Generator.GenRecordConvert(&Ctx) << std::endl; - FuncDefinelFile << Generator.GenCallbackWrap(&Ctx) << std::endl; - FuncDefinelFile << Generator.GenFuncDefine(&Ctx) << std::endl; - FuncDefinelFile.close(); + std::ofstream FuncDefineFile("wrapped" + Generator.libname + ".c", std::ios::out); + FuncDefineFile << "#include <stdio.h>\n" + "#include <stdlib.h>\n" + "#include <string.h>\n" + "#define _GNU_SOURCE /* See feature_test_macros(7) */\n" + "#include <dlfcn.h>\n" + "\n" + "#include \"wrappedlibs.h\"\n" + "\n" + "#include \"debug.h\"\n" + "#include \"wrapper.h\"\n" + "#include \"bridge.h\"\n" + "#include \"x64emu.h\"\n" + "#include \"box64context.h\"\n" + "\n" + "const char* " + Generator.libname + "Name = \"" + Generator.libname + "\";\n" + "#define LIBNAME " + Generator.libname + "\n" + "\n" + "#define ADDED_FUNCTIONS() \\\n" + "\n" + "#include \"generated/wrapped" + Generator.libname + "types.h\"\n"; + FuncDefineFile << Generator.GenRecordDeclare(&Ctx); + FuncDefineFile << Generator.GenRecordConvert(&Ctx); + FuncDefineFile << Generator.GenCallbackWrap(&Ctx); + FuncDefineFile << Generator.GenFuncDefine(&Ctx); + FuncDefineFile.close(); std::cout << "--------------- Generator gen complete -----------------\n"; } private: @@ -142,6 +161,7 @@ public: MyGenAction(const std::string& libname, const std::string& host_triple, const std::string& guest_triple) : libname(libname), host_triple(host_triple), guest_triple(guest_triple) {} std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance& Compiler, clang::StringRef file) override { + (void)file; return std::make_unique<MyASTConsumer>(&Compiler.getASTContext(), libname, host_triple, guest_triple); } private: @@ -162,4 +182,4 @@ private: std::string libname; std::string host_triple; std::string guest_triple; -}; \ No newline at end of file +}; diff --git a/wrapperhelper/gen.cpp b/wrapperhelper/gen.cpp index 0bf6904b..14ff8725 100644 --- a/wrapperhelper/gen.cpp +++ b/wrapperhelper/gen.cpp @@ -5,47 +5,162 @@ #include <clang/AST/Type.h> #include <clang/Basic/LLVM.h> +using namespace clang; +using namespace clang::tooling; + +static std::vector<uint64_t> GetRecordFieldOff(const std::string& Code, const std::string& Triple) { + std::vector<uint64_t> FieldOff; + std::vector<std::string> Args = {"-target", Triple}; + std::unique_ptr<clang::ASTUnit> AST = clang::tooling::buildASTFromCodeWithArgs(Code, Args); + auto& Ctx = AST->getASTContext(); + auto TranslateDecl = Ctx.getTranslationUnitDecl(); + for (const auto& Decl : TranslateDecl->decls()) { + if (const auto RecordDecl = clang::dyn_cast<clang::RecordDecl>(Decl)) { + auto& RecordLayout = Ctx.getASTRecordLayout(RecordDecl); + for (unsigned i = 0; i < RecordLayout.getFieldCount(); i++) { + FieldOff.push_back(RecordLayout.getFieldOffset(i) / 8); + } + break; + } + } + return FieldOff; +} + +static uint64_t GetRecordSize(const std::string& Code, const std::string& Triple) { + std::vector<std::string> Args = {"-target", Triple}; + std::unique_ptr<ASTUnit> AST = buildASTFromCodeWithArgs(Code, Args); + auto& Ctx = AST->getASTContext(); + auto TranslateDecl = Ctx.getTranslationUnitDecl(); + for (const auto& Decl : TranslateDecl->decls()) { + if (const auto recordDecl = dyn_cast<RecordDecl>(Decl)) { + return Ctx.getTypeSize(recordDecl->getTypeForDecl()) / 8; + } + } + return 0; +} + +static CharUnits::QuantityType GetRecordAlign(const std::string& Code, const std::string& Triple) { + std::vector<std::string> Args = {"-target", Triple}; + std::unique_ptr<ASTUnit> AST = buildASTFromCodeWithArgs(Code, Args); + auto& Ctx = AST->getASTContext(); + auto TranslateDecl = Ctx.getTranslationUnitDecl(); + for (const auto& Decl : TranslateDecl->decls()) { + if (const auto recordDecl = dyn_cast<RecordDecl>(Decl)) { + auto& RecordLayout = Ctx.getASTRecordLayout(recordDecl); + for (unsigned i = 0; i < RecordLayout.getFieldCount(); i++) { + return RecordLayout.getAlignment().getQuantity() / 8; + } + break; + } + } + return 0; +} + +static uint64_t GetTypeSize(const Type* Type, const std::string& Triple) { + std::string Code = Type->getCanonicalTypeInternal().getAsString() + " dummy;"; + std::vector<std::string> Args = {"-target", Triple}; + std::unique_ptr<ASTUnit> AST = buildASTFromCodeWithArgs(Code, Args); + auto& Ctx = AST->getASTContext(); + auto TranslateDecl = Ctx.getTranslationUnitDecl(); + for (const auto& Decl : TranslateDecl->decls()) { + if (const auto varDecl = dyn_cast<VarDecl>(Decl)) { + return Ctx.getTypeSize(varDecl->getType()) / 8; + } + } + return 0; +} + +static std::string TypeToSig(ASTContext* Ctx, const Type* Type) { + if (Type->isPointerType()) { + return "p"; + } else if (Type->isVoidType()) { + return "v"; + } else if (Type->isUnsignedIntegerOrEnumerationType()) { + switch(Ctx->getTypeSizeInChars(Type).getQuantity()) { + case 1: + return "C"; + case 2: + return "W"; + case 4: + return "u"; + case 8: + return "U"; + default: + std::cout << "Unsupported UnsignedInteger Type: " << Type->getCanonicalTypeInternal().getAsString() << std::endl; + } + } else if (Type->isSignedIntegerOrEnumerationType()) { + switch(Ctx->getTypeSizeInChars(Type).getQuantity()) { + case 1: + return "c"; + case 2: + return "w"; + case 4: + return "i"; + case 8: + return "I"; + default: + std::cout << "Unsupported SignedInteger Type: " << Type->getCanonicalTypeInternal().getAsString() << std::endl; + } + } else if (Type->isCharType()) { + return "c"; + } else if (Type->isFloatingType()) { + switch(Ctx->getTypeSizeInChars(Type).getQuantity()) { + case 4: + return "f"; + case 8: + return "d"; + case 16: + return "D"; + default: + std::cout << "Unsupported Floating Type: " << Type->getCanonicalTypeInternal().getAsString() + << " (quantity = " << Ctx->getTypeSizeInChars(Type).getQuantity() << ")" << std::endl; + } + } else { + std::cout << "Unsupported Type: " << Type->getCanonicalTypeInternal().getAsString() << std::endl; + } + return "?"; +} + // Prepare for generation, collect the structures and functions that need to be prcessed -void WrapperGenerator::Prepare(clang::ASTContext *Ctx) { +void WrapperGenerator::Prepare(ASTContext *Ctx) { for (const auto &func_pair : funcs) { for (auto Type : func_pair.second.callback_args) { if (Type && Type->isTypedefNameType()) { callbacks[StripTypedef(Type->getPointeeType())] = - Type->getAs<clang::TypedefType>()->getDecl()->getNameAsString(); + Type->getAs<TypedefType>()->getDecl()->getNameAsString(); } else if (Type) { callbacks[StripTypedef(Type->getPointeeType())] = GetFuncSig(Ctx, Type->getPointeeType().getTypePtr()) + "_t"; } } } - std::vector<const clang::Type *> Types; + std::vector<const Type *> Types; for (const auto &record_pair : records) { - auto Record = &record_pair.second; Types.push_back(record_pair.first); } - for (auto Type : Types) { - std::set<const clang::Type *> Visited{Type}; + for (auto type : Types) { + std::set<const Type*> Visited{type}; bool Special = false; - ParseRecordRecursive(Ctx, Type, Special, Visited); + ParseRecordRecursive(Ctx, type, Special, Visited); } for (auto it = records.begin(); it != records.end();) { if (!it->second.is_special) { it = records.erase(it); } else { - for (auto Type : it->second.callback_fields) { - if (Type->isTypedefNameType()) { - callbacks[StripTypedef(Type->getPointeeType())] = - Type->getAs<clang::TypedefType>()->getDecl()->getNameAsString(); + for (auto field : it->second.callback_fields) { + if (field->isTypedefNameType()) { + callbacks[StripTypedef(field->getPointeeType())] = + field->getAs<TypedefType>()->getDecl()->getNameAsString(); } else { - callbacks[StripTypedef(Type->getPointeeType())] = - GetFuncSig(Ctx, Type->getPointeeType().getTypePtr()) + "_t"; + callbacks[StripTypedef(field->getPointeeType())] = + GetFuncSig(Ctx, field->getPointeeType().getTypePtr()) + "_t"; } } ++it; } } for (auto &func_pair : funcs) { - for (int i = 0; i < func_pair.second.decl->getNumParams(); i++) { + for (unsigned i = 0; i < func_pair.second.decl->getNumParams(); i++) { auto ParamDecl = func_pair.second.decl->getParamDecl(i); auto ParamType = ParamDecl->getType(); if (ParamType->isPointerType() && @@ -77,33 +192,28 @@ void WrapperGenerator::Prepare(clang::ASTContext *Ctx) { } // Gen callback typedef -std::string WrapperGenerator::GenCallbackTypeDefs(clang::ASTContext *Ctx) { - std::string res{}; +std::string WrapperGenerator::GenCallbackTypeDefs(ASTContext *Ctx) { + (void)Ctx; + std::string res; for (auto callback : callbacks) { auto Type = callback.first; - auto Definiton = GetFuncDefinition(Type); - res += "typedef " + Definiton.ret_str + "(*" + callback.second + ")("; - for (int i = 0; i < Definiton.arg_size - 1; i++) { - res += Definiton.arg_types_str[i]; - res += " "; - res += Definiton.arg_names[i]; - res += ", "; + auto Definition = GetFuncDefinition(Type); + res += "typedef " + Definition.ret_str + "(*" + callback.second + ")("; + for (int i = 0; i < Definition.arg_size - 1; i++) { + res += Definition.arg_types_str[i] + Definition.arg_names[i] + ", "; } - if (Definiton.arg_size) { - res += Definiton.arg_types_str[Definiton.arg_size - 1]; - res += " "; - res += Definiton.arg_names[Definiton.arg_size - 1]; + if (Definition.arg_size) { + res += Definition.arg_types_str[Definition.arg_size - 1] + Definition.arg_names[Definition.arg_size - 1]; } - res += ");"; - res += "\n"; + res += ");\n"; } return res; } // Gen function declare -std::string WrapperGenerator::GenDeclare(clang::ASTContext *Ctx, +std::string WrapperGenerator::GenDeclare(ASTContext *Ctx, const FuncInfo &Func) { - std::string res{}; + std::string res; std::string sig = GetFuncSig(Ctx, Func); res += "GO"; if (Func.is_weak) { @@ -118,16 +228,17 @@ std::string WrapperGenerator::GenDeclare(clang::ASTContext *Ctx, } // Gen structure declare -std::string WrapperGenerator::GenDeclare(clang::ASTContext *Ctx, +std::string WrapperGenerator::GenDeclare(ASTContext *Ctx, const RecordInfo &Record) { - std::string RecordStr{}; - RecordStr += "typedef "; + (void)Ctx; + std::string RecordStr; + RecordStr += "\ntypedef "; RecordStr += (Record.is_union ? "union " : "struct ") + Record.type_name + " {\n"; for (const auto &Field : Record.decl->fields()) { auto Type = Field->getType(); std::string Name = Field->getNameAsString(); - RecordStr += " "; + RecordStr += " "; if (Type->isFunctionPointerType()) { auto FuncType = StripTypedef(Type->getPointeeType()); if (callbacks.count(FuncType)) { @@ -136,9 +247,7 @@ std::string WrapperGenerator::GenDeclare(clang::ASTContext *Ctx, FieldStr += Name; RecordStr += FieldStr; } else { - std::cout << "Err: " - << "FuncPtr(" << Record.type_name << "." << Name - << ") is not supported\n"; + std::cout << "Err: FuncPtr(" << Record.type_name << "." << Name << ") is not supported\n"; } } else if (Type->isPointerType()) { auto PointeeType = Type->getPointeeType(); @@ -149,10 +258,10 @@ std::string WrapperGenerator::GenDeclare(clang::ASTContext *Ctx, FieldStr += Name; RecordStr += FieldStr; } else { - RecordStr += "void * " + Name; + RecordStr += "void *" + Name; } } else { - RecordStr += "void * " + Name; + RecordStr += "void *" + Name; } } else if (Type->isRecordType()) { if (records.count(Type.getTypePtr())) { @@ -161,23 +270,24 @@ std::string WrapperGenerator::GenDeclare(clang::ASTContext *Ctx, FieldStr += Name; RecordStr += FieldStr; } else { - RecordStr += TypeStrify(StripTypedef(Type), Field, nullptr); + RecordStr += TypeStringify(StripTypedef(Type), Field, nullptr); } } else { - RecordStr += TypeStrify(StripTypedef(Type), Field, nullptr); + RecordStr += TypeStringify(StripTypedef(Type), Field, nullptr); } RecordStr += ";\n"; } - RecordStr += "}"; + RecordStr += "} "; RecordStr += Record.type_name + ", *" + Record.type_name + "_ptr;\n"; return RecordStr; } -std::string WrapperGenerator::GenCallbackWrap(clang::ASTContext *Ctx, +std::string WrapperGenerator::GenCallbackWrap(ASTContext *Ctx, const FuncInfo &Func) { - std::string res{}; + (void)Ctx; + std::string res; - for (int i = 0; i < Func.decl->getNumParams(); i++) { + for (unsigned i = 0; i < Func.decl->getNumParams(); i++) { auto ParamType = Func.decl->getParamDecl(i)->getType(); if (ParamType->isFunctionPointerType()) { @@ -185,62 +295,46 @@ std::string WrapperGenerator::GenCallbackWrap(clang::ASTContext *Ctx, auto Definition = GetFuncDefinition(PointeeType.getTypePtr()); std::string my_funcname = std::string("my_") + Func.decl->getParamDecl(i)->getNameAsString(); - std::string funcname = - std::string("my_") + Func.decl->getParamDecl(i)->getNameAsString(); - res += "#define GO(A) \\\n"; - res += - std::string("static uintptr_t ") + my_funcname + "_fct_##A = 0; \\\n"; - res += Definition.ret_str + " " + my_funcname + "("; + std::string funcname = Func.decl->getParamDecl(i)->getNameAsString(); + res += "\n#define GO(A) \\\n" + "static uintptr_t " + my_funcname + "_fct_##A = 0; \\\n" + + Definition.ret_str + " " + my_funcname + "("; int arg_size = Definition.arg_names.size(); if (arg_size) { for (int i = 0; i < arg_size - 1; i++) { - res += Definition.arg_types_str[i]; - res += " "; - res += Definition.arg_names[i]; - res += ", "; + res += Definition.arg_types_str[i] + " " + Definition.arg_names[i] + ", "; } - res += Definition.arg_types_str[arg_size - 1]; - res += " "; - res += Definition.arg_names[arg_size - 1]; + res += Definition.arg_types_str[arg_size - 1] + " " + Definition.arg_names[arg_size - 1]; } - res += ") {\\\n"; - res += " "; - res += - "return RunFunction(my_context, " + my_funcname + "_fct_##A" + ", ", - std::to_string(arg_size); - if (arg_size) { - for (int i = 0; i < arg_size; i++) { - res += ", " + Definition.arg_names[i]; - } + res += ") { \\\n" + " return RunFunction(my_context, " + my_funcname + "_fct_##A" + ", " + std::to_string(arg_size); + for (int i = 0; i < arg_size; i++) { + res += ", " + Definition.arg_names[i]; } - res += ");\\\n"; - res += "}\n"; - res += "#undef GO\n"; - res += "static void* find" + funcname + "Fct(void* fct) {\n"; - res += " if(!fct) return fct;\n"; - res += " if(GetNativeFnc((uintptr_t)fct)) return " - "GetNativeFnc((uintptr_t)fct);\n"; - res += " #define GO(A) if(" + my_funcname + - "_fct_##A == (uintptr_t)fct) return " + my_funcname + "_##A;}\n"; - res += " SUPER()\n"; - res += " #undef GO\n"; - res += " #define GO(A) if(" + my_funcname + "_fct_##A == 0) {" + - my_funcname + "_fct_##A = (uintptr_t)fct;" + "return " + - my_funcname + "_##A;}\n"; - res += " SUPER()\n"; - res += " #undef GO\n"; - res += " return NULL;\n"; - res += "}\n"; + res += "); \\\n" + "}\n" + "SUPER()\n" + "#undef GO\n" + "static void* find" + funcname + "Fct(void* fct) {\n" + " if (!fct) return fct;\n" + " if (GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);\n" + " #define GO(A) if (" + my_funcname + "_fct_##A == (uintptr_t)fct) return " + my_funcname + "_##A;\n" + " SUPER()\n" + " #undef GO\n" + " #define GO(A) if (" + my_funcname + "_fct_##A == 0) { " + my_funcname + "_fct_##A = (uintptr_t)fct; return " + my_funcname + "_##A; }\n" + " SUPER()\n" + " #undef GO\n" + " return NULL;\n" + "}\n"; } } return res; } -std::string WrapperGenerator::GenCallbackWrap(clang::ASTContext *Ctx, +std::string WrapperGenerator::GenCallbackWrap(ASTContext *Ctx, const RecordInfo &Struct) { - std::string res{}; - auto Type = Struct.type; - auto RecordType = Type->getAs<clang::RecordType>(); + (void)Ctx; + std::string res; for (const auto &field : Struct.decl->fields()) { auto FieldType = field->getType(); if (FieldType->isFunctionPointerType()) { @@ -248,179 +342,156 @@ std::string WrapperGenerator::GenCallbackWrap(clang::ASTContext *Ctx, auto Definition = GetFuncDefinition(PointeeType.getTypePtr()); std::string my_funcname = std::string("my_") + field->getNameAsString(); std::string funcname = field->getNameAsString(); - res += "#define GO(A) \\\n"; - res += - std::string("static uintptr_t ") + my_funcname + "_fct_##A = 0;\\\n"; - res += Definition.ret_str + " " + my_funcname + "_##A("; + res += "\n#define GO(A) \\\n" + "static uintptr_t " + my_funcname + "_fct_##A = 0; \\\n" + + Definition.ret_str + " " + my_funcname + "_##A("; int arg_size = Definition.arg_names.size(); if (arg_size) { for (int i = 0; i < arg_size - 1; i++) { - res += Definition.arg_types_str[i]; - res += " "; - res += Definition.arg_names[i]; - res += ", "; + res += Definition.arg_types_str[i] + " " + Definition.arg_names[i] + ", "; } - res += Definition.arg_types_str[arg_size - 1]; - res += " "; - res += Definition.arg_names[arg_size - 1]; + res += Definition.arg_types_str[arg_size - 1] + " " + Definition.arg_names[arg_size - 1]; } - res += ") {\\\n"; - res += " "; - res += "return RunFunction(my_context, " + my_funcname + "_fct_##A" + - ", " + std::to_string(arg_size); - if (arg_size) { - for (int i = 0; i < arg_size; i++) { - res += ", " + Definition.arg_names[i]; - } + res += ") { \\\n" + " return RunFunction(my_context, " + my_funcname + "_fct_##A" + ", " + std::to_string(arg_size); + for (int i = 0; i < arg_size; i++) { + res += ", " + Definition.arg_names[i]; } - res += ");\\\n"; - res += "}\n"; - res += "#undef GO\n"; - res += "static void* find" + funcname + "Fct(void* fct) {\n"; - res += " if(!fct) return fct;\n"; - res += " if(GetNativeFnc((uintptr_t)fct)) return " - "GetNativeFnc((uintptr_t)fct);\n"; - res += " #define GO(A) if(" + my_funcname + - "_fct_##A == (uintptr_t)fct) return " + my_funcname + "_##A;}\n"; - res += " SUPER()\n"; - res += " #undef GO\n"; - res += " #define GO(A) if(" + my_funcname + "_fct_##A == 0) {" + - my_funcname + "_fct_##A = (uintptr_t)fct;" + "return " + - my_funcname + "_##A;}\n"; - res += " SUPER()\n"; - res += " #undef GO\n"; - res += " return NULL;\n"; - res += "}\n"; + res += "); \\\n" + "}\n" + "SUPER()\n" + "#undef GO\n" + "static void* find" + funcname + "Fct(void* fct) {\n" + " if(!fct) return fct;\n" + " if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);\n" + " #define GO(A) if(" + my_funcname + "_fct_##A == (uintptr_t)fct) return " + my_funcname + "_##A;}\n" + " SUPER()\n" + " #undef GO\n" + " #define GO(A) if(" + my_funcname + "_fct_##A == 0) {" + my_funcname + "_fct_##A = (uintptr_t)fct;" + "return " + my_funcname + "_##A;}\n" + " SUPER()\n" + " #undef GO\n" + " return NULL;\n" + "}\n"; } } return res; } -std::string WrapperGenerator::GenDefine(clang::ASTContext *Ctx, +std::string WrapperGenerator::GenDefine(ASTContext *Ctx, const FuncInfo &Func) { - std::string Res{}; + std::string res; auto Definition = GetFuncDefinition(Func.decl); std::string Sig = GetFuncSig(Ctx, Func.type); - Res += "EXPORT "; - Res += Definition.ret_str; - Res += "my_" + Func.func_name + "("; + res += "\nEXPORT " + Definition.ret_str + "my_" + Func.func_name + "("; if (Sig.find('E')) { - Res += "void* emu, "; + res += "void *emu, "; } int arg_size = Definition.arg_names.size(); if (arg_size) { for (int i = 0; i < arg_size - 1; i++) { if (Definition.arg_types[i]->isPointerType()) { auto PointeeType = Definition.arg_types[i]->getPointeeType(); - if (records.count( - Definition.arg_types[i]->getPointeeType().getTypePtr())) { - Res += + if (records.count(PointeeType.getTypePtr())) { + res += Definition.arg_types[i]->getCanonicalTypeInternal().getAsString(); } else { - Res += Definition.arg_types_str[i]; + res += Definition.arg_types_str[i]; } } else { - Res += Definition.arg_types_str[i]; + res += Definition.arg_types_str[i]; } - Res += " "; - Res += Definition.arg_names[i]; - Res += ", "; + res += " " + Definition.arg_names[i] + ", "; } if (Definition.arg_types[arg_size - 1]->isPointerType()) { auto PointeeType = Definition.arg_types[arg_size - 1]->getPointeeType(); - if (records.count(Definition.arg_types[arg_size - 1] - ->getPointeeType() - .getTypePtr())) { - Res += Definition.arg_types[arg_size - 1] + if (records.count(PointeeType.getTypePtr())) { + res += Definition.arg_types[arg_size - 1] ->getCanonicalTypeInternal() .getAsString(); } else { - Res += Definition.arg_types_str[arg_size - 1]; + res += Definition.arg_types_str[arg_size - 1]; } } else { - Res += Definition.arg_types_str[arg_size - 1]; + res += Definition.arg_types_str[arg_size - 1]; } - Res += " "; - Res += Definition.arg_names[arg_size - 1]; + res += " "; + res += Definition.arg_names[arg_size - 1]; } - Res += ") {\n"; - std::string FuncBodyStr{}; + res += ") {\n"; if (Func.has_special_arg) { - FuncBodyStr += " // WARN: This function's arg has structure ptr which is " - "special, may be need wrap it for host\n"; + res += " // WARN: This function's arg has a structure ptr which is " + "special, may need to wrap it for the host\n"; } else if (Func.has_special_ret) { - FuncBodyStr += " // WARN: This function's ret structure ptr which is " - "special, may be need wrap it for guest\n"; + res += " // WARN: This function's ret is a structure ptr which is " + "special, may need to wrap it for the guest\n"; } if (Func.has_callback_arg) { - FuncBodyStr += " " + my_lib_type + "my = " + "(" + my_lib_type + ")" + - my_lib + "->priv.w.p2;\n"; - FuncBodyStr += " my->" + Func.func_name + "("; + res += " " + my_lib_type + " *my = " + "(" + my_lib_type + "*)" + + my_lib + "->priv.w.p2;\n" + " my->" + Func.func_name + "("; if (arg_size) { for (int i = 0; i < arg_size - 1; i++) { if (Func.callback_args[i]) { if (!Func.callback_args[i]->isTypedefNameType()) { - FuncBodyStr += + res += "find" + Func.func_name + "_arg" + std::to_string(i) + "Fct"; } else { - FuncBodyStr += "find" + + res += "find" + Func.callback_args[i] - ->getAs<clang::TypedefType>() + ->getAs<TypedefType>() ->getDecl() ->getNameAsString() + "Fct"; } - FuncBodyStr += "(" + Definition.arg_names[i] + ")"; + res += "(" + Definition.arg_names[i] + ")"; } else { - FuncBodyStr += Definition.arg_names[i]; + res += Definition.arg_names[i]; } - FuncBodyStr += ", "; + res += ", "; } if (Func.callback_args[arg_size - 1]) { if (!Func.callback_args[arg_size - 1]->isTypedefNameType()) { - FuncBodyStr += "find" + Func.func_name + "_arg" + + res += "find" + Func.func_name + "_arg" + std::to_string(arg_size - 1) + "Fct"; } else { - FuncBodyStr += "find" + + res += "find" + Func.callback_args[arg_size - 1] - ->getAs<clang::TypedefType>() + ->getAs<TypedefType>() ->getDecl() ->getNameAsString() + "Fct"; } - FuncBodyStr += "(" + Definition.arg_names[arg_size - 1] + ")"; + res += "(" + Definition.arg_names[arg_size - 1] + ")"; } else { - FuncBodyStr += Definition.arg_names[arg_size - 1]; + res += Definition.arg_names[arg_size - 1]; } - FuncBodyStr += ")\n"; + res += ")\n"; } } else { - FuncBodyStr += " " + my_lib_type + "my = " + "(" + my_lib_type + ")" + - my_lib + "->priv.w.p2;\n"; - FuncBodyStr += " my->" + Func.func_name + "("; + res += " " + my_lib_type + " *my = (" + my_lib_type + "*)" + my_lib + "->priv.w.p2;\n" + " my->" + Func.func_name + "("; if (arg_size) { for (int i = 0; i < arg_size - 1; i++) { - FuncBodyStr += Definition.arg_names[i]; - FuncBodyStr += ", "; + res += Definition.arg_names[i] + ", "; } - FuncBodyStr += Definition.arg_names[arg_size - 1]; - FuncBodyStr += ");\n"; + res += Definition.arg_names[arg_size - 1]; } + res += ");\n"; } - Res += FuncBodyStr; - Res += "}\n"; - return Res; + res += "}\n"; + return res; } std::string WrapperGenerator::GenDeclareDiffTriple( - clang::ASTContext *Ctx, const RecordInfo &Record, + ASTContext *Ctx, const RecordInfo &Record, const std::string &GuestTriple, const std::string &HostTriple) { - std::string GuestRecord{}; - std::string HostRecord{}; - std::vector<int> GuestFieldOff; - std::vector<int> HostFieldOff; + (void)Ctx; + std::string GuestRecord; + std::string HostRecord; + std::vector<uint64_t> GuestFieldOff; + std::vector<uint64_t> HostFieldOff; GuestRecord += "typedef "; HostRecord += "typedef "; GuestRecord += @@ -429,22 +500,21 @@ std::string WrapperGenerator::GenDeclareDiffTriple( std::string("host_") + Record.type_name + " {\n"; auto OffDiff = GetRecordFieldOffDiff(Record.type, GuestTriple, HostTriple, GuestFieldOff, HostFieldOff); - int GuestRecordSize = GetRecordSize(Record.type, GuestTriple); - int HostRecordSize = GetRecordSize(Record.type, HostTriple); - int SizeDiff = GuestRecordSize - HostRecordSize; + uint64_t GuestRecordSize = GetRecordSize(Record.type, GuestTriple); + uint64_t HostRecordSize = GetRecordSize(Record.type, HostTriple); + uint64_t SizeDiff = GuestRecordSize - HostRecordSize; int FieldIndex = 0; - std::set<clang::FieldDecl *> AlignDiffFields; + std::set<FieldDecl *> AlignDiffFields; for (const auto &Field : Record.decl->fields()) { if (OffDiff[FieldIndex] == 0) { FieldIndex++; continue; } - auto Type = Field->getType(); std::string Name = Field->getNameAsString(); if (OffDiff[FieldIndex] != SizeDiff) { auto Diff = OffDiff[FieldIndex]; AlignDiffFields.insert(Field); - for (int i = FieldIndex; i < OffDiff.size(); i++) { + for (size_t i = FieldIndex; i < OffDiff.size(); i++) { if (OffDiff[i] == Diff) { OffDiff[i] = 0; } else { @@ -463,16 +533,16 @@ std::string WrapperGenerator::GenDeclareDiffTriple( GuestRecord += " "; HostRecord += " "; if (AlignDiffFields.find(Field) != AlignDiffFields.end()) { - switch (GetTypeSize(StripTypedef(Field->getType()), guest_triple)) { + auto typeSize = GetTypeSize(StripTypedef(Field->getType()), guest_triple); + switch (typeSize) { // FIXME: should test more case in different triple - case 4: - GuestRecord += "int " + Name; - case 8: - GuestRecord += "int " + Name + "[2]"; + case 4: GuestRecord += "int " + Name ; break; + case 8: GuestRecord += "int " + Name + "[2]"; break; default: + std::cout << "Err: unknown type size " << typeSize << std::endl; break; } - HostRecord += TypeStrify(StripTypedef(Type), Field, nullptr); + HostRecord += TypeStringify(StripTypedef(Type), Field, nullptr); } else if (Type->isFunctionPointerType()) { auto FuncType = StripTypedef(Type->getPointeeType()); if (callbacks.count(FuncType)) { @@ -482,77 +552,67 @@ std::string WrapperGenerator::GenDeclareDiffTriple( GuestRecord += FieldStr; HostRecord += FieldStr; } else { - std::cout << "Err: " - << "FuncPtr(" << Record.type_name << "." << Name - << ") is not supported\n"; + std::cout << "Err: FuncPtr(" << Record.type_name << "." << Name << ") is not supported" << std::endl; } } else if (Type->isPointerType()) { auto PointeeType = Type->getPointeeType(); if (PointeeType->isRecordType()) { if (records.count(PointeeType.getTypePtr())) { std::string FieldStr = records[PointeeType.getTypePtr()].type_name; - FieldStr += "_ptr "; - FieldStr += Name; + FieldStr += "_ptr " + Name; GuestRecord += FieldStr; HostRecord += "host_" + FieldStr; } else { - GuestRecord += "void * " + Name; - HostRecord += "void * " + Name; + GuestRecord += "void *" + Name; + HostRecord += "void *" + Name; } } else { - GuestRecord += "void * " + Name; - HostRecord += "void * " + Name; + GuestRecord += "void *" + Name; + HostRecord += "void *" + Name; } } else if (Type->isRecordType()) { if (records.count(Type.getTypePtr())) { std::string FieldStr = records[Type.getTypePtr()].type_name; - FieldStr += " "; - FieldStr += Name; + FieldStr += " " + Name; GuestRecord += FieldStr; HostRecord += "host_" + FieldStr; } else { - GuestRecord += TypeStrify(StripTypedef(Type), Field, nullptr); - HostRecord += TypeStrify(StripTypedef(Type), Field, nullptr); + GuestRecord += TypeStringify(StripTypedef(Type), Field, nullptr); + HostRecord += TypeStringify(StripTypedef(Type), Field, nullptr); } } else { - HostRecord += TypeStrify(StripTypedef(Type), Field, nullptr); - GuestRecord += TypeStrify(StripTypedef(Type), Field, nullptr); + HostRecord += TypeStringify(StripTypedef(Type), Field, nullptr); + GuestRecord += TypeStringify(StripTypedef(Type), Field, nullptr); } GuestRecord += ";\n"; HostRecord += ";\n"; } - GuestRecord += "}"; - GuestRecord += Record.type_name + ", *" + Record.type_name + "_ptr;\n"; - - HostRecord += "}"; - HostRecord += - "host_" + Record.type_name + ", *host_" + Record.type_name + "_ptr;\n"; + GuestRecord += "} " + Record.type_name + ", *" + Record.type_name + "_ptr;\n"; + HostRecord += "} host_" + Record.type_name + ", *host_" + Record.type_name + "_ptr;\n"; return GuestRecord + HostRecord; } // Gen record convert function between host and guest std::string WrapperGenerator::GenRecordConvert(const RecordInfo &Record) { - std::string res{}; + std::string res; if (Record.guest_size != Record.host_size) { auto RecordDecl = Record.decl; - std::vector<int> GuestFieldOff; - std::vector<int> HostFieldOff; + std::vector<uint64_t> GuestFieldOff; + std::vector<uint64_t> HostFieldOff; auto OffDiff = GetRecordFieldOffDiff(Record.type, guest_triple, host_triple, GuestFieldOff, HostFieldOff); int FieldIndex = 0; - std::vector<clang::FieldDecl *> AlignDiffFields; - int SizeDiff = Record.guest_size - Record.host_size; + std::vector<FieldDecl *> AlignDiffFields; + uint64_t SizeDiff = Record.guest_size - Record.host_size; for (const auto &Field : RecordDecl->fields()) { if (OffDiff[FieldIndex] == 0) { FieldIndex++; continue; } - auto Type = Field->getType(); - std::string Name = Field->getNameAsString(); if (OffDiff[FieldIndex] != SizeDiff) { auto Diff = OffDiff[FieldIndex]; AlignDiffFields.push_back(Field); - for (int i = FieldIndex; i < OffDiff.size(); i++) { + for (size_t i = FieldIndex; i < OffDiff.size(); i++) { if (OffDiff[i] == Diff) { OffDiff[i] = 0; } else { @@ -568,14 +628,13 @@ std::string WrapperGenerator::GenRecordConvert(const RecordInfo &Record) { if (!AlignDiffFields.size()) { return res; } - res += "void g2h_" + Record.type_name + "(" + "struct host_" + - Record.type_name + "* d, struct" + Record.type_name + "* s) {\n"; - std::string body = " memcpy(d, s, offsetof(struct " + Record.type_name + + res += "void g2h_" + Record.type_name + "(" + "struct host_" + Record.type_name + "*d, struct" + Record.type_name + "*s) {\n"; + std::string body = " memcpy(d, s, offsetof(struct " + Record.type_name + ", " + AlignDiffFields[0]->getNameAsString() + "));\n"; std::string offstr = "offsetof(struct " + Record.type_name + ", " + AlignDiffFields[0]->getNameAsString() + ")"; - for (int i = 1; i < AlignDiffFields.size() - 1; i++) { - body += " memcpy(d->" + AlignDiffFields[i]->getNameAsString() + ", " + + for (size_t i = 1; i < AlignDiffFields.size() - 1; i++) { + body += " memcpy(d->" + AlignDiffFields[i]->getNameAsString() + ", " + "s->" + AlignDiffFields[i]->getNameAsString() + ", " + "offsetof(struct " + Record.type_name + ", " + AlignDiffFields[i + 1]->getNameAsString() + ") - " + offstr + @@ -583,17 +642,15 @@ std::string WrapperGenerator::GenRecordConvert(const RecordInfo &Record) { offstr = "offsetof(struct " + Record.type_name + ", " + AlignDiffFields[i + 1]->getNameAsString() + ")"; } - body += " memcpy(d->" + + body += " memcpy(d->" + AlignDiffFields[AlignDiffFields.size() - 1]->getNameAsString() + ", " + "s->" + AlignDiffFields[AlignDiffFields.size() - 1]->getNameAsString() + ", " + std::to_string(GetRecordSize(Record.type, guest_triple)) + " - " + offstr + ");\n"; - res += body; - res += "}\n"; + res += body + "}\n"; - res += "void h2g_" + Record.type_name + "(struct" + Record.type_name + - "* d, " + "struct host_" + Record.type_name + "* s) {\n"; + res += "void h2g_" + Record.type_name + "(struct" + Record.type_name + "*d, " + "struct host_" + Record.type_name + "*s) {\n"; res += body; res += "}\n"; } @@ -601,14 +658,14 @@ std::string WrapperGenerator::GenRecordConvert(const RecordInfo &Record) { } void WrapperGenerator::ParseRecordRecursive( - clang::ASTContext *Ctx, const clang::Type *Type, bool &Special, - std::set<const clang::Type *> &Visited) { - auto RecordType = Type->getAs<clang::RecordType>(); - auto RecordDecl = RecordType->getDecl(); + ASTContext *Ctx, const Type *type, bool &Special, + std::set<const Type *> &Visited) { + auto recordType = type->getAs<RecordType>(); + auto RecordDecl = recordType->getDecl(); for (const auto &field : RecordDecl->fields()) { auto FieldType = field->getType(); if (FieldType->isFunctionPointerType()) { - auto Record = &records[Type]; + auto Record = &records[type]; Record->callback_fields.push_back(field->getType().getTypePtr()); // Record->type_name = Special = true; @@ -633,18 +690,18 @@ void WrapperGenerator::ParseRecordRecursive( Special = true; } } - int GuestSize = GetRecordSize(Type, guest_triple); - int HostSize = GetRecordSize(Type, host_triple); + uint64_t GuestSize = GetRecordSize(type, guest_triple); + uint64_t HostSize = GetRecordSize(type, host_triple); - auto Record = &records[Type]; + auto Record = &records[type]; if (GuestSize != HostSize) { Special = 1; } - if (Type->isUnionType()) { + if (type->isUnionType()) { Record->is_union = true; } if (!Record->decl) { - Record->type = Type; + Record->type = type; Record->decl = RecordDecl; if (RecordDecl->getIdentifier()) Record->type_name = RecordDecl->getIdentifier()->getName().str(); @@ -658,11 +715,12 @@ void WrapperGenerator::ParseRecordRecursive( } // Type to String -std::string WrapperGenerator::TypeStrify(const clang::Type *Type, - clang::FieldDecl *FieldDecl, - clang::ParmVarDecl *ParmDecl, +std::string WrapperGenerator::TypeStringify(const Type *Type, + FieldDecl *FieldDecl, + ParmVarDecl *ParmDecl, + std::string indent, std::string Name) { - std::string res{}; + std::string res; std::string name = FieldDecl ? FieldDecl->getNameAsString() : (ParmDecl ? ParmDecl->getNameAsString() : Name); @@ -674,32 +732,30 @@ std::string WrapperGenerator::TypeStrify(const clang::Type *Type, } else if (PointeeType->isRecordType()) { if (records.find(StripTypedef(PointeeType)) != records.end() && records[StripTypedef(PointeeType)].is_special) { - res += PointeeType->isUnionType() ? "union {\n" : "struct "; - res += records[StripTypedef(PointeeType)].type_name; + res += (PointeeType->isUnionType() ? "union " : "struct ") + records[StripTypedef(PointeeType)].type_name; } else { res += "void"; } } else { res += "void"; } - res += " * " + name; + res += " *" + name; } else if (Type->isEnumeralType()) { - res += "int "; - res += name; + res += "int " + name; } else if (Type->isRecordType()) { if (records.find(StripTypedef(Type->getCanonicalTypeInternal())) != records.end() && records[StripTypedef(Type->getCanonicalTypeInternal())].is_special) { - res += Type->isUnionType() ? "union {\n" : "struct "; + res += Type->isUnionType() ? "union " : "struct "; res += records[StripTypedef(Type->getCanonicalTypeInternal())].type_name; res += " "; } else { - res += AnonRecordDecl(Type->getAs<clang::RecordType>()); + res += AnonRecordDecl(Type->getAs<RecordType>(), indent); } res += name; } else if (Type->isConstantArrayType()) { auto ArrayType = - clang::dyn_cast<clang::ConstantArrayType>(Type->getAsArrayTypeUnsafe()); + dyn_cast<ConstantArrayType>(Type->getAsArrayTypeUnsafe()); int EleSize = ArrayType->getSize().getZExtValue(); if (ArrayType->getElementType()->isPointerType()) { res += "void *"; @@ -720,36 +776,37 @@ std::string WrapperGenerator::TypeStrify(const clang::Type *Type, res += " "; res += name; } - return res; + return indent + res; } // Type to String, less detail -std::string WrapperGenerator::SimpleTypeStrify(const clang::Type *Type, - clang::FieldDecl *FieldDecl, - clang::ParmVarDecl *ParmDecl, +std::string WrapperGenerator::SimpleTypeStringify(const Type *Type, + FieldDecl *FieldDecl, + ParmVarDecl *ParmDecl, + std::string indent, std::string Name) { - std::string res{}; + std::string res; std::string name = FieldDecl ? FieldDecl->getNameAsString() : (ParmDecl ? ParmDecl->getNameAsString() : Name); if (Type->isPointerType()) { - res += "void * " + name; + res += "void *" + name; } else if (Type->isEnumeralType()) { res += "int "; res += name; } else if (Type->isRecordType()) { if (records.find(StripTypedef(Type->getCanonicalTypeInternal())) != records.end()) { - res += Type->isUnionType() ? "union {\n" : "struct "; + res += Type->isUnionType() ? "union " : "struct "; res += records[StripTypedef(Type->getCanonicalTypeInternal())].type_name; res += " "; } else { - res += SimpleAnonRecordDecl(Type->getAs<clang::RecordType>()); + res += SimpleAnonRecordDecl(Type->getAs<RecordType>(), indent); } res += name; } else if (Type->isConstantArrayType()) { auto ArrayType = - clang::dyn_cast<clang::ConstantArrayType>(Type->getAsArrayTypeUnsafe()); + dyn_cast<ConstantArrayType>(Type->getAsArrayTypeUnsafe()); int EleSize = ArrayType->getSize().getZExtValue(); if (ArrayType->getElementType()->isPointerType()) { res += "void *"; @@ -770,50 +827,48 @@ std::string WrapperGenerator::SimpleTypeStrify(const clang::Type *Type, res += " "; res += name; } - return res; + return indent + res; } -std::string WrapperGenerator::AnonRecordDecl(const clang::RecordType *Type) { +std::string WrapperGenerator::AnonRecordDecl(const RecordType *Type, std::string indent) { auto RecordDecl = Type->getDecl(); - std::string res{}; + std::string res; res += Type->isUnionType() ? "union {\n" : "struct {\n"; for (const auto &field : RecordDecl->fields()) { auto FieldType = field->getType(); - res += " "; - res += TypeStrify(StripTypedef(FieldType), field, nullptr); + res += TypeStringify(StripTypedef(FieldType), field, nullptr, indent + " "); res += ";\n"; } - res += " } "; + res += indent + "} "; return res; } std::string -WrapperGenerator::SimpleAnonRecordDecl(const clang::RecordType *Type) { +WrapperGenerator::SimpleAnonRecordDecl(const RecordType *Type, std::string indent) { auto RecordDecl = Type->getDecl(); - std::string res{}; + std::string res; res += Type->isUnionType() ? "union {\n" : "struct {\n"; for (const auto &field : RecordDecl->fields()) { auto FieldType = field->getType(); - res += " "; - res += SimpleTypeStrify(StripTypedef(FieldType), field, nullptr); + res += SimpleTypeStringify(StripTypedef(FieldType), field, nullptr, indent + " "); res += ";\n"; } - res += " } "; + res += indent + "} "; return res; } // Get func info from FunctionType -FuncDefinition WrapperGenerator::GetFuncDefinition(const clang::Type *Type) { +FuncDefinition WrapperGenerator::GetFuncDefinition(const Type *Type) { FuncDefinition res; - auto ProtoType = Type->getAs<clang::FunctionProtoType>(); + auto ProtoType = Type->getAs<FunctionProtoType>(); res.ret = StripTypedef(ProtoType->getReturnType()); res.ret_str = - TypeStrify(StripTypedef(ProtoType->getReturnType()), nullptr, nullptr); - for (int i = 0; i < ProtoType->getNumParams(); i++) { + TypeStringify(StripTypedef(ProtoType->getReturnType()), nullptr, nullptr); + for (unsigned i = 0; i < ProtoType->getNumParams(); i++) { auto ParamType = ProtoType->getParamType(i); res.arg_types.push_back(StripTypedef(ParamType)); res.arg_types_str.push_back( - TypeStrify(StripTypedef(ParamType), nullptr, nullptr)); + TypeStringify(StripTypedef(ParamType), nullptr, nullptr)); res.arg_names.push_back(std::string("a") + std::to_string(i)); } if (ProtoType->isVariadic()) { @@ -824,17 +879,17 @@ FuncDefinition WrapperGenerator::GetFuncDefinition(const clang::Type *Type) { } // Get funcdecl info from FunctionDecl -FuncDefinition WrapperGenerator::GetFuncDefinition(clang::FunctionDecl *Decl) { +FuncDefinition WrapperGenerator::GetFuncDefinition(FunctionDecl *Decl) { FuncDefinition res; auto RetType = Decl->getReturnType(); res.ret = RetType.getTypePtr(); - res.ret_str = TypeStrify(StripTypedef(RetType), nullptr, nullptr, ""); - for (int i = 0; i < Decl->getNumParams(); i++) { + res.ret_str = TypeStringify(StripTypedef(RetType), nullptr, nullptr); + for (unsigned i = 0; i < Decl->getNumParams(); i++) { auto ParamDecl = Decl->getParamDecl(i); auto ParamType = ParamDecl->getType(); res.arg_types.push_back(ParamType.getTypePtr()); res.arg_types_str.push_back( - TypeStrify(StripTypedef(ParamType), nullptr, nullptr, "")); + TypeStringify(StripTypedef(ParamType), nullptr, nullptr)); res.arg_names.push_back(ParamDecl->getNameAsString()); } if (Decl->isVariadic()) { @@ -844,36 +899,46 @@ FuncDefinition WrapperGenerator::GetFuncDefinition(clang::FunctionDecl *Decl) { } // Get the offset diff between two different triple -std::vector<int> WrapperGenerator::GetRecordFieldOffDiff( - const clang::Type *Type, const std::string &GuestTriple, - const std::string &HostTriple, std::vector<int> &GuestFieldOff, - std::vector<int> &HostFieldOff) { - std::string Code = TypeStrify(Type, nullptr, nullptr, "dummy;"); - return ::GetRecordFieldOffDiff(Code, GuestTriple, HostTriple, GuestFieldOff, - HostFieldOff); +std::vector<uint64_t> WrapperGenerator::GetRecordFieldOffDiff( + const Type *Type, const std::string &GuestTriple, + const std::string &HostTriple, std::vector<uint64_t> &GuestFieldOff, + std::vector<uint64_t> &HostFieldOff) { + std::string Code = TypeStringify(Type, nullptr, nullptr, "", "dummy;"); + std::vector<uint64_t> OffsetDiff; + GuestFieldOff = GetRecordFieldOff(Code, GuestTriple); + HostFieldOff = GetRecordFieldOff(Code, HostTriple); + if (GuestFieldOff.size() != HostFieldOff.size()) { + // Should not happen + std::cout << "Greater field offsets in guest than in host" << std::endl; + return OffsetDiff; + } + for (size_t i = 0; i < GuestFieldOff.size(); i++) { + OffsetDiff.push_back(GuestFieldOff[i] - HostFieldOff[i]); + } + return OffsetDiff; } // Get the size under a specific triple -int WrapperGenerator::GetRecordSize(const clang::Type *Type, +uint64_t WrapperGenerator::GetRecordSize(const Type *Type, const std::string &Triple) { - std::string Code = TypeStrify(Type, nullptr, nullptr, "dummy;"); + std::string Code = TypeStringify(Type, nullptr, nullptr, "", "dummy;"); return ::GetRecordSize(Code, Triple); } // Get the align under a specific triple -int WrapperGenerator::GetRecordAlign(const clang::Type *Type, +CharUnits::QuantityType WrapperGenerator::GetRecordAlign(const Type *Type, const std::string &Triple) { - std::string Code = TypeStrify(Type, nullptr, nullptr, "dummy;"); + std::string Code = TypeStringify(Type, nullptr, nullptr, "", "dummy;"); return ::GetRecordAlign(Code, Triple); } // Generate the func sig by type, used for export func -std::string WrapperGenerator::GetFuncSig(clang::ASTContext *CTX, +std::string WrapperGenerator::GetFuncSig(ASTContext *CTX, const FuncInfo &Func) { - std::string sig{}; + std::string sig; auto Decl = Func.decl; auto Type = Decl->getType().getTypePtr(); - auto ProtoType = Type->getAs<clang::FunctionProtoType>(); + auto ProtoType = Type->getAs<FunctionProtoType>(); auto RetType = ProtoType->getReturnType(); sig += TypeToSig(CTX, RetType.getTypePtr()); @@ -882,7 +947,7 @@ std::string WrapperGenerator::GetFuncSig(clang::ASTContext *CTX, sig += "E"; } if (ProtoType->getNumParams()) { - for (int i = 0; i < ProtoType->getNumParams(); i++) { + for (unsigned i = 0; i < ProtoType->getNumParams(); i++) { sig += TypeToSig(CTX, ProtoType->getParamType(i).getTypePtr()); } } else { @@ -895,19 +960,19 @@ std::string WrapperGenerator::GetFuncSig(clang::ASTContext *CTX, } // Generate the func sig by type, used for callbacks -std::string WrapperGenerator::GetFuncSig(clang::ASTContext *CTX, - const clang::Type *Type) { - std::string sig{}; - auto ProtoType = Type->getAs<clang::FunctionProtoType>(); +std::string WrapperGenerator::GetFuncSig(ASTContext *CTX, + const Type *Type) { + std::string sig; + auto ProtoType = Type->getAs<FunctionProtoType>(); auto RetType = ProtoType->getReturnType(); sig += TypeToSig(CTX, RetType.getTypePtr()); sig += "F"; if (ProtoType->getNumParams()) { - for (int i = 0; i < ProtoType->getNumParams(); i++) { + for (unsigned i = 0; i < ProtoType->getNumParams(); i++) { sig += TypeToSig(CTX, ProtoType->getParamType(i).getTypePtr()); } } else { sig += "v"; } return sig; -} \ No newline at end of file +} diff --git a/wrapperhelper/gen.h b/wrapperhelper/gen.h index 9bfa8cfb..64c1e319 100644 --- a/wrapperhelper/gen.h +++ b/wrapperhelper/gen.h @@ -35,8 +35,8 @@ struct RecordInfo { bool is_union; bool is_special; - int guest_size; - int host_size; + uint64_t guest_size; + uint64_t host_size; std::vector<const clang::Type*> callback_fields; }; @@ -98,7 +98,8 @@ struct WrapperGenerator { } std::string GenRecordConvert(clang::ASTContext* Ctx) { - std::string res{}; + (void)Ctx; + std::string res; for (const auto& record : records) { if (record.second.host_size != record.second.guest_size) { res += GenRecordConvert(record.second); @@ -127,17 +128,17 @@ private: std::string GenDeclare(clang::ASTContext* Ctx, const RecordInfo& Struct); std::string GenCallbackWrap(clang::ASTContext* Ctx, const RecordInfo& Struct); - void ParseRecordRecursive(clang::ASTContext* Ctx, const clang::Type* ReocrdType, bool& Special, std::set<const clang::Type*>& Visited); - std::string TypeStrify(const clang::Type* Type, clang::FieldDecl* FieldDecl, clang::ParmVarDecl* ParmDecl, std::string Name = ""); - std::string SimpleTypeStrify(const clang::Type* Type, clang::FieldDecl* FieldDecl, clang::ParmVarDecl* ParmDecl, std::string Name = ""); - std::string AnonRecordDecl(const clang::RecordType* Type); - std::string SimpleAnonRecordDecl(const clang::RecordType* Type); + void ParseRecordRecursive(clang::ASTContext* Ctx, const clang::Type* Type, bool& Special, std::set<const clang::Type*>& Visited); + std::string TypeStringify(const clang::Type* Type, clang::FieldDecl* FieldDecl, clang::ParmVarDecl* ParmDecl, std::string indent = "", std::string Name = ""); + std::string SimpleTypeStringify(const clang::Type* Type, clang::FieldDecl* FieldDecl, clang::ParmVarDecl* ParmDecl, std::string indent = "", std::string Name = ""); + std::string AnonRecordDecl(const clang::RecordType* Type, std::string indent); + std::string SimpleAnonRecordDecl(const clang::RecordType* Type, std::string indent); FuncDefinition GetFuncDefinition(const clang::Type* Type); FuncDefinition GetFuncDefinition(clang::FunctionDecl* Decl); - int GetRecordSize(const clang::Type* Type, const std::string& Triple); - std::vector<int> GetRecordFieldOffDiff(const clang::Type* Type, const std::string& GuestTriple, const std::string& HostTriple, std::vector<int>& GuestFieldOff, std::vector<int>& HostFieldOff); - int GetRecordAlign(const clang::Type* Type, const std::string& Triple); + uint64_t GetRecordSize(const clang::Type* Type, const std::string& Triple); + std::vector<uint64_t> GetRecordFieldOffDiff(const clang::Type* Type, const std::string& GuestTriple, const std::string& HostTriple, std::vector<uint64_t>& GuestFieldOff, std::vector<uint64_t>& HostFieldOff); + clang::CharUnits::QuantityType GetRecordAlign(const clang::Type* Type, const std::string& Triple); std::string GetFuncSig(clang::ASTContext* CTX, const FuncInfo& Decl); std::string GetFuncSig(clang::ASTContext* CTX, const clang::Type* Type); -}; \ No newline at end of file +}; diff --git a/wrapperhelper/main.cpp b/wrapperhelper/main.cpp index 1d228b43..bb182359 100644 --- a/wrapperhelper/main.cpp +++ b/wrapperhelper/main.cpp @@ -1,61 +1,63 @@ #include "ast.h" #include "utils.h" - -void dump_usage() { +static void dump_usage() { std::string Usage = R"usage( usage: command <filename> <libname> [guest_triple] [host_triple] -- <clang_flags> - <filename> : set the header file to be parsed - <libname> : set libname required for wrapping func - [guest_triple]: set guest triple arm32/arm64/x86/x64, default is x86 - [host_triple]: set host tripe arm32/arm64/x86/x64, default is arm32 - -- : is necessary + <filename> : set the header file to be parsed + <libname> : set libname required for wrapping func + [guest_triple]: set guest triple: can be arm32/arm64/x86/x64, default is x64 + [host_triple] : set host triple: can be arm32/arm64/x86/x64, default is arm64 + -- : mandatory + <clang_flags> : extra compiler flags )usage"; std::cerr << Usage << std::endl; } std::string parse_triple(const char* arg) { - if (strcmp(arg, "arm32") == 0) { - return TripleName[ARM32]; - } else if (strcmp(arg, "arm64") == 0) { - return TripleName[ARM64]; - } else if (strcmp(arg, "x86") == 0) { - return TripleName[X86]; + if (strcmp(arg, "x86") == 0) { + return "i386-pc-linux-gnu"; } else if (strcmp(arg, "x64") == 0) { - return TripleName[X64]; + return "x86_64-pc-linux-gnu"; + } else if (strcmp(arg, "arm32") == 0) { + return "armv7-unknown-linux-gnueabihf"; + } else if (strcmp(arg, "arm64") == 0) { + return "aarch64-unknown-linux-gnu"; } else { + std::cerr << "Invalid triple: '" << arg << "'\n"; + dump_usage(); return ""; } } -using namespace clang::tooling; int main(int argc, const char* argv[]) { if (argc < 4) { dump_usage(); return 0; } std::string libname = argv[2]; - std::string guest_triple = TripleName[X64]; - std::string host_triple = TripleName[ARM64]; + std::string guest_triple = parse_triple("x64"); + std::string host_triple = parse_triple("arm64"); if (argc >= 5) { guest_triple = parse_triple(argv[3]); } if (argc >= 6) { host_triple = parse_triple(argv[4]); } - bool has_nessary_tag = false; + bool has_necessary_tag = false; for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "--") == 0) { - has_nessary_tag = true; + has_necessary_tag = true; break; } } - if (!has_nessary_tag) { - std::cerr << "Please add '--' after triple arg" << std::endl; + if (!has_necessary_tag) { + std::cerr << "Please add '--' after the triples" << std::endl; + dump_usage(); return 0; } std::string err; - auto compile_db = FixedCompilationDatabase::loadFromCommandLine(argc, argv, err); - ClangTool Tool(*compile_db, {argv[1]}); + auto compile_db = clang::tooling::FixedCompilationDatabase::loadFromCommandLine(argc, argv, err); + clang::tooling::ClangTool Tool(*compile_db, {argv[1]}); return Tool.run(std::make_unique<MyFrontendActionFactory>(libname, host_triple, guest_triple).get()); } diff --git a/wrapperhelper/utils.h b/wrapperhelper/utils.h index baf71878..25865376 100644 --- a/wrapperhelper/utils.h +++ b/wrapperhelper/utils.h @@ -12,23 +12,6 @@ #include <cstring> #include <iostream> -enum Triple { - X86, - X64, - ARM32, - ARM64, - RISCV64, - TripleCnt, -}; - -static const char* TripleName[TripleCnt] = { - "i386-pc-linux-gnu", - "x86_64-pc-linux-gnu", - "armv7-unknown-linux-gnueabihf", - "aarch64-unknown-linux-gnu", - "riscv64-unknown-linux-gnu" -}; - static const clang::Type* StripTypedef(clang::QualType type) { if (type->isTypedefNameType()) { return StripTypedef(type->getAs<clang::TypedefType>()->getDecl()->getUnderlyingType()); @@ -36,140 +19,3 @@ static const clang::Type* StripTypedef(clang::QualType type) { return type.getTypePtr(); } } - -static int GetRecordSize(const std::string& Code, const std::string& Triple) { - std::vector<std::string> Args = {"-target", Triple}; - std::unique_ptr<clang::ASTUnit> AST = clang::tooling::buildASTFromCodeWithArgs(Code, Args); - auto& Ctx = AST->getASTContext(); - auto TranslateDecl = Ctx.getTranslationUnitDecl(); - for (const auto& Decl : TranslateDecl->decls()) { - if (const auto RecordDecl = clang::dyn_cast<clang::RecordDecl>(Decl)) { - return Ctx.getTypeSize(RecordDecl->getTypeForDecl()) / 8; - } - } - return 0; -} - -static std::vector<int> GetRecordFieldOff(const std::string& Code, const std::string& Triple) { - std::vector<int> FieldOff; - std::vector<std::string> Args = {"-target", Triple}; - std::unique_ptr<clang::ASTUnit> AST = clang::tooling::buildASTFromCodeWithArgs(Code, Args); - auto& Ctx = AST->getASTContext(); - auto TranslateDecl = Ctx.getTranslationUnitDecl(); - for (const auto& Decl : TranslateDecl->decls()) { - if (const auto RecordDecl = clang::dyn_cast<clang::RecordDecl>(Decl)) { - auto& RecordLayout = Ctx.getASTRecordLayout(RecordDecl); - for (int i = 0; i < RecordLayout.getFieldCount(); i++) { - FieldOff.push_back(RecordLayout.getFieldOffset(i) / 8); - } - break; - } - } - return FieldOff; -} - -static int GetRecordAlign(const std::string& Code, const std::string& Triple) { - std::vector<std::string> Args = {"-target", Triple}; - std::unique_ptr<clang::ASTUnit> AST = clang::tooling::buildASTFromCodeWithArgs(Code, Args); - auto& Ctx = AST->getASTContext(); - auto TranslateDecl = Ctx.getTranslationUnitDecl(); - for (const auto& Decl : TranslateDecl->decls()) { - if (const auto RecordDecl = clang::dyn_cast<clang::RecordDecl>(Decl)) { - auto& RecordLayout = Ctx.getASTRecordLayout(RecordDecl); - for (int i = 0; i < RecordLayout.getFieldCount(); i++) { - return RecordLayout.getAlignment().getQuantity() / 8; - } - break; - } - } - return 0; -} - -static std::vector<int> GetRecordFieldOffDiff(const std::string& Code, const std::string& GuestTriple, const std::string& HostTriple, std::vector<int>& GuestFieldOff, std::vector<int>& HostFieldOff) { - std::vector<int> OffsetDiff; - GuestFieldOff = GetRecordFieldOff(Code, GuestTriple); - HostFieldOff = GetRecordFieldOff(Code, HostTriple); - if (GuestFieldOff.size() != HostFieldOff.size()) { - return OffsetDiff; - } - for (int i = 0; i < GuestFieldOff.size(); i++) { - OffsetDiff.push_back(GuestFieldOff[i] - HostFieldOff[i]); - } - return OffsetDiff; -} - -static int GetTypeSize(const clang::Type* Type, const std::string& Triple) { - std::string Code = Type->getCanonicalTypeInternal().getAsString() + " dummy;"; - std::vector<std::string> Args = {"-target", Triple}; - std::unique_ptr<clang::ASTUnit> AST = clang::tooling::buildASTFromCodeWithArgs(Code, Args); - auto& Ctx = AST->getASTContext(); - auto TranslateDecl = Ctx.getTranslationUnitDecl(); - for (const auto& Decl : TranslateDecl->decls()) { - if (const auto VarDecl = clang::dyn_cast<clang::VarDecl>(Decl)) { - return Ctx.getTypeSize(VarDecl->getType()) / 8; - } - } - return 0; -} - -static int GetTypeAlign(const clang::Type* Type, const std::string& Triple) { - std::string Code = Type->getCanonicalTypeInternal().getAsString() + " dummy;"; - std::vector<std::string> Args = {"-target", Triple}; - std::unique_ptr<clang::ASTUnit> AST = clang::tooling::buildASTFromCodeWithArgs(Code, Args); - auto& Ctx = AST->getASTContext(); - auto TranslateDecl = Ctx.getTranslationUnitDecl(); - for (const auto& Decl : TranslateDecl->decls()) { - if (const auto VarDecl = clang::dyn_cast<clang::VarDecl>(Decl)) { - return Ctx.getTypeAlign(VarDecl->getType());; - } - } - return 0; -} - -static std::string TypeToSig(clang::ASTContext* Ctx, const clang::Type* Type) { - if (Type->isPointerType()) { - return "p"; - } else if (Type->isVoidType()) { - return "v"; - } else if (Type->isUnsignedIntegerOrEnumerationType()) { - switch(Ctx->getTypeSizeInChars(Type).getQuantity()) { - case 1: - return "c"; - case 2: - return "w"; - case 4: - return "i"; - case 8: - return "I"; - default: - std::cout << "Unsupported UnSignedInteger Type: " << Type->getCanonicalTypeInternal().getAsString() << std::endl; - } - } else if (Type->isSignedIntegerOrEnumerationType()) { - switch(Ctx->getTypeSizeInChars(Type).getQuantity()) { - case 1: - return "C"; - case 2: - return "W"; - case 4: - return "u"; - case 8: - return "U"; - default: - std::cout << "Unsupported SignedInteger Type: " << Type->getCanonicalTypeInternal().getAsString() << std::endl; - } - } else if (Type->isCharType()) { - return "c"; - } else if (Type->isFloatingType()) { - switch(Ctx->getTypeSizeInChars(Type).getQuantity()) { - case 4: - return "f"; - case 8: - return "d"; - default: - std::cout << "Unsupported Floating Type: " << Type->getCanonicalTypeInternal().getAsString() << std::endl; - } - } else { - std::cout << "Unsupported Type: " << Type->getCanonicalTypeInternal().getAsString() << std::endl; - } - return "?"; -} |