1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
#pragma once
#include <clang/AST/ASTContext.h>
#include <clang/AST/Type.h>
#include <cstdint>
#include <string>
#include <vector>
#include <set>
struct FuncDefinition {
std::vector<const clang::Type*> arg_types;
std::vector<std::string> arg_types_str;
std::vector<std::string> arg_names;
const clang::Type* ret;
std::string ret_str;
int arg_size;
bool is_variadaic;
};
struct FuncInfo {
const clang::Type* type;
clang::FunctionDecl* decl;
std::string func_name;
bool is_weak;
bool is_variadaic;
bool has_special_arg;
bool has_special_ret;
bool has_callback_arg;
std::vector<const clang::Type*> callback_args;
};
struct RecordInfo {
const clang::Type* type;
clang::RecordDecl* decl;
std::string type_name;
bool is_union;
bool is_special;
uint64_t guest_size;
uint64_t host_size;
std::vector<const clang::Type*> callback_fields;
};
struct ObjectInfo {
const clang::Type* type;
std::string object_name;
};
struct WrapperGenerator {
void Init(const std::string& libname, const std::string& host_triple, const std::string& guest_triple) {
this->host_triple = host_triple;
this->guest_triple = guest_triple;
this->libname = libname;
this->my_lib_type = libname + "_my_t";
this->my_lib = "my_lib";
}
void Prepare(clang::ASTContext* Ctx);
std::string GenCallbackTypeDefs(clang::ASTContext* Ctx);
std::string GenFuncDeclare(clang::ASTContext* Ctx) {
std::string res{};
for (const auto& func : funcs) {
res += GenDeclare(Ctx, func.second);
}
return res;
}
std::string GenRecordDeclare(clang::ASTContext* Ctx) {
std::string res{};
for (const auto& st : records) {
if (st.second.host_size == st.second.guest_size)
res += GenDeclare(Ctx, st.second);
else {
res += GenDeclareDiffTriple(Ctx, st.second, guest_triple, host_triple);
}
}
return res;
}
std::string GenFuncDefine(clang::ASTContext* Ctx) {
std::string res{};
for (const auto& func : funcs) {
res += GenDefine(Ctx, func.second);
}
return res;
}
std::string GenCallbackWrap(clang::ASTContext* Ctx) {
std::string res{};
for (const auto& func : funcs) {
res += GenCallbackWrap(Ctx, func.second);
}
for (const auto& st : records) {
res += GenCallbackWrap(Ctx, st.second);
}
return res;
}
std::string GenRecordConvert(clang::ASTContext* Ctx) {
(void)Ctx;
std::string res;
for (const auto& record : records) {
if (record.second.host_size != record.second.guest_size) {
res += GenRecordConvert(record.second);
}
}
return res;
}
std::map<const clang::Type*, FuncInfo> funcs;
std::map<const clang::Type*, RecordInfo> records;
std::map<const clang::Type*, ObjectInfo> objects;
std::map<const clang::Type*, std::string> callbacks;
std::string host_triple;
std::string guest_triple;
std::string libname;
std::string my_lib_type;
std::string my_lib;
private:
std::string GenRecordConvert(const RecordInfo& Record);
std::string GenDeclare(clang::ASTContext* Ctx, const FuncInfo& Func);
std::string GenDefine(clang::ASTContext* Ctx, const FuncInfo& Func);
std::string GenCallbackWrap(clang::ASTContext* Ctx, const FuncInfo& Func);
std::string GenDeclareDiffTriple(clang::ASTContext* Ctx, const RecordInfo& Record, const std::string& GuestTriple, const std::string& HostTriple);
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* Type, bool& Special, std::set<const clang::Type*>& Visited);
std::string TypeStringify(const clang::Type* Type, clang::FieldDecl* FieldDecl, clang::ParmVarDecl* ParmDecl, std::string& PreDecl, 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& PreDecl, std::string indent);
std::string SimpleAnonRecordDecl(const clang::RecordType* Type, std::string indent);
FuncDefinition GetFuncDefinition(const clang::Type* Type);
FuncDefinition GetFuncDefinition(clang::FunctionDecl* Decl);
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);
};
|