Fixed unhelpful coredump when parsing (invalid) command-line arguments,
[dyninst.git] / igen / src / parse.h
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 #ifndef PARSE_H
43 #define PARSE_H
44
45 /*
46  * Parse.h - define the classes that are used in parsing an interface.
47  */
48
49 #if defined(i386_unknown_nt4_0)
50 // XXX kludge for bison.simple
51 #include <malloc.h>
52 #define alloca _alloca
53 #endif
54
55 #include "util/h/String.h"
56 /* trace data streams */
57 #include "util/h/ByteArray.h"
58 #include "util/h/Vector.h"
59 #include "util/h/Dictionary.h"
60 #include <fstream.h>
61
62 extern void dump_to_dot_h(const char*);
63
64 // forward decl
65 class type_defn;
66 class remote_func;
67 class signature;
68 class interface_spec;
69
70 class arg {
71 public:
72   // gen_variable()
73   arg(const string *type, const unsigned star_count, const bool is_const,
74       const string *name, const bool is_ref);
75   arg() { }
76   ~arg() { }
77   bool operator== (const arg &other) const { return (type_ == other.type()); }
78
79   bool is_void() const { return (type_ == "void");}
80   string gen_bundler_name() const;
81   void gen_bundler(ofstream &outStream, const string obj_name,
82                    const string data_name) const;
83
84   string pointers() const { return pointers_; }
85   string base_type() const { return type_;}
86   string type(const bool use_const=false, const bool use_ref=false) const;
87   string name() const { return name_; }
88   bool is_const() const { return constant_;}
89   bool tag_bundle_send(ofstream &out_stream, const string bundle_value, 
90                        const string tag_value, const string return_value) const;
91   unsigned stars() const { return stars_;}
92   bool is_ref() const { return is_ref_;}
93   string deref(const bool local) const;
94
95 private:
96   string pointers_;
97   string type_;
98   string name_;
99   bool constant_;
100   unsigned stars_;
101   bool is_ref_;
102
103   bool tag_bundle_send_one(ofstream &out_stream, const string bundle_value, 
104                        const string tag_value, const string return_value) const;
105   bool tag_bundle_send_many(ofstream &out_stream, const string bundle_value, 
106                        const string tag_value, const string return_value) const;
107 };
108
109 class type_defn {
110 public:
111   friend void recursive_dump_kids(const type_defn *from, ofstream &output);
112
113   typedef enum { TYPE_SCALAR, TYPE_COMPLEX } type_type;
114
115   type_defn(string stl_name, string element_name, const unsigned star_count,
116             const bool in_lib);
117   type_defn(const string name, const bool is_class, const bool is_abstract,
118             const bool is_derived, const string parent, 
119             const type_type type, vector<arg*> *arglist = NULL, 
120             const bool can_point=false, bool in_lib=false, const string ignore="",
121             const string bundle_name="");
122   ~type_defn() { }
123
124   string gen_bundler_name() const;
125   string gen_bundler_call(const string obj_name, const string data_name,
126                           const unsigned pointer_count) const;
127   bool gen_bundler_body(const string bundler_prefix, const string class_prefix,
128                         ofstream &out_stream) const;
129   bool gen_bundler_sig(const bool &print_extern, const string class_prefix,
130                        const string &bundler_prefix, ofstream &out_stream) const;
131   bool gen_bundler_ptr(const string bundler_prefix, const string class_prefix,
132                        ofstream &out_c, ofstream &out_h) const;
133   bool gen_class(const string bundler_prefix, ofstream &out_stream);
134
135   string unqual_id() const { return (unqual_name_ + "_id");}
136   string qual_id() const;
137   string name() const { return name_;}
138   string bundle_name() const { return bundle_name_;}
139   type_type my_type() const { return my_type_;}
140   bool is_in_library() const { return in_lib_;}
141   bool operator== (const type_defn &other) const { return (other.name() == name_); }
142   bool is_same_type(vector<arg*> *arglist) const;
143   string dump_args(const string data_name, const string sep) const;
144   void dump_type();
145   string unqual_name() const { return unqual_name_;}
146   bool is_stl() const { return is_stl_;}
147   string prefix() const { return prefix_;}
148   bool assign_to(const string prefix, const vector<arg*> &alist, ofstream &out_stream) const;
149   bool pointer_used() const { return pointer_used_;}
150   void set_pointer_used() { pointer_used_ = true;}
151   bool can_point() const { return can_point_;}
152   const vector<arg*> &copy_args() const { return (arglist_);}
153   string ignore() const { return ignore_;}
154   bool is_class() const { return is_class_;}
155   bool is_abstract() const { return is_abstract_; }
156   bool is_derived() const { return is_derived_;}
157   string parent() const { return parent_;}
158   void add_kid(const string kid_name);
159   bool has_kids() const { return (kids_.size());}
160
161 private:
162   type_type my_type_;
163   string name_;
164   string bundle_name_;
165   bool in_lib_;
166   vector<arg*> arglist_;
167   string unqual_name_;
168   bool is_stl_;
169   string prefix_;
170   bool pointer_used_;
171   bool can_point_;
172   arg *stl_arg_;
173   string ignore_;
174   bool is_class_;
175   bool is_abstract_;
176   bool is_derived_;
177   string parent_;
178   vector<string> kids_;
179
180   bool gen_bundler_ptr_struct(const string bundler_prefix, const string class_prefix,
181                        ofstream &out_c, ofstream &out_h) const;
182   bool gen_bundler_ptr_class(const string bundler_prefix, const string class_prefix,
183                        ofstream &out_c, ofstream &out_h) const;
184
185   bool gen_bundler_body_class(const string bundler_prefix, const string class_prefix,
186                         ofstream &out_stream) const;
187   bool gen_bundler_body_struct(const string bundler_prefix, const string class_prefix,
188                         ofstream &out_stream) const;
189 };
190
191 class signature {
192 public:
193   signature(vector<arg*> *alist, const string rf_name);
194   ~signature() { }
195
196   string type(const bool use_bool=false) const;
197   string base_type() const { return type_;}
198   void type(const string t, const unsigned star);
199   bool gen_sig(ofstream &out_stream) const;
200   bool tag_bundle_send(ofstream &out_stream, const string return_value,
201                        const string req_tag) const;
202   bool tag_bundle_send_many(ofstream &out_stream, const string return_value,
203                             const string req_tag) const;
204   bool tag_bundle_send_one(ofstream &out_stream, const string return_value,
205                            const string req_tag) const;
206   bool arg_struct(ofstream &out_stream) const;
207   string dump_args(const string message, const string sep) const;
208   string gen_bundler_call(const string obj_name, const string data_name) const;
209
210 private:
211   vector<arg*> args;
212   string type_;
213   bool is_const_;
214   unsigned stars_;
215 };
216
217 class remote_func { 
218 public:
219   typedef enum { async_upcall,      // from server to client, async
220                  sync_call,         // from client to server, sync
221                  async_call         // from client to server, async
222                  } call_type; 
223
224   remote_func(const string name, vector<arg*> *arglist, const call_type &ct,
225               const bool &is_v, const arg &return_arg, const bool do_free);
226   ~remote_func() { }
227   bool operator== (const remote_func &other) const { return (other.name() == name_);}
228
229   bool gen_stub(ofstream &out_srvr, ofstream &out_clnt) const;
230   bool gen_signature(ofstream &out_stream, const bool &hdr, const bool srvr) const;
231   bool gen_async_struct(ofstream &out_stream) const;
232   bool save_async_request(ofstream &out_stream, const bool srvr) const;
233   bool free_async(ofstream &out_stream, const bool srvr) const;
234   bool handle_request(ofstream &out_stream, const bool srvr, bool special=false) const;
235
236   string request_tag(bool unqual=false) const;
237   string response_tag(bool unqual=false) const;
238
239   bool is_virtual() const { return is_virtual_;}
240   bool is_void() const { return (return_arg_.is_void());}
241   bool is_srvr_call() const { return (function_type_ == async_upcall);}
242   bool is_async_call() const {
243     return ((function_type_ == async_upcall) || (function_type_ == async_call));}
244
245   string name() const { return name_; }
246   call_type function_type() const { return function_type_;}
247   string return_value() const
248     { return ((is_async_call()||is_void()) ? string("") : string("ret_arg"));}
249   bool do_free() const { return do_free_;}
250   string sig_type(const bool use_const=false) const { return call_sig_.type(use_const);}
251   string ret_type(const bool use_const=false) const { return return_arg_.type(use_const);}
252
253 private:
254   string name_;
255   call_type function_type_;
256   bool is_virtual_;
257   signature call_sig_;
258   arg return_arg_;
259   bool do_free_;
260
261   bool gen_stub_helper(ofstream &out_srvr, ofstream &out_clnt,
262                        const bool server) const;
263   bool gen_stub_helper_many(ofstream &out_srvr,
264                             ofstream &out_clnt, const bool server) const;
265   bool gen_stub_helper_one(ofstream &out_srvr, ofstream &out_clnt,
266                            const bool server) const;
267 };
268
269 class interface_spec {
270 public:
271   interface_spec(const string *name, const unsigned &b, const unsigned &v);
272   ~interface_spec();
273
274   bool gen_interface() const;
275
276   // TODO reverse arg list ?
277   bool new_remote_func(const string *name, vector<arg*> *arglist,
278                        const remote_func::call_type &callT,
279                        const bool &is_virtual, const arg &return_arg,
280                        const bool do_free);
281   
282   void ignore(bool is_srvr, char *text);
283   bool are_bundlers_generated() const;
284   string name() const { return name_;}
285   unsigned base() const { return base_;}
286   unsigned version() const { return version_;}
287
288   string gen_class_name(const bool &server) const { 
289     return (server ? server_name_ : client_name_); }
290   string gen_class_prefix(const bool &server) const {
291     return (server ? server_prefix_ : client_prefix_);}
292   bool gen_process_buffered(ofstream &out_stream, const bool &srvr) const;
293   bool gen_await_response(ofstream &out_stream, const bool srvr) const;
294   bool gen_wait_loop(ofstream &out_stream, const bool srvr) const;
295   bool gen_scope(ofstream &out_h, ofstream &out_c) const;
296   bool gen_client_verify(ofstream &out_stream) const;
297   bool gen_server_verify(ofstream &out_stream) const;
298
299 private:
300   string name_;
301   unsigned base_;
302   unsigned version_;
303   string client_prefix_;
304   string server_prefix_;
305   string client_name_;
306   string server_name_;
307
308   vector<string> client_ignore;
309   vector<string> server_ignore;
310
311   bool gen_stl_temps() const;
312   bool gen_stl_bundler(ofstream &out_h, ofstream &out_c) const;
313   bool gen_stl_bundler_ptr(ofstream &out_h, ofstream &out_c) const;
314   bool gen_header(ofstream &out_stream, const bool &server) const;
315   bool gen_inlines(ofstream &out_stream, const bool &server) const;
316   bool gen_prelude(ofstream &out_stream, const bool &server) const;
317   bool gen_dtor_hdr(ofstream &out_stream, const bool &server, const bool &hdr) const;
318   bool gen_ctor_hdr(ofstream &out_stream, const bool &server) const;
319   bool gen_dtor_body(ofstream &out_stream, const bool &server) const;
320   bool gen_ctor_body(ofstream &out_stream, const bool &server) const;
321   bool gen_ctor_helper(ofstream &out_stream, const bool &server) const;
322   bool gen_ctor_1(ofstream &out_stream, const bool &server,
323                   const bool &hdr) const;
324   bool gen_ctor_2(ofstream &out_stream, const bool &server,
325                   const bool &hdr) const;
326   bool gen_ctor_3(ofstream &out_stream, const bool &server,
327                   const bool &hdr) const;
328   bool gen_ctor_4(ofstream &out_stream, const bool &server,
329                   const bool &hdr) const;
330
331   dictionary_hash<string, remote_func*> all_functions_;
332 };
333
334 class message_layer {
335 public:
336   typedef enum { AS_one, AS_many, AS_none } AS;
337   typedef enum { Med_xdr, Med_pvm, Med_thread, Med_other, Med_none, Med_rpc } medium;
338
339   message_layer() { med_ = Med_none; }
340   message_layer(const string) { }
341   message_layer(const string nm, const medium md, const string bp, const string brt,
342                 const string mdp, const string mo, const string mop, const AS as,
343                 const string bfail, const string bok, const string dir_f,
344                 const string pack_f, const string unpack_f, const string free_c,
345                 const string rpc_par, const string send_msg, const bool r_used,
346                 const string skip_msg, const string r_msg, const string incs,
347                 const bool do_serial, const string enc, const string dec,
348                 const bool do_skip);
349   ~message_layer() { }
350   bool operator== (const message_layer &other) const { return (name_ == other.name());}
351
352   string name() const { return name_;}
353   medium med() const { return med_;}
354   string bundler_prefix() const { return bundler_prefix_;}
355   string bundler_return_type() const { return bundler_return_type_;}
356   string marshall_data_ptr() const { return marshall_data_ptr_;}
357   string marshall_obj() const { return marshall_obj_;}  
358   string marshall_obj_ptr() const { return marshall_obj_ptr_;}
359   AS address_space() const { return address_space_;}
360   string bundle_fail() const { return bundle_fail_;}
361   string bundle_ok() const { return bundle_ok_;}
362   string dir_field() const { return dir_field_;}
363   string pack_const() const { return pack_const_;}
364   string unpack_const() const { return unpack_const_;}
365   string free_const() const { return free_const_;}
366   string rpc_parent() const { return rpc_parent_;}
367   string send_message() const { return send_message_;}
368   string read_tag(const string obj_name, const string tag) const;
369   bool records_used() const { return records_used_;}
370   string skip_message() const { return skip_message_;}
371   string recv_message() const { return recv_message_;}
372   string includes() const { return incs_;}
373   bool serial() const { return serial_;}
374   string set_dir_decode() const { return decode_;}
375   string set_dir_encode() const { return encode_;}
376   bool skip() const { return skip_;}
377
378 private:
379   string name_;
380   medium med_;
381   string bundler_prefix_;
382   string bundler_return_type_;
383   string dir_is_free_;
384   string marshall_data_ptr_;
385   string marshall_obj_;
386   string marshall_obj_ptr_;
387   AS address_space_;
388   string bundle_fail_;
389   string bundle_ok_;
390   string dir_field_;
391   string pack_const_;
392   string unpack_const_;
393   string free_const_;
394   string rpc_parent_;
395   string send_message_;
396   bool records_used_;
397   string skip_message_;
398   string recv_message_;
399   string incs_;
400   bool serial_;
401   string encode_;
402   string decode_;
403   bool skip_;
404 };
405
406 class Options {
407 public:
408   typedef enum { Mem_ignore, Mem_detect, Mem_handle } mem_type;
409
410   static string make_ptrs(unsigned count);
411   static string qual_to_unqual(const string type);
412   static string file_base() { return file_base_;}
413   static void set_file_base(const string f) { file_base_ = f;}
414   static string input_file() { return input_file_;}
415   static void set_input_file(const string f) { input_file_ = f;}
416
417   static bool profile() { return profile_;}
418   static void set_profile(const bool b) { profile_ = b;}
419   static mem_type mem() { return mem_;}
420   static void set_mem(const mem_type m) { mem_ = m;}
421
422   static string error_state(const string err_name, const string return_value);
423   static interface_spec *current_interface;
424   static dictionary_hash<string, type_defn*> all_types;
425   static vector<type_defn*> vec_types;
426   static vector<message_layer*> all_ml;
427   static message_layer *ml;
428
429   static void ignore(string &s, bool is_server);
430   static vector<string> client_ignores;
431   static vector<string> server_ignores;
432   static vector<string> forward_decls;
433
434   typedef struct el_data {
435     string type;
436     unsigned stars;
437     string name;
438   } el_data;
439
440   typedef struct stl_data {
441     string include_file;
442     string name;
443     bool need_include;
444     string pragma_name;
445     vector<el_data> elements;
446   } stl_data;
447   static vector<stl_data> stl_types;
448
449   static ifstream input;
450   static ofstream dot_h;
451   static ofstream dot_c;
452   static ofstream clnt_dot_h;
453   static ofstream clnt_dot_c;
454   static ofstream srvr_dot_h;
455   static ofstream srvr_dot_c;
456   static ofstream temp_dot_c;
457
458   static void dump_types();
459
460   static string allocate_stl_type(string stl_type, string element_name,
461                                   const unsigned star_count, const bool in_lib);
462   static string allocate_type(const string name, const bool is_class, const bool is_abstract,
463                               const bool is_derived, const string parent,
464                               const type_defn::type_type &typ,
465                               const bool can_point, const bool &in_lib,
466                               vector<arg*> *arglist=NULL, const string ignore_text="",
467                               const string bundle_name="");
468
469   static string add_type(const string name, const bool is_class, const bool is_abstract,
470                          const bool is_derived, const string parent,
471                          const type_defn::type_type &type, 
472                          const bool can_point, const bool in_lib,
473                          vector<arg*> *arglist=NULL, const string ignore="",
474                          const string bundler_name="");
475
476   static string obj() { return (string("obj"));}
477   static string obj_ptr() { return (string("obj->") + Options::ml->dir_field());}
478   static string gen_name();
479   static string set_dir_encode();
480   static string set_dir_decode();
481   static string type_class() { return (string("T_") + file_base_);}
482   static string type_prefix() { return (type_class() + "::");}
483   static bool types_defined(const string name) {
484     return (all_types.defines(name) || all_types.defines(type_prefix()+name));
485   }
486   static string get_type(const string name) {
487     if (all_types.defines(name))
488       return name;
489     else if (all_types.defines(type_prefix()+name))
490       return (type_prefix()+name);
491     else {
492       abort();
493       return(NULL); // some compilers will complain if we don't return a value
494     }
495   }
496   static bool stl_seen;
497   static bool dont_gen_handle_err;
498
499 private:
500   static string file_base_;
501   static string input_file_;
502   static bool profile_;
503   static mem_type mem_;
504   static unsigned var_count_;
505 };
506
507
508 typedef struct functype_data {
509   remote_func::call_type call;
510   bool is_virtual;
511 } Type_data;
512
513 typedef struct derived_data {
514   bool is_derived;
515   string *name;
516 } Derived_data;
517
518 typedef struct cl {
519   bool b;
520   bool abs;
521 } cl;
522
523 union parse_stack {
524   string *cp;
525   int i;
526   unsigned u;
527   float f;
528   bool b;
529   cl class_data;
530   arg *args;
531   functype_data fd;
532   derived_data derived;
533   vector<arg*> *arg_vector;
534   interface_spec *spec;
535   char *charp;
536 };
537
538 #endif