1 #ifndef ISL_INTERFACE_TEMPLATE_CPP_H
2 #define ISL_INTERFACE_TEMPLATE_CPP_H
3 
4 #include <initializer_list>
5 #include <iostream>
6 #include <map>
7 #include <memory>
8 #include <set>
9 #include <string>
10 #include <unordered_map>
11 
12 #include "cpp.h"
13 
14 struct Fixed;
15 
16 struct TupleKind;
17 
18 /* A shared pointer to a TupleKind.
19  */
20 struct TupleKindPtr : public std::shared_ptr<const TupleKind> {
21   using Base = std::shared_ptr<const TupleKind>;
22   TupleKindPtr() = default;
23   TupleKindPtr(Fixed);
TupleKindPtrTupleKindPtr24   TupleKindPtr(Base base) : Base(base) {}
25   TupleKindPtr(const std::string &name);
26   TupleKindPtr(const TupleKindPtr &left, const TupleKindPtr &right);
27 };
28 
29 /* A substitution mapping leaf tuple kind names to tuple kinds.
30  */
31 using Substitution = std::unordered_map<std::string, TupleKindPtr>;
32 
33 /* A representation of a (possibly improper) tuple kind.
34  * That is, this also includes tuple kinds for types
35  * that do not have any tuples.
36  *
37  * The kind could be a name (the base case) or
38  * a (currently) unnamed nested pair of tuple kinds.
39  */
40 struct TupleKind {
TupleKindTupleKind41 	TupleKind(const std::string &name) : name(name) {}
42 
43 	virtual std::string to_string() const;
44 	virtual std::vector<std::string> params() const;
45 	virtual TupleKindPtr apply(const Substitution &subs,
46 		const TupleKindPtr &self) const;
47 	virtual TupleKindPtr left() const;
48 	virtual TupleKindPtr right() const;
49 
50 	const std::string name;
51 };
52 
53 /* A sequence of tuple kinds, representing a kind of objects.
54  */
55 struct Kind : public std::vector<TupleKindPtr> {
KindKind56 	Kind() {}
KindKind57 	Kind(std::initializer_list<TupleKindPtr> list) : vector(list) {}
58 
59 	bool is_anon() const;
60 	bool is_set() const;
61 	bool is_anon_set() const;
62 	std::vector<std::string> params() const;
63 	Kind apply(const Substitution &subs) const;
64 };
65 
66 /* A representation of a template class.
67  *
68  * "class_name" is the name of the template class.
69  * "super_name" is the (fully qualified) name of the corresponding
70  * plain C++ interface class, from which this template class derives.
71  * "clazz" describes the plain class.
72  *
73  * "class_tuples" contains the specializations.
74  * It is initialized with a predefined set of specializations,
75  * but may be extended during the generations of the specializations.
76  */
77 struct template_class {
78 	const std::string class_name;
79 	const std::string super_name;
80 	const isl_class &clazz;
81 
82 	std::vector<Kind> class_tuples;
83 
84 	bool is_anon() const;
85 	bool is_anon_set() const;
86 	void add_specialization(const Kind &kind);
87 };
88 
89 /* A generator for templated C++ bindings.
90  *
91  * "template_classes" contains all generated template classes,
92  * keyed on their names.
93  */
94 class template_cpp_generator : public cpp_generator {
95 	struct class_printer;
96 	struct method_decl_printer;
97 	struct method_impl_printer;
98 	struct class_decl_printer;
99 	struct class_impl_printer;
100 
101 	void add_template_class(const isl_class &clazz, const std::string &name,
102 		const std::vector<Kind> &base_kinds);
103 public:
104 	template_cpp_generator(clang::SourceManager &SM,
105 		std::set<clang::RecordDecl *> &exported_types,
106 		std::set<clang::FunctionDecl *> exported_functions,
107 		std::set<clang::FunctionDecl *> functions);
108 
109 	virtual void generate() override;
110 	void foreach_template_class(
111 		const std::function<void(const template_class &)> &fn) const;
112 	void print_forward_declarations(std::ostream &os);
113 	void print_friends(std::ostream &os);
114 
115 	std::map<std::string, template_class> template_classes;
116 };
117 
118 #endif
119