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 11using namespace std; 12using namespace clang; 13 14/* Compare the prefix of "s" to "prefix" up to the length of "prefix". 15 */ 16inline 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 */ 26struct 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 */ 37struct 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 */ 45typedef 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 */ 80struct 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(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 */ 144class generator { 145protected: 146 SourceManager &SM; 147 map<string,isl_class> classes; 148 map<string, FunctionDecl *> functions_by_name; 149 150public: 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 158protected: 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; 167private: 168 static const std::set<std::string> automatic_conversion_functions; 169 void extract_automatic_conversion(FunctionDecl *fd); 170 void extract_class_automatic_conversions(const isl_class &clazz); 171 void extract_automatic_conversions(); 172public: 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 extract_type(QualType type); 198 static const FunctionProtoType *extract_prototype(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