1*5971e316Smrg /*
2*5971e316Smrg * Copyright 2018 Sven Verdoolaege
3*5971e316Smrg *
4*5971e316Smrg * Use of this software is governed by the MIT license
5*5971e316Smrg *
6*5971e316Smrg * Written by Sven Verdoolaege.
7*5971e316Smrg */
8*5971e316Smrg
9*5971e316Smrg #include <stdio.h>
10*5971e316Smrg #include <map>
11*5971e316Smrg #include <string>
12*5971e316Smrg
13*5971e316Smrg #include "cpp.h"
14*5971e316Smrg #include "cpp_conversion.h"
15*5971e316Smrg
16*5971e316Smrg /* If "clazz" describes a subclass of a C type, then print code
17*5971e316Smrg * for converting an object of the class derived from the C type
18*5971e316Smrg * to the subclass. Do this by first converting this class
19*5971e316Smrg * to the immediate superclass of the subclass and then converting
20*5971e316Smrg * from this superclass to the subclass.
21*5971e316Smrg */
cast(const isl_class & clazz,const char * to)22*5971e316Smrg void cpp_conversion_generator::cast(const isl_class &clazz, const char *to)
23*5971e316Smrg {
24*5971e316Smrg string name = cpp_generator::type2cpp(clazz);
25*5971e316Smrg
26*5971e316Smrg if (!clazz.is_type_subclass())
27*5971e316Smrg return;
28*5971e316Smrg
29*5971e316Smrg cast(classes[clazz.superclass_name], to);
30*5971e316Smrg printf(".as<%s%s>()", to, name.c_str());
31*5971e316Smrg }
32*5971e316Smrg
33*5971e316Smrg /* Print a function called "function" for converting objects of
34*5971e316Smrg * "clazz" from the "from" bindings to the "to" bindings.
35*5971e316Smrg * If "clazz" describes a subclass of a C type, then the result
36*5971e316Smrg * of the conversion between bindings is derived from the C type and
37*5971e316Smrg * needs to be converted back to the subclass.
38*5971e316Smrg */
convert(const isl_class & clazz,const char * from,const char * to,const char * function)39*5971e316Smrg void cpp_conversion_generator::convert(const isl_class &clazz,
40*5971e316Smrg const char *from, const char *to, const char *function)
41*5971e316Smrg {
42*5971e316Smrg string name = cpp_generator::type2cpp(clazz);
43*5971e316Smrg
44*5971e316Smrg printf("%s%s %s(%s%s obj) {\n",
45*5971e316Smrg to, name.c_str(), function, from, name.c_str());
46*5971e316Smrg printf("\t""return %s""manage(obj.copy())", to);
47*5971e316Smrg cast(clazz, to);
48*5971e316Smrg printf(";\n");
49*5971e316Smrg printf("}\n");
50*5971e316Smrg printf("\n");
51*5971e316Smrg }
52*5971e316Smrg
53*5971e316Smrg /* Print functions for converting objects of "clazz"
54*5971e316Smrg * between the default and the checked C++ bindings.
55*5971e316Smrg *
56*5971e316Smrg * The conversion from default to checked is called "check".
57*5971e316Smrg * The inverse conversion is called "uncheck".
58*5971e316Smrg * For example, to "set", the following two functions are generated:
59*5971e316Smrg *
60*5971e316Smrg * checked::set check(set obj) {
61*5971e316Smrg * return checked::manage(obj.copy());
62*5971e316Smrg * }
63*5971e316Smrg *
64*5971e316Smrg * set uncheck(checked::set obj) {
65*5971e316Smrg * return manage(obj.copy());
66*5971e316Smrg * }
67*5971e316Smrg */
print(const isl_class & clazz)68*5971e316Smrg void cpp_conversion_generator::print(const isl_class &clazz)
69*5971e316Smrg {
70*5971e316Smrg convert(clazz, "", "checked::", "check");
71*5971e316Smrg convert(clazz, "checked::", "", "uncheck");
72*5971e316Smrg }
73*5971e316Smrg
74*5971e316Smrg /* Generate conversion functions for converting objects between
75*5971e316Smrg * the default and the checked C++ bindings.
76*5971e316Smrg * Do this for each exported class.
77*5971e316Smrg */
generate()78*5971e316Smrg void cpp_conversion_generator::generate()
79*5971e316Smrg {
80*5971e316Smrg map<string, isl_class>::iterator ci;
81*5971e316Smrg
82*5971e316Smrg printf("namespace isl {\n\n");
83*5971e316Smrg for (ci = classes.begin(); ci != classes.end(); ++ci)
84*5971e316Smrg print(ci->second);
85*5971e316Smrg printf("} // namespace isl\n");
86*5971e316Smrg }
87