about summary refs log tree commit diff stats
path: root/wrapperhelper/gen.cpp
diff options
context:
space:
mode:
authorrajdakin <rajdakin@gmail.com>2024-09-06 15:07:38 +0200
committerGitHub <noreply@github.com>2024-09-06 15:07:38 +0200
commit6044feb7fd58ff69f63f5418f516b1f3ded346e9 (patch)
tree9935288f145df5b80f6d118c8a487b0a10afb1e8 /wrapperhelper/gen.cpp
parent7dc59ac342d315dbb352becbeabc4e7057992de0 (diff)
downloadbox64-6044feb7fd58ff69f63f5418f516b1f3ded346e9.tar.gz
box64-6044feb7fd58ff69f63f5418f516b1f3ded346e9.zip
Wrapper helper (#1799)
* [WRAPPERHELPER] Added wrapperhelper v0.1, tested on libc

* [WRAPPED] Removed updates to libc from this branch

* [WRAPPERHELPER] Removed GPL header and added modified LGPL header, added notes about licensing issues
Diffstat (limited to 'wrapperhelper/gen.cpp')
-rw-r--r--wrapperhelper/gen.cpp1059
1 files changed, 0 insertions, 1059 deletions
diff --git a/wrapperhelper/gen.cpp b/wrapperhelper/gen.cpp
deleted file mode 100644
index 743474cd..00000000
--- a/wrapperhelper/gen.cpp
+++ /dev/null
@@ -1,1059 +0,0 @@
-#include "gen.h"
-#include "utils.h"
-#include <clang/AST/ASTContext.h>
-#include <clang/AST/Decl.h>
-#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->isBuiltinType()) {
-        switch (Type->getAs<clang::BuiltinType>()->getKind()) {
-        case clang::BuiltinType::Kind::Void:
-            return "v";
-        case clang::BuiltinType::Kind::Bool:
-            return "i";
-        case clang::BuiltinType::Kind::Char_U:
-            return "C";
-        case clang::BuiltinType::Kind::Char_S:
-            return "c";
-        case clang::BuiltinType::Kind::Char8:
-            return "c";
-        case clang::BuiltinType::Kind::UChar:
-            return "C";
-        case clang::BuiltinType::Kind::SChar:
-            return "c";
-        case clang::BuiltinType::Kind::WChar_U:
-            return "W";
-        case clang::BuiltinType::Kind::UShort:
-            return "W";
-        case clang::BuiltinType::Kind::WChar_S:
-            return "w";
-        case clang::BuiltinType::Kind::Char16:
-            return "w";
-        case clang::BuiltinType::Kind::Short:
-            return "w";
-        case clang::BuiltinType::Kind::UInt:
-            return "u";
-        case clang::BuiltinType::Kind::Char32:
-            return "i";
-        case clang::BuiltinType::Kind::Int:
-            return "i";
-        case clang::BuiltinType::Kind::ULong:
-            return "L";
-        case clang::BuiltinType::Kind::Long:
-            return "l";
-        case clang::BuiltinType::Kind::ULongLong:
-            return "U";
-        case clang::BuiltinType::Kind::LongLong:
-            return "I";
-        case clang::BuiltinType::Kind::UInt128:
-            return "H";
-        case clang::BuiltinType::Kind::Int128:
-            return "H";
-        case clang::BuiltinType::Kind::Float:
-            return "f";
-        case clang::BuiltinType::Kind::Double:
-            return "d";
-        case clang::BuiltinType::Kind::LongDouble:
-            return "D";
-        case clang::BuiltinType::Kind::NullPtr:
-            return "p"; // nullptr_t
-        default:
-            std::cout << "Unsupported BuiltinType: " << Type->getCanonicalTypeInternal().getAsString() << std::endl;
-        }
-    } else {
-        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(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<TypedefType>()->getDecl()->getNameAsString();
-      } else if (Type) {
-        callbacks[StripTypedef(Type->getPointeeType())] =
-            GetFuncSig(Ctx, Type->getPointeeType().getTypePtr()) + "_t";
-      }
-    }
-  }
-  std::vector<const Type *> Types;
-  for (const auto &record_pair : records) {
-    Types.push_back(record_pair.first);
-  }
-  for (auto type : Types) {
-    std::set<const Type*> Visited{type};
-    bool Special = false;
-    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 field : it->second.callback_fields) {
-        if (field->isTypedefNameType()) {
-          callbacks[StripTypedef(field->getPointeeType())] =
-              field->getAs<TypedefType>()->getDecl()->getNameAsString();
-        } else {
-          callbacks[StripTypedef(field->getPointeeType())] =
-              GetFuncSig(Ctx, field->getPointeeType().getTypePtr()) + "_t";
-        }
-      }
-      ++it;
-    }
-  }
-  for (auto &func_pair : funcs) {
-    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() &&
-          ParamType->getPointeeType()->isRecordType()) {
-        if (records.find(StripTypedef(ParamType->getPointeeType())) !=
-            records.end()) {
-          func_pair.second.has_special_arg = true;
-          break;
-        }
-      } else if (ParamType->isRecordType()) {
-        if (records.find(StripTypedef(ParamType)) != records.end()) {
-          func_pair.second.has_special_arg = true;
-          break;
-        }
-      }
-    }
-    auto RetType = func_pair.second.decl->getReturnType();
-    if (RetType->isPointerType() && RetType->getPointeeType()->isRecordType()) {
-      if (records.find(StripTypedef(RetType->getPointeeType())) !=
-          records.end()) {
-        func_pair.second.has_special_ret = true;
-      }
-    } else if (RetType->isRecordType()) {
-      if (records.find(StripTypedef(RetType)) != records.end()) {
-        func_pair.second.has_special_ret = true;
-      }
-    }
-  }
-}
-
-// Gen callback typedef
-std::string WrapperGenerator::GenCallbackTypeDefs(ASTContext *Ctx) {
-  (void)Ctx;
-  std::string res;
-  for (auto callback : callbacks) {
-    auto Type = callback.first;
-    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 (Definition.arg_size) {
-      res += Definition.arg_types_str[Definition.arg_size - 1] + Definition.arg_names[Definition.arg_size - 1];
-    }
-    res += ");\n";
-  }
-  return res;
-}
-
-// Gen function declare
-std::string WrapperGenerator::GenDeclare(ASTContext *Ctx,
-                                         const FuncInfo &Func) {
-  std::string res;
-  std::string sig = GetFuncSig(Ctx, Func);
-  res += "GO";
-  if (Func.is_weak) {
-    res += "W";
-  }
-  if (sig.find('E') != std::string::npos) {
-    res += "M";
-  }
-  res += "(" + Func.func_name + ", " + sig + ")\n";
-  ;
-  return res;
-}
-
-// Gen structure declare
-std::string WrapperGenerator::GenDeclare(ASTContext *Ctx,
-                                         const RecordInfo &Record) {
-  (void)Ctx;
-  std::string RecordStr;
-  std::string PreDecl;
-  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 += "    ";
-    if (Type->isFunctionPointerType()) {
-      auto FuncType = StripTypedef(Type->getPointeeType());
-      if (callbacks.count(FuncType)) {
-        std::string FieldStr = callbacks[FuncType];
-        FieldStr += " ";
-        FieldStr += Name;
-        RecordStr += FieldStr;
-      } else {
-        std::cout << "Err: FuncPtr(" << Record.type_name << "." << Name << ") is not supported\n";
-      }
-    } 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;
-          RecordStr += FieldStr;
-        } else {
-          RecordStr += "void *" + Name;
-        }
-      } else {
-        RecordStr += "void *" + Name;
-      }
-    } else if (Type->isRecordType()) {
-      if (records.count(Type.getTypePtr())) {
-        std::string FieldStr = records[Type.getTypePtr()].type_name;
-        FieldStr += " ";
-        FieldStr += Name;
-        RecordStr += FieldStr;
-      } else {
-        RecordStr += TypeStringify(StripTypedef(Type), Field, nullptr, PreDecl);
-      }
-    } else {
-      RecordStr += TypeStringify(StripTypedef(Type), Field, nullptr, PreDecl);
-    }
-    RecordStr += ";\n";
-  }
-  RecordStr += "} ";
-  RecordStr += Record.type_name + ", *" + Record.type_name + "_ptr;\n";
-  return RecordStr;
-}
-
-std::string WrapperGenerator::GenCallbackWrap(ASTContext *Ctx,
-                                              const FuncInfo &Func) {
-  (void)Ctx;
-  std::string res;
-
-  for (unsigned i = 0; i < Func.decl->getNumParams(); i++) {
-    auto ParamType = Func.decl->getParamDecl(i)->getType();
-    if (ParamType->isFunctionPointerType()) {
-
-      auto PointeeType = ParamType->getPointeeType();
-      auto Definition = GetFuncDefinition(PointeeType.getTypePtr());
-      std::string my_funcname =
-          std::string("my_") + Func.decl->getParamDecl(i)->getNameAsString();
-      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] + " " + Definition.arg_names[i] + ", ";
-        }
-        res += Definition.arg_types_str[arg_size - 1] + " " + Definition.arg_names[arg_size - 1];
-      }
-      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"
-             "}\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(ASTContext *Ctx,
-                                              const RecordInfo &Struct) {
-  (void)Ctx;
-  std::string res;
-  for (const auto &field : Struct.decl->fields()) {
-    auto FieldType = field->getType();
-    if (FieldType->isFunctionPointerType()) {
-      auto PointeeType = FieldType->getPointeeType();
-      auto Definition = GetFuncDefinition(PointeeType.getTypePtr());
-      std::string my_funcname = std::string("my_") + field->getNameAsString();
-      std::string funcname = field->getNameAsString();
-      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] + " " + Definition.arg_names[i] + ", ";
-        }
-        res += Definition.arg_types_str[arg_size - 1] + " " + Definition.arg_names[arg_size - 1];
-      }
-      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"
-             "}\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(ASTContext *Ctx,
-                                        const FuncInfo &Func) {
-  std::string res;
-  auto Definition = GetFuncDefinition(Func.decl);
-  std::string Sig = GetFuncSig(Ctx, Func.type);
-  res += "\nEXPORT " + Definition.ret_str + "my_" + Func.func_name + "(";
-  if (Sig.find('E')) {
-    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(PointeeType.getTypePtr())) {
-          res +=
-              Definition.arg_types[i]->getCanonicalTypeInternal().getAsString();
-        } else {
-          res += Definition.arg_types_str[i];
-        }
-      } else {
-        res += Definition.arg_types_str[i];
-      }
-      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(PointeeType.getTypePtr())) {
-        res += Definition.arg_types[arg_size - 1]
-                   ->getCanonicalTypeInternal()
-                   .getAsString();
-      } else {
-        res += Definition.arg_types_str[arg_size - 1];
-      }
-    } else {
-      res += Definition.arg_types_str[arg_size - 1];
-    }
-    res += " ";
-    res += Definition.arg_names[arg_size - 1];
-  }
-  res += ") {\n";
-  if (Func.has_special_arg) {
-    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) {
-    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) {
-    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()) {
-            res +=
-                "find" + Func.func_name + "_arg" + std::to_string(i) + "Fct";
-          } else {
-            res += "find" +
-                           Func.callback_args[i]
-                               ->getAs<TypedefType>()
-                               ->getDecl()
-                               ->getNameAsString() +
-                           "Fct";
-          }
-          res += "(" + Definition.arg_names[i] + ")";
-        } else {
-          res += Definition.arg_names[i];
-        }
-        res += ", ";
-      }
-      if (Func.callback_args[arg_size - 1]) {
-        if (!Func.callback_args[arg_size - 1]->isTypedefNameType()) {
-          res += "find" + Func.func_name + "_arg" +
-                         std::to_string(arg_size - 1) + "Fct";
-        } else {
-          res += "find" +
-                         Func.callback_args[arg_size - 1]
-                             ->getAs<TypedefType>()
-                             ->getDecl()
-                             ->getNameAsString() +
-                         "Fct";
-        }
-        res += "(" + Definition.arg_names[arg_size - 1] + ")";
-      } else {
-        res += Definition.arg_names[arg_size - 1];
-      }
-      res += ")\n";
-    }
-  } else {
-    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++) {
-        res += Definition.arg_names[i] + ", ";
-      }
-      res += Definition.arg_names[arg_size - 1];
-    }
-      res += ");\n";
-  }
-
-  res += "}\n";
-  return res;
-}
-
-std::string WrapperGenerator::GenDeclareDiffTriple(
-    ASTContext *Ctx, const RecordInfo &Record,
-    const std::string &GuestTriple, const std::string &HostTriple) {
-  (void)Ctx;
-  std::string GuestRecord;
-  std::string HostRecord;
-  std::string PreDecl;
-  std::vector<uint64_t> GuestFieldOff;
-  std::vector<uint64_t> HostFieldOff;
-  GuestRecord += "typedef ";
-  HostRecord += "typedef ";
-  GuestRecord +=
-      (Record.is_union ? "union " : "struct ") + Record.type_name + " {\n";
-  HostRecord += (Record.is_union ? "union " : "struct ") +
-                std::string("host_") + Record.type_name + " {\n";
-  auto OffDiff = GetRecordFieldOffDiff(Record.type, GuestTriple, HostTriple,
-                                       GuestFieldOff, HostFieldOff);
-  uint64_t GuestRecordSize = GetRecordSize(Record.type, GuestTriple);
-  uint64_t HostRecordSize = GetRecordSize(Record.type, HostTriple);
-  uint64_t SizeDiff = GuestRecordSize - HostRecordSize;
-  int FieldIndex = 0;
-  std::set<FieldDecl *> AlignDiffFields;
-  for (const auto &Field : Record.decl->fields()) {
-    if (OffDiff[FieldIndex] == 0) {
-      FieldIndex++;
-      continue;
-    }
-    std::string Name = Field->getNameAsString();
-    if (OffDiff[FieldIndex] != SizeDiff) {
-      auto Diff = OffDiff[FieldIndex];
-      AlignDiffFields.insert(Field);
-      for (size_t i = FieldIndex; i < OffDiff.size(); i++) {
-        if (OffDiff[i] == Diff) {
-          OffDiff[i] = 0;
-        } else {
-          break;
-        }
-      }
-    } else {
-      AlignDiffFields.insert(Field);
-      break;
-    }
-    FieldIndex++;
-  }
-  for (const auto &Field : Record.decl->fields()) {
-    auto Type = Field->getType();
-    std::string Name = Field->getNameAsString();
-    GuestRecord += "  ";
-    HostRecord += "  ";
-    if (AlignDiffFields.find(Field) != AlignDiffFields.end()) {
-      auto typeSize = GetTypeSize(StripTypedef(Field->getType()), guest_triple);
-      switch (typeSize) {
-      // FIXME: should test more case in different triple
-      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 += TypeStringify(StripTypedef(Type), Field, nullptr, PreDecl);
-    } else if (Type->isFunctionPointerType()) {
-      auto FuncType = StripTypedef(Type->getPointeeType());
-      if (callbacks.count(FuncType)) {
-        std::string FieldStr = callbacks[FuncType];
-        FieldStr += " ";
-        FieldStr += Name;
-        GuestRecord += FieldStr;
-        HostRecord += FieldStr;
-      } else {
-        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 " + Name;
-          GuestRecord += FieldStr;
-          HostRecord += "host_" + FieldStr;
-        } else {
-          GuestRecord += "void *" + Name;
-          HostRecord += "void *" + Name;
-        }
-      } else {
-        GuestRecord += "void *" + Name;
-        HostRecord += "void *" + Name;
-      }
-    } else if (Type->isRecordType()) {
-      if (records.count(Type.getTypePtr())) {
-        std::string FieldStr = records[Type.getTypePtr()].type_name;
-        FieldStr += " " + Name;
-        GuestRecord += FieldStr;
-        HostRecord += "host_" + FieldStr;
-      } else {
-        GuestRecord += TypeStringify(StripTypedef(Type), Field, nullptr, PreDecl);
-        HostRecord += TypeStringify(StripTypedef(Type), Field, nullptr, PreDecl);
-      }
-    } else {
-      HostRecord += TypeStringify(StripTypedef(Type), Field, nullptr, PreDecl);
-      GuestRecord += TypeStringify(StripTypedef(Type), Field, nullptr, PreDecl);
-    }
-    GuestRecord += ";\n";
-    HostRecord += ";\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;
-  if (Record.guest_size != Record.host_size) {
-    auto RecordDecl = Record.decl;
-    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<FieldDecl *> AlignDiffFields;
-    uint64_t SizeDiff = Record.guest_size - Record.host_size;
-    for (const auto &Field : RecordDecl->fields()) {
-      if (OffDiff[FieldIndex] == 0) {
-        FieldIndex++;
-        continue;
-      }
-      if (OffDiff[FieldIndex] != SizeDiff) {
-        auto Diff = OffDiff[FieldIndex];
-        AlignDiffFields.push_back(Field);
-        for (size_t i = FieldIndex; i < OffDiff.size(); i++) {
-          if (OffDiff[i] == Diff) {
-            OffDiff[i] = 0;
-          } else {
-            break;
-          }
-        }
-      } else {
-        AlignDiffFields.push_back(Field);
-        break;
-      }
-      FieldIndex++;
-    }
-    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 +
-                       ", " + AlignDiffFields[0]->getNameAsString() + "));\n";
-    std::string offstr = "offsetof(struct " + Record.type_name + ", " +
-                         AlignDiffFields[0]->getNameAsString() + ")";
-    for (size_t i = 0; 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 +
-              ");\n";
-      offstr = "offsetof(struct " + Record.type_name + ", " +
-               AlignDiffFields[i + 1]->getNameAsString() + ")";
-    }
-    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 + "}\n";
-
-    res += "void h2g_" + Record.type_name + "(struct " + Record.type_name + " *d, " + "struct host_" + Record.type_name + " *s) {\n";
-    res += body;
-    res += "}\n";
-  }
-  return res;
-}
-
-void WrapperGenerator::ParseRecordRecursive(
-    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];
-      Record->callback_fields.push_back(field->getType().getTypePtr());
-      // Record->type_name =
-      Special = true;
-    } else if (FieldType->isPointerType() &&
-               FieldType->getPointeeType()->isRecordType()) {
-      auto FieldRecordType = StripTypedef(FieldType->getPointeeType());
-      if (Visited.find(FieldRecordType) != Visited.end())
-        continue;
-      Visited.insert(FieldRecordType);
-      bool _Special = false;
-      ParseRecordRecursive(Ctx, FieldRecordType, _Special, Visited);
-      if (_Special)
-        Special = true;
-    } else if (FieldType->isRecordType()) {
-      auto FieldRecordType = StripTypedef(FieldType);
-      if (Visited.find(FieldRecordType) != Visited.end())
-        continue;
-      Visited.insert(FieldRecordType);
-      bool _Special = false;
-      ParseRecordRecursive(Ctx, FieldRecordType, _Special, Visited);
-      if (_Special)
-        Special = true;
-    }
-  }
-  uint64_t GuestSize = GetRecordSize(type, guest_triple);
-  uint64_t HostSize = GetRecordSize(type, host_triple);
-
-  auto Record = &records[type];
-  if (GuestSize != HostSize) {
-    Special = 1;
-  }
-  if (type->isUnionType()) {
-    Record->is_union = true;
-  }
-  if (!Record->decl) {
-    Record->type = type;
-    Record->decl = RecordDecl;
-    if (RecordDecl->getIdentifier())
-      Record->type_name = RecordDecl->getIdentifier()->getName().str();
-  }
-  Record->guest_size = GuestSize;
-  Record->host_size = HostSize;
-  if (Record->type_name.empty()) {
-    Record->is_special = false;
-  } else
-    Record->is_special = Special;
-}
-
-// Type to String
-std::string WrapperGenerator::TypeStringify(const Type *Type,
-                                         FieldDecl *FieldDecl,
-                                         ParmVarDecl *ParmDecl,
-                                         std::string& PreDecl,
-                                         std::string indent,
-                                         std::string Name) {
-  std::string res;
-  std::string name = FieldDecl
-                         ? FieldDecl->getNameAsString()
-                         : (ParmDecl ? ParmDecl->getNameAsString() : Name);
-  if (Type->isPointerType()) {
-    auto PointeeType = Type->getPointeeType();
-    if (PointeeType->isBuiltinType()) {
-      res +=
-          StripTypedef(PointeeType)->getCanonicalTypeInternal().getAsString();
-    } else if (PointeeType->isRecordType()) {
-      if (records.find(StripTypedef(PointeeType)) != records.end() &&
-          records[StripTypedef(PointeeType)].is_special) {
-        res += (PointeeType->isUnionType() ? "union " : "struct ") + records[StripTypedef(PointeeType)].type_name;
-      } else {
-        res += "void";
-      }
-    } else {
-      res += "void";
-    }
-    res += " *" + name;
-  } else if (Type->isEnumeralType()) {
-    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 " : "struct ";
-      res += records[StripTypedef(Type->getCanonicalTypeInternal())].type_name;
-      res += " ";
-    } else {
-      res += AnonRecordDecl(Type->getAs<RecordType>(), PreDecl, indent + "  ");
-    }
-    res += name;
-  } else if (Type->isConstantArrayType()) {
-    auto ArrayType =
-        dyn_cast<ConstantArrayType>(Type->getAsArrayTypeUnsafe());
-    int EleSize = ArrayType->getSize().getZExtValue();
-    if (ArrayType->getElementType()->isPointerType()) {
-      res += "void *";
-    } else if (ArrayType->getElementType()->isEnumeralType()) {
-      res += "int ";
-    } else if (ArrayType->getElementType()->isRecordType()) {
-      auto RecordType = ArrayType->getElementType()->getAs<clang::RecordType>();
-      auto RecordDecl = RecordType->getDecl();
-      if (RecordDecl->isCompleteDefinition()) {
-        auto& Ctx = RecordDecl->getDeclContext()->getParentASTContext();
-        PreDecl += "#include \"";
-        PreDecl += GetDeclHeaderFile(Ctx, RecordDecl);
-        PreDecl += "\"";
-        PreDecl += "\n";
-      }
-      res += StripTypedef(ArrayType->getElementType())
-                ->getCanonicalTypeInternal()
-                .getAsString();
-    } else {
-      res += StripTypedef(ArrayType->getElementType())
-                 ->getCanonicalTypeInternal()
-                 .getAsString();
-    }
-    res += " ";
-    res += name;
-    res += "[";
-    res += std::to_string(EleSize);
-    res += "]";
-  } else {
-    res += StripTypedef(Type->getCanonicalTypeInternal())
-               ->getCanonicalTypeInternal()
-               .getAsString();
-    res += " ";
-    res += name;
-  }
-  return indent + res;
-}
-
-// Type to String, less detail
-std::string WrapperGenerator::SimpleTypeStringify(const Type *Type,
-                                               FieldDecl *FieldDecl,
-                                               ParmVarDecl *ParmDecl,
-                                               std::string indent,
-                                               std::string Name) {
-  std::string res;
-  std::string name = FieldDecl
-                         ? FieldDecl->getNameAsString()
-                         : (ParmDecl ? ParmDecl->getNameAsString() : Name);
-  if (Type->isPointerType()) {
-    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 " : "struct ";
-      res += records[StripTypedef(Type->getCanonicalTypeInternal())].type_name;
-      res += " ";
-    } else {
-      res += SimpleAnonRecordDecl(Type->getAs<RecordType>(), indent);
-    }
-    res += name;
-  } else if (Type->isConstantArrayType()) {
-    auto ArrayType =
-        dyn_cast<ConstantArrayType>(Type->getAsArrayTypeUnsafe());
-    int EleSize = ArrayType->getSize().getZExtValue();
-    if (ArrayType->getElementType()->isPointerType()) {
-      res += "void *";
-    } else {
-      res += StripTypedef(ArrayType->getElementType())
-                 ->getCanonicalTypeInternal()
-                 .getAsString();
-    }
-    res += " ";
-    res += name;
-    res += "[";
-    res += std::to_string(EleSize);
-    res += "]";
-  } else {
-    res += StripTypedef(Type->getCanonicalTypeInternal())
-               ->getCanonicalTypeInternal()
-               .getAsString();
-    res += " ";
-    res += name;
-  }
-  return indent + res;
-}
-
-std::string WrapperGenerator::AnonRecordDecl(const RecordType *Type, std::string& PreDecl, std::string indent) {
-  auto RecordDecl = Type->getDecl();
-  std::string res;
-  res += Type->isUnionType() ? "union {\n" : "struct {\n";
-  for (const auto &field : RecordDecl->fields()) {
-    auto FieldType = field->getType();
-    res += TypeStringify(StripTypedef(FieldType), field, nullptr, PreDecl, indent + "  ");
-    res += ";\n";
-  }
-  res += indent + "} ";
-  return res;
-}
-
-std::string
-WrapperGenerator::SimpleAnonRecordDecl(const RecordType *Type, std::string indent) {
-  auto RecordDecl = Type->getDecl();
-  std::string res;
-  res += Type->isUnionType() ? "union {\n" : "struct {\n";
-  for (const auto &field : RecordDecl->fields()) {
-    auto FieldType = field->getType();
-    res += SimpleTypeStringify(StripTypedef(FieldType), field, nullptr, indent + "  ");
-    res += ";\n";
-  }
-  res += indent + "} ";
-  return res;
-}
-
-// Get func info from FunctionType
-FuncDefinition WrapperGenerator::GetFuncDefinition(const Type *Type) {
-  FuncDefinition res;
-  std::string PreDecl;
-  auto ProtoType = Type->getAs<FunctionProtoType>();
-  res.ret = StripTypedef(ProtoType->getReturnType());
-  res.ret_str =
-      TypeStringify(StripTypedef(ProtoType->getReturnType()), nullptr, nullptr, PreDecl);
-  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(
-        TypeStringify(StripTypedef(ParamType), nullptr, nullptr, PreDecl));
-    res.arg_names.push_back(std::string("a") + std::to_string(i));
-  }
-  if (ProtoType->isVariadic()) {
-    res.is_variadaic = true;
-  }
-  res.arg_size = ProtoType->getNumParams();
-  return res;
-}
-
-// Get funcdecl info from FunctionDecl
-FuncDefinition WrapperGenerator::GetFuncDefinition(FunctionDecl *Decl) {
-  FuncDefinition res;
-  std::string PreDecl;
-  auto RetType = Decl->getReturnType();
-  res.ret = RetType.getTypePtr();
-  res.ret_str = TypeStringify(StripTypedef(RetType), nullptr, nullptr, PreDecl);
-  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(
-        TypeStringify(StripTypedef(ParamType), nullptr, nullptr, PreDecl));
-    res.arg_names.push_back(ParamDecl->getNameAsString());
-  }
-  if (Decl->isVariadic()) {
-    res.is_variadaic = true;
-  }
-  return res;
-}
-
-// Get the offset diff between two different triple
-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 PreDecl;
-  std::string Code = TypeStringify(Type, nullptr, nullptr, PreDecl, "", "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
-uint64_t WrapperGenerator::GetRecordSize(const Type *Type,
-                                    const std::string &Triple) {
-  std::string PreDecl;
-  std::string Code = TypeStringify(Type, nullptr, nullptr, PreDecl, "", "dummy;");
-  auto Size = ::GetRecordSize(PreDecl + Code, Triple);
-  return Size;
-}
-
-// Get the align under a specific triple
-CharUnits::QuantityType WrapperGenerator::GetRecordAlign(const Type *Type,
-                                     const std::string &Triple) {
-  std::string PreDecl{};
-  std::string Code = TypeStringify(Type, nullptr, nullptr, PreDecl, "", "dummy;");
-  return ::GetRecordAlign(PreDecl + Code, Triple);
-}
-
-// Generate the func sig by type, used for export func
-std::string WrapperGenerator::GetFuncSig(ASTContext *CTX,
-                                         const FuncInfo &Func) {
-  std::string sig;
-  auto Decl = Func.decl;
-  auto Type = Decl->getType().getTypePtr();
-  auto ProtoType = Type->getAs<FunctionProtoType>();
-  auto RetType = ProtoType->getReturnType();
-
-  sig += TypeToSig(CTX, RetType.getTypePtr());
-  sig += "F";
-  if (Func.has_special_arg || Func.has_special_ret || Func.has_callback_arg) {
-    sig += "E";
-  }
-  if (ProtoType->getNumParams()) {
-    for (unsigned i = 0; i < ProtoType->getNumParams(); i++) {
-      sig += TypeToSig(CTX, ProtoType->getParamType(i).getTypePtr());
-    }
-  } else {
-    sig += "v";
-  }
-  if (Decl->isVariadic()) {
-    sig += "VV";
-  }
-  return sig;
-}
-
-// Generate the func sig by type, used for callbacks
-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 (unsigned i = 0; i < ProtoType->getNumParams(); i++) {
-      sig += TypeToSig(CTX, ProtoType->getParamType(i).getTypePtr());
-    }
-  } else {
-    sig += "v";
-  }
-  return sig;
-}