1 | #ifndef ISL_INTERFACE_GENERATOR_H |
2 | #define ISL_INTERFACE_GENERATOR_H |
3 | |
4 | #include <map> |
5 | #include <set> |
6 | #include <string> |
7 | #include <vector> |
8 | |
9 | #include <clang/AST/Decl.h> |
10 | |
11 | using namespace std; |
12 | using namespace clang; |
13 | |
14 | /* Compare the prefix of "s" to "prefix" up to the length of "prefix". |
15 | */ |
16 | inline int prefixcmp(const char *s, const char *prefix) |
17 | { |
18 | return strncmp(s, prefix, strlen(prefix)); |
19 | } |
20 | |
21 | /* Information about a single enum value of an enum set by a function. |
22 | * "value" is the enum value. |
23 | * "name" is the corresponding name. |
24 | * "method_name" is the the name of the method that sets this value. |
25 | */ |
26 | struct set_enum { |
27 | int value; |
28 | string name; |
29 | string method_name; |
30 | set_enum(int value, string name, string method_name) : |
31 | value(value), name(name), method_name(method_name) {} |
32 | }; |
33 | |
34 | /* Helper structure for sorting FunctionDecl pointers |
35 | * on the corresponding function names. |
36 | */ |
37 | struct function_name_less { |
38 | bool operator()(FunctionDecl *x, FunctionDecl *y) const { |
39 | return x->getName() < y->getName(); |
40 | } |
41 | }; |
42 | |
43 | /* Set of FunctionDecl pointers sorted on function name. |
44 | */ |
45 | typedef std::set<FunctionDecl *, function_name_less> function_set; |
46 | |
47 | /* isl_class collects all constructors and methods for an isl "class". |
48 | * "name" is the name of the class. |
49 | * If this object describes a subclass of a C type, then |
50 | * "subclass_name" is the name of that subclass and "superclass_name" |
51 | * is the name of the immediate superclass of that subclass. Otherwise, |
52 | * "subclass_name" is equal to "name" and "superclass_name" is undefined. |
53 | * "type" is the declaration that introduces the type. |
54 | * "persistent_callbacks" contains the set of functions that |
55 | * set a persistent callback. |
56 | * "set_enums" maps the set of functions that set an enum value |
57 | * to information associated to each value. |
58 | * A function is considered to set an enum value if it returns |
59 | * an object of the same type and if its last argument is of an enum type. |
60 | * "methods" contains the set of methods, grouped by method name. |
61 | * "fn_to_str" is a reference to the *_to_str method of this class, if any. |
62 | * "fn_copy" is a reference to the *_copy method of this class, if any. |
63 | * "fn_free" is a reference to the *_free method of this class, if any. |
64 | * "fn_type" is a reference to a function that described subclasses, if any. |
65 | * If "fn_type" is set, then "type_subclasses" maps the values returned |
66 | * by that function to the names of the corresponding subclasses. |
67 | * |
68 | * The following fields are only used for the C++ bindings. |
69 | * For methods that are not derived from a function that applies |
70 | * directly to this class, but are rather copied from some ancestor, |
71 | * "copied_from" records the direct superclass from which the method |
72 | * was copied (where it may have been copied from a further ancestor) and |
73 | * "copy_depth" records the distance to the ancestor to which |
74 | * the function applies. |
75 | * "construction_types" contains the set of isl classes that can be |
76 | * implicitly converted to this class through a unary constructor, |
77 | * mapped to the single argument |
78 | * of this unary constructor. |
79 | */ |
80 | struct isl_class { |
81 | string name; |
82 | string superclass_name; |
83 | string subclass_name; |
84 | RecordDecl *type; |
85 | function_set constructors; |
86 | set<FunctionDecl *> persistent_callbacks; |
87 | map<FunctionDecl *, vector<set_enum> > set_enums; |
88 | map<string, function_set> methods; |
89 | map<int, string> type_subclasses; |
90 | FunctionDecl *fn_type; |
91 | FunctionDecl *fn_to_str; |
92 | FunctionDecl *fn_copy; |
93 | FunctionDecl *fn_free; |
94 | |
95 | std::map<clang::FunctionDecl *, const isl_class &> copied_from; |
96 | std::map<clang::FunctionDecl *, int> copy_depth; |
97 | std::map<std::string, clang::ParmVarDecl *> construction_types; |
98 | |
99 | /* Is the first argument an instance of the class? */ |
100 | bool first_arg_matches_class(FunctionDecl *method) const; |
101 | /* Does "method" correspond to a static method? */ |
102 | bool is_static(FunctionDecl *method) const; |
103 | /* Is this class a subclass based on a type function? */ |
104 | bool is_type_subclass() const { return name != subclass_name; } |
105 | /* Return name of "fd" without type suffixes, if any. */ |
106 | static string name_without_type_suffixes(FunctionDecl *fd); |
107 | /* Extract the method name corresponding to "fd" |
108 | * (including "get" method prefix if any). |
109 | */ |
110 | string base_method_name(FunctionDecl *fd) const { |
111 | string m_name = name_without_type_suffixes(fd); |
112 | return m_name.substr(pos: subclass_name.length() + 1); |
113 | } |
114 | /* The prefix of a "get" method. */ |
115 | static const char *get_prefix; |
116 | /* Is function "fd" with the given name a "get" method? */ |
117 | bool is_get_method_name(FunctionDecl *fd, const string &name) const; |
118 | /* Is function "fd" a "get" method? */ |
119 | bool is_get_method(FunctionDecl *fd) const { |
120 | return is_get_method_name(fd, base_method_name(fd)); |
121 | } |
122 | /* Extract the method name corresponding to "fd". */ |
123 | string method_name(FunctionDecl *fd) const; |
124 | /* The prefix of any method that may set a (persistent) callback. */ |
125 | static const char *set_callback_prefix; |
126 | /* Given a function that sets a persistent callback, |
127 | * return the name of the callback. |
128 | */ |
129 | string persistent_callback_name(FunctionDecl *fd) const { |
130 | return method_name(fd).substr(strlen(set_callback_prefix)); |
131 | } |
132 | /* Does this class have any functions that set a persistent callback? |
133 | */ |
134 | bool has_persistent_callbacks() const { |
135 | return persistent_callbacks.size() != 0; |
136 | } |
137 | }; |
138 | |
139 | /* Base class for interface generators. |
140 | * |
141 | * "conversions" maps the target type of automatic conversion |
142 | * to the second input argument of the conversion function. |
143 | */ |
144 | class generator { |
145 | protected: |
146 | SourceManager &SM; |
147 | map<string,isl_class> classes; |
148 | map<string, FunctionDecl *> functions_by_name; |
149 | |
150 | public: |
151 | generator(SourceManager &SM, set<RecordDecl *> &exported_types, |
152 | set<FunctionDecl *> exported_functions, |
153 | set<FunctionDecl *> functions); |
154 | |
155 | virtual void generate() = 0; |
156 | virtual ~generator() {}; |
157 | |
158 | protected: |
159 | void add_subclass(RecordDecl *decl, const string &name, |
160 | const string &sub_name); |
161 | void add_class(RecordDecl *decl); |
162 | void add_type_subclasses(FunctionDecl *method); |
163 | isl_class *method2class(FunctionDecl *fd); |
164 | bool callback_takes_argument(ParmVarDecl *param, int pos); |
165 | FunctionDecl *find_by_name(const string &name, bool required); |
166 | std::map<const Type *, ParmVarDecl *> conversions; |
167 | private: |
168 | static const std::set<std::string> automatic_conversion_functions; |
169 | void (FunctionDecl *fd); |
170 | void (const isl_class &clazz); |
171 | void (); |
172 | public: |
173 | static std::string drop_suffix(const std::string &s, |
174 | const std::string &suffix); |
175 | static void die(const char *msg) __attribute__((noreturn)); |
176 | static void die(string msg) __attribute__((noreturn)); |
177 | static vector<string> find_superclasses(Decl *decl); |
178 | static bool is_subclass(FunctionDecl *decl); |
179 | static bool is_overload(Decl *decl); |
180 | static bool is_constructor(Decl *decl); |
181 | static bool takes(Decl *decl); |
182 | static bool keeps(Decl *decl); |
183 | static bool gives(Decl *decl); |
184 | static bool is_isl_ctx(QualType type); |
185 | static bool first_arg_is_isl_ctx(FunctionDecl *fd); |
186 | static bool is_isl_type(QualType type); |
187 | static bool is_isl_neg_error(QualType type); |
188 | static bool is_isl_bool(QualType type); |
189 | static bool is_isl_stat(QualType type); |
190 | static bool is_isl_size(QualType type); |
191 | static bool is_long(QualType type); |
192 | static bool is_callback(QualType type); |
193 | static bool is_callback_arg(FunctionDecl *fd, int i); |
194 | static bool is_string(QualType type); |
195 | static bool is_static(const isl_class &clazz, FunctionDecl *method); |
196 | static bool is_mutator(const isl_class &clazz, FunctionDecl *fd); |
197 | static string (QualType type); |
198 | static const FunctionProtoType *(QualType type); |
199 | static int prototype_n_args(QualType type); |
200 | static ParmVarDecl *persistent_callback_arg(FunctionDecl *fd); |
201 | }; |
202 | |
203 | #endif /* ISL_INTERFACE_GENERATOR_H */ |
204 | |