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