]> git.buserror.net Git - polintos/scott/priv.git/blob - idlcomp/languages/c++/c++.h
Some weak symbol usage, and some marshalling stuff.
[polintos/scott/priv.git] / idlcomp / languages / c++ / c++.h
1 #ifndef IDLC_CPP_H
2 #define IDLC_CPP_H
3
4 #include <fstream>
5 #include <list>
6
7 #include <lang.h>
8 #include <util.h>
9
10 using std::ofstream;
11 using std::ostream;
12
13 // Output the namespace-qualified symbol name, including
14 // user namespaces.   A prefix for the final component (i.e. the
15 // actual name) can optionally be specified.
16
17 void cpp_output_name(ostream &file, Symbol *sym, const char *prefix = "");
18
19 // Output the C++ type, not including the array, including
20 // a trailing space.
21
22 void cpp_output_type(ostream &file, Type *t, bool array, bool is_mutable);
23 void cpp_output_type(ostream &file, CompiledBasicType &t, bool is_mutable);
24
25 // Output the param's fully-qualified type, a space, and the name
26 // of the param.
27
28 void cpp_output_one_param(ostream &file, Param *p, bool is_server,
29                           bool is_copy = false);
30         
31 // Each IDL namespace is mapped to a C++ header file,
32 // represented by a CPPFile.
33
34 class CPPFile : public LangCallback {
35         Indent indent;
36         string dirname;
37         ofstream file;
38         UserNameSpace *ns;
39         StrList *fqname;
40
41         //// Interface caller-side members:
42         
43         // Outputs the body of the internal _i_<ifacename> struct,
44         // containing a vtable pointer (and definition).
45
46         void output_internal(Interface *sym);
47         
48         // Outputs the user-visible class wrapper that is used to
49         // allow implicit upcasts.
50         
51         void output_wrapper(Interface *sym);
52
53         // Output implementations of the cast methods prototyped in the wrapper.
54         // The implementation is delayed to avoid circular dependency problems.
55
56         void output_casts(Interface *sym);
57         
58         //// Marshalling methods
59         
60         void output_marshall(Struct *sym, int pass);
61
62         // Output the downcast and implicit upcast methods for
63         // the given interface/superinterface pair.
64
65         static void wrapper_cast_callback(Interface *iface, void *arg);
66         void output_downcast(Interface *iface, Interface *super);
67         void output_upcast(Interface *iface, Interface *super);
68
69         static void wrapper_cast_proto_callback(Interface *iface, void *arg);
70         void output_downcast_proto(Interface *iface, Interface *super);
71         void output_upcast_proto(Interface *iface, Interface *super);
72
73         static void wrapper_method_proto_callback(Interface *iface, void *arg);
74         static void wrapper_method_callback(Interface *iface, void *arg);
75
76         void output_iface_tbl(Interface *iface);
77         static void tbl_callback(Interface *iface, void *arg);
78         void output_iface_tbl_entry(Interface *iface, Interface *super);
79
80         static void output_method_ptrs_callback(Interface *iface, void *arg);
81         void output_method_ptrs(Interface *iface);
82         void output_methods(Interface *iface, Interface *super, bool prototype);
83         void output_method_defs(Interface *iface);
84
85         void output_one_method(Interface *iface, Method *m,
86                                bool prototype, bool retval);
87         void output_one_method_ptr(Method *m, Interface *iface);
88         
89         //// Misc members:
90
91         // Output the static const guid[] value, and the IFaceInfo struct.
92
93         void output_guid(const uint64_t *guid);
94         void output_ifaceinfo(Interface *iface);
95
96         // Output a datum in the given struct, along with any necessary
97         // padding.  Return the offset of the next datum.
98         
99         int output_datum(Struct *ns, Datum *d, int offset);
100
101         void output_vstruct_info(Struct *sym);
102         void output_vstruct_main(Struct *sym);
103         void output_struct_ctor(Struct *sym, bool extra_vstruct);
104         int output_struct_ctor_rec1(Struct *sym, int num);
105         int output_struct_ctor_rec2(Struct *sym, int num);
106
107         void output_bf_elem(Datum *d, int pos, int bits, string &prefix);
108         void output_bf(BitField *bf, int bits, int typebits, string &prefix);
109                 
110         // Call ns_in on the symbol in order to declare the containing
111         // namespace.  Call ns_out when finished.  ns_out also takes care
112         // of inserting the extra newline separating declarations.  The
113         // "extra" parameter allows extra output passes to have unique
114         // #ifndef names, and should have a trailing underscore.
115         
116         void ns_in(Symbol *sym, const char *extra = "DEF_");
117         void ns_out(Symbol *sym);
118
119         // As above, but also outputs non-user namespaces (optionally
120         // including "sym" itself).
121
122         void all_ns_in(Symbol *sym, bool include_self = false,
123                        const char *extra = "DEF_");
124         void all_ns_out(Symbol *sym, bool include_self = false);
125
126         // Output a protective #ifndef/#define block to keep a type
127         // from being declared more than once.  Call ifndef_out()
128         // for the #endif.
129         
130         void ifndef_in(Symbol *sym, const char *extra = "DEF_");
131         void ifndef_out();
132         
133         // Return the namespace-qualified symbol name, excluding
134         // user namespaces.  This is used when defining a name
135         // which (if it is nested) has been previously forward
136         // declared.  A prefix for the final component (i.e. the
137         // actual name) can optionally be specified.
138         
139         String &get_definition_name(Symbol *sym, const char *prefix = "");
140         
141         // Output the _ns declaration of a struct or interface.
142         // If a callback is supplied, it is called inside the
143         // namespace, before any namespace members have been
144         // emitted.
145         
146         void output_nsdecl_begin(NameSpace *ns);
147         void output_nsdecl_children(NameSpace *ns);
148         void output_nsdecl_end(NameSpace *ns);
149         void output_nsdecl(NameSpace *ns);
150
151         void output_aliases_and_types(NameSpace *ns);
152         
153         // When a top-level struct or interface is about to be generated,
154         // it is scanned for other types which need to be generated.  If the
155         // full definition is needed, it goes on the need_to_declare list;
156         // otherwise, it goes on the need_to_forward_declare list.  When
157         // processing the lists, if a node has already been marked as
158         // traversed, it is skipped.
159         
160         // Full declaration is needed for superstructs, superinterfaces,
161         // inline structs (once implemented) used, and typedefs used.
162         // It is also necessary to fully declare any type which contains
163         // a type whose forward declaration is needed, as such types
164         // cannot (as far as I know) be forward-declared.
165         
166         std::list<Symbol *> need_to_declare;
167         
168         // Forward declaration is needed for types used via a pointer only.
169         
170         std::list<Symbol *> need_to_forward_declare;
171         
172         void declare_dependencies(Struct *sym);
173         void declare_dependencies(Interface *iface, bool need_obj_def = false);
174         void declare_type_dependency(Type *t, bool need_obj_def = false);
175
176         // This is the traversal of the first namespace; any symbol
177         // whose last traversal is at least this has been written to
178         // at least one of the included namespaces (and/or the
179         // current namespace).
180
181         int first_traversal;
182
183         // The traversal indices are also passed as "arg1" to determine
184         // which pass to generate.  Higher numbers are performed first.
185         
186         enum {
187                 trav_full = 0,     // Full, final output
188                 trav_obj_def = 1,  // Object struct definition
189                 trav_obj_stub = 2, // Object pointer stub,
190                               // so it can be used in structs.
191                 trav_nsdecl = 3,   // _ns declaration
192                 trav_forward = 4,  // Forward declaration of
193                               // structs/interfaces in nsdecl
194         };
195
196         bool pass_needed(Symbol *sym, int pass)
197         {
198                 return first_traversal > sym->traversed[pass];
199         }
200
201         void output_pass(Symbol *sym, int pass)
202         {
203                 if (pass_needed(sym, pass)) {
204                         sym->traversed[pass] = traversal;
205                         sym->output_lang(this, pass);
206                 }
207         }
208
209         bool do_extra_newline;
210
211         void downscope()
212         {
213                 indent.indent_level++;
214                 do_extra_newline = false;
215         }
216         
217         void upscope()
218         {
219                 indent.indent_level--;
220                 do_extra_newline = true;
221         }
222         
223         void extra_newline()
224         {
225                 if (do_extra_newline)
226                         file << "\n";
227                 
228                 do_extra_newline = true;
229         }
230
231 public:
232         CPPFile(UserNameSpace *ns, const char *dir);
233         virtual ~CPPFile();
234
235         void output(UserNameSpace *sym, int pass = trav_full, void *arg2 = NULL);
236         void output(Struct *sym, int pass = trav_full, void *arg2 = NULL);
237         void output(Interface *sym, int pass = trav_full, void *arg2 = NULL);
238         void output(BitField *sym, int pass = trav_full, void *arg2 = NULL);
239         void output(Enum *sym, int pass = trav_full, void *arg2 = NULL);
240         void output(BasicType *sym, int pass = trav_full, void *arg2 = NULL);
241         void output(Alias *sym, int pass = trav_full, void *arg2 = NULL);
242         void output(TypeDef *sym, int pass = trav_full, void *arg2 = NULL);
243         void output(Datum *sym, int pass = trav_full, void *arg2 = NULL);
244 };
245
246 class CPPBinding : public Language {
247 public:
248         CPPBinding()
249         {
250                 name = "C++";
251                 next = first_lang;
252                 first_lang = this;
253         }
254
255         void output_root(UserNameSpace *ns, const char *dir);
256         void output_server(UserNameSpace *ns, const char *dir);
257 };
258
259 #endif