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