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.
17 void cpp_output_name(ostream &file, Symbol *sym, const char *prefix = "");
19 // Output the C++ type, not including the array, including
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);
25 // Output the param's fully-qualified type, a space, and the name
28 void cpp_output_one_param(ostream &file, Param *p, bool is_server,
29 bool is_copy = false);
32 trav_full, // Full, final output
33 trav_obj_def, // Object struct definition
34 trav_obj_stub, // Object pointer stub,
35 // so it can be used in structs.
36 trav_nsdecl, // _ns declaration
37 trav_forward, // Forward declaration of
38 // structs/interfaces in nsdecl
42 // Values beyond this point are not part of the
43 // above sequential pass scheme; they are merely
44 // for dynamic dispatch.
49 // Per-symbol language-private data
50 struct CPPData : public Releasable {
51 // The traversal indices are also passed as "arg1" to determine
52 // which pass to generate. Higher numbers are performed first.
54 int traversed[num_traversals];
56 CPPData() : Releasable(1)
58 memset(traversed, 0, sizeof(traversed));
62 static inline CPPData &cpp_symdata(Symbol *sym)
65 sym->lang_priv = new CPPData;
67 CPPData *ptr = dynamic_cast<CPPData *>(sym->lang_priv);
72 // Each IDL namespace is mapped to a C++ header file,
73 // represented by a CPPFile.
75 class CPPFile : public LangCallback {
82 //// Interface caller-side members:
84 // Outputs the body of the internal _i_<ifacename> struct,
85 // containing a vtable pointer (and definition).
87 void output_internal(Interface *sym);
89 // Outputs the user-visible class wrapper that is used to
90 // allow implicit upcasts.
92 void output_wrapper(Interface *sym);
94 // Output implementations of the cast methods prototyped in the wrapper.
95 // The implementation is delayed to avoid circular dependency problems.
97 void output_casts(Interface *sym);
99 //// Marshalling methods
101 void output_marshall_pass(Struct *sym, int pass);
102 void output_marshall_method(Struct *sym);
103 void output_marshall_inline_method(Struct *sym);
104 void marshall_members(Struct *sym);
106 void output_marshall_array(Datum *d);
107 void output_marshall(Struct *sym, Datum *d);
108 void output_marshall(Interface *sym, Datum *d);
109 void output_marshall(Enum *sym, Datum *d);
110 void output_marshall(BitField *sym, Datum *d);
111 void output_marshall(BasicType *sym, Datum *d);
112 void output_marshall(CompiledBasicType &cbt, Datum *d);
114 void align_type(Symbol *sym);
117 // Output the downcast and implicit upcast methods for
118 // the given interface/superinterface pair.
120 static void wrapper_cast_callback(Interface *iface, void *arg);
121 void output_downcast(Interface *iface, Interface *super);
122 void output_upcast(Interface *iface, Interface *super);
124 static void wrapper_cast_proto_callback(Interface *iface, void *arg);
125 void output_downcast_proto(Interface *iface, Interface *super);
126 void output_upcast_proto(Interface *iface, Interface *super);
128 static void wrapper_method_proto_callback(Interface *iface, void *arg);
129 static void wrapper_method_callback(Interface *iface, void *arg);
131 void output_iface_tbl(Interface *iface);
132 static void tbl_callback(Interface *iface, void *arg);
133 void output_iface_tbl_entry(Interface *iface, Interface *super);
135 static void output_method_ptrs_callback(Interface *iface, void *arg);
136 void output_method_ptrs(Interface *iface);
137 void output_methods(Interface *iface, Interface *super, bool prototype);
138 void output_method_defs(Interface *iface);
140 void output_one_method(Interface *iface, Method *m,
141 bool prototype, bool retval);
142 void output_one_method_ptr(Method *m, Interface *iface);
146 // Output the static const guid[] value, and the IFaceInfo struct.
148 void output_guid(const uint64_t *guid);
149 void output_ifaceinfo(Interface *iface);
151 // Output a datum in the given struct, along with any necessary
152 // padding. Return the offset of the next datum.
154 int output_datum(Struct *ns, Datum *d, int offset);
156 void output_vstruct_info(Struct *sym);
157 void output_vstruct_main(Struct *sym);
158 void output_struct_ctor(Struct *sym, bool extra_vstruct);
159 int output_struct_ctor_rec1(Struct *sym, int num);
160 int output_struct_ctor_rec2(Struct *sym, int num);
162 void output_bf_elem(Datum *d, int pos, int bits, string &prefix);
163 void output_bf(BitField *bf, int bits, int typebits, string &prefix);
165 // Call ns_in on the symbol in order to declare the containing
166 // namespace. Call ns_out when finished. ns_out also takes care
167 // of inserting the extra newline separating declarations. The
168 // "extra" parameter allows extra output passes to have unique
169 // #ifndef names, and should have a trailing underscore.
171 void ns_in(Symbol *sym, const char *extra = "DEF_");
172 void ns_out(Symbol *sym);
174 // As above, but also outputs non-user namespaces (optionally
175 // including "sym" itself).
177 void all_ns_in(Symbol *sym, bool include_self = false,
178 const char *extra = "DEF_");
179 void all_ns_out(Symbol *sym, bool include_self = false);
181 // Output a protective #ifndef/#define block to keep a type
182 // from being declared more than once. Call ifndef_out()
185 void ifndef_in(Symbol *sym, const char *extra = "DEF_");
188 // Return the namespace-qualified symbol name, excluding
189 // user namespaces. This is used when defining a name
190 // which (if it is nested) has been previously forward
191 // declared. A prefix for the final component (i.e. the
192 // actual name) can optionally be specified.
194 String &get_definition_name(Symbol *sym, const char *prefix = "");
196 // Output the _ns declaration of a struct or interface.
197 // If a callback is supplied, it is called inside the
198 // namespace, before any namespace members have been
201 void output_nsdecl_begin(NameSpace *ns);
202 void output_nsdecl_children(NameSpace *ns);
203 void output_nsdecl_end(NameSpace *ns);
204 void output_nsdecl(NameSpace *ns);
206 void output_aliases_and_types(NameSpace *ns);
208 // When a top-level struct or interface is about to be generated,
209 // it is scanned for other types which need to be generated. If the
210 // full definition is needed, it goes on the need_to_declare list;
211 // otherwise, it goes on the need_to_forward_declare list. When
212 // processing the lists, if a node has already been marked as
213 // traversed, it is skipped.
215 // Full declaration is needed for superstructs, superinterfaces,
216 // inline structs (once implemented) used, and typedefs used.
217 // It is also necessary to fully declare any type which contains
218 // a type whose forward declaration is needed, as such types
219 // cannot (as far as I know) be forward-declared.
221 std::list<Symbol *> need_to_declare;
223 // Forward declaration is needed for types used via a pointer only.
225 std::list<Symbol *> need_to_forward_declare;
227 void declare_dependencies(Struct *sym);
228 void declare_dependencies(Interface *iface, bool need_obj_def = false);
229 void declare_type_dependency(Type *t, bool need_obj_def = false);
231 // This is the traversal of the first namespace; any symbol
232 // whose last traversal is at least this has been written to
233 // at least one of the included namespaces (and/or the
234 // current namespace).
238 bool pass_needed(Symbol *sym, int pass)
240 return first_traversal > cpp_symdata(sym).traversed[pass];
243 void output_pass(Symbol *sym, int pass)
245 if (pass_needed(sym, pass)) {
246 cpp_symdata(sym).traversed[pass] = traversal;
247 sym->output_lang(this, pass);
251 bool do_extra_newline;
255 indent.indent_level++;
256 do_extra_newline = false;
261 indent.indent_level--;
262 do_extra_newline = true;
267 if (do_extra_newline)
270 do_extra_newline = true;
274 CPPFile(UserNameSpace *ns, const char *dir);
277 void output(UserNameSpace *sym, int pass = trav_full, void *arg2 = NULL);
278 void output(Struct *sym, int pass = trav_full, void *arg2 = NULL);
279 void output(Interface *sym, int pass = trav_full, void *arg2 = NULL);
280 void output(BitField *sym, int pass = trav_full, void *arg2 = NULL);
281 void output(Enum *sym, int pass = trav_full, void *arg2 = NULL);
282 void output(BasicType *sym, int pass = trav_full, void *arg2 = NULL);
283 void output(Alias *sym, int pass = trav_full, void *arg2 = NULL);
284 void output(TypeDef *sym, int pass = trav_full, void *arg2 = NULL);
285 void output(Datum *sym, int pass = trav_full, void *arg2 = NULL);
287 void marshall(Struct *sym);
288 void marshall(Interface *sym);
289 void marshall(BitField *sym);
290 void marshall(Enum *sym);
291 void marshall(BasicType *sym);
293 void unmarshall(Struct *sym);
294 void unmarshall(Interface *sym);
295 void unmarshall(BitField *sym);
296 void unmarshall(Enum *sym);
297 void unmarshall(BasicType *sym);
300 class CPPBinding : public Language {
309 void output_root(UserNameSpace *ns, const char *dir);
310 void output_server(UserNameSpace *ns, const char *dir);