C-Breeze
C Compiler Infrastructure

[ Project home page]

ast.h

Go to the documentation of this file.
00001 // $Id: ast.h,v 1.34 2003/11/11 19:23:14 benh Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 //  Adam Brown
00013 // 
00014 //  Permission is hereby granted, free of charge, to any person
00015 //  obtaining a copy of this software and associated documentation
00016 //  files (the "Software"), to deal in the Software without
00017 //  restriction, including without limitation the rights to use, copy,
00018 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00019 //  of the Software, and to permit persons to whom the Software is
00020 //  furnished to do so, subject to the following conditions:
00021 //  
00022 //  The above copyright notice and this permission notice shall be
00023 //  included in all copies or substantial portions of the Software.
00024 //  
00025 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00026 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00027 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00028 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00029 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00030 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00031 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00032 //  THE SOFTWARE.
00033 //
00034 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00035 //  Computer Science for inspiring parts of the C-Breeze design.
00036 //
00037 // ----------------------------------------------------------------------
00038 
00039 #ifndef CBZ_AST_H
00040 #define CBZ_AST_H
00041 
00042 
00043 // -- REF and TREE are empty defines for information only
00044 
00045 #define REF
00046 #define TREE
00047 
00074 class Node
00075 {
00076 
00077 private:
00078 
00084   NodeType     _typ;
00085 
00093   Coord        _coord;
00094 
00103   bool         _parenthesized;
00104 
00112   annote_list  _annotations;
00113 
00120   FlowVal * _gen;
00121 
00128   FlowVal * _kill;
00129 
00136 
00138   int _uid;
00139 
00141   static int _count;
00142 
00144   static int _t_count[50];
00145 
00147   static int _uid_count;
00148 
00150 
00151 public:
00152 
00160 
00162   static node_list nodes;
00163 
00165   static map <Node *, bool> deleted_nodes;
00166 
00168   bool mark;
00169 
00171 
00182   Node(NodeType typ, const Coord coord, bool parenthesized = false);
00183 
00193   Node(const Node & other);
00194 
00201   virtual ~Node();
00202 
00207 
00216   inline NodeType typ() const { return _typ; }
00217 
00230   inline Coord coord() const { return _coord; }
00231 
00243   inline void coord(const Coord coord) { _coord = coord; }
00244 
00250   inline bool parenthesized() const { return _parenthesized; }
00251 
00262   inline void parenthesized(bool paren) { _parenthesized = paren; }
00263 
00274   inline annote_list & annotations() { return _annotations; }
00275 
00284   inline FlowVal * gen() const { return _gen; }
00285 
00297   inline void gen(FlowVal * g) { _gen = g; }
00298 
00307   inline FlowVal * kill() const { return _kill; }
00308 
00320   inline void kill(FlowVal * k) { _kill = k; }
00321 
00323 
00330   static void report();
00331 
00342   virtual typeNode * type() const { return 0; }
00343 
00354   virtual typeNode * base_type(bool TdefIndir) const;
00355 
00359   typeNode * datatype() const;
00360 
00363   typeNode * datatype_superior() const;
00364 
00375 
00386   virtual void visit(Visitor * the_visitor) =0;
00387 
00396   virtual void walk(Walker & the_walker) =0;
00397 
00406   virtual Node * change(Changer & the_changer, bool redispatch = false) =0;
00407 
00409 
00421   virtual void dataflow(FlowVal * v, FlowProblem & fp) =0;
00422 
00430   virtual Node * clone() const =0;
00431 
00441   virtual void output(output_context & ct, Node * par) =0;
00442 };
00443 
00467 class unitNode : public Node
00468 {
00469 
00470 private:
00471 
00477   TREE def_list _defs;
00478 
00484   int _symbol_level;
00485 
00492   int _pragma_level;
00493 
00500   Identifiers_table * _types;
00501 
00508   Tags_table * _tags;
00509 
00514   string _input_file;
00515 
00521   string _output_file;
00522 
00527   string _obj_file;
00528 
00533   int _errors;
00534 
00539   int _warnings;
00540 
00546   TREE decl_list _undef_funcs; 
00547 
00548   // -- Maintain a global list of all struct/enum/union. This means
00549   // that the spec component of a sueNode is never a part of the TREE.
00550 
00559   TREE suespec_list _suespecs;
00560 
00566   FILE * _open_input_file(str_list * cpp_flags);
00567 
00574   text_list _pragmas;
00575   
00576 public:
00577 
00588   unitNode(string input_file, string output_file, string obj_file,
00589            const Coord coord = Coord::Unknown);
00590 
00596   virtual ~unitNode();
00597 
00606   void parse(str_list * cpp_flags, bool abortOnError = true);
00607 
00612   void fixup();
00613   
00618 
00619   // -- Fields
00620 
00621   inline def_list & defs() { return _defs; }
00622   inline const def_list & defs() const { return _defs; }
00623 
00624   inline int symbol_level() const { return _symbol_level; }
00625   inline int pragma_level() const { return _pragma_level; }
00626   inline Identifiers_table * types() const { return _types; }
00627   inline Tags_table * tags() const { return _tags; }
00628 
00629   inline string & input_file() { return _input_file; }
00630   inline string & output_file() { return _output_file; }
00631   inline string & obj_file() { return _obj_file; }
00632 
00633   inline int errors() const { return _errors; }
00634   inline void inc_errors() { ++_errors; }
00635 
00636   inline int warnings() const { return _warnings; }
00637   inline void inc_warnings() { ++_warnings; }
00638 
00639   inline decl_list & undef_funcs() { return _undef_funcs; }
00640 
00641   inline suespec_list & suespecs() { return _suespecs; }
00642   
00643   inline text_list & pragmas() { return _pragmas; }
00645 
00646   // -- Merge in definitions...
00647   // NOTE: the defs is deleted
00648 
00658   void merge_in(def_list * defs) {
00659    _defs.splice(_defs.end(), * defs); delete defs; }
00660 
00667   void enter_scope();
00668 
00675   void exit_scope();
00676 
00682   void enter_pragmas();
00683 
00689   void exit_pragmas();
00690 
00695 
00696   virtual void visit(Visitor * the_visitor);
00697   virtual void walk(Walker & the_walker);
00698   virtual Node * change(Changer & the_changer, bool redispatch = false);
00699 
00701 
00702   // -- Dataflow
00703 
00704   virtual void dataflow(FlowVal * v, FlowProblem & fp);
00705 
00706   // -- Clone
00707 
00708   virtual Node * clone() const { return new unitNode ( *this ); }
00709 
00710   // -- Output
00711 
00712   virtual void output(output_context & ct, Node * par);
00713 };
00714 
00723 class defNode : public Node
00724 {
00725 private:
00726 
00733   text_list _pragmas;
00734 
00735 public:
00736 
00742   defNode(NodeType typ, const Coord coord);
00743 
00748 
00749   inline text_list & pragmas() { return _pragmas; }
00750 
00752 
00757   virtual void grab_pragmas(void);
00758 
00764   virtual ~defNode();
00765 };
00766 
00777 class declNode : public defNode
00778 {
00779 
00780 public:
00781 
00790   typedef enum {
00791     UNKNOWN,  
00792     TOP,      
00794     BLOCK,    
00795     FORMAL,   
00796     SU,       
00797     ENUM,     
00798     PROC      
00799   } Decl_location;
00800 
00807   typedef enum {
00808     NONE, AUTO, EXTERN, REGISTER, STATIC, TYPEDEF
00809   } Storage_class;
00810 
00821 
00825   static string storage_class_name(Storage_class sc);
00826 
00830   static string decl_location_name(Decl_location dl);
00831 
00832   // @}
00833 
00834 private:
00835 
00840   TREE typeNode * _type;
00841 
00846   string _name;
00847 
00853   Decl_location _decl_location;
00854 
00860   Storage_class _storage_class;
00861 
00867   bool _is_redundant_extern;
00868 
00874   TREE exprNode * _init;
00875 
00881   TREE exprNode * _bitsize;
00882 
00888   int _references;
00889 
00895   REF id_list _ref_list;
00896 
00901   TREE attrib_list _attribs;
00902 
00903 public:
00904 
00932   declNode(const char * name, Storage_class sc, typeNode * the_type, 
00933            exprNode * init, exprNode * bitsize,
00934            const Coord coord = Coord::Unknown);
00935 
00942 
00956   declNode(idNode * id, Storage_class sc, typeNode * the_type, 
00957            exprNode * init, exprNode * bitsize);
00958 
00970   declNode(idNode * name, exprNode * value);
00971 
00981   declNode(typeNode * the_type, Storage_class sc);
00982 
00984 
00990   virtual ~declNode();
00991 
00996 
01000   inline typeNode * type() const { return _type; }
01001 
01006   inline typeNode * get_type() { typeNode * out = _type; _type = 0; return out; }
01007 
01013   inline void type(typeNode * the_type) { _type = the_type; }
01014 
01018   inline string & name() { return _name; }
01019 
01023   inline void name(string name) { _name = name; }
01024 
01028   inline Decl_location decl_location() const { return _decl_location; }
01029 
01033   inline void decl_location(Decl_location loc) { _decl_location = loc; }
01034 
01038   inline Storage_class storage_class() const { return _storage_class; }
01039 
01043   inline void storage_class(Storage_class sc) { _storage_class = sc; }
01044 
01051   inline bool is_redundant_extern() const { return _is_redundant_extern; }
01052 
01056   inline void set_redundant_extern(bool v) { _is_redundant_extern = v; }
01057 
01061   inline void inc_references() { _references++; }
01062 
01066   inline exprNode * init() const { return _init; }
01067 
01074   void init(exprNode * init) { _init = init; }
01075 
01078   inline exprNode * bitsize() const { return _bitsize; }
01079 
01085   inline void bitsize(exprNode * bitsize) { _bitsize = bitsize; }
01086 
01090   inline int references() const { return _references; }
01091 
01095   inline void references(int references) { _references = references; }
01096 
01097   inline id_list & ref_list() { return _ref_list; }
01098   inline const id_list & ref_list() const { return _ref_list; }
01099 
01103   inline attrib_list & attribs() { return _attribs; }
01104 
01108   inline const attrib_list & attribs() const { return _attribs; }
01109 
01113   void merge_attribs(attrib_list * attribs);
01114 
01116 
01142 
01143   //    Was SetDeclType in complex-types.c
01144 
01145   void       set_type(typeNode * the_type, Storage_class sc, ScopeState redeclare);
01146   declNode * set_type_and(typeNode * the_type, Storage_class sc, ScopeState redeclare);
01147   declNode * set_type_and(declNode * the_decltype, Storage_class sc, ScopeState redeclare);
01148 
01149   //    Was AppendDecl in complex-types.c
01150 
01151   void       inherit_type(decl_list * others, ScopeState redeclare);
01152   declNode * inherit_type_and(decl_list * others, ScopeState redeclare);
01153 
01154   //    Was ModifyType in complex-types.c
01155 
01156   void       modify_type(typeNode * the_type);
01157   declNode * modify_type_and(typeNode * the_type);
01158   declNode * modify_type_and(declNode * the_type);
01159 
01160   //    Was SetDeclInit in complex-types.c
01161 
01162   void       set_init(exprNode * init);
01163   declNode * set_init_and(exprNode * init);
01164 
01165   //    Was AddParameterTypes in procedure.c
01166 
01167   void       add_parameter_types(decl_list * types);
01168   declNode * add_parameter_types_and(decl_list * types);
01169 
01170   //    FinishDecl in complex-types.c
01171 
01172   void       finish(Storage_class sc);
01173   declNode * finish_and(Storage_class sc);
01174 
01176 
01177   // -- Data type base
01178 
01179   typeNode * base_type(bool TdefIndir) const;
01180 
01187   typeNode * no_tdef_type();
01188 
01197   virtual declNode * original() { return this; }
01198 
01203 
01204   virtual void visit(Visitor * the_visitor);
01205   virtual void walk(Walker & the_walker);
01206   virtual Node * change(Changer & the_changer, bool redispatch = false);
01207 
01209 
01210   // -- Dataflow
01211 
01212   virtual void dataflow(FlowVal * v, FlowProblem & fp);
01213 
01214   // -- Clone
01215 
01216   virtual Node * clone() const { return new declNode ( *this ); }
01217 
01218   // -- Output
01219 
01220   virtual void output(output_context & ct, Node * par);
01221 };
01222 
01239 class subdeclNode : public declNode
01240 {
01241 private:
01242 
01243   REF declNode * _original;
01244   int _index;
01245 
01246 public:
01247 
01258   subdeclNode(declNode * orig, int index);
01259 
01265   virtual ~subdeclNode();
01266 
01271 
01272   virtual declNode * original() { return _original->original(); }
01273   int index() const { return _index; }
01274 
01276 
01285   string name_with_index();
01286 
01291 
01292   virtual void visit(Visitor * the_visitor);
01293   virtual void walk(Walker & the_walker);
01294   virtual Node * change(Changer & the_changer, bool redispatch = false);
01295 
01297 
01298   // -- Clone
01299 
01300   virtual Node * clone() const { return new subdeclNode ( *this ); }
01301 
01302   // -- Output
01303 
01304   virtual void output(output_context & ct, Node * par);
01305 };
01306 
01316 class procNode : public defNode
01317 {
01318 
01319 private:
01320 
01329   TREE declNode * _decl;
01330 
01335   TREE blockNode * _body;
01336 
01343   static procNode * _current;
01344 
01345 
01355 
01356   FlowVal * _at_entry;
01357   FlowVal * _at_exit;
01358 
01360 
01361   /* These fields are set by the ThreeAddrReturnDismantle.
01362    * They are only valid in dismantled code
01363    */
01364 
01365   labelNode * _return_label;
01366   declNode * _return_decl;
01367 
01368 public:
01369 
01376   procNode(declNode * decl, blockNode * body,
01377            const Coord coord = Coord::Unknown);
01378 
01389   procNode(bool old_style, declNode * decl);
01390 
01396   virtual ~procNode();
01397 
01402 
01403 
01410   inline declNode * decl() const { return _decl; }
01411 
01419   inline declNode * get_decl() { declNode * out = _decl; _decl = 0; return out; }
01420 
01427   inline void decl(declNode * decl) { _decl = decl; }
01428 
01431   inline blockNode * body() const { return _body; }
01432 
01436   inline blockNode * get_body() { blockNode * out = _body; _body = 0; return out; }
01437 
01443   inline void body(blockNode * body) { _body = body; }
01444 
01445   // -- Flow values (for IP analyzer)
01446 
01450   inline FlowVal * at_entry() const { return _at_entry; }
01451 
01455   inline void at_entry(FlowVal * ae) { _at_entry = ae; }
01456 
01460   inline FlowVal * at_exit() const { return _at_exit; }
01461 
01465   inline void at_exit(FlowVal * ae) { _at_exit = ae; }
01466 
01468 
01469   void return_label(labelNode * label) { _return_label = label; }
01470   labelNode * return_label() { return _return_label; }
01471   void return_decl(declNode * decl) { _return_decl = decl; }
01472   declNode * return_decl() { return _return_decl; }
01473 
01485 
01490   basicblockNode * entry() const;
01491 
01496   basicblockNode * exit() const;
01497 
01499 
01506 
01507   // -- DefineProc in procedure.c
01508 
01509   void       define(blockNode * body); 
01510   procNode * define_and(blockNode * body); 
01511 
01512   static procNode * current() { return _current; }
01513 
01515 
01516   // -- Data type base
01517 
01518   typeNode * base_type(bool TdefIndir) const;
01519 
01524 
01525   virtual void visit(Visitor * the_visitor);
01526   virtual void walk(Walker & the_walker);
01527   virtual Node * change(Changer & the_changer, bool redispatch = false);
01528 
01530 
01531   // -- Dataflow
01532 
01533   virtual void dataflow(FlowVal * v, FlowProblem & fp);
01534 
01535   // -- Clone
01536 
01537   virtual Node * clone() const { return new procNode ( *this ); }
01538 
01539   // -- Output
01540 
01541   virtual void output(output_context & ct, Node * par);
01542 };
01543 
01555 class typeNode : public Node
01556 {
01557 
01558 public:
01559 
01566   typedef enum {
01567     NONE     = 0x0,     
01568     CONST    = 0x1,     
01569     VOLATILE = 0x2,     
01570     INLINE   = 0x4,     
01572     COMPATIBLE = 0x3    
01573   } Type_qualifiers;
01574 
01583   static string type_qualifiers_name(Type_qualifiers tq);
01584 
01597   static typeNode * integral_promotions(typeNode * old_type);
01598 
01618   static pair<typeNode *, typeNode *> usual_arithmetic_conversions(typeNode * left,
01619                                                                    typeNode * right);
01620 
01621 private:
01622 
01628   TREE typeNode * _type;
01629 
01634   Type_qualifiers _type_qualifiers;
01635 
01636 
01642   int _alloc_size;
01643 
01649   int _alloc_align;
01650 
01651 public:
01652 
01663   typeNode(NodeType typ, Type_qualifiers tq, typeNode * subtype,
01664            const Coord coord);
01665 
01671   virtual ~typeNode();
01672 
01677 
01680   inline typeNode * type() const { return _type; }
01681 
01685   inline typeNode * get_type() { typeNode * out = _type; _type = 0; return out; }
01686 
01692   inline void type(typeNode * the_type) { _type = the_type; }
01693 
01696   inline Type_qualifiers type_qualifiers() const { return _type_qualifiers; }
01697 
01700   inline void type_qualifiers(Type_qualifiers the_tq) { _type_qualifiers = the_tq; }
01701 
01703   inline string type_qualifiers_name() { return type_qualifiers_name(type_qualifiers()); }
01704 
01707   inline void add_type_qualifiers(Type_qualifiers the_tq)
01708   { _type_qualifiers = Type_qualifiers(_type_qualifiers | the_tq); }
01709 
01713   inline typeNode * add_type_qualifiers_and(Type_qualifiers the_tq)
01714   { add_type_qualifiers(the_tq); return this; }
01715 
01718   inline void remove_type_qualifiers(Type_qualifiers the_tq)
01719   { _type_qualifiers = Type_qualifiers(_type_qualifiers & ~the_tq); }
01720 
01722   inline int alloc_size(void) const { return _alloc_size; }
01723 
01725   inline void alloc_size(int size) { _alloc_size = size; }
01726 
01728   inline int alloc_align(void) const { return _alloc_align; }
01729   
01731   inline void alloc_align(int align) { _alloc_align = align; }
01732 
01734 
01741 
01742   void       finish();
01743   typeNode * finish_and();
01744 
01745   // -- Set base type
01746   //    Was SetBaseType from complex-types.c
01747 
01748   void       set_base_type(typeNode * base);
01749   typeNode * set_base_type_and(typeNode * base);
01750 
01751   // -- SUE complete
01752 
01753   void verify_sue_complete();
01754 
01756 
01767 
01776   bool operator==(typeNode & second) {
01777     return equal_to(this, & second, true, true); }
01778 
01788   bool operator<=(typeNode & second) {
01789     return equal_to(this, & second, false, false); }
01790 
01798   bool operator!=(typeNode & second) {
01799     return ! ( (*this) == second ); }
01800 
01802 
01824   static bool equal_to(typeNode * first, typeNode * second,
01825                        bool strict_toplevel, bool strict_recursive);
01826 
01840   virtual bool qualified_equal_to(typeNode * other,
01841                                   bool strict_toplevel, bool strict_recursive);
01842 
01852   typeNode * unwind_tdefs(Type_qualifiers & the_tq);
01853 
01854   typeNode * no_tdef_type();
01855 
01862   typeNode * follow_tdefs();
01863 
01870 
01871   virtual bool is_char() const { return false; }
01872   virtual bool is_int() const { return false; }
01873   virtual bool is_float() const { return false; }
01874   virtual bool is_void() const { return false; }
01875   virtual bool is_ellipsis() const { return false; }
01876 
01877   virtual bool is_integer() const { return false; }
01878   virtual bool is_arithmetic() const { return false; }
01879   virtual bool is_scalar() const { return false; }
01880   virtual bool is_aggregate() const { return false; }
01881   virtual bool is_derived() const { return false; }
01882   virtual bool is_pointer() const { return false; }
01883 
01885 
01892   virtual typeNode * usual_unary_conversion_type() { return this; }
01893 
01894   // -- Data type base
01895 
01896   virtual typeNode * base_type(bool TdefIndir) const {
01897     return (typeNode *)this; }
01898 
01899   // -- Deep base type
01900 
01901   typeNode * deep_base_type();
01902 
01903   // -- Dataflow
01904   //    Note: All type nodes share a no-op dataflow function
01905 
01906   virtual void dataflow(FlowVal * v, FlowProblem & fp) { }
01907 
01908   // -- Output
01909 
01910   virtual void output(output_context & ct, Node * par);
01911 
01924   virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q) =0;
01925 };
01926 
01936 class primNode : public typeNode
01937 {
01938 
01939 private:
01940 
01946   basic_type _basic;
01947 
01948 public:
01949 
01958   primNode(Type_qualifiers tq, basic_type basic,
01959            const Coord coord = Coord::Unknown);
01960 
01970   primNode(Type_qualifiers tq,
01971            const Coord coord = Coord::Unknown);
01972 
01981   primNode(const Coord coord);
01982 
01991   primNode(basic_type basic, const Coord coord = Coord::Unknown);
01992 
01998   virtual ~primNode();
01999 
02004 
02005   //    Return a reference so basic_type can be modified...
02006 
02007   inline const basic_type & basic() const { return _basic; }
02008   inline basic_type & basic() { return _basic; }
02009   inline void basic(basic_type basic) { _basic = basic; }
02010 
02012 
02017   // -- FinishPrimType from type.c
02018 
02019   void       finish();
02020   primNode * finish_and();
02021 
02022   // -- MergePrimTypes from type.c (other is deleted)
02023 
02024   void       merge_in(primNode * other);
02025   primNode * merge_in_and(primNode * other);
02026 
02028 
02035 
02036   virtual bool is_int() const      { return _basic.is_int(); }
02037   virtual bool is_char() const     { return _basic.is_char(); }
02038   virtual bool is_float() const    { return _basic.is_float(); }
02039   virtual bool is_void() const     { return _basic.is_void(); }
02040   virtual bool is_ellipsis() const { return _basic.is_ellipsis(); }
02041 
02042   virtual bool is_integer() const  { return _basic.is_integer(); }
02043   virtual bool is_arithmetic() const { return _basic.is_arithmetic(); }
02044   virtual bool is_scalar() const   { return _basic.is_scalar(); }
02045 
02047 
02048   // -- Type equal
02049 
02050   bool qualified_equal_to(typeNode * node2,
02051                           bool strict_toplevel, bool strict_recursive);
02052 
02057 
02058   virtual void visit(Visitor * the_visitor);
02059   virtual void walk(Walker & the_walker);
02060   virtual Node * change(Changer & the_changer, bool redispatch = false);
02061 
02063 
02064   // -- Clone
02065 
02066   virtual Node * clone() const { return new primNode ( *this ); }
02067 
02068   // -- Output
02069 
02070   virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02071 };
02072 
02089 class tdefNode : public typeNode
02090 {
02091 
02092 private:
02093 
02099   string _name;
02100 
02108   REF typeNode * _def;
02109 
02110 public:
02111 
02121   tdefNode(Type_qualifiers tq, const char * name,
02122            const Coord coord = Coord::Unknown);
02123 
02135   tdefNode(idNode * the_id, Type_qualifiers tq, typeNode * the_type);
02136 
02142   virtual ~tdefNode();
02143 
02148 
02151   inline string & name() { return _name; }
02152 
02155   inline void name(string name) { _name = name; }
02156 
02159   inline typeNode * def() const { return _def; }
02160 
02166   inline void def(typeNode * d) { _def = d; }
02167 
02169 
02170   // -- Data type base
02171 
02172   typeNode * base_type(bool TdefIndir) const;
02173 
02174   // -- Data type predicates
02175 
02180 
02181   virtual void visit(Visitor * the_visitor);
02182   virtual void walk(Walker & the_walker);
02183   virtual Node * change(Changer & the_changer, bool redispatch = false);
02184 
02186 
02187   // -- Clone
02188 
02189   virtual Node * clone() const { return new tdefNode ( *this ); }
02190 
02191   // -- Output
02192 
02193   virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02194 };
02195 
02205 class ptrNode : public typeNode
02206 {
02207 
02208 private:
02209 
02210 public:
02211 
02221   ptrNode(Type_qualifiers tq, typeNode * the_type,
02222           const Coord coord = Coord::Unknown);
02223 
02229   virtual ~ptrNode();
02230 
02231   // -- Type equal
02232 
02233   bool qualified_equal_to(typeNode * node2,
02234                           bool strict_toplevel, bool strict_recursive);
02235 
02242 
02243   virtual bool is_scalar() const { return true; }
02244   virtual bool is_derived() const { return true; }
02245   virtual bool is_pointer() const { return true; }
02246 
02248 
02253 
02254   virtual void visit(Visitor * the_visitor);
02255   virtual void walk(Walker & the_walker);
02256   virtual Node * change(Changer & the_changer, bool redispatch = false);
02257 
02259 
02260   // -- Clone
02261 
02262   virtual Node * clone() const { return new ptrNode ( *this ); }
02263 
02264   // -- Output
02265 
02266   virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02267 };
02268 
02291 class arrayNode : public typeNode
02292 {
02293 
02294 private:
02295 
02305   TREE exprNode * _dim;
02306 
02315   int _size;
02316 
02317 public:
02318 
02329   arrayNode(Type_qualifiers tq, typeNode * the_type, exprNode * the_dim,
02330            const Coord coord = Coord::Unknown);
02331 
02337   virtual ~arrayNode();
02338 
02343 
02344   inline exprNode * dim() const { return _dim; }
02345   inline exprNode * get_dim() { exprNode * out = _dim; _dim = 0; return out; }
02346   inline void dim(exprNode * the_dim) { _dim = the_dim; }
02347 
02348   inline int size() const { return _size; }
02349   inline void size(int the_size) { _size = the_size; }
02350 
02352 
02359 
02360   virtual bool is_aggregate() const { return true; }
02361   virtual bool is_derived() const { return true; }
02362   virtual bool is_pointer() const { return true; }
02363 
02364   // an array will be seen as a pointer (thus a scalar)
02365   // if it has no dimension, e.g., is a parameter
02366 
02367   virtual bool is_scalar() const { return _dim == NULL; }
02368   
02369   bool is_string() const;
02370 
02372 
02373   // -- Type equal
02374 
02375   bool qualified_equal_to(typeNode * node2,
02376                           bool strict_toplevel, bool strict_recursive);
02377 
02382 
02383   virtual void visit(Visitor * the_visitor);
02384   virtual void walk(Walker & the_walker);
02385   virtual Node * change(Changer & the_changer, bool redispatch = false);
02386 
02388 
02389   // -- Clone
02390 
02391   virtual Node * clone() const { return new arrayNode ( *this ); }
02392 
02393   // -- Output
02394 
02395   virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02396 };
02397 
02408 class funcNode : public typeNode
02409 {
02410 
02411 private:
02412 
02431   TREE decl_list _args;
02432 
02437   bool _is_knr;
02438 
02439 public:
02440 
02451   funcNode(Type_qualifiers tq, decl_list * args, typeNode * returns,
02452            const Coord coord = Coord::Unknown);
02453 
02459   virtual ~funcNode();
02460 
02465 
02466   inline decl_list & args() { return _args; }
02467   inline const decl_list & args() const { return _args; }
02468 
02469   inline typeNode * returns() const { return type(); }
02470   inline void returns(typeNode * returns) { type(returns); }
02471 
02472   inline bool is_knr() const { return _is_knr; }
02473   inline void is_knr (bool v) { _is_knr = v; }
02474 
02476 
02477   // -- Type equal
02478 
02479   bool qualified_equal_to(typeNode * node2,
02480                           bool strict_toplevel, bool strict_recursive);
02481 
02488 
02489   virtual bool is_derived() const { return true; }
02490   virtual bool is_pointer() const { return true; }
02491 
02493 
02498   bool is_void_args();
02499 
02507   bool check_conversions();
02508 
02518   bool is_compatible_with(funcNode * nfunc);
02519 
02531   void add_parameter_types(decl_list * types);
02532 
02537 
02538   virtual void visit(Visitor * the_visitor);
02539   virtual void walk(Walker & the_walker);
02540   virtual Node * change(Changer & the_changer, bool redispatch = false);
02541 
02543 
02544   // -- Clone
02545 
02546   virtual Node * clone() const { return new funcNode ( *this ); }
02547 
02548   // -- Output
02549 
02550   virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02551 };
02552 
02586 class sueNode : public typeNode
02587 {
02588 
02589 private:
02590 
02596   REF suespecNode * _spec;
02597 
02602   bool _elaborated;
02603 
02604 public:
02605 
02614   sueNode(NodeType typ, const Coord coord);
02615 
02621   virtual ~sueNode();
02622 
02627 
02628   inline bool elaborated() const { return _elaborated; }
02629   inline void elaborated(bool elab) { _elaborated = elab; }
02630 
02631   inline suespecNode * spec() const { return _spec; }
02632   inline void spec(suespecNode * s) { _spec = s; }
02633 
02635 
02639 
02640   // --- Was SetSUdclNameFields from sue.c
02641 
02642   void      set_name_fields(idNode *id, decl_list * fields, 
02643                             bool elaborated,
02644                             const Coord left_coord,
02645                             const Coord the_right_coord);
02646 
02647   sueNode * set_name_fields_and(idNode *id, decl_list * fields, 
02648                                 bool elaborated,
02649                                 const Coord left_coord,
02650                                 const Coord the_right_coord);
02651 
02652   // -- Was SetSUdclName in sue.c
02653 
02654   void      set_name(idNode * id, const Coord coord);
02655   sueNode * set_name_and(idNode * id, const Coord coord);
02656 
02657   // -- ForceNewSU in sue.c
02658 
02659   void      force_new(const Coord coord);
02660   sueNode * force_new_and(const Coord coord);
02661 
02662   // -- Tags
02663 
02664   bool same_tag_as(sueNode * other);
02665   void tag_conflict(sueNode * new_sue); // from sue.c
02666 
02668 
02669   // -- Type equal
02670 
02671   bool qualified_equal_to(typeNode * node2,
02672                           bool strict_toplevel, bool strict_recursive);
02673 
02674   // -- Data type predicates
02675 
02676   // -- Output
02677 
02678   virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
02679 };
02680 
02695 class structNode : public sueNode
02696 {
02697 
02698 private:
02699 
02700 public:
02701 
02710   structNode(const Coord coord = Coord::Unknown);
02711 
02717   virtual ~structNode();
02718 
02725 
02726   virtual bool is_aggregate() const { return true; }
02727 
02729 
02734 
02735   virtual void visit(Visitor * the_visitor);
02736   virtual void walk(Walker & the_walker);
02737   virtual Node * change(Changer & the_changer, bool redispatch = false);
02738 
02740 
02741   // -- Clone
02742 
02743   virtual Node * clone() const { return new structNode ( *this ); }
02744 };
02745 
02760 class unionNode : public sueNode
02761 {
02762 
02763 private:
02764 
02765 public:
02766 
02775   unionNode(const Coord coord = Coord::Unknown);
02776 
02782   virtual ~unionNode();
02783 
02788 
02789   virtual void visit(Visitor * the_visitor);
02790   virtual void walk(Walker & the_walker);
02791   virtual Node * change(Changer & the_changer, bool redispatch = false);
02792 
02794 
02795   // -- Clone
02796 
02797   virtual Node * clone() const { return new unionNode ( *this ); }
02798 };
02799 
02814 class enumNode : public sueNode
02815 {
02816 
02817 private:
02818 
02819 public:
02820 
02829   enumNode(const Coord coord = Coord::Unknown);
02830 
02843   enumNode(idNode *id, decl_list * values, 
02844            const Coord enum_coord, const Coord left_coord,
02845            const Coord right_coord);
02846 
02852   virtual ~enumNode();
02853 
02860 
02861   virtual bool is_int() const { return true; }
02862   virtual bool is_integer() const { return true; }
02863   virtual bool is_arithmetic() const { return true; }
02864   virtual bool is_scalar() const { return true; }
02865 
02867 
02872 
02873   virtual void visit(Visitor * the_visitor);
02874   virtual void walk(Walker & the_walker);
02875   virtual Node * change(Changer & the_changer, bool redispatch = false);
02876 
02878 
02879   // -- Clone
02880 
02881   virtual Node * clone() const { return new enumNode ( *this ); }
02882 };
02883 
02900 class suespecNode : public typeNode
02901 {
02902 
02903 private:
02904 
02912   string _name;
02913 
02920   TREE decl_list _fields;
02921 
02929   bool _complete;
02930 
02938   bool _visited;
02939 
02950   int _scope_output;
02951 
02956   int _size;
02957 
02962   int _align;
02963 
02969   NodeType _owner;
02970 
02971 public:
02972 
02985   suespecNode(const char * name, decl_list * fields, NodeType owner,
02986               unitNode * the_unit,
02987               const Coord coord);
02988 
02994   virtual ~suespecNode();
02995 
03000 
03001   inline bool complete() const { return _complete; }
03002   inline void complete(bool comp) { _complete = comp; }
03003 
03004   inline bool visited() const { return _visited; }
03005   inline void visited(bool v) { _visited = v; }
03006 
03007   inline bool scope_output() const { return _scope_output; }
03008   inline void scope_output(int v) { _scope_output = v; }
03009 
03010   inline int size() const { return _size; }
03011   inline void size(int size) { _size = size; }
03012 
03013   inline int align() const { return _align; }
03014   inline void align(int align) { _align = align; }
03015 
03016   inline string & name() { return _name; }
03017   inline void name(string name) { _name = name; }
03018 
03019   inline decl_list & fields() { return _fields; }
03020   inline const decl_list & fields() const { return _fields; }
03021 
03022   inline NodeType owner() const { return _owner; }
03023 
03025 
03026   // -- Tags and fields
03027 
03038   bool same_tag_as(suespecNode * other);
03039 
03048   void update(decl_list * fields, sueNode * sue, const Coord right);
03049 
03059   declNode * find_field(const string & name);
03060 
03065 
03066   virtual void visit(Visitor * the_visitor);
03067   virtual void walk(Walker & the_walker);
03068   virtual Node * change(Changer & the_changer, bool redispatch = false);
03069 
03071 
03072   // -- Clone
03073 
03074   virtual Node * clone() const { return new suespecNode ( *this ); }
03075 
03076   // -- Output
03077 
03078   virtual void output_type(output_context & ct, Node * par, Assoc context, Type_qualifiers q);
03079 };
03080 
03081 
03099 class exprNode : public Node
03100 {
03101 public:
03102 
03115   static exprNode * integral_promotions(exprNode * old_expr);
03116 
03131   static pair<exprNode *, exprNode *>
03132     usual_arithmetic_conversions(exprNode * left,
03133                                  exprNode * right);
03134 
03135 private:
03136 
03141   TREE typeNode * _type;
03142 
03150   constant _value;
03151 
03152 public:
03153 
03163   exprNode(NodeType typ, typeNode * type, const Coord coord);
03164 
03170   virtual ~exprNode();
03171 
03176 
03177   virtual typeNode * type() const { return _type; }
03178   inline typeNode * get_type() { typeNode * out = _type; _type = 0; return out; }
03179   virtual void type(typeNode *type) { _type = type; }
03180 
03181   inline const constant & value() const { return _value; }
03182   inline constant & value() { return _value; }
03183   inline void value(const constant & newval) { _value = newval; }
03184 
03186 
03187   // -- Data type base
03188 
03189   virtual typeNode * base_type(bool TdefIndir) const;
03190 
03191   // -- Symbol lookup
03192   // LookupPostfixExpression in type.c
03193 
03194   // virtual void lookup() {  } // -- Default; do nothing
03195 
03196   // -- Type conversions
03197   // THESE ARE NOT USED
03198   // exprNode * assignment_conversions(typeNode * to_type);
03199   // exprNode * call_conversions(typeNode * to_type);
03200   // exprNode * return_conversions(typeNode * to_type);
03201   // exprNode * cast_conversions(typeNode * to_type);
03202   // exprNode * usual_unary_conversions(typeNode * to_type, bool f_to_d);
03203   // exprNode * usual_binary_conversions(typeNode * to_type);
03204 
03214   virtual void eval() =0;
03215 
03224   virtual bool is_lvalue() { return true; } // THIS IS A TBD
03225 
03226   typeNode * no_tdef_type() { return type()->follow_tdefs(); }
03227 
03228   // -- Output
03229 
03230   virtual void output(output_context & ct, Node * par);
03231 
03252   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc) =0;
03253 
03266   virtual int precedence(Assoc & assoc);
03267 
03280   bool parens(int outer_prec, Assoc outer_assoc);
03281 };
03282 
03290 class indexNode : public exprNode {
03291  public:
03292   indexNode(NodeType typ, typeNode * type, const Coord coord);
03293 };
03294 
03304 class constNode : public indexNode
03305 {
03306 
03307 private:
03308 
03318   string _text;
03319 
03320 public:
03321 
03331   constNode(constant value, const char * text = "",
03332             const Coord coord = Coord::Unknown);
03333 
03339   virtual ~constNode();
03340 
03345 
03346   inline string & text() { return _text; }
03347 
03349 
03354   typeNode * usual_unary_conversion_type() 
03355       { return type()->usual_unary_conversion_type(); }
03356 
03357   // -- Constant folding
03358 
03359   virtual void eval();
03360 
03365 
03366   virtual void visit(Visitor * the_visitor);
03367   virtual void walk(Walker & the_walker);
03368   virtual Node * change(Changer & the_changer, bool redispatch = false);
03369 
03371 
03372   // -- Dataflow
03373 
03374   virtual void dataflow(FlowVal * v, FlowProblem & fp);
03375 
03376   // -- Clone
03377 
03378   virtual Node * clone() const { return new constNode ( *this ); }
03379 
03380   // -- Output
03381 
03382   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03383 };
03384 
03396 class idNode : public indexNode
03397 {
03398 
03399 private:
03400 
03405   string _name;
03406 
03414   REF declNode * _decl;
03415 
03416 public:
03417 
03426   idNode(const char * text, const Coord coord = Coord::Unknown);
03427 
03437   idNode(declNode * the_decl, const Coord coord = Coord::Unknown);
03438 
03444   virtual ~idNode();
03445 
03450 
03451   inline string & name() { return _name; }
03452   inline const string & name() const { return _name; }
03453   inline void name(string nm) { _name = nm; }
03454 
03455   inline declNode * decl() const { return _decl; }
03456   void decl(declNode *decl);
03457 
03459 
03460   // -- Data type base
03461 
03462   typeNode * base_type(bool TdefIndir) const;
03463 
03464   // -- Symbol lookup
03465 
03466   // virtual void lookup();
03467   // idNode * lookup_and();
03468 
03469   // -- Constant folding
03470 
03471   virtual void eval();
03472 
03477 
03478   virtual void visit(Visitor * the_visitor);
03479   virtual void walk(Walker & the_walker);
03480   virtual Node * change(Changer & the_changer, bool redispatch = false);
03481 
03483 
03484   // -- Dataflow
03485 
03486   virtual void dataflow(FlowVal * v, FlowProblem & fp);
03487 
03488   // -- Clone
03489 
03490   virtual Node * clone() const { return new idNode ( *this ); }
03491 
03492   // -- Output
03493 
03494   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03495 };
03496 
03514 class binaryNode : public exprNode
03515 {
03516 
03517 private:
03518 
03526   Operator * _op;
03527 
03530   TREE exprNode * _left;
03531 
03534   TREE exprNode * _right;
03535 
03536 public:
03537 
03556   binaryNode(unsigned int op_id, exprNode * left, exprNode * right,
03557              const Coord coord = Coord::Unknown);
03558 
03564   virtual ~binaryNode();
03565 
03570 
03571   inline Operator * op() const { return _op; }
03572   inline void op(Operator * op) { _op = op; }
03573 
03574   inline exprNode * left() const { return _left; }
03575   inline exprNode * get_left() { exprNode * out = _left; _left = 0; return out; }
03576   inline void left(exprNode * left) { _left = left; }
03577 
03578   inline exprNode * right() const { return _right; }
03579   inline exprNode * get_right() { exprNode * out = _right; _right = 0; return out; }
03580   inline void right(exprNode * right) { _right = right; }
03581 
03583 
03584   // -- Symbol lookup
03585 
03586   // virtual void lookup();
03587 
03588   // -- Constant folding
03589 
03590   virtual void eval();
03591 
03596 
03597   virtual void visit(Visitor * the_visitor);
03598   virtual void walk(Walker & the_walker);
03599   virtual Node * change(Changer & the_changer, bool redispatch = false);
03600 
03602 
03603   // -- Dataflow
03604 
03605   virtual void dataflow(FlowVal * v, FlowProblem & fp);
03606 
03607   // -- Clone
03608 
03609   virtual Node * clone() const { return new binaryNode ( *this ); }
03610 
03611   // -- Output
03612 
03613   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03614   virtual int precedence(Assoc & assoc);
03615 };
03616 
03625 class unaryNode : public exprNode
03626 {
03627 
03628 private:
03629 
03637   Operator * _op;
03638 
03641   TREE exprNode * _expr;
03642 
03647   TREE typeNode * _sizeof_type;
03648 
03649 public:
03650 
03668   unaryNode(unsigned int op_id, exprNode * expr,
03669             const Coord coord = Coord::Unknown);
03670 
03679   unaryNode(unsigned int op_id, typeNode * the_type,
03680             const Coord coord = Coord::Unknown);
03681 
03687   virtual ~unaryNode();
03688 
03693 
03694   inline Operator * op() const { return _op; }
03695   inline void op(Operator * op) { _op = op; }
03696 
03697   inline exprNode * expr() const { return _expr; }
03698   inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
03699   inline void expr(exprNode * expr) { _expr = expr; }
03700 
03701   //    sizeof_type is only used if the operation is "sizeof()"
03702 
03703   inline typeNode * sizeof_type() const { return _sizeof_type; }
03704   inline typeNode * get_sizeof_type() 
03705   { typeNode * out = _sizeof_type; _sizeof_type = 0; return out; }
03706   inline void sizeof_type(typeNode *sizeof_type)
03707   { _sizeof_type = sizeof_type; }
03708 
03710 
03711   // -- Symbol lookup
03712 
03713   // virtual void lookup();
03714 
03715   // -- Constant folding
03716 
03717   virtual void eval();
03718 
03723 
03724   virtual void visit(Visitor * the_visitor);
03725   virtual void walk(Walker & the_walker);
03726   virtual Node * change(Changer & the_changer, bool redispatch = false);
03727 
03729 
03730   // -- Dataflow
03731 
03732   virtual void dataflow(FlowVal * v, FlowProblem & fp);
03733 
03734   // -- Clone
03735 
03736   virtual Node * clone() const { return new unaryNode ( *this ); }
03737 
03738   // -- Output
03739 
03740   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03741   virtual int precedence(Assoc & assoc);
03742 };
03743 
03759 class castNode : public exprNode
03760 {
03761 
03762 private:
03763 
03766   TREE exprNode * _expr;
03767 
03774   bool _implicit;
03775 
03776 public:
03777 
03787   castNode(typeNode * type, exprNode * expr, bool implicit = false,
03788            const Coord coord = Coord::Unknown);
03789 
03795   virtual ~castNode();
03796 
03801 
03802   inline exprNode * expr() const { return _expr; }
03803   inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
03804   inline void expr(exprNode * expr) { _expr = expr; }
03805 
03806   inline bool is_implicit() const { return _implicit; }
03808 
03809   // -- Constant folding
03810 
03811   virtual void eval();
03812 
03817 
03818   virtual void visit(Visitor * the_visitor);
03819   virtual void walk(Walker & the_walker);
03820   virtual Node * change(Changer & the_changer, bool redispatch = false);
03821 
03823 
03824   // -- Dataflow
03825 
03826   virtual void dataflow(FlowVal * v, FlowProblem & fp);
03827 
03828   // -- Clone
03829 
03830   virtual Node * clone() const { return new castNode ( *this ); }
03831 
03832   // -- Output
03833 
03834   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03835   virtual int precedence(Assoc & assoc);
03836 };
03837 
03838 
03848 class commaNode : public exprNode
03849 {
03850 
03851 private:
03852 
03858   TREE expr_list _exprs;
03859 
03860 public:
03861 
03870   commaNode(expr_list * exprs, const Coord coord = Coord::Unknown);
03871 
03878   commaNode(const Coord coord = Coord::Unknown);
03879 
03885   virtual ~commaNode();
03886 
03891 
03892   inline expr_list & exprs() { return _exprs; }
03893   inline const expr_list & exprs() const { return _exprs; }
03894 
03896 
03897   // -- Data type base
03898 
03899   typeNode * base_type(bool TdefIndir) const;
03900 
03901   // -- Constant folding
03902 
03903   virtual void eval();
03904 
03909 
03910   virtual void visit(Visitor * the_visitor);
03911   virtual void walk(Walker & the_walker);
03912   virtual Node * change(Changer & the_changer, bool redispatch = false);
03913 
03915 
03916   // -- Dataflow
03917 
03918   virtual void dataflow(FlowVal * v, FlowProblem & fp);
03919 
03920   // -- Clone
03921 
03922   virtual Node * clone() const { return new commaNode ( *this ); }
03923 
03924   // -- Output
03925 
03926   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
03927   virtual int precedence(Assoc & assoc);
03928 };
03929 
03937 class ternaryNode : public exprNode
03938 {
03939 
03940 private:
03941 
03944   TREE exprNode * _cond;
03945 
03948   TREE exprNode * _true_br;
03949 
03952   TREE exprNode * _false_br;
03953 
03956   Coord _colon_coord;
03957 
03958 public:
03959 
03971   ternaryNode(exprNode * cond, exprNode * true_br, exprNode * false_br,
03972               const Coord qmark_coord = Coord::Unknown,
03973               const Coord colon_coord = Coord::Unknown);
03974 
03980   virtual ~ternaryNode();
03981 
03986 
03987   inline exprNode * cond() const { return _cond; }
03988   inline exprNode * get_cond() { exprNode * out = _cond; _cond = 0; return out; }
03989   inline void cond(exprNode * cond) { _cond = cond; }
03990 
03991   inline exprNode * true_br() const { return _true_br; }
03992   inline exprNode * get_true_br() { exprNode * out = _true_br; _true_br = 0; return out; }
03993   inline void true_br(exprNode * true_br) { _true_br = true_br; }
03994 
03995   inline exprNode * false_br() const { return _false_br; }
03996   inline exprNode * get_false_br() { exprNode * out = _false_br; _false_br = 0; return out; }
03997   inline void false_br(exprNode * false_br) { _false_br = false_br; }
03998 
04000 
04001   // -- Constant folding
04002 
04003   virtual void eval();
04004 
04009 
04010   virtual void visit(Visitor * the_visitor);
04011   virtual void walk(Walker & the_walker);
04012   virtual Node * change(Changer & the_changer, bool redispatch = false);
04013 
04015 
04016   // -- Dataflow
04017 
04018   virtual void dataflow(FlowVal * v, FlowProblem & fp);
04019 
04020   // -- Clone
04021 
04022   virtual Node * clone() const { return new ternaryNode ( *this ); }
04023 
04024   // -- Output
04025 
04026   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
04027   virtual int precedence(Assoc & assoc);
04028 };
04029 
04057 class callNode : public exprNode
04058 {
04059 
04060 private:
04061 
04064   TREE exprNode * _name;
04065 
04071   TREE expr_list _args;
04072 
04082   REF procNode * _proc;
04083 
04084 public:
04085 
04096   callNode(exprNode * name, expr_list * args,
04097            const Coord coord = Coord::Unknown);
04098 
04104   virtual ~callNode();
04105 
04110 
04111   inline exprNode * name() const { return _name; }
04112   inline exprNode * get_name() { exprNode * out = _name; _name = 0; return out; }
04113   inline void name(exprNode * name) { _name = name; }
04114 
04115   inline expr_list & args() { return _args; }
04116   inline const expr_list & args() const { return _args; }
04117 
04118   inline procNode * proc() const { return _proc; }
04119   inline void proc(procNode * proc) { _proc = proc; }
04120 
04122 
04123   // -- Data type base
04124 
04125   typeNode * base_type(bool TdefIndir) const;
04126 
04127   // -- Symbol lookup
04128 
04129   // virtual void lookup();
04130 
04131   // -- Constant folding
04132 
04133   virtual void eval();
04134 
04139 
04140   virtual void visit(Visitor * the_visitor);
04141   virtual void walk(Walker & the_walker);
04142   virtual Node * change(Changer & the_changer, bool redispatch = false);
04143 
04145 
04146   // -- Dataflow
04147 
04148   virtual void dataflow(FlowVal * v, FlowProblem & fp);
04149 
04150   // -- Clone
04151 
04152   virtual Node * clone() const { return new callNode ( *this ); }
04153 
04154   // -- Output
04155 
04156   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
04157 };
04158 
04174 class initializerNode : public exprNode
04175 {
04176 
04177 private:
04178 
04179   TREE expr_list _exprs;
04180 
04181 public:
04182 
04183   // -- Constructors
04184 
04185   initializerNode(expr_list * exprs, const Coord coord = Coord::Unknown);
04186 
04192   virtual ~initializerNode();
04193 
04198 
04199   inline expr_list & exprs() { return _exprs; }
04200   inline const expr_list & exprs() const { return _exprs; }
04201   inline void add_expr(exprNode * the_expr) { _exprs.push_back(the_expr); }
04202 
04204 
04205   // -- Constant folding
04206 
04207   virtual void eval();
04208 
04213 
04214   virtual void visit(Visitor * the_visitor);
04215   virtual void walk(Walker & the_walker);
04216   virtual Node * change(Changer & the_changer, bool redispatch = false);
04217 
04219 
04220   // -- Dataflow
04221 
04222   virtual void dataflow(FlowVal * v, FlowProblem & fp);
04223 
04224   // -- Clone
04225 
04226   virtual Node * clone() const { return new initializerNode ( *this ); }
04227 
04228   // -- Output
04229 
04230   virtual void output_expr(output_context & ct, Node * par, int prec, Assoc assoc);
04231 };
04232 
04240 class stmtNode : public Node
04241 {
04242 
04243 private:
04244 
04250   FlowVal * _at_exit;
04251 
04260   string _comment;
04261 
04262 public:
04263 
04272   stmtNode(NodeType typ, const Coord coord);
04273 
04279   virtual ~stmtNode();
04280 
04285 
04286   inline string & comment() { return _comment; }
04287 
04288   // -- Dataflow
04289 
04290   inline FlowVal * at_exit() const { return _at_exit; }
04291   inline void at_exit(FlowVal * ae) { _at_exit = ae; }
04292 
04294 
04295   // -- Output
04296 
04297   virtual void output(output_context & ct, Node * par);
04298 
04309   virtual void output_stmt(output_context & ct, Node * par) =0;
04310 
04311   void output_comment(output_context & ct);
04312 };
04313 
04332 class blockNode : public stmtNode
04333 {
04334 
04335 public:
04336 
04366   static blockNode * toBlock(stmtNode * stmt, Coord coord);
04367 
04368 private:
04369 
04374   TREE decl_list _decls;
04375 
04380   TREE stmt_list _stmts;
04381 
04384   Coord _right_brace;
04385   // TREE typeNode * _type; Why does block have a type?
04386 
04387 public:
04388 
04401   blockNode(decl_list * decls, stmt_list * stmts,
04402             const Coord left_coord = Coord::Unknown,
04403             const Coord right_brace = Coord::Unknown);
04404 
04410   virtual ~blockNode();
04411 
04416 
04417   inline decl_list & decls() { return _decls; }
04418   inline const decl_list & decls() const { return _decls; }
04419 
04420   inline stmt_list & stmts() { return _stmts; }
04421   inline const stmt_list & stmts() const { return _stmts; }
04422 
04423   inline Coord right_brace() const { return _right_brace; }
04424   inline void right_brace(const Coord right_brace) { _right_brace = right_brace; }
04425 
04427 
04428   // -- Data type base
04429 
04430   typeNode * base_type(bool TdefIndir) const;
04431 
04436 
04437   virtual void visit(Visitor * the_visitor);
04438   virtual void walk(Walker & the_walker);
04439   virtual Node * change(Changer & the_changer, bool redispatch = false);
04440 
04442 
04443   // -- Dataflow
04444 
04445   virtual void dataflow(FlowVal * v, FlowProblem & fp);
04446 
04447   // -- Clone
04448 
04449   virtual Node * clone() const { return new blockNode ( *this ); }
04450 
04451   // -- Output 
04452   virtual void output_stmt(output_context & ct, Node * par);
04453 
04454 };
04455 
04456 class algorithm_info
04457 {
04458 };
04459 
04485 class basicblockNode : public blockNode {
04486 
04487 private:
04488 
04491   basicblock_list _preds;
04492 
04495   basicblock_list _succs;
04496 
04501   basicblockNode * _parent;
04502 
04508   basicblock_list _children;
04509 
04515   algorithm_info * _info;
04516 
04523   int _dfn;
04524 
04531   FlowVal * _at_entry;
04532 
04540   FlowVal * _at_exit;
04541 
04542 public:
04543 
04555   basicblockNode(decl_list * decls, stmt_list * stmts,
04556             const Coord left_coord = Coord::Unknown,
04557             const Coord right_brace = Coord::Unknown);
04558 
04564   virtual ~basicblockNode();
04565 
04570 
04571   inline basicblock_list & preds() { return _preds; }
04572   inline const basicblock_list & preds() const { return _preds; }
04573 
04574   inline basicblock_list & succs() { return _succs; }
04575   inline const basicblock_list & succs() const { return _succs; }
04576 
04577   inline basicblockNode * parent() const { return _parent; }
04578   inline void parent(basicblockNode *par) { _parent = par; }
04579 
04580   inline basicblock_list & children() { return _children; }
04581   inline const basicblock_list & children() const { return _children; }
04582 
04583   inline algorithm_info * info() const { return _info; }
04584   inline void info(algorithm_info * i) { _info = i; }
04585 
04586   inline int dfn() const { return _dfn; }
04587   inline void dfn(int d) { _dfn = d; }
04588 
04589   // -- Flow values (for IP analyzer)
04590 
04591   inline FlowVal * at_entry() const { return _at_entry; }
04592   inline void at_entry(FlowVal * ae) { _at_entry = ae; }
04593 
04594   inline FlowVal * at_exit() const { return _at_exit; }
04595   inline void at_exit(FlowVal * ae) { _at_exit = ae; }
04596 
04598 
04603 
04604   virtual void visit(Visitor * the_visitor);
04605   virtual void walk(Walker & the_walker);
04606   virtual Node * change(Changer & the_changer, bool redispatch = false);
04607 
04609 
04610   // Dataflow is inherited from blockNode
04611 
04612   // -- Clone
04613 
04614   virtual Node * clone() const { return new basicblockNode ( *this ); }
04615 
04616 };
04617  
04618   
04619 
04629 class exprstmtNode : public stmtNode
04630 {
04631 
04632 private:
04633 
04636   TREE exprNode * _expr;
04637 
04638 public:
04639 
04646   exprstmtNode(exprNode * expr);
04647 
04653   virtual ~exprstmtNode();
04654 
04659 
04660   inline exprNode * expr() const { return _expr; }
04661   inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
04662   inline void expr(exprNode * expr) { _expr = expr; }
04663 
04665 
04666   // -- Data type base
04667 
04668   typeNode * base_type(bool TdefIndir) const;
04669 
04670 
04675 
04676   virtual void visit(Visitor * the_visitor);
04677   virtual void walk(Walker & the_walker);
04678   virtual Node * change(Changer & the_changer, bool redispatch = false);
04679 
04681 
04682   // -- Dataflow
04683 
04684   virtual void dataflow(FlowVal * v, FlowProblem & fp);
04685 
04686   // -- Clone
04687 
04688   virtual Node * clone() const { return new exprstmtNode ( *this ); }
04689 
04690   // -- Output
04691 
04692   virtual void output_stmt(output_context & ct, Node * par);
04693 };
04694 
04708 class targetNode : public stmtNode
04709 {
04710 
04711 private:
04712 
04715   TREE blockNode * _stmt;
04716 
04722   FlowVal * _at_entry;
04723 
04724 public:
04725 
04733   targetNode(NodeType typ, stmtNode * stmt, const Coord coord);
04734 
04740   virtual ~targetNode();
04741 
04746 
04747   inline blockNode * stmt() const { return _stmt; }
04748   inline blockNode * get_stmt() { blockNode * out = _stmt; _stmt = 0; return out; }
04749   inline void stmt(blockNode * stmt) { _stmt = stmt; }
04750 
04751   // -- Dataflow
04752 
04753   inline FlowVal * at_entry() const { return _at_entry; }
04754   inline void at_entry(FlowVal * ae) { _at_entry = ae; }
04755 
04757 };
04758 
04773 class labelNode : public targetNode
04774 {
04775 
04776 private:
04777 
04780   string _name;
04781 
04787   REF goto_list _references;
04788 
04789 public:
04790 
04800   labelNode(const char * name, stmtNode * stmt,
04801             const Coord coord = Coord::Unknown);
04802 
04806 
04815   labelNode(idNode * ident, stmtNode * stmt);
04816 
04824   labelNode(idNode * ident);
04825 
04827 
04833   virtual ~labelNode();
04834 
04839 
04840   inline string & name() { return _name; }
04841   inline void name(string name) { _name = name; }
04842 
04843   inline goto_list & references() { return _references; }
04844   inline const goto_list & references() const { return _references; }
04845 
04847 
04848   // -- Undeclared
04849 
04850   bool is_undeclared() const;
04851 
04856 
04857   virtual void visit(Visitor * the_visitor);
04858   virtual void walk(Walker & the_walker);
04859   virtual Node * change(Changer & the_changer, bool redispatch = false);
04860 
04862 
04863   // -- Dataflow
04864 
04865   virtual void dataflow(FlowVal * v, FlowProblem & fp);
04866 
04867   // -- Clone
04868 
04869   virtual Node * clone() const { return new labelNode ( *this ); }
04870 
04871   // -- Output
04872 
04873   virtual void output_stmt(output_context & ct, Node * par);
04874 };
04875 
04890 class caseNode : public targetNode
04891 {
04892 
04893 private:
04894 
04899   TREE exprNode * _expr;
04900 
04907   REF switchNode * _container;
04908 
04909 public:
04910 
04921   caseNode(exprNode * expr, stmtNode * stmt, switchNode * the_container,
04922            const Coord coord = Coord::Unknown);
04923 
04934   caseNode(exprNode * expr, stmtNode * stmt,
04935            const Coord coord = Coord::Unknown);
04936 
04942   virtual ~caseNode();
04943 
04948 
04949   inline exprNode * expr() const { return _expr; }
04950   inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
04951   inline void expr(exprNode * expr) { _expr = expr; }
04952 
04953   inline switchNode * container() const { return _container; }
04954   void container(switchNode * container);
04955 
04957 
04962 
04963   virtual void visit(Visitor * the_visitor);
04964   virtual void walk(Walker & the_walker);
04965   virtual Node * change(Changer & the_changer, bool redispatch = false);
04966 
04968 
04969   // -- Dataflow
04970 
04971   virtual void dataflow(FlowVal * v, FlowProblem & fp);
04972 
04973   // -- Clone
04974 
04975   virtual Node * clone() const { return new caseNode ( *this ); }
04976 
04977   // -- Output
04978 
04979   virtual void output_stmt(output_context & ct, Node * par);
04980 };
04981 
04994 class selectionNode : public stmtNode
04995 {
04996 
04997 private:
04998 
05001   TREE exprNode * _expr;
05002 
05005   TREE blockNode * _stmt;
05006 
05007 public:
05008 
05020   selectionNode(NodeType typ, exprNode * expr, stmtNode * stmt,
05021                 const Coord coord);
05022 
05028   virtual ~selectionNode();
05029 
05034 
05035   inline exprNode * expr() const { return _expr; }
05036   inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
05037   inline void expr(exprNode * expr) { _expr = expr; }
05038 
05039   inline blockNode * stmt() const { return _stmt; }
05040   inline blockNode * get_stmt() { blockNode * out = _stmt; _stmt = 0; return out; }
05041   inline void stmt(blockNode * stmt) { _stmt = stmt; }
05042 
05044 };
05045 
05057 class ifNode : public selectionNode
05058 {
05059 
05060 private:
05061 
05064   TREE blockNode * _false_br;
05065 
05068   Coord _else_coord;
05069 
05070 public:
05071 
05084   ifNode(exprNode * expr, stmtNode * true_br, stmtNode * false_br,
05085              const Coord if_coord = Coord::Unknown, 
05086              const Coord else_coord = Coord::Unknown);
05087 
05093   virtual ~ifNode();
05094 
05099 
05100   inline blockNode * true_br() const { return selectionNode::stmt(); }
05101   inline blockNode * get_true_br() { return selectionNode::get_stmt(); }
05102   inline void true_br(blockNode * true_br) { selectionNode::stmt(true_br); }
05103 
05104   inline blockNode * false_br() const { return _false_br; }
05105   inline blockNode * get_false_br() { blockNode * out = _false_br; _false_br = 0; return out; }
05106   inline void false_br(blockNode * false_br) { _false_br = false_br; }
05107 
05108   inline Coord else_coord() const { return _else_coord; }
05109   inline void else_coord(const Coord the_coord) { _else_coord = the_coord; }
05110 
05112 
05117 
05118   virtual void visit(Visitor * the_visitor);
05119   virtual void walk(Walker & the_walker);
05120   virtual Node * change(Changer & the_changer, bool redispatch = false);
05121 
05123 
05124   // -- Dataflow
05125 
05126   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05127 
05128   // -- Clone
05129 
05130   virtual Node * clone() const { return new ifNode ( *this ); }
05131 
05132   // -- Output
05133 
05134   virtual void output_stmt(output_context & ct, Node * par);
05135 };
05136 
05149 class switchNode : public selectionNode
05150 {
05151 
05152 private:
05153 
05159   REF target_list _cases;
05160 
05163   bool _has_default;
05164 
05170   FlowVal * _at_top;
05171 
05172 public:
05173 
05183   switchNode(exprNode * expr, stmtNode * stmt,
05184              const Coord coord = Coord::Unknown);
05185 
05191   virtual ~switchNode();
05192 
05197 
05198   inline target_list & cases() { return _cases; }
05199   inline const target_list & cases() const { return _cases; }
05200 
05201   inline bool has_default() const { return _has_default; }
05202   inline void has_default(bool has_default) { _has_default = has_default; }
05203 
05204   inline FlowVal * at_top() const { return _at_top; }
05205   inline void at_top(FlowVal * at) { _at_top = at; }
05206 
05208 
05213 
05214   virtual void visit(Visitor * the_visitor);
05215   virtual void walk(Walker & the_walker);
05216   virtual Node * change(Changer & the_changer, bool redispatch = false);
05217 
05219 
05220   // -- Dataflow
05221 
05222   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05223 
05224   // -- Clone
05225 
05226   virtual Node * clone() const { return new switchNode ( *this ); }
05227 
05228   // -- Output
05229 
05230   virtual void output_stmt(output_context & ct, Node * par);
05231 };
05232 
05241 class loopNode : public stmtNode
05242 {
05243 
05244 private:  
05245 
05248   TREE exprNode * _cond;
05249 
05252   TREE blockNode * _body;
05253 
05259   FlowVal * _at_loop_head;
05260 
05266   FlowVal * _at_loop_tail;
05267 
05268 public:
05269 
05281   loopNode(NodeType typ, exprNode * cond, stmtNode * body, const Coord coord);
05282 
05290   loopNode(NodeType typ, const Coord coord);
05291 
05297   virtual ~loopNode();
05298 
05303 
05304   inline exprNode * cond() const { return _cond; }
05305   inline exprNode * get_cond() { exprNode * out = _cond; _cond = 0; return out; }
05306   inline void cond(exprNode * cond) { _cond = cond; }
05307 
05308   inline blockNode * body() const { return _body; }
05309   inline blockNode * get_body() { blockNode * out = _body; _body = 0; return out; }
05310   inline void body(blockNode * body) { _body = body; }
05311 
05312   // -- Dataflow
05313 
05314   inline FlowVal * at_loop_head() const { return _at_loop_head; }
05315   inline void at_loop_head(FlowVal * ae) { _at_loop_head = ae; }
05316 
05317   inline FlowVal * at_loop_tail() const { return _at_loop_tail; }
05318   inline void at_loop_tail(FlowVal * ae) { _at_loop_tail = ae; }
05319 
05321 };
05322 
05331 class whileNode : public loopNode
05332 {
05333 
05334 private:
05335 
05336 public:
05337 
05346   whileNode(exprNode * cond, stmtNode * body,
05347             const Coord coord = Coord::Unknown);
05348 
05354   virtual ~whileNode();
05355 
05360 
05361   virtual void visit(Visitor * the_visitor);
05362   virtual void walk(Walker & the_walker);
05363   virtual Node * change(Changer & the_changer, bool redispatch = false);
05364 
05366 
05367   // -- Dataflow
05368 
05369   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05370 
05371   // -- Clone
05372 
05373   virtual Node * clone() const { return new whileNode ( *this ); }
05374 
05375   // -- Output
05376 
05377   virtual void output_stmt(output_context & ct, Node * par);
05378 };
05379 
05388 class doNode : public loopNode
05389 {
05390 
05391 private:
05392 
05395   Coord _while_coord;
05396 
05397 public:
05398 
05408   doNode(stmtNode * body, exprNode * cond,
05409          const Coord coord = Coord::Unknown,
05410          const Coord while_coord = Coord::Unknown);
05411 
05417   virtual ~doNode();
05418 
05423 
05424   inline Coord while_coord() const { return _while_coord; }
05425   inline void while_coord(const Coord while_coord) { _while_coord = while_coord; }
05426 
05428 
05433 
05434   virtual void visit(Visitor * the_visitor);
05435   virtual void walk(Walker & the_walker);
05436   virtual Node * change(Changer & the_changer, bool redispatch = false);
05437 
05439 
05440   // -- Dataflow
05441 
05442   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05443 
05444   // -- Clone
05445 
05446   virtual Node * clone() const { return new doNode ( *this ); }
05447 
05448   // -- Output
05449 
05450   virtual void output_stmt(output_context & ct, Node * par);
05451 };
05452 
05474 class forNode : public loopNode
05475 {
05476 
05477 private:
05478 
05481   TREE exprNode * _init;
05482 
05485   TREE exprNode * _next;
05486 
05487   // FlowVal * _loop_val;
05488   // FlowVal * _break_val;
05489   // FlowVal * _continue_val;
05490 
05491 public:
05492 
05503   forNode(exprNode * init, exprNode * cond, exprNode * next,
05504           stmtNode * body, const Coord coord = Coord::Unknown);
05505 
05511   virtual ~forNode();
05512 
05517 
05518   inline exprNode * init() const { return _init; }
05519   inline exprNode * get_init() { exprNode * out = _init; _init = 0; return out; }
05520   inline void init(exprNode * init) { _init = init; }
05521 
05522   inline exprNode * next() const { return _next; }
05523   inline exprNode * get_next() { exprNode * out = _next; _next = 0; return out; }
05524   inline void next(exprNode * next) { _next = next; }
05525 
05527 
05532 
05533   virtual void visit(Visitor * the_visitor);
05534   virtual void walk(Walker & the_walker);
05535   virtual Node * change(Changer & the_changer, bool redispatch = false);
05536 
05538 
05539   // -- Dataflow
05540 
05541   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05542 
05543   // -- Clone
05544 
05545   virtual Node * clone() const { return new forNode ( *this ); }
05546 
05547   // -- Output
05548 
05549   virtual void output_stmt(output_context & ct, Node * par);
05550 };
05551 
05562 class jumpNode : public stmtNode
05563 {
05564 
05565 private:
05566 
05567 public:
05568 
05578   jumpNode(NodeType typ, const Coord coord);
05579 
05585   virtual ~jumpNode();
05586 
05587 };
05588 
05601 class gotoNode : public jumpNode
05602 {
05603 
05604 private:
05605 
05611   REF labelNode * _label;
05612 
05615   string _name;
05616 
05617 public:
05618 
05627   gotoNode(labelNode * label, const Coord coord = Coord::Unknown,
05628            NodeType typ = Goto);
05629 
05639   gotoNode(idNode * ident, const Coord coord);
05640 
05646   virtual ~gotoNode();
05647 
05652 
05653   inline labelNode * label() const { return _label; }
05654   void label(labelNode * label);
05655 
05656   inline string & name() { return _name; }
05657   inline void name(string name) { _name = name; }
05658 
05660 
05665 
05666   virtual void visit(Visitor * the_visitor);
05667   virtual void walk(Walker & the_walker);
05668   virtual Node * change(Changer & the_changer, bool redispatch = false);
05669 
05671 
05672   // -- Dataflow
05673 
05674   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05675 
05676   // -- Clone
05677 
05678   virtual Node * clone() const { return new gotoNode ( *this ); }
05679 
05680   // -- Output
05681 
05682   virtual void output_stmt(output_context & ct, Node * par);
05683 };
05684 
05696 class continueNode : public jumpNode
05697 {
05698 
05699 private:
05700 
05706   REF loopNode * _container;
05707 
05708 public:
05709 
05718   continueNode(loopNode * container, const Coord coord = Coord::Unknown);
05719 
05727   continueNode(const Coord coord = Coord::Unknown);
05728 
05734   virtual ~continueNode();
05735 
05740 
05741   inline loopNode * container() const { return _container; }
05742   inline void container(loopNode * container) { _container = container; }
05743 
05745 
05750 
05751   virtual void visit(Visitor * the_visitor);
05752   virtual void walk(Walker & the_walker);
05753   virtual Node * change(Changer & the_changer, bool redispatch = false);
05754 
05756 
05757   // -- Dataflow
05758 
05759   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05760 
05761   // -- Clone
05762 
05763   virtual Node * clone() const { return new continueNode ( *this ); }
05764 
05765   // -- Output
05766 
05767   virtual void output_stmt(output_context & ct, Node * par);
05768 };
05769   
05781 class breakNode : public jumpNode
05782 {
05783 
05784 private:
05785 
05792   REF stmtNode * _container;
05793 
05794 public:
05795 
05804   breakNode(stmtNode * container, const Coord coord = Coord::Unknown);
05805 
05813   breakNode(const Coord coord = Coord::Unknown);
05814 
05820   virtual ~breakNode();
05821 
05826 
05827   inline stmtNode * container() const { return _container; }
05828   inline void container(stmtNode * container) { _container = container; }
05829 
05831 
05836 
05837   virtual void visit(Visitor * the_visitor);
05838   virtual void walk(Walker & the_walker);
05839   virtual Node * change(Changer & the_changer, bool redispatch = false);
05840 
05842 
05843   // -- Dataflow
05844 
05845   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05846 
05847   // -- Clone
05848 
05849   virtual Node * clone() const { return new breakNode ( *this ); }
05850 
05851   // -- Output
05852 
05853   virtual void output_stmt(output_context & ct, Node * par);
05854 };
05855 
05865 class returnNode : public jumpNode
05866 {
05867 
05868 private:
05869 
05872   TREE exprNode * _expr;
05873 
05876   REF procNode * _proc;
05877 
05882   bool _is_proc_exit;
05883 
05884 public:
05885 
05896   returnNode(exprNode * expr, procNode * proc,
05897              const Coord coord = Coord::Unknown);
05898 
05899   returnNode(exprNode * expr, procNode * proc, bool proc_exit, 
05900              const Coord coord = Coord::Unknown);
05901 
05907   virtual ~returnNode();
05908 
05913 
05914   inline exprNode * expr() const { return _expr; }
05915   inline exprNode * get_expr() { exprNode * out = _expr; _expr = 0; return out; }
05916   inline void expr(exprNode * expr) { _expr = expr; }
05917 
05918   inline procNode * proc() const { return _proc; }
05919   inline void proc(procNode * proc) { _proc = proc; }
05920 
05921   bool proc_exit() { return _is_proc_exit; }
05922  private:
05923   void proc_exit(bool proc_exit) { _is_proc_exit = proc_exit; }
05924  public:
05925 
05927 
05932 
05933   virtual void visit(Visitor * the_visitor);
05934   virtual void walk(Walker & the_walker);
05935   virtual Node * change(Changer & the_changer, bool redispatch = false);
05936 
05938 
05939   // -- Dataflow
05940 
05941   virtual void dataflow(FlowVal * v, FlowProblem & fp);
05942 
05943   // -- Clone
05944 
05945   virtual Node * clone() const;
05946 
05947   // -- Output
05948 
05949   virtual void output_stmt(output_context & ct, Node * par);
05950 };
05951 
05958 class attribNode : public stmtNode
05959 {
05960 
05961 private:
05962 
05963   TREE exprNode * _arg;
05964   string _name;
05965 
05966 public:
05967 
05968   // -- Constructors
05969 
05970   attribNode(const char * name, exprNode * arg,
05971              const Coord coord = Coord::Unknown);
05972 
05973   //    Was ConvertIdToAttrib in ast.c
05974 
05975   attribNode(idNode * id, exprNode * arg);
05976 
05982   virtual ~attribNode();
05983 
05988 
05989   inline string & name() { return _name; }
05990   inline void name(string name) { _name = name; }
05991 
05992   inline exprNode * arg() const { return _arg; }
05993   inline exprNode * get_arg() { exprNode * out = _arg; _arg = 0; return out; }
05994   inline void arg(exprNode * arg) { _arg = arg; }
05995 
05997 
06002 
06003   virtual void visit(Visitor * the_visitor);
06004   virtual void walk(Walker & the_walker);
06005   virtual Node * change(Changer & the_changer, bool redispatch = false);
06006 
06008 
06009   // -- Dataflow
06010 
06011   virtual void dataflow(FlowVal * v, FlowProblem & fp) {}
06012 
06013   // -- Clone
06014 
06015   virtual Node * clone() const { return new attribNode ( *this ); }
06016 
06017   // -- Output
06018 
06019   virtual void output_stmt(output_context & ct, Node * par);
06020 };
06021 
06040 class operandNode : public exprNode {
06041  private:
06042   bool _star;  // *foo
06043   bool _addr;  // &foo
06044   typeNode * _cast;
06045   indexNode * _var;
06046   id_list _fields;  // for var.foo.bar.baz
06047   indexNode * _index; // this field is intended for array indices.
06048  public:
06049   operandNode(indexNode * the_var, const Coord coord = Coord::Unknown);
06050   operandNode(indexNode * the_var, bool star, bool addr, 
06051               const Coord coord = Coord::Unknown);
06052   operandNode(indexNode * the_var, bool star, bool addr, id_list * fields, 
06053               indexNode * array_index, const Coord coord = Coord::Unknown);
06054 
06055   void addr(bool addr) { _addr = addr; }
06056   bool addr() const { return _addr; }
06057   void star(bool star) { _star = star; }
06058   bool star() const { return _star; }
06059   void cast(typeNode * cast) { _cast = cast; }
06060   typeNode * cast(void) { return _cast; }
06061   const typeNode * cast(void) const { return _cast; }
06062   inline id_list & fields() { return _fields; }
06063   inline const id_list & fields() const { return _fields; }
06064   void index(indexNode * index) { _index = index; }
06065   indexNode * index(void) { return _index; }
06066   const indexNode * index(void) const { return _index; }
06067   void var(indexNode * var) { _var = var; }
06068   indexNode * var(void) { return _var; }
06069   const indexNode * var(void) const { return _var; }
06070 
06071   // TODO: do we want these?
06072 /*   virtual typeNode * base_type(bool TdefIndir) const; */
06073 
06074   virtual typeNode * type() const;
06075   virtual void type(typeNode *);
06076   virtual typeNode * noncast_type(bool convertArrays = true) const;
06077 
06078   virtual void eval();
06079   virtual void visit(Visitor * the_visitor);
06080   virtual void walk(Walker & the_walker);
06081   virtual Node * change(Changer & the_changer, bool redispatch = false);
06082   virtual void dataflow(FlowVal * v, FlowProblem & fp);
06083   virtual Node * clone() const { return new operandNode(*this); }
06084   virtual void output_expr(output_context & ct, Node * parent, int prec, 
06085                            Assoc assoc);
06086 };
06087 
06088 
06099 class conditiongotoNode : public gotoNode {
06100  private:
06101   indexNode * _oper1;
06102   indexNode * _oper2;
06103   Operator * _op; // must be a relational operator
06104  public:
06105   // if ( left <op_id> right ) goto label
06106   conditiongotoNode(labelNode * label, indexNode * left, unsigned int op_id,
06107                     indexNode * right, const Coord coord = Coord::Unknown);
06108   
06109   void left(indexNode * left) { _oper1 = left; }
06110   indexNode * left(void) { return _oper1; }
06111   void right(indexNode * right) { _oper2 = right; }
06112   indexNode * right(void) { return _oper2; }
06113   void op(Operator * op);
06114   // TODO:  is this safe?  can't code change the op_id directly with this?
06115   Operator * op(void) { return _op; }
06116 
06117   virtual void visit(Visitor * the_visitor);
06118   virtual void walk(Walker & the_walker);
06119   virtual Node * change(Changer & the_changer, bool redispatch = false);
06120   virtual void dataflow(FlowVal * v, FlowProblem & fp);
06121   virtual Node * clone() const { return new conditiongotoNode(*this); }
06122   virtual void output_stmt(output_context & ct, Node * par);
06123 };
06124 
06125 
06126 
06150 class threeAddrNode : public stmtNode {
06151  private:
06152   operandNode * _lhs;
06153   operandNode * _rhs1; // if op == FUNC_CALL, this is the function "name"
06154   Operator * _op; // TODO: need to add operator for FUNC_CALL
06155   operandNode * _rhs2; // NULL if op == FUNC_CALL
06156   typeNode * _sizeof_type; // if op == SIZEOF
06157   operand_list _arg_list; // for function calls
06158  public:
06159   // a = b;
06160   threeAddrNode(operandNode * lhs, operandNode * rhs, 
06161                 const Coord coord = Coord::Unknown);
06162   // a = -b;
06163   threeAddrNode(operandNode * lhs, unsigned int op_id, 
06164                 operandNode * rhs, const Coord coord = Coord::Unknown);
06165   // a = sizeof(<type>)
06166   threeAddrNode(operandNode * lhs, typeNode * type,
06167                 const Coord coord = Coord::Unknown);
06168   // a = b (op) c;
06169   threeAddrNode(operandNode * lhs, operandNode * rhs1, unsigned int op_id,
06170                 operandNode * rhs2, const Coord coord = Coord::Unknown);
06171   // a = b(...);
06172   threeAddrNode(operandNode * lhs, operandNode * func, 
06173                 operand_list * arg_list, const Coord coord = Coord::Unknown);
06174   // a(...);
06175   threeAddrNode(operandNode * func, operand_list * arg_list, 
06176                 const Coord coord = Coord::Unknown);
06177 
06178   void lhs(operandNode * lhs) { _lhs = lhs; }
06179   operandNode * lhs(void) { return _lhs; }
06180   void rhs1(operandNode * rhs1) { _rhs1 = rhs1; }
06181   operandNode * rhs1(void) { return _rhs1; }
06182   void op(Operator * op) { _op = op; }
06183   // TODO:  is this safe?  can't code change the op_id directly with this?
06184   Operator * op(void) { return _op; }
06185   // TODO:  is this safe?  if _op is FUNC_CALL, this shouldn't be allowed
06186   void rhs2(operandNode * rhs2) { _rhs2 = rhs2; }
06187   operandNode * rhs2(void) { return _rhs2; }
06188   void sizeof_type(typeNode * type) { _sizeof_type = type; }
06189   typeNode * sizeof_type(void) { return _sizeof_type; }
06190   inline operand_list & arg_list() { return _arg_list; }
06191   inline const operand_list & arg_list() const { return _arg_list; }
06192 
06193   virtual void visit(Visitor * the_visitor);
06194   virtual void walk(Walker & the_walker);
06195   virtual Node * change(Changer & the_changer, bool redispatch = false);
06196   virtual void dataflow(FlowVal * v, FlowProblem & fp);
06197   virtual Node * clone() const { return new threeAddrNode(*this); }
06198   virtual void output_stmt(output_context & ct, Node * par);
06199 };
06200 
06207 class textNode : public Node
06208 {
06209 
06210 private:
06211 
06212   string _text;
06213   bool _start_new_line;
06214   bool _suppress_output;
06215 
06216 public:
06217 
06218   // -- Constructors
06219 
06220   textNode(const char * text, bool start_new_line,
06221            const Coord coord = Coord::Unknown);
06222 
06228   virtual ~textNode();
06229 
06234 
06235   inline string & text() { return _text; }
06236   inline void text(string text) { _text = text; }
06237 
06238   inline bool start_new_line() const { return _start_new_line; }
06239   inline void start_new_line(bool start_new_line) { _start_new_line = start_new_line; }
06240 
06241   inline bool suppress_output() const { return _suppress_output; }
06242   inline void suppress_output(bool suppress) { _suppress_output = suppress; }
06243 
06245 
06250 
06251   virtual void visit(Visitor * the_visitor);
06252   virtual void walk(Walker & the_walker);
06253   virtual Node * change(Changer & the_changer, bool redispatch = false);
06254 
06256 
06257   // -- Dataflow
06258 
06259   virtual void dataflow(FlowVal * v, FlowProblem & fp) {}
06260 
06261   // -- Clone
06262 
06263   virtual Node * clone() const { return new textNode ( *this ); }
06264 
06265   // -- Output
06266 
06267   virtual void output(output_context & ct, Node * par);
06268 };
06269 
06270 // ------------------------------------------------------------
06271 //   Template functions
06272 // ------------------------------------------------------------
06273 
06274 template< class T >
06275 void dataflow_forward_list(list< T > & l, FlowVal * v, FlowProblem & fp)
06276 {
06277   for (typename list< T >::iterator p = l.begin();
06278        p != l.end();
06279        ++p)
06280     (*p)->dataflow(v, fp);
06281 }
06282 
06283 template< class T >
06284 void dataflow_reverse_list(list< T > & l, FlowVal * v, FlowProblem & fp)
06285 {
06286   for (typename list< T >::reverse_iterator p = l.rbegin();
06287        p != l.rend();
06288        ++p)
06289     (*p)->dataflow(v, fp);
06290 }
06291 
06292 template< class T >
06293 void output_list(list< T > & l, output_context & ct, Node * par)
06294 {
06295   for (typename list< T >::iterator p = l.begin();
06296        p != l.end();
06297        ++p)
06298     (*p)->output(ct, par);
06299 }
06300 
06301 template< class T >
06302 void output_delim_list(list< T > & l, output_context & ct, Node * par, char delim)
06303 {
06304   for (typename list< T >::iterator p = l.begin();
06305        p != l.end();
06306        ++p)
06307     {
06308       if (p != l.begin()) {
06309         ct << delim;
06310         ct.space();
06311         ct.continue_line();
06312       }
06313       (*p)->output(ct, par);
06314     }
06315 }
06316 
06317 template< class T >
06318 void delete_list(list< T > & l)
06319 {
06320   for (typename list< T >::iterator p = l.begin();
06321        p != l.end();
06322        ++p)
06323     delete (*p);
06324 }
06325 
06326 #endif // CBZ_AST_H

Generated on February 1, 2006
Back to the C-Breeze home page