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