00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef CBZ_AST_H
00038 #define CBZ_AST_H
00039
00040
00041
00042
00043 #define REF
00044 #define TREE
00045
00071 */
00072
00073 class Node
00074 {
00075
00076 private:
00077
00083 NodeType _typ;
00084
00092 Coord _coord;
00093
00102 bool _parenthesized;
00103
00111 annote_list _annotations;
00112
00119 FlowVal * _gen;
00120
00127 FlowVal * _kill;
00128
00135
00137 int _uid;
00138
00140 static int _count;
00141
00143 static int _t_count[50];
00144
00146 static int _uid_count;
00147
00149
00150 public:
00151
00159
00161 static node_list nodes;
00162
00164 static map <Node *, bool> deleted_nodes;
00165
00167 bool mark;
00168
00170
00181 Node(NodeType typ, const Coord coord, bool parenthesized = false);
00182
00192 Node(const Node & other);
00193
00200 virtual ~Node();
00201
00206
00215 inline NodeType typ() const { return _typ; }
00216
00229 inline Coord coord() const { return _coord; }
00230
00242 inline void coord(const Coord coord) { _coord = coord; }
00243
00249 inline bool parenthesized() const { return _parenthesized; }
00250
00261 inline void parenthesized(bool paren) { _parenthesized = paren; }
00262
00273 inline annote_list & annotations() { return _annotations; }
00274
00283 inline FlowVal * gen() const { return _gen; }
00284
00296 inline void gen(FlowVal * g) { _gen = g; }
00297
00306 inline FlowVal * kill() const { return _kill; }
00307
00319 inline void kill(FlowVal * k) { _kill = k; }
00320
00322
00329 static void report();
00330
00341 virtual typeNode * type() const { return 0; }
00342
00353 virtual typeNode * base_type(bool TdefIndir) const;
00354
00358 typeNode * datatype() const;
00359
00362 typeNode * datatype_superior() const;
00363
00374
00385 virtual void visit(Visitor * the_visitor) =0;
00386
00395 virtual void walk(Walker & the_walker) =0;
00396
00405 virtual Node * change(Changer & the_changer, bool redispatch = false) =0;
00406
00408
00420 virtual void dataflow(FlowVal * v, FlowProblem & fp) =0;
00421
00429 virtual Node * clone() const =0;
00430
00440 virtual void output(output_context & ct, Node * par) =0;
00441 };
00442
00466 class unitNode : public Node
00467 {
00468
00469 private:
00470
00476 TREE def_list _defs;
00477
00483 int _symbol_level;
00484
00491 Identifiers_table * _types;
00492
00499 Tags_table * _tags;
00500
00505 string _input_file;
00506
00512 string _output_file;
00513
00518 int _errors;
00519
00524 int _warnings;
00525
00531 TREE decl_list _undef_funcs;
00532
00533
00534
00535
00544 TREE suespec_list _suespecs;
00545
00551 FILE * _open_input_file(str_list * cpp_flags);
00552
00553 public:
00554
00564 unitNode(string input_file, string output_file,
00565 const Coord coord = Coord::Unknown);
00566
00572 virtual ~unitNode();
00573
00582 void parse(str_list * cpp_flags);
00583
00588 void fixup();
00589
00594
00595
00596
00597 inline def_list & defs() { return _defs; }
00598 inline const def_list & defs() const { return _defs; }
00599
00600 inline int symbol_level() const { return _symbol_level; }
00601 inline Identifiers_table * types() const { return _types; }
00602 inline Tags_table * tags() const { return _tags; }
00603
00604 inline string & input_file() { return _input_file; }
00605 inline string & output_file() { return _output_file; }
00606
00607 inline int errors() const { return _errors; }
00608 inline void inc_errors() { ++_errors; }
00609
00610 inline int warnings() const { return _warnings; }
00611 inline void inc_warnings() { ++_warnings; }
00612
00613 inline decl_list & undef_funcs() { return _undef_funcs; }
00614
00615 inline suespec_list & suespecs() { return _suespecs; }
00616
00618
00619
00620
00621
00631 void merge_in(def_list * defs) {
00632 _defs.splice(_defs.end(), * defs); delete defs; }
00633
00640 void enter_scope();
00641
00648 void exit_scope();
00649
00654
00655 virtual void visit(Visitor * the_visitor);
00656 virtual void walk(Walker & the_walker);
00657 virtual Node * change(Changer & the_changer, bool redispatch = false);
00658
00660
00661
00662
00663 virtual void dataflow(FlowVal * v, FlowProblem & fp);
00664
00665
00666
00667 virtual Node * clone() const { return new unitNode ( *this ); }
00668
00669
00670
00671 virtual void output(output_context & ct, Node * par);
00672 };
00673
00682 class defNode : public Node
00683 {
00684 private:
00685
00692 text_list _pragmas;
00693
00694 public:
00695
00701 defNode(NodeType typ, const Coord coord);
00702
00707
00708 inline text_list & pragmas() { return _pragmas; }
00709
00711
00717 virtual ~defNode();
00718 };
00719
00730 class declNode : public defNode
00731 {
00732
00733 public:
00734
00743 typedef enum {
00744 UNKNOWN,
00745 TOP,
00747 BLOCK,
00748 FORMAL,
00749 SU,
00750 ENUM,
00751 PROC
00752 } Decl_location;
00753
00760 typedef enum {
00761 NONE, AUTO, EXTERN, REGISTER, STATIC, TYPEDEF
00762 } Storage_class;
00763
00769
00773 static string storage_class_name(Storage_class sc);
00774
00778 static string decl_location_name(Decl_location dl);
00779
00780
00781
00782 private:
00783
00788 TREE typeNode * _type;
00789
00794 string _name;
00795
00801 Decl_location _decl_location;
00802
00808 Storage_class _storage_class;
00809
00815 bool _is_redundant_extern;
00816
00822 TREE exprNode * _init;
00823
00829 TREE exprNode * _bitsize;
00830
00836 int _references;
00837
00842 TREE attrib_list _attribs;
00843
00844 public:
00845
00873 declNode(const char * name, Storage_class sc, typeNode * the_type,
00874 exprNode * init, exprNode * bitsize,
00875 const Coord coord = Coord::Unknown);
00876
00883
00897 declNode(idNode * id, Storage_class sc, typeNode * the_type,
00898 exprNode * init, exprNode * bitsize);
00899
00911 declNode(idNode * name, exprNode * value);
00912
00922 declNode(typeNode * the_type, Storage_class sc);
00923
00925
00931 virtual ~declNode();
00932
00937
00941 inline typeNode * type() const { return _type; }
00942
00947 inline typeNode * get_type() { typeNode * out = _type; _type = 0; return out; }
00948
00954 inline void type(typeNode * the_type) { _type = the_type; }
00955
00959 inline string & name() { return _name; }
00960
00964 inline void name(string name) { _name = name; }
00965
00969 inline Decl_location decl_location() const { return _decl_location; }
00970 '
00973
00974 inline void decl_location(Decl_location loc) { _decl_location = loc; }
00975
00979 inline Storage_class storage_class() const { return _storage_class; }
00980
00984 inline void storage_class(Storage_class sc) { _storage_class = sc; }
00985
00992 inline bool is_redundant_extern() const { return _is_redundant_extern; }
00993
00997 inline void set_redundant_extern(bool v) { _is_redundant_extern = v; }
00998
01002 inline void inc_references() { _references++; }
01003
01007 inline exprNode * init() const { return _init; }
01008
01015 void init(exprNode * init) { _init = init; }
01016
01019 inline exprNode * bitsize() const { return _bitsize; }
01020
01026 inline void bitsize(exprNode * bitsize) { _bitsize = bitsize; }
01027
01031 inline int references() const { return _references; }
01032
01036 inline void references(int references) { _references = references; }
01037
01041 inline attrib_list & attribs() { return _attribs; }
01042
01046 inline const attrib_list & attribs() const { return _attribs; }
01047
01051 void merge_attribs(attrib_list * attribs);
01052
01054
01080
01081
01082
01083 void set_type(typeNode * the_type, Storage_class sc, ScopeState redeclare);
01084 declNode * set_type_and(typeNode * the_type, Storage_class sc, ScopeState redeclare);
01085 declNode * set_type_and(declNode * the_decltype, Storage_class sc, ScopeState redeclare);
01086
01087
01088
01089 void inherit_type(decl_list * others, ScopeState redeclare);
01090 declNode * inherit_type_and(decl_list * others, ScopeState redeclare);
01091
01092
01093
01094 void modify_type(typeNode * the_type);
01095 declNode * modify_type_and(typeNode * the_type);
01096 declNode * modify_type_and(declNode * the_type);
01097
01098
01099
01100 void set_init(exprNode * init);
01101 declNode * set_init_and(exprNode * init);
01102
01103
01104
01105 void add_parameter_types(decl_list * types);
01106 declNode * add_parameter_types_and(decl_list * types);
01107
01108
01109
01110 void finish(Storage_class sc);
01111 declNode * finish_and(Storage_class sc);
01112
01114
01115
01116
01117 typeNode * base_type(bool TdefIndir) const;
01118
01125 typeNode * no_tdef_type();
01126
01135 virtual declNode * original() { return this; }
01136
01141
01142 virtual void visit(Visitor * the_visitor);
01143 virtual void walk(Walker & the_walker);
01144 virtual Node * change(Changer & the_changer, bool redispatch = false);
01145
01147
01148
01149
01150 virtual void dataflow(FlowVal * v, FlowProblem & fp);
01151
01152
01153
01154 virtual Node * clone() const { return new declNode ( *this ); }
01155
01156
01157
01158 virtual void output(output_context & ct, Node * par);
01159 };
01160
01177 class subdeclNode : public declNode
01178 {
01179 private:
01180
01181 REF declNode * _original;
01182 int _index;
01183
01184 public:
01185
01196 subdeclNode(declNode * orig, int index);
01197
01203 virtual ~subdeclNode();
01204
01209
01210 virtual declNode * original() { return _original->original(); }
01211 int index() const { return _index; }
01212
01214
01223 string name_with_index();
01224
01229
01230 virtual void visit(Visitor * the_visitor);
01231 virtual void walk(Walker & the_walker);
01232 virtual Node * change(Changer & the_changer, bool redispatch = false);
01233
01235
01236
01237
01238 virtual Node * clone() const { return new subdeclNode ( *this ); }
01239
01240
01241
01242 virtual void output(output_context & ct, Node * par);
01243 };
01244
01254 class procNode : public defNode
01255 {
01256
01257 private:
01258
01267 TREE declNode * _decl;
01268
01273 TREE blockNode * _body;
01274
01281 static procNode * _current;
01282
01283
01293
01294 FlowVal * _at_entry;
01295 FlowVal * _at_exit;
01296
01298
01299 public:
01300
01307 procNode(declNode * decl, blockNode * body,
01308 const Coord coord = Coord::Unknown);
01309
01320 procNode(bool old_style, declNode * decl);
01321
01327 virtual ~procNode();
01328
01333
01334
01341 inline declNode * decl() const { return _decl; }
01342
01350 inline declNode * get_decl() { declNode * out = _decl; _decl = 0; return out; }
01351
01358 inline void decl(declNode * decl) { _decl = decl; }
01359
01362 inline blockNode * body() const { return _body; }
01363
01367 inline blockNode * get_body() { blockNode * out = _body; _body = 0; return out; }
01368
01374 inline void body(blockNode * body) { _body = body; }
01375
01376
01377
01381 inline FlowVal * at_entry() const { return _at_entry; }
01382
01386 inline void at_entry(FlowVal * ae) { _at_entry = ae; }
01387
01391 inline FlowVal * at_exit() const { return _at_exit; }
01392
01396 inline void at_exit(FlowVal * ae) { _at_exit = ae; }
01397
01399
01411
01416 basicblockNode * entry() const;
01417
01422 basicblockNode * exit() const;
01423
01425
01432
01433
01434
01435 void define(blockNode * body);
01436 procNode * define_and(blockNode * body);
01437
01438 static procNode * current() { return _current; }
01439
01441
01442
01443
01444 typeNode * base_type(bool TdefIndir) const;
01445
01450
01451 virtual void visit(Visitor * the_visitor);
01452 virtual void walk(Walker & the_walker);
01453 virtual Node * change(Changer & the_changer, bool redispatch = false);
01454
01456
01457
01458
01459 virtual void dataflow(FlowVal * v, FlowProblem & fp);
01460
01461
01462
01463 virtual Node * clone() const { return new procNode ( *this ); }
01464
01465
01466
01467 virtual void output(output_context & ct, Node * par);
01468 };
01469
01481 class typeNode : public Node
01482 {
01483
01484 public:
01485
01492 typedef enum {
01493 NONE = 0x0,
01494 CONST = 0x1,
01495 VOLATILE = 0x2,
01496 INLINE = 0x4,
01498 COMPATIBLE = 0x3
01499 } Type_qualifiers;
01500
01509 static string type_qualifiers_name(Type_qualifiers tq);
01510
01523 static typeNode * integral_promotions(typeNode * old_type);
01524
01544 static pair<typeNode *, typeNode *> usual_arithmetic_conversions(typeNode * left,
01545 typeNode * right);
01546
01547 private:
01548
01554 TREE typeNode * _type;
01555
01560 Type_qualifiers _type_qualifiers;
01561
01562 public:
01563
01574 typeNode(NodeType typ, Type_qualifiers tq, typeNode * subtype,
01575 const Coord coord);
01576
01582 virtual ~typeNode();
01583
01588
01591 inline typeNode * type() const { return _type; }
01592
01596 inline typeNode * get_type() { typeNode * out = _type; _type = 0; return out; }
01597
01603 inline void type(typeNode * the_type) { _type = the_type; }
01604
01607 inline Type_qualifiers type_qualifiers() const { return _type_qualifiers; }
01608
01611 inline void type_qualifiers(Type_qualifiers the_tq) { _type_qualifiers = the_tq; }
01612
01614 inline string type_qualifiers_name() { return type_qualifiers_name(type_qualifiers()); }
01615
01618 inline void add_type_qualifiers(Type_qualifiers the_tq)
01619 { _type_qualifiers = Type_qualifiers(_type_qualifiers | the_tq); }
01620
01624 inline typeNode * add_type_qualifiers_and(Type_qualifiers the_tq)
01625 { add_type_qualifiers(the_tq); return this; }
01626
01629 inline void remove_type_qualifiers(Type_qualifiers the_tq)
01630 { _type_qualifiers = Type_qualifiers(_type_qualifiers & ~the_tq); }
01631
01633
01640
01641 void finish();
01642 typeNode * finish_and();
01643
01644
01645
01646
01647 void set_base_type(typeNode * base);
01648 typeNode * set_base_type_and(typeNode * base);
01649
01650
01651
01652 void verify_sue_complete();
01653
01655
01666
01675 bool operator==(typeNode & second) {
01676 return equal_to(this, & second, true, true); }
01677
01687 bool operator<=(typeNode & second) {
01688 return equal_to(this, & second, false, false); }
01689
01697 bool operator!=(typeNode & second) {
01698 return ! ( (*this) == second ); }
01699
01701
01723 static bool equal_to(typeNode * first, typeNode * second,
01724 bool strict_toplevel, bool strict_recursive);
01725
01739 virtual bool qualified_equal_to(typeNode * other,
01740 bool strict_toplevel, bool strict_recursive);
01741
01751 typeNode * unwind_tdefs(Type_qualifiers & the_tq);
01752
01753 typeNode * no_tdef_type();
01754
01761 typeNode * follow_tdefs();
01762
01769
01770 virtual bool is_int() const { return false; }
01771 virtual bool is_char() const { return false; }
01772 virtual bool is_float() const { return false; }
01773 virtual bool is_void() const { return false; }
01774 virtual bool is_ellipsis() const { return false; }
01775
01776 virtual bool is_integer() const { return false; }
01777 virtual bool is_arithmetic() const { return false; }
01778 virtual bool is_scalar() const { return false; }
01779 virtual bool is_aggregate() const { return false; }
01780 virtual bool is_derived() const { return false; }
01781 virtual bool is_pointer() const { return false; }
01782
01784
01791 virtual typeNode * usual_unary_conversion_type() { return this; }
01792
01793
01794
01795 virtual typeNode * base_type(bool TdefIndir) const {
01796 return (typeNode *)this; }
01797
01798
01799
01800 typeNode * deep_base_type();
01801
01802
01803
01804
01805 virtual void dataflow(FlowVal * v, FlowProblem & fp) { }
01806
01807
01808
01809 virtual void output(output_context & ct, Node * par);
01810
01823 virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q) =0;
01824 };
01825
01835 class primNode : public typeNode
01836 {
01837
01838 private:
01839
01845 basic_type _basic;
01846
01847 public:
01848
01857 primNode(Type_qualifiers tq, basic_type basic,
01858 const Coord coord = Coord::Unknown);
01859
01869 primNode(Type_qualifiers tq,
01870 const Coord coord = Coord::Unknown);
01871
01880 primNode(const Coord coord);
01881
01890 primNode(basic_type basic, const Coord coord = Coord::Unknown);
01891
01897 virtual ~primNode();
01898
01903
01904
01905
01906 inline const basic_type & basic() const { return _basic; }
01907 inline basic_type & basic() { return _basic; }
01908 inline void basic(basic_type basic) { _basic = basic; }
01909
01911
01916
01917
01918 void finish();
01919 primNode * finish_and();
01920
01921
01922
01923 void merge_in(primNode * other);
01924 primNode * merge_in_and(primNode * other);
01925
01927
01934
01935 virtual bool is_int() const { return _basic.is_int(); }
01936 virtual bool is_char() const { return _basic.is_char(); }
01937 virtual bool is_float() const { return _basic.is_float(); }
01938 virtual bool is_void() const { return _basic.is_void(); }
01939 virtual bool is_ellipsis() const { return _basic.is_ellipsis(); }
01940
01941 virtual bool is_integer() const { return _basic.is_integer(); }
01942 virtual bool is_arithmetic() const { return _basic.is_arithmetic(); }
01943 virtual bool is_scalar() const { return _basic.is_scalar(); }
01944
01946
01947
01948
01949 bool qualified_equal_to(typeNode * node2,
01950 bool strict_toplevel, bool strict_recursive);
01951
01956
01957 virtual void visit(Visitor * the_visitor);
01958 virtual void walk(Walker & the_walker);
01959 virtual Node * change(Changer & the_changer, bool redispatch = false);
01960
01962
01963
01964
01965 virtual Node * clone() const { return new primNode ( *this ); }
01966
01967
01968
01969 virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
01970 };
01971
01988 class tdefNode : public typeNode
01989 {
01990
01991 private:
01992
01998 string _name;
01999
02007 REF typeNode * _def;
02008
02009 public:
02010
02020 tdefNode(Type_qualifiers tq, const char * name,
02021 const Coord coord = Coord::Unknown);
02022
02034 tdefNode(idNode * the_id, Type_qualifiers tq, typeNode * the_type);
02035
02041 virtual ~tdefNode();
02042
02047
02050 inline string & name() { return _name; }
02051
02054 inline void name(string name) { _name = name; }
02055
02058 inline typeNode * def() const { return _def; }
02059
02065 inline void def(typeNode * d) { _def = d; }
02066
02068
02069
02070
02071 typeNode * base_type(bool TdefIndir) const;
02072
02073
02074
02079
02080 virtual void visit(Visitor * the_visitor);
02081 virtual void walk(Walker & the_walker);
02082 virtual Node * change(Changer & the_changer, bool redispatch = false);
02083
02085
02086
02087
02088 virtual Node * clone() const { return new tdefNode ( *this ); }
02089
02090
02091
02092 virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02093 };
02094
02104 class ptrNode : public typeNode
02105 {
02106
02107 private:
02108
02109 public:
02110
02120 ptrNode(Type_qualifiers tq, typeNode * the_type,
02121 const Coord coord = Coord::Unknown);
02122
02128 virtual ~ptrNode();
02129
02130
02131
02132 bool qualified_equal_to(typeNode * node2,
02133 bool strict_toplevel, bool strict_recursive);
02134
02141
02142 virtual bool is_scalar() const { return true; }
02143 virtual bool is_derived() const { return true; }
02144 virtual bool is_pointer() const { return true; }
02145
02147
02152
02153 virtual void visit(Visitor * the_visitor);
02154 virtual void walk(Walker & the_walker);
02155 virtual Node * change(Changer & the_changer, bool redispatch = false);
02156
02158
02159
02160
02161 virtual Node * clone() const { return new ptrNode ( *this ); }
02162
02163
02164
02165 virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02166 };
02167
02190 class arrayNode : public typeNode
02191 {
02192
02193 private:
02194
02204 TREE exprNode * _dim;
02205
02214 int _size;
02215
02216 public:
02217
02228 arrayNode(Type_qualifiers tq, typeNode * the_type, exprNode * the_dim,
02229 const Coord coord = Coord::Unknown);
02230
02236 virtual ~arrayNode();
02237
02242
02243 inline exprNode * dim() const { return _dim; }
02244 inline exprNode * get_dim() { exprNode * out = _dim; _dim = 0; return out; }
02245 inline void dim(exprNode * the_dim) { _dim = the_dim; }
02246
02247 inline int size() const { return _size; }
02248 inline void size(int the_size) { _size = the_size; }
02249
02251
02258
02259 virtual bool is_aggregate() const { return true; }
02260 virtual bool is_derived() const { return true; }
02261 virtual bool is_pointer() const { return true; }
02262
02263
02264
02265
02266 virtual bool is_scalar() const { return _dim == NULL; }
02267
02268 bool is_string() const;
02269
02271
02272
02273
02274 bool qualified_equal_to(typeNode * node2,
02275 bool strict_toplevel, bool strict_recursive);
02276
02281
02282 virtual void visit(Visitor * the_visitor);
02283 virtual void walk(Walker & the_walker);
02284 virtual Node * change(Changer & the_changer, bool redispatch = false);
02285
02287
02288
02289
02290 virtual Node * clone() const { return new arrayNode ( *this ); }
02291
02292
02293
02294 virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02295 };
02296
02307 class funcNode : public typeNode
02308 {
02309
02310 private:
02311
02330 TREE decl_list _args;
02331
02336 bool _is_knr;
02337
02338 public:
02339
02350 funcNode(Type_qualifiers tq, decl_list * args, typeNode * returns,
02351 const Coord coord = Coord::Unknown);
02352
02358 virtual ~funcNode();
02359
02364
02365 inline decl_list & args() { return _args; }
02366 inline const decl_list & args() const { return _args; }
02367
02368 inline typeNode * returns() const { return type(); }
02369 inline void returns(typeNode * returns) { type(returns); }
02370
02371 inline bool is_knr() const { return _is_knr; }
02372 inline void is_knr (bool v) { _is_knr = v; }
02373
02375
02376
02377
02378 bool qualified_equal_to(typeNode * node2,
02379 bool strict_toplevel, bool strict_recursive);
02380
02387
02388 virtual bool is_derived() const { return true; }
02389 virtual bool is_pointer() const { return true; }
02390
02392
02397 bool is_void_args();
02398
02406 bool check_conversions();
02407
02417 bool is_compatible_with(funcNode * nfunc);
02418
02430 void add_parameter_types(decl_list * types);
02431
02436
02437 virtual void visit(Visitor * the_visitor);
02438 virtual void walk(Walker & the_walker);
02439 virtual Node * change(Changer & the_changer, bool redispatch = false);
02440
02442
02443
02444
02445 virtual Node * clone() const { return new funcNode ( *this ); }
02446
02447
02448
02449 virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02450 };
02451
02485 class sueNode : public typeNode
02486 {
02487
02488 private:
02489
02495 REF suespecNode * _spec;
02496
02501 bool _elaborated;
02502
02503 public:
02504
02513 sueNode(NodeType typ, const Coord coord);
02514
02520 virtual ~sueNode();
02521
02526
02527 inline bool elaborated() const { return _elaborated; }
02528 inline void elaborated(bool elab) { _elaborated = elab; }
02529
02530 inline suespecNode * spec() const { return _spec; }
02531 inline void spec(suespecNode * s) { _spec = s; }
02532
02534
02538
02539
02540
02541 void set_name_fields(idNode *id, decl_list * fields,
02542 const Coord left_coord,
02543 const Coord the_right_coord);
02544
02545 sueNode * set_name_fields_and(idNode *id, decl_list * fields,
02546 const Coord left_coord,
02547 const Coord the_right_coord);
02548
02549
02550
02551 void set_name(idNode * id, const Coord coord);
02552 sueNode * set_name_and(idNode * id, const Coord coord);
02553
02554
02555
02556 void force_new(const Coord coord);
02557 sueNode * force_new_and(const Coord coord);
02558
02559
02560
02561 bool same_tag_as(sueNode * other);
02562 void tag_conflict(sueNode * new_sue);
02563
02565
02566
02567
02568 bool qualified_equal_to(typeNode * node2,
02569 bool strict_toplevel, bool strict_recursive);
02570
02571
02572
02573
02574
02575 virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02576 };
02577
02592 class structNode : public sueNode
02593 {
02594
02595 private:
02596
02597 public:
02598
02607 structNode(const Coord coord = Coord::Unknown);
02608
02614 virtual ~structNode();
02615
02622
02623 virtual bool is_aggregate() const { return true; }
02624
02626
02631
02632 virtual void visit(Visitor * the_visitor);
02633 virtual void walk(Walker & the_walker);
02634 virtual Node * change(Changer & the_changer, bool redispatch = false);
02635
02637
02638
02639
02640 virtual Node * clone() const { return new structNode ( *this ); }
02641 };
02642
02657 class unionNode : public sueNode
02658 {
02659
02660 private:
02661
02662 public:
02663
02672 unionNode(const Coord coord = Coord::Unknown);
02673
02679 virtual ~unionNode();
02680
02685
02686 virtual void visit(Visitor * the_visitor);
02687 virtual void walk(Walker & the_walker);
02688 virtual Node * change(Changer & the_changer, bool redispatch = false);
02689
02691
02692
02693
02694 virtual Node * clone() const { return new unionNode ( *this ); }
02695 };
02696
02711 class enumNode : public sueNode
02712 {
02713
02714 private:
02715
02716 public:
02717
02726 enumNode(const Coord coord = Coord::Unknown);
02727
02740 enumNode(idNode *id, decl_list * values,
02741 const Coord enum_coord, const Coord left_coord,
02742 const Coord right_coord);
02743
02749 virtual ~enumNode();
02750
02757
02758 virtual bool is_int() const { return true; }
02759 virtual bool is_integer() const { return true; }
02760 virtual bool is_arithmetic() const { return true; }
02761 virtual bool is_scalar() const { return true; }
02762
02764
02769
02770 virtual void visit(Visitor * the_visitor);
02771 virtual void walk(Walker & the_walker);
02772 virtual Node * change(Changer & the_changer, bool redispatch = false);
02773
02775
02776
02777
02778 virtual Node * clone() const { return new enumNode ( *this ); }
02779 };
02780
02797 class suespecNode : public typeNode
02798 {
02799
02800 private:
02801
02809 string _name;
02810
02817 TREE decl_list _fields;
02818
02826 bool _complete;
02827
02835 bool _visited;
02836
02844 bool _already_output;
02845
02856 int _scope_output;
02857
02862 int _size;
02863
02868 int _align;
02869
02875 NodeType _owner;
02876
02877 public:
02878
02891 suespecNode(const char * name, decl_list * fields, NodeType owner,
02892 unitNode * the_unit,
02893 const Coord coord);
02894
02900 virtual ~suespecNode();
02901
02906
02907 inline bool complete() const { return _complete; }
02908 inline void complete(bool comp) { _complete = comp; }
02909
02910 inline bool visited() const { return _visited; }
02911 inline void visited(bool v) { _visited = v; }
02912
02913 inline bool already_output() const { return _already_output; }
02914 inline void already_output(bool v) { _already_output = v; }
02915
02916 inline bool scope_output() const { return _scope_output; }
02917 inline void scope_output(int v) { _scope_output = v; }
02918
02919 inline int size() const { return _size; }
02920 inline void size(int size) { _size = size; }
02921
02922 inline int align() const { return _align; }
02923 inline void align(int align) { _align = align; }
02924
02925 inline string & name() { return _name; }
02926 inline void name(string name) { _name = name; }
02927
02928 inline decl_list & fields() { return _fields; }
02929 inline const decl_list & fields() const { return _fields; }
02930
02931 inline NodeType owner() const { return _owner; }
02932
02934
02935
02936
02947 bool same_tag_as(suespecNode * other);
02948
02957 void update(decl_list * fields, sueNode * sue, const Coord right);
02958
02968 declNode * find_field(const string & name);
02969
02974
02975 virtual void visit(Visitor * the_visitor);
02976 virtual void walk(Walker & the_walker);
02977 virtual Node * change(Changer & the_changer, bool redispatch = false);
02978
02980
02981
02982
02983 virtual Node * clone() const { return new suespecNode ( *this ); }
02984
02985
02986
02987 virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02988 };
02989
02990
03008 class exprNode : public Node
03009 {
03010 public:
03011
03024 static exprNode * integral_promotions(exprNode * old_expr);
03025
03040 static pair<exprNode *, exprNode *>
03041 usual_arithmetic_conversions(exprNode * left,
03042 exprNode * right);
03043
03044 private:
03045
03050 TREE typeNode * _type;
03051
03059 constant _value;
03060
03061 public:
03062
03072 exprNode(NodeType typ, typeNode * type, const Coord coord);
03073
03079 virtual ~exprNode();
03080
03085
03086 inline typeNode * type() const { return _type; }
03087 inline typeNode * get_type() { typeNode * out = _type; _type = 0; return out; }
03088 inline void type(typeNode *type) { _type = type; }
03089
03090 inline const constant & value() const { return _value; }
03091 inline constant & value() { return _value; }
03092 inline void value(const constant & newval) { _value = newval; }
03093
03095
03096
03097
03098 virtual typeNode * base_type(bool TdefIndir) const;
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03123 virtual void eval() =0;
03124
03133 virtual bool is_lvalue() { return true; }
03134
03135 typeNode * no_tdef_type() { return type()->follow_tdefs(); }
03136
03137
03138
03139 virtual void output(output_context & ct, Node * par);
03140
03161 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc) =0;
03162
03175 virtual int precedence(Assoc & assoc);
03176
03189 bool parens(int outer_prec, Assoc outer_assoc);
03190 };
03191
03201 class constNode : public exprNode
03202 {
03203
03204 private:
03205
03215 string _text;
03216
03217 public:
03218
03228 constNode(constant value, const char * text = "",
03229 const Coord coord = Coord::Unknown);
03230
03236 virtual ~constNode();
03237
03242
03243 inline string & text() { return _text; }
03244
03246
03251 typeNode * usual_unary_conversion_type()
03252 { return type()->usual_unary_conversion_type(); }
03253
03254
03255
03256 virtual void eval();
03257
03262
03263 virtual void visit(Visitor * the_visitor);
03264 virtual void walk(Walker & the_walker);
03265 virtual Node * change(Changer & the_changer, bool redispatch = false);
03266
03268
03269
03270
03271 virtual void dataflow(FlowVal * v, FlowProblem & fp);
03272
03273
03274
03275 virtual Node * clone() const { return new constNode ( *this ); }
03276
03277
03278
03279 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03280 };
03281
03293 class idNode : public exprNode
03294 {
03295
03296 private:
03297
03302 string _name;
03303
03311 REF declNode * _decl;
03312
03313 public:
03314
03323 idNode(const char * text, const Coord coord = Coord::Unknown);
03324
03334 idNode(declNode * the_decl, const Coord coord = Coord::Unknown);
03335
03341 virtual ~idNode();
03342
03347
03348 inline string & name() { return _name; }
03349 inline const string & name() const { return _name; }
03350 inline void name(string nm) { _name = nm; }
03351
03352 inline declNode * decl() const { return _decl; }
03353 inline void decl(declNode *decl) { _decl = decl; }
03354
03356
03357
03358
03359 typeNode * base_type(bool TdefIndir) const;
03360
03361
03362
03363
03364
03365
03366
03367
03368 virtual void eval();
03369
03374
03375 virtual void visit(Visitor * the_visitor);
03376 virtual void walk(Walker & the_walker);
03377 virtual Node * change(Changer & the_changer, bool redispatch = false);
03378
03380
03381
03382
03383 virtual void dataflow(FlowVal * v, FlowProblem & fp);
03384
03385
03386
03387 virtual Node * clone() const { return new idNode ( *this ); }
03388
03389
03390
03391 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03392 };
03393
03411 class binaryNode : public exprNode
03412 {
03413
03414 private:
03415
03423 Operator * _op;
03424
03427 TREE exprNode * _left;
03428
03431 TREE exprNode * _right;
03432
03433 public:
03434
03453 binaryNode(unsigned int op_id, exprNode * left, exprNode * right,
03454 const Coord coord = Coord::Unknown);
03455
03461 virtual ~binaryNode();
03462
03467
03468 inline Operator * op() const { return _op; }
03469 inline void op(Operator * op) { _op = op; }
03470
03471 inline exprNode * left() const { return _left; }
03472 inline exprNode * get_left() { exprNode * out = _left; _left = 0; return out; }
03473 inline void left(exprNode * left) { _left = left; }
03474
03475 inline exprNode * right() const { return _right; }
03476 inline exprNode * get_right() { exprNode * out = _right; _right = 0; return out; }
03477 inline void right(exprNode * right) { _right = right; }
03478
03480
03481
03482
03483
03484
03485
03486
03487 virtual void eval();
03488
03493
03494 virtual void visit(Visitor * the_visitor);
03495 virtual void walk(Walker & the_walker);
03496 virtual Node * change(Changer & the_changer, bool redispatch = false);
03497
03499
03500
03501
03502 virtual void dataflow(FlowVal * v, FlowProblem & fp);
03503
03504
03505
03506 virtual Node * clone() const { return new binaryNode ( *this ); }
03507
03508
03509
03510 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03511 virtual int precedence(Assoc & assoc);
03512 };
03513
03522 class unaryNode : public exprNode
03523 {
03524
03525 private:
03526
03534 Operator * _op;
03535
03538 TREE exprNode * _expr;
03539
03544 TREE typeNode * _sizeof_type;
03545
03546 public:
03547
03565 unaryNode(unsigned int op_id, exprNode * expr,
03566 const Coord coord = Coord::Unknown);
03567
03576 unaryNode(unsigned int op_id, typeNode * the_type,
03577 const Coord coord = Coord::Unknown);
03578
03584 virtual ~unaryNode();
03585
03590
03591 inline Operator * op() const { return _op; }
03592 inline void op(Operator * op) { _op = op; }
03593
03594 inline exprNode * expr() const { return _expr; }
03595 inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
03596 inline void expr(exprNode * expr) { _expr = expr; }
03597
03598
03599
03600 inline typeNode * sizeof_type() const { return _sizeof_type; }
03601 inline typeNode * get_sizeof_type()
03602 { typeNode * out = _sizeof_type; _sizeof_type = 0; return out; }
03603 inline void sizeof_type(typeNode *sizeof_type)
03604 { _sizeof_type = sizeof_type; }
03605
03607
03608
03609
03610
03611
03612
03613
03614 virtual void eval();
03615
03620
03621 virtual void visit(Visitor * the_visitor);
03622 virtual void walk(Walker & the_walker);
03623 virtual Node * change(Changer & the_changer, bool redispatch = false);
03624
03626
03627
03628
03629 virtual void dataflow(FlowVal * v, FlowProblem & fp);
03630
03631
03632
03633 virtual Node * clone() const { return new unaryNode ( *this ); }
03634
03635
03636
03637 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03638 virtual int precedence(Assoc & assoc);
03639 };
03640
03656 class castNode : public exprNode
03657 {
03658
03659 private:
03660
03663 TREE exprNode * _expr;
03664
03671 bool _implicit;
03672
03673 public:
03674
03684 castNode(typeNode * type, exprNode * expr, bool implicit = false,
03685 const Coord coord = Coord::Unknown);
03686
03692 virtual ~castNode();
03693
03698
03699 inline exprNode * expr() const { return _expr; }
03700 inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
03701 inline void expr(exprNode * expr) { _expr = expr; }
03702
03703 inline bool is_implicit() const { return _implicit; }
03705
03706
03707
03708 virtual void eval();
03709
03714
03715 virtual void visit(Visitor * the_visitor);
03716 virtual void walk(Walker & the_walker);
03717 virtual Node * change(Changer & the_changer, bool redispatch = false);
03718
03720
03721
03722
03723 virtual void dataflow(FlowVal * v, FlowProblem & fp);
03724
03725
03726
03727 virtual Node * clone() const { return new castNode ( *this ); }
03728
03729
03730
03731 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03732 virtual int precedence(Assoc & assoc);
03733 };
03734
03735
03745 class commaNode : public exprNode
03746 {
03747
03748 private:
03749
03755 TREE expr_list _exprs;
03756
03757 public:
03758
03767 commaNode(expr_list * exprs, const Coord coord = Coord::Unknown);
03768
03775 commaNode(const Coord coord = Coord::Unknown);
03776
03782 virtual ~commaNode();
03783
03788
03789 inline expr_list & exprs() { return _exprs; }
03790 inline const expr_list & exprs() const { return _exprs; }
03791
03793
03794
03795
03796 typeNode * base_type(bool TdefIndir) const;
03797
03798
03799
03800 virtual void eval();
03801
03806
03807 virtual void visit(Visitor * the_visitor);
03808 virtual void walk(Walker & the_walker);
03809 virtual Node * change(Changer & the_changer, bool redispatch = false);
03810
03812
03813
03814
03815 virtual void dataflow(FlowVal * v, FlowProblem & fp);
03816
03817
03818
03819 virtual Node * clone() const { return new commaNode ( *this ); }
03820
03821
03822
03823 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03824 virtual int precedence(Assoc & assoc);
03825 };
03826
03834 class ternaryNode : public exprNode
03835 {
03836
03837 private:
03838
03841 TREE exprNode * _cond;
03842
03845 TREE exprNode * _true_br;
03846
03849 TREE exprNode * _false_br;
03850
03853 Coord _colon_coord;
03854
03855 public:
03856
03868 ternaryNode(exprNode * cond, exprNode * true_br, exprNode * false_br,
03869 const Coord qmark_coord = Coord::Unknown,
03870 const Coord colon_coord = Coord::Unknown);
03871
03877 virtual ~ternaryNode();
03878
03883
03884 inline exprNode * cond() const { return _cond; }
03885 inline exprNode * get_cond() { exprNode * out = _cond; _cond = 0; return out; }
03886 inline void cond(exprNode * cond) { _cond = cond; }
03887
03888 inline exprNode * true_br() const { return _true_br; }
03889 inline exprNode * get_true_br() { exprNode * out = _true_br; _true_br = 0; return out; }
03890 inline void true_br(exprNode * true_br) { _true_br = true_br; }
03891
03892 inline exprNode * false_br() const { return _false_br; }
03893 inline exprNode * get_false_br() { exprNode * out = _false_br; _false_br = 0; return out; }
03894 inline void false_br(exprNode * false_br) { _false_br = false_br; }
03895
03897
03898
03899
03900 virtual void eval();
03901
03906
03907 virtual void visit(Visitor * the_visitor);
03908 virtual void walk(Walker & the_walker);
03909 virtual Node * change(Changer & the_changer, bool redispatch = false);
03910
03912
03913
03914
03915 virtual void dataflow(FlowVal * v, FlowProblem & fp);
03916
03917
03918
03919 virtual Node * clone() const { return new ternaryNode ( *this ); }
03920
03921
03922
03923 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03924 virtual int precedence(Assoc & assoc);
03925 };
03926
03954 class callNode : public exprNode
03955 {
03956
03957 private:
03958
03961 TREE exprNode * _name;
03962
03968 TREE expr_list _args;
03969
03979 REF procNode * _proc;
03980
03981 public:
03982
03993 callNode(exprNode * name, expr_list * args,
03994 const Coord coord = Coord::Unknown);
03995
04001 virtual ~callNode();
04002
04007
04008 inline exprNode * name() const { return _name; }
04009 inline exprNode * get_name() { exprNode * out = _name; _name = 0; return out; }
04010 inline void name(exprNode * name) { _name = name; }
04011
04012 inline expr_list & args() { return _args; }
04013 inline const expr_list & args() const { return _args; }
04014
04015 inline procNode * proc() const { return _proc; }
04016 inline void proc(procNode * proc) { _proc = proc; }
04017
04019
04020
04021
04022 typeNode * base_type(bool TdefIndir) const;
04023
04024
04025
04026
04027
04028
04029
04030 virtual void eval();
04031
04036
04037 virtual void visit(Visitor * the_visitor);
04038 virtual void walk(Walker & the_walker);
04039 virtual Node * change(Changer & the_changer, bool redispatch = false);
04040
04042
04043
04044
04045 virtual void dataflow(FlowVal * v, FlowProblem & fp);
04046
04047
04048
04049 virtual Node * clone() const { return new callNode ( *this ); }
04050
04051
04052
04053 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
04054 };
04055
04071 class initializerNode : public exprNode
04072 {
04073
04074 private:
04075
04076 TREE expr_list _exprs;
04077
04078 public:
04079
04080
04081
04082 initializerNode(expr_list * exprs, const Coord coord = Coord::Unknown);
04083
04089 virtual ~initializerNode();
04090
04095
04096 inline expr_list & exprs() { return _exprs; }
04097 inline const expr_list & exprs() const { return _exprs; }
04098 inline void add_expr(exprNode * the_expr) { _exprs.push_back(the_expr); }
04099
04101
04102
04103
04104 virtual void eval();
04105
04110
04111 virtual void visit(Visitor * the_visitor);
04112 virtual void walk(Walker & the_walker);
04113 virtual Node * change(Changer & the_changer, bool redispatch = false);
04114
04116
04117
04118
04119 virtual void dataflow(FlowVal * v, FlowProblem & fp);
04120
04121
04122
04123 virtual Node * clone() const { return new initializerNode ( *this ); }
04124
04125
04126
04127 virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
04128 };
04129
04137 class stmtNode : public Node
04138 {
04139
04140 private:
04141
04147 FlowVal * _at_exit;
04148
04157 string _comment;
04158
04165 text_list _pragmas;
04166
04167 public:
04168
04177 stmtNode(NodeType typ, const Coord coord);
04178
04184 virtual ~stmtNode();
04185
04190
04191 inline string & comment() { return _comment; }
04192
04193
04194
04195 inline FlowVal * at_exit() const { return _at_exit; }
04196 inline void at_exit(FlowVal * ae) { _at_exit = ae; }
04197
04198
04199
04200 inline text_list & pragmas() { return _pragmas; }
04201
04203
04204
04205
04206 virtual void output(output_context & ct, Node * par);
04207
04218 virtual void output_stmt(output_context & ct, Node * par) =0;
04219
04220 void output_comment(output_context & ct);
04221 };
04222
04241 class blockNode : public stmtNode
04242 {
04243
04244 public:
04245
04275 static blockNode * toBlock(stmtNode * stmt, Coord coord);
04276
04277 private:
04278
04283 TREE decl_list _decls;
04284
04289 TREE stmt_list _stmts;
04290
04293 Coord _right_brace;
04294
04295
04296 public:
04297
04310 blockNode(decl_list * decls, stmt_list * stmts,
04311 const Coord left_coord = Coord::Unknown,
04312 const Coord right_brace = Coord::Unknown);
04313
04319 virtual ~blockNode();
04320
04325
04326 inline decl_list & decls() { return _decls; }
04327 inline const decl_list & decls() const { return _decls; }
04328
04329 inline stmt_list & stmts() { return _stmts; }
04330 inline const stmt_list & stmts() const { return _stmts; }
04331
04332 inline Coord right_brace() const { return _right_brace; }
04333 inline void right_brace(const Coord right_brace) { _right_brace = right_brace; }
04334
04336
04337
04338
04339 typeNode * base_type(bool TdefIndir) const;
04340
04345
04346 virtual void visit(Visitor * the_visitor);
04347 virtual void walk(Walker & the_walker);
04348 virtual Node * change(Changer & the_changer, bool redispatch = false);
04349
04351
04352
04353
04354 virtual void dataflow(FlowVal * v, FlowProblem & fp);
04355
04356
04357
04358 virtual Node * clone() const { return new blockNode ( *this ); }
04359
04360
04361 virtual void output_stmt(output_context & ct, Node * par);
04362
04363 };
04364
04365 class algorithm_info
04366 {
04367 };
04368
04394 class basicblockNode : public blockNode {
04395
04396 private:
04397
04400 basicblock_list _preds;
04401
04404 basicblock_list _succs;
04405
04410 basicblockNode * _parent;
04411
04417 basicblock_list _children;
04418
04424 algorithm_info * _info;
04425
04432 int _dfn;
04433
04440 FlowVal * _at_entry;
04441
04449 FlowVal * _at_exit;
04450
04451 public:
04452
04464 basicblockNode(decl_list * decls, stmt_list * stmts,
04465 const Coord left_coord = Coord::Unknown,
04466 const Coord right_brace = Coord::Unknown);
04467
04473 virtual ~basicblockNode();
04474
04479
04480 inline basicblock_list & preds() { return _preds; }
04481 inline const basicblock_list & preds() const { return _preds; }
04482
04483 inline basicblock_list & succs() { return _succs; }
04484 inline const basicblock_list & succs() const { return _succs; }
04485
04486 inline basicblockNode * parent() const { return _parent; }
04487 inline void parent(basicblockNode *par) { _parent = par; }
04488
04489 inline basicblock_list & children() { return _children; }
04490 inline const basicblock_list & children() const { return _children; }
04491
04492 inline algorithm_info * info() const { return _info; }
04493 inline void info(algorithm_info * i) { _info = i; }
04494
04495 inline int dfn() const { return _dfn; }
04496 inline void dfn(int d) { _dfn = d; }
04497
04498
04499
04500 inline FlowVal * at_entry() const { return _at_entry; }
04501 inline void at_entry(FlowVal * ae) { _at_entry = ae; }
04502
04503 inline FlowVal * at_exit() const { return _at_exit; }
04504 inline void at_exit(FlowVal * ae) { _at_exit = ae; }
04505
04507
04512
04513 virtual void visit(Visitor * the_visitor);
04514 virtual void walk(Walker & the_walker);
04515 virtual Node * change(Changer & the_changer, bool redispatch = false);
04516
04518
04519
04520
04521
04522
04523 virtual Node * clone() const { return new basicblockNode ( *this ); }
04524
04525 };
04526
04527
04528
04538 class exprstmtNode : public stmtNode
04539 {
04540
04541 private:
04542
04545 TREE exprNode * _expr;
04546
04547 public:
04548
04555 exprstmtNode(exprNode * expr);
04556
04562 virtual ~exprstmtNode();
04563
04568
04569 inline exprNode * expr() const { return _expr; }
04570 inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
04571 inline void expr(exprNode * expr) { _expr = expr; }
04572
04574
04575
04576
04577 typeNode * base_type(bool TdefIndir) const;
04578
04579
04584
04585 virtual void visit(Visitor * the_visitor);
04586 virtual void walk(Walker & the_walker);
04587 virtual Node * change(Changer & the_changer, bool redispatch = false);
04588
04590
04591
04592
04593 virtual void dataflow(FlowVal * v, FlowProblem & fp);
04594
04595
04596
04597 virtual Node * clone() const { return new exprstmtNode ( *this ); }
04598
04599
04600
04601 virtual void output_stmt(output_context & ct, Node * par);
04602 };
04603
04617 class targetNode : public stmtNode
04618 {
04619
04620 private:
04621
04624 TREE blockNode * _stmt;
04625
04631 FlowVal * _at_entry;
04632
04633 public:
04634
04642 targetNode(NodeType typ, stmtNode * stmt, const Coord coord);
04643
04649 virtual ~targetNode();
04650
04655
04656 inline blockNode * stmt() const { return _stmt; }
04657 inline blockNode * get_stmt() { blockNode * out = _stmt; _stmt = 0; return out; }
04658 inline void stmt(blockNode * stmt) { _stmt = stmt; }
04659
04660
04661
04662 inline FlowVal * at_entry() const { return _at_entry; }
04663 inline void at_entry(FlowVal * ae) { _at_entry = ae; }
04664
04666 };
04667
04682 class labelNode : public targetNode
04683 {
04684
04685 private:
04686
04689 string _name;
04690
04696 REF goto_list _references;
04697
04698 public:
04699
04709 labelNode(const char * name, stmtNode * stmt,
04710 const Coord coord = Coord::Unknown);
04711
04715
04724 labelNode(idNode * ident, stmtNode * stmt);
04725
04733 labelNode(idNode * ident);
04734
04736
04742 virtual ~labelNode();
04743
04748
04749 inline string & name() { return _name; }
04750 inline void name(string name) { _name = name; }
04751
04752 inline goto_list & references() { return _references; }
04753 inline const goto_list & references() const { return _references; }
04754
04756
04757
04758
04759 bool is_undeclared() const;
04760
04765
04766 virtual void visit(Visitor * the_visitor);
04767 virtual void walk(Walker & the_walker);
04768 virtual Node * change(Changer & the_changer, bool redispatch = false);
04769
04771
04772
04773
04774 virtual void dataflow(FlowVal * v, FlowProblem & fp);
04775
04776
04777
04778 virtual Node * clone() const { return new labelNode ( *this ); }
04779
04780
04781
04782 virtual void output_stmt(output_context & ct, Node * par);
04783 };
04784
04799 class caseNode : public targetNode
04800 {
04801
04802 private:
04803
04808 TREE exprNode * _expr;
04809
04816 REF switchNode * _container;
04817
04818 public:
04819
04830 caseNode(exprNode * expr, stmtNode * stmt, switchNode * container,
04831 const Coord coord = Coord::Unknown);
04832
04843 caseNode(exprNode * expr, stmtNode * stmt,
04844 const Coord coord = Coord::Unknown);
04845
04851 virtual ~caseNode();
04852
04857
04858 inline exprNode * expr() const { return _expr; }
04859 inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
04860 inline void expr(exprNode * expr) { _expr = expr; }
04861
04862 inline switchNode * container() const { return _container; }
04863 inline void container(switchNode * container) { _container = container; }
04864
04866
04871
04872 virtual void visit(Visitor * the_visitor);
04873 virtual void walk(Walker & the_walker);
04874 virtual Node * change(Changer & the_changer, bool redispatch = false);
04875
04877
04878
04879
04880 virtual void dataflow(FlowVal * v, FlowProblem & fp);
04881
04882
04883
04884 virtual Node * clone() const { return new caseNode ( *this ); }
04885
04886
04887
04888 virtual void output_stmt(output_context & ct, Node * par);
04889 };
04890
04903 class selectionNode : public stmtNode
04904 {
04905
04906 private:
04907
04910 TREE exprNode * _expr;
04911
04914 TREE blockNode * _stmt;
04915
04916 public:
04917
04929 selectionNode(NodeType typ, exprNode * expr, stmtNode * stmt,
04930 const Coord coord);
04931
04937 virtual ~selectionNode();
04938
04943
04944 inline exprNode * expr() const { return _expr; }
04945 inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
04946 inline void expr(exprNode * expr) { _expr = expr; }
04947
04948 inline blockNode * stmt() const { return _stmt; }
04949 inline blockNode * get_stmt() { blockNode * out = _stmt; _stmt = 0; return out; }
04950 inline void stmt(blockNode * stmt) { _stmt = stmt; }
04951
04953 };
04954
04966 class ifNode : public selectionNode
04967 {
04968
04969 private:
04970
04973 TREE blockNode * _false_br;
04974
04977 Coord _else_coord;
04978
04979 public:
04980
04993 ifNode(exprNode * expr, stmtNode * true_br, stmtNode * false_br,
04994 const Coord if_coord = Coord::Unknown,
04995 const Coord else_coord = Coord::Unknown);
04996
05002 virtual ~ifNode();
05003
05008
05009 inline blockNode * true_br() const { return selectionNode::stmt(); }
05010 inline blockNode * get_true_br() { return selectionNode::get_stmt(); }
05011 inline void true_br(blockNode * true_br) { selectionNode::stmt(true_br); }
05012
05013 inline blockNode * false_br() const { return _false_br; }
05014 inline blockNode * get_false_br() { blockNode * out = _false_br; _false_br = 0; return out; }
05015 inline void false_br(blockNode * false_br) { _false_br = false_br; }
05016
05017 inline Coord else_coord() const { return _else_coord; }
05018 inline void else_coord(const Coord the_coord) { _else_coord = the_coord; }
05019
05021
05026
05027 virtual void visit(Visitor * the_visitor);
05028 virtual void walk(Walker & the_walker);
05029 virtual Node * change(Changer & the_changer, bool redispatch = false);
05030
05032
05033
05034
05035 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05036
05037
05038
05039 virtual Node * clone() const { return new ifNode ( *this ); }
05040
05041
05042
05043 virtual void output_stmt(output_context & ct, Node * par);
05044 };
05045
05058 class switchNode : public selectionNode
05059 {
05060
05061 private:
05062
05068 REF target_list _cases;
05069
05072 bool _has_default;
05073
05079 FlowVal * _at_top;
05080
05081 public:
05082
05092 switchNode(exprNode * expr, stmtNode * stmt,
05093 const Coord coord = Coord::Unknown);
05094
05100 virtual ~switchNode();
05101
05106
05107 inline target_list & cases() { return _cases; }
05108 inline const target_list & cases() const { return _cases; }
05109
05110 inline bool has_default() const { return _has_default; }
05111 inline void has_default(bool has_default) { _has_default = has_default; }
05112
05113 inline FlowVal * at_top() const { return _at_top; }
05114 inline void at_top(FlowVal * at) { _at_top = at; }
05115
05117
05122
05123 virtual void visit(Visitor * the_visitor);
05124 virtual void walk(Walker & the_walker);
05125 virtual Node * change(Changer & the_changer, bool redispatch = false);
05126
05128
05129
05130
05131 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05132
05133
05134
05135 virtual Node * clone() const { return new switchNode ( *this ); }
05136
05137
05138
05139 virtual void output_stmt(output_context & ct, Node * par);
05140 };
05141
05150 class loopNode : public stmtNode
05151 {
05152
05153 private:
05154
05157 TREE exprNode * _cond;
05158
05161 TREE blockNode * _body;
05162
05168 FlowVal * _at_loop_head;
05169
05175 FlowVal * _at_loop_tail;
05176
05177 public:
05178
05190 loopNode(NodeType typ, exprNode * cond, stmtNode * body, const Coord coord);
05191
05199 loopNode(NodeType typ, const Coord coord);
05200
05206 virtual ~loopNode();
05207
05212
05213 inline exprNode * cond() const { return _cond; }
05214 inline exprNode * get_cond() { exprNode * out = _cond; _cond = 0; return out; }
05215 inline void cond(exprNode * cond) { _cond = cond; }
05216
05217 inline blockNode * body() const { return _body; }
05218 inline blockNode * get_body() { blockNode * out = _body; _body = 0; return out; }
05219 inline void body(blockNode * body) { _body = body; }
05220
05221
05222
05223 inline FlowVal * at_loop_head() const { return _at_loop_head; }
05224 inline void at_loop_head(FlowVal * ae) { _at_loop_head = ae; }
05225
05226 inline FlowVal * at_loop_tail() const { return _at_loop_tail; }
05227 inline void at_loop_tail(FlowVal * ae) { _at_loop_tail = ae; }
05228
05230 };
05231
05240 class whileNode : public loopNode
05241 {
05242
05243 private:
05244
05245 public:
05246
05255 whileNode(exprNode * cond, stmtNode * body,
05256 const Coord coord = Coord::Unknown);
05257
05263 virtual ~whileNode();
05264
05269
05270 virtual void visit(Visitor * the_visitor);
05271 virtual void walk(Walker & the_walker);
05272 virtual Node * change(Changer & the_changer, bool redispatch = false);
05273
05275
05276
05277
05278 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05279
05280
05281
05282 virtual Node * clone() const { return new whileNode ( *this ); }
05283
05284
05285
05286 virtual void output_stmt(output_context & ct, Node * par);
05287 };
05288
05297 class doNode : public loopNode
05298 {
05299
05300 private:
05301
05304 Coord _while_coord;
05305
05306 public:
05307
05317 doNode(stmtNode * body, exprNode * cond,
05318 const Coord coord = Coord::Unknown,
05319 const Coord while_coord = Coord::Unknown);
05320
05326 virtual ~doNode();
05327
05332
05333 inline Coord while_coord() const { return _while_coord; }
05334 inline void while_coord(const Coord while_coord) { _while_coord = while_coord; }
05335
05337
05342
05343 virtual void visit(Visitor * the_visitor);
05344 virtual void walk(Walker & the_walker);
05345 virtual Node * change(Changer & the_changer, bool redispatch = false);
05346
05348
05349
05350
05351 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05352
05353
05354
05355 virtual Node * clone() const { return new doNode ( *this ); }
05356
05357
05358
05359 virtual void output_stmt(output_context & ct, Node * par);
05360 };
05361
05383 class forNode : public loopNode
05384 {
05385
05386 private:
05387
05390 TREE exprNode * _init;
05391
05394 TREE exprNode * _next;
05395
05396
05397
05398
05399
05400 public:
05401
05412 forNode(exprNode * init, exprNode * cond, exprNode * next,
05413 stmtNode * body, const Coord coord = Coord::Unknown);
05414
05420 virtual ~forNode();
05421
05426
05427 inline exprNode * init() const { return _init; }
05428 inline exprNode * get_init() { exprNode * out = _init; _init = 0; return out; }
05429 inline void init(exprNode * init) { _init = init; }
05430
05431 inline exprNode * next() const { return _next; }
05432 inline exprNode * get_next() { exprNode * out = _next; _next = 0; return out; }
05433 inline void next(exprNode * next) { _next = next; }
05434
05436
05441
05442 virtual void visit(Visitor * the_visitor);
05443 virtual void walk(Walker & the_walker);
05444 virtual Node * change(Changer & the_changer, bool redispatch = false);
05445
05447
05448
05449
05450 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05451
05452
05453
05454 virtual Node * clone() const { return new forNode ( *this ); }
05455
05456
05457
05458 virtual void output_stmt(output_context & ct, Node * par);
05459 };
05460
05471 class jumpNode : public stmtNode
05472 {
05473
05474 private:
05475
05476 public:
05477
05487 jumpNode(NodeType typ, const Coord coord);
05488
05494 virtual ~jumpNode();
05495
05496 };
05497
05510 class gotoNode : public jumpNode
05511 {
05512
05513 private:
05514
05520 REF labelNode * _label;
05521
05524 string _name;
05525
05526 public:
05527
05536 gotoNode(labelNode * label, const Coord coord = Coord::Unknown);
05537
05547 gotoNode(idNode * ident, const Coord coord);
05548
05554 virtual ~gotoNode();
05555
05560
05561 inline labelNode * label() const { return _label; }
05562 inline void label(labelNode * label) { _label = label; }
05563
05564 inline string & name() { return _name; }
05565 inline void name(string name) { _name = name; }
05566
05568
05573
05574 virtual void visit(Visitor * the_visitor);
05575 virtual void walk(Walker & the_walker);
05576 virtual Node * change(Changer & the_changer, bool redispatch = false);
05577
05579
05580
05581
05582 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05583
05584
05585
05586 virtual Node * clone() const { return new gotoNode ( *this ); }
05587
05588
05589
05590 virtual void output_stmt(output_context & ct, Node * par);
05591 };
05592
05604 class continueNode : public jumpNode
05605 {
05606
05607 private:
05608
05614 REF loopNode * _container;
05615
05616 public:
05617
05626 continueNode(loopNode * container, const Coord coord = Coord::Unknown);
05627
05635 continueNode(const Coord coord = Coord::Unknown);
05636
05642 virtual ~continueNode();
05643
05648
05649 inline loopNode * container() const { return _container; }
05650 inline void container(loopNode * container) { _container = container; }
05651
05653
05658
05659 virtual void visit(Visitor * the_visitor);
05660 virtual void walk(Walker & the_walker);
05661 virtual Node * change(Changer & the_changer, bool redispatch = false);
05662
05664
05665
05666
05667 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05668
05669
05670
05671 virtual Node * clone() const { return new continueNode ( *this ); }
05672
05673
05674
05675 virtual void output_stmt(output_context & ct, Node * par);
05676 };
05677
05689 class breakNode : public jumpNode
05690 {
05691
05692 private:
05693
05700 REF stmtNode * _container;
05701
05702 public:
05703
05712 breakNode(stmtNode * container, const Coord coord = Coord::Unknown);
05713
05721 breakNode(const Coord coord = Coord::Unknown);
05722
05728 virtual ~breakNode();
05729
05734
05735 inline stmtNode * container() const { return _container; }
05736 inline void container(stmtNode * container) { _container = container; }
05737
05739
05744
05745 virtual void visit(Visitor * the_visitor);
05746 virtual void walk(Walker & the_walker);
05747 virtual Node * change(Changer & the_changer, bool redispatch = false);
05748
05750
05751
05752
05753 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05754
05755
05756
05757 virtual Node * clone() const { return new breakNode ( *this ); }
05758
05759
05760
05761 virtual void output_stmt(output_context & ct, Node * par);
05762 };
05763
05773 class returnNode : public jumpNode
05774 {
05775
05776 private:
05777
05780 TREE exprNode * _expr;
05781
05784 REF procNode * _proc;
05785
05786 public:
05787
05798 returnNode(exprNode * expr, procNode * proc,
05799 const Coord coord = Coord::Unknown);
05800
05806 virtual ~returnNode();
05807
05812
05813 inline exprNode * expr() const { return _expr; }
05814 inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
05815 inline void expr(exprNode * expr) { _expr = expr; }
05816
05817 inline procNode * proc() const { return _proc; }
05818 inline void proc(procNode * proc) { _proc = proc; }
05819
05821
05826
05827 virtual void visit(Visitor * the_visitor);
05828 virtual void walk(Walker & the_walker);
05829 virtual Node * change(Changer & the_changer, bool redispatch = false);
05830
05832
05833
05834
05835 virtual void dataflow(FlowVal * v, FlowProblem & fp);
05836
05837
05838
05839 virtual Node * clone() const { return new returnNode ( *this ); }
05840
05841
05842
05843 virtual void output_stmt(output_context & ct, Node * par);
05844 };
05845
05852 class attribNode : public stmtNode
05853 {
05854
05855 private:
05856
05857 TREE exprNode * _arg;
05858 string _name;
05859
05860 public:
05861
05862
05863
05864 attribNode(const char * name, exprNode * arg,
05865 const Coord coord = Coord::Unknown);
05866
05867
05868
05869 attribNode(idNode * id, exprNode * arg);
05870
05876 virtual ~attribNode();
05877
05882
05883 inline string & name() { return _name; }
05884 inline void name(string name) { _name = name; }
05885
05886 inline exprNode * arg() const { return _arg; }
05887 inline exprNode * get_arg() { exprNode * out = _arg; _arg = 0; return out; }
05888 inline void arg(exprNode * arg) { _arg = arg; }
05889
05891
05896
05897 virtual void visit(Visitor * the_visitor);
05898 virtual void walk(Walker & the_walker);
05899 virtual Node * change(Changer & the_changer, bool redispatch = false);
05900
05902
05903
05904
05905 virtual void dataflow(FlowVal * v, FlowProblem & fp) {}
05906
05907
05908
05909 virtual Node * clone() const { return new attribNode ( *this ); }
05910
05911
05912
05913 virtual void output_stmt(output_context & ct, Node * par);
05914 };
05915
05922 class textNode : public Node
05923 {
05924
05925 private:
05926
05927 string _text;
05928 bool _start_new_line;
05929
05930 public:
05931
05932
05933
05934 textNode(const char * text, bool start_new_line,
05935 const Coord coord = Coord::Unknown);
05936
05942 virtual ~textNode();
05943
05948
05949 inline string & text() { return _text; }
05950 inline void text(string text) { _text = text; }
05951
05952 inline bool start_new_line() const { return _start_new_line; }
05953 inline void start_new_line(bool start_new_line) { _start_new_line = start_new_line; }
05954
05956
05961
05962 virtual void visit(Visitor * the_visitor);
05963 virtual void walk(Walker & the_walker);
05964 virtual Node * change(Changer & the_changer, bool redispatch = false);
05965
05967
05968
05969
05970 virtual void dataflow(FlowVal * v, FlowProblem & fp) {}
05971
05972
05973
05974 virtual Node * clone() const { return new textNode ( *this ); }
05975
05976
05977
05978 virtual void output(output_context & ct, Node * par);
05979 };
05980
05981
05982
05983
05984
05985 template< class T >
05986 void dataflow_forward_list(list< T > & l, FlowVal * v, FlowProblem & fp)
05987 {
05988 for (list< T >::iterator p = l.begin();
05989 p != l.end();
05990 ++p)
05991 (*p)->dataflow(v, fp);
05992 }
05993
05994 template< class T >
05995 void dataflow_reverse_list(list< T > & l, FlowVal * v, FlowProblem & fp)
05996 {
05997 for (list< T >::reverse_iterator p = l.rbegin();
05998 p != l.rend();
05999 ++p)
06000 (*p)->dataflow(v, fp);
06001 }
06002
06003 template< class T >
06004 void output_list(list< T > & l, output_context & ct, Node * par)
06005 {
06006 for (list< T >::iterator p = l.begin();
06007 p != l.end();
06008 ++p)
06009 (*p)->output(ct, par);
06010 }
06011
06012 template< class T >
06013 void output_delim_list(list< T > & l, output_context & ct, Node * par, char delim)
06014 {
06015 for (list< T >::iterator p = l.begin();
06016 p != l.end();
06017 ++p)
06018 {
06019 if (p != l.begin()) {
06020 ct << delim;
06021 ct.space();
06022 ct.continue_line();
06023 }
06024 (*p)->output(ct, par);
06025 }
06026 }
06027
06028 template< class T >
06029 void delete_list(list< T > & l)
06030 {
06031 for (list< T >::iterator p = l.begin();
06032 p != l.end();
06033 ++p)
06034 delete (*p);
06035 }
06036
06037 #endif // CBZ_AST_H