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);
31 // Each IDL namespace is mapped to a C++ header file,
32 // represented by a CPPFile.
34 class CPPFile : public LangCallback {
41 //// Interface caller-side members:
43 // Outputs the body of the internal _i_<ifacename> struct,
44 // containing a vtable pointer (and definition).
46 void output_internal(Interface *sym);
48 // Outputs the user-visible class wrapper that is used to
49 // allow implicit upcasts.
51 void output_wrapper(Interface *sym);
53 // Output implementations of the cast methods prototyped in the wrapper.
54 // The implementation is delayed to avoid circular dependency problems.
56 void output_casts(Interface *sym);
58 // Output the downcast and implicit upcast methods for
59 // the given interface/superinterface pair.
61 static void wrapper_cast_callback(Interface *iface, void *arg);
62 void output_downcast(Interface *iface, Interface *super);
63 void output_upcast(Interface *iface, Interface *super);
65 static void wrapper_cast_proto_callback(Interface *iface, void *arg);
66 void output_downcast_proto(Interface *iface, Interface *super);
67 void output_upcast_proto(Interface *iface, Interface *super);
69 static void wrapper_method_proto_callback(Interface *iface, void *arg);
70 static void wrapper_method_callback(Interface *iface, void *arg);
72 void output_iface_tbl(Interface *iface);
73 static void tbl_callback(Interface *iface, void *arg);
74 void output_iface_tbl_entry(Interface *iface, Interface *super);
76 static void output_method_ptrs_callback(Interface *iface, void *arg);
77 void output_method_ptrs(Interface *iface);
78 void output_methods(Interface *iface, Interface *super, bool prototype);
79 void output_method_defs(Interface *iface);
81 void output_one_method(Interface *iface, Method *m,
82 bool prototype, bool retval);
83 void output_one_method_ptr(Method *m, Interface *iface);
85 static void output_iface_ns(CPPFile *file, NameSpace *sym);
89 // Output the static const guid[] value, and the IFaceInfo struct.
91 void output_guid(const uint64_t *guid);
92 void output_ifaceinfo(Interface *iface);
94 // Output a datum in the given struct, along with any necessary
95 // padding. Return the offset of the next datum.
97 int output_datum(Struct *ns, Datum *d, int offset);
99 static void output_vstruct_ns(CPPFile *file, NameSpace *sym);
100 void output_vstruct_info(Struct *sym);
101 void output_vstruct_main(Struct *sym);
102 void output_struct_ctor(Struct *sym, bool extra_vstruct);
103 int output_struct_ctor_rec1(Struct *sym, int num);
104 int output_struct_ctor_rec2(Struct *sym, int num);
106 void output_bf_elem(Datum *d, int pos, int bits, string &prefix);
107 void output_bf(BitField *bf, int bits, int typebits, string &prefix);
109 // Call ns_in on the symbol in order to declare the containing
110 // namespace. Call ns_out when finished. ns_out also takes care
111 // of inserting the extra newline separating declarations. The
112 // "extra" parameter allows extra output passes to have unique
113 // #ifndef names, and should have a trailing underscore.
115 void ns_in(Symbol *sym, const char *extra = "DEF_");
116 void ns_out(Symbol *sym);
118 // As above, but also outputs non-user namespaces (optionally
119 // including "sym" itself).
121 void all_ns_in(Symbol *sym, bool include_self = false,
122 const char *extra = "DEF_");
123 void all_ns_out(Symbol *sym, bool include_self = false);
125 // Output a protective #ifndef/#define block to keep a type
126 // from being declared more than once. Call ifndef_out()
129 void ifndef_in(Symbol *sym, const char *extra = "DEF_");
132 // Return the namespace-qualified symbol name, excluding
133 // user namespaces. This is used when defining a name
134 // which (if it is nested) has been previously forward
135 // declared. A prefix for the final component (i.e. the
136 // actual name) can optionally be specified.
138 String &get_definition_name(Symbol *sym, const char *prefix = "");
140 // Output the _ns declaration of a struct or interface.
141 // If a callback is supplied, it is called inside the
142 // namespace, before any namespace members have been
145 typedef void (*nsdecl_callback)(CPPFile *file, NameSpace *ns);
146 void output_nsdecl(NameSpace *ns, nsdecl_callback cb = NULL);
148 void output_aliases_and_types(NameSpace *ns);
150 // When a top-level struct or interface is about to be generated,
151 // it is scanned for other types which need to be generated. If the
152 // full definition is needed, it goes on the need_to_declare list;
153 // otherwise, it goes on the need_to_forward_declare list. When
154 // processing the lists, if a node has already been marked as
155 // traversed, it is skipped.
157 // Full declaration is needed for superstructs, superinterfaces,
158 // inline structs (once implemented) used, and typedefs used.
159 // It is also necessary to fully declare any type which contains
160 // a type whose forward declaration is needed, as such types
161 // cannot (as far as I know) be forward-declared.
163 std::list<Symbol *> need_to_declare;
165 // Forward declaration is needed for types used via a pointer only.
167 std::list<Symbol *> need_to_forward_declare;
169 void declare_dependencies(Struct *sym);
170 void declare_dependencies(Interface *iface, bool need_obj_def = false);
171 void declare_type_dependency(Type *t, bool need_obj_def = false);
173 // This is the traversal of the first namespace; any symbol
174 // whose last traversal is at least this has been written to
175 // at least one of the included namespaces (and/or the
176 // current namespace).
180 // The traversal indices are also passed as "arg1" to determine
181 // which pass to generate. Higher numbers are performed first.
184 trav_full = 0, // Full, final output
185 trav_obj_def = 1, // Object struct definition
186 trav_obj_stub = 2, // Object pointer stub,
187 // so it can be used in structs.
188 trav_nsdecl = 3, // _ns declaration
189 trav_forward = 4, // Forward declaration of
190 // structs/interfaces in nsdecl
193 bool pass_needed(Symbol *sym, int pass)
195 return first_traversal > sym->traversed[pass];
198 void output_pass(Symbol *sym, int pass)
200 if (pass_needed(sym, pass)) {
201 sym->traversed[pass] = traversal;
202 sym->output_lang(this, pass);
206 bool do_extra_newline;
210 indent.indent_level++;
211 do_extra_newline = false;
216 indent.indent_level--;
217 do_extra_newline = true;
222 if (do_extra_newline)
225 do_extra_newline = true;
229 CPPFile(UserNameSpace *ns, const char *dir);
232 void output(UserNameSpace *sym, int pass = trav_full, void *arg2 = NULL);
233 void output(Struct *sym, int pass = trav_full, void *arg2 = NULL);
234 void output(Interface *sym, int pass = trav_full, void *arg2 = NULL);
235 void output(BitField *sym, int pass = trav_full, void *arg2 = NULL);
236 void output(Enum *sym, int pass = trav_full, void *arg2 = NULL);
237 void output(BasicType *sym, int pass = trav_full, void *arg2 = NULL);
238 void output(Alias *sym, int pass = trav_full, void *arg2 = NULL);
239 void output(TypeDef *sym, int pass = trav_full, void *arg2 = NULL);
240 void output(Datum *sym, int pass = trav_full, void *arg2 = NULL);
243 class CPPBinding : public Language {
252 void output_root(UserNameSpace *ns, const char *dir);
253 void output_server(UserNameSpace *ns, const char *dir);