home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / smc / treenode.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  12.7 KB  |  403 lines

  1. /*****************************************************************************/
  2. #ifndef _TREENODE_H_
  3. #define _TREENODE_H_
  4. /*****************************************************************************
  5.  *
  6.  *  The following enum defines a set of bit flags that can be used
  7.  *  to classify expression tree nodes. Note that some operators will
  8.  *  have more than one bit set, as follows:
  9.  *
  10.  *          TNK_CONST    implies    TNK_LEAF
  11.  *          TNK_RELOP    implies    TNK_BINOP
  12.  *          TNK_LOGOP    implies    TNK_BINOP
  13.  */
  14.  
  15. enum genTreeKinds
  16. {
  17.     TNK_NONE        = 0x0000,   // unclassified operator
  18.  
  19.     TNK_CONST       = 0x0001,   // constant     operator
  20.     TNK_LEAF        = 0x0002,   // leaf         operator
  21.     TNK_UNOP        = 0x0004,   // unary        operator
  22.     TNK_BINOP       = 0x0008,   // binary       operator
  23.     TNK_RELOP       = 0x0010,   // comparison   operator
  24.     TNK_LOGOP       = 0x0020,   // logical      operator
  25.     TNK_ASGOP       = 0x0040,   // assignment   oeprator
  26.  
  27.     /* Define composite value(s) */
  28.  
  29.     TNK_SMPOP       = TNK_UNOP|TNK_BINOP|TNK_RELOP|TNK_LOGOP
  30. };
  31.  
  32. /*****************************************************************************
  33.  *
  34.  *  The following are the values used for the 'tnFlags' field of TreeNode.
  35.  *
  36.  *  The first set of flags can be used with a large set of nodes, and thus
  37.  *  their values need to be unique. That is, one can take any expression
  38.  *  node and safely test for one of these flags.
  39.  */
  40.  
  41. enum treeNodeFlags
  42. {
  43.     TNF_BOUND       = 0x0001,   // bound ('compiled') node
  44.     TNF_LVALUE      = 0x0002,   // tree is an lvalue
  45.     TNF_NOT_USER    = 0x0004,   // compiler-added code
  46.     TNF_ASG_DEST    = 0x0008,   // expression is an assignment target
  47.     TNF_BEEN_CAST   = 0x0010,   // this value has been cast
  48.     TNF_COND_TRUE   = 0x0020,   // condition is known to be true
  49.     TNF_PAREN       = 0x0040,   // expression was explicitly parenthesized
  50.  
  51.     //---------------------------------------------------------------------
  52.     //  The remaining flags can be used only with one or a few nodes, and
  53.     //  so their values need not be distinct (other than within the set
  54.     //  that goes with a particular node, of course). That is, testing
  55.     //  one of these flags only makes sense if the node kind is tested
  56.     //  as well to make sure it's the right one for the particular flag.
  57.     //---------------------------------------------------------------------
  58.  
  59.     TNF_IF_HASELSE  = 0x8000,   // TN_IF        is an "else" part present?
  60.  
  61.     TNF_LCL_BASE    = 0x8000,   // TN_LCL_SYM   this is a "baseclass" ref
  62.  
  63.     TNF_VAR_ARG     = 0x8000,   // TN_VAR_DECL  this is an argument decl
  64.     TNF_VAR_INIT    = 0x4000,   // TN_VAR_DECL  there is an initializer
  65.     TNF_VAR_STATIC  = 0x2000,   // TN_VAR_DECL  variable is static
  66.     TNF_VAR_CONST   = 0x1000,   // TN_VAR_DECL  variable is constant
  67.     TNF_VAR_SEALED  = 0x0800,   // TN_VAR_DECL  variable is read-only
  68.     TNF_VAR_UNREAL  = 0x0400,   // TN_VAR_DECL  variable is compiler-invented
  69.  
  70.     TNF_ADR_IMPLICIT= 0x8000,   // TN_ADDROF    automatic "&" for arrays/funcs
  71.     TNF_ADR_OUTARG  = 0x4000,   // TN_ADDROF    this is an "out" argument
  72.  
  73.     TNF_EXP_CAST    = 0x8000,   // TN_CAST      explicit cast?
  74.     TNF_CHK_CAST    = 0x4000,   // TN_CAST      cast that needs to be checked?
  75.     TNF_CTX_CAST    = 0x2000,   // TN_CAST      context wrap/unwrap cast?
  76.  
  77.     TNF_STR_ASCII   = 0x8000,   // TN_CNS_STR   A"string"
  78.     TNF_STR_WIDE    = 0x4000,   // TN_CNS_STR   L"string"
  79.     TNF_STR_STR     = 0x2000,   // TN_CNS_STR   S"string"
  80.  
  81.     TNF_BLK_CATCH   = 0x8000,   // TN_BLOCK     this is a "catch" block
  82.     TNF_BLK_FOR     = 0x4000,   // TN_BLOCK     this is an implicit for loop scope
  83.     TNF_BLK_NUSER   = 0x2000,   // TN_BLOCK     scope added by compiler
  84.  
  85.     TNF_BLK_HASFIN  = 0x8000,   // TN_TRY       is a "finally" present?
  86.  
  87.     TNF_ADD_NOCAT   = 0x8000,   // TN_ADD       operands bound, not string concat
  88.  
  89.     TNF_ASG_INIT    = 0x8000,   // TN_ASG       initialization assignment
  90.  
  91.     TNF_REL_NANREV  = 0x8000,   // TN_GT/LT/..  reversed NaN sense
  92.  
  93.     TNF_CALL_NVIRT  = 0x8000,   // TN_CALL      the call is non-virtual
  94.     TNF_CALL_VARARG = 0x4000,   // TN_CALL      the call has "extra" args
  95.     TNF_CALL_MODOBJ = 0x2000,   // TN_CALL      args may modify instance ptr
  96.     TNF_CALL_STRCAT = 0x1000,   // TN_CALL      string concat assignment
  97.     TNF_CALL_ASGOP  = 0x0800,   // TN_CALL      assignment  operator
  98.     TNF_CALL_ASGPRE = 0x0400,   // TN_CALL      pre-inc/dec operator
  99.     TNF_CALL_GOTADR = 0x0200,   // TN_CALL      addr of result already computed
  100.     TNF_CALL_CHKOVL = 0x0100,   // TN_CALL      checking overloaded operator
  101.  
  102.     TNF_NAME_TYPENS = 0x8000,   // TN_NAME      the name should be a type
  103. };
  104.  
  105. /*****************************************************************************/
  106.  
  107. DEFMGMT
  108. class TreeNode
  109. {
  110. public:
  111.  
  112. #ifdef FAST
  113.     BYTE            tnOper;                 // operator
  114.     BYTE            tnVtyp;                 // var_type of the node
  115. #else
  116.     treeOps         tnOper;                 // operator
  117.     var_types       tnVtyp;                 // var_type of the node
  118. #endif
  119.  
  120.     treeOps         tnOperGet() { return (treeOps  )tnOper; }
  121.     var_types       tnVtypGet() { return (var_types)tnVtyp; }
  122.  
  123.     unsigned short  tnFlags;                // see TNF_xxxx above
  124.  
  125.     unsigned        tnLineNo;               // for error reporting
  126. //  unsigned short  tnColumn;               // for error reporting
  127.  
  128.     TypDef          tnType;                 // type of the node (if bound)
  129.  
  130.     //----------------------------------------------------------------
  131.  
  132.     union
  133.     {
  134.         /* tnOp     -- unary/binary operator */
  135.  
  136.         struct
  137.         {
  138.             Tree            tnOp1;
  139.             Tree            tnOp2;
  140.         }
  141.             tnOp;
  142.  
  143.         /* tnIntCon -- integer constant (TN_CNS_INT) */
  144.  
  145.         struct
  146.         {
  147.             __int32         tnIconVal;
  148.         }
  149.             tnIntCon;
  150.  
  151.         /* tnLngCon -- long    constant (TN_CNS_LNG) */
  152.  
  153.         struct
  154.         {
  155.             __int64         tnLconVal;
  156.         }
  157.             tnLngCon;
  158.  
  159.         /* tnFltCon -- float   constant (TN_CNS_FLT) */
  160.  
  161.         struct
  162.         {
  163.             float           tnFconVal;
  164.         }
  165.             tnFltCon;
  166.  
  167.         /* tnDblCon -- double  constant (TN_CNS_DBL) */
  168.  
  169.         struct
  170.         {
  171.             double          tnDconVal;
  172.         }
  173.             tnDblCon;
  174.  
  175.         /* tnStrCon -- string  constant (TN_CNS_STR) */
  176.  
  177.         struct
  178.         {
  179.             stringBuff      tnSconVal;
  180.             size_t          tnSconLen   :31;
  181.             size_t          tnSconLCH   :1; // encoded "large" characters present?
  182.         }
  183.             tnStrCon;
  184.  
  185.         /* tnName   -- unbound name reference */
  186.  
  187.         struct
  188.         {
  189.             Ident           tnNameId;
  190.         }
  191.             tnName;
  192.  
  193.         /* tnSym    -- unbound symbol reference */
  194.  
  195.         struct
  196.         {
  197.             SymDef          tnSym;
  198.             SymDef          tnScp;
  199.         }
  200.             tnSym;
  201.  
  202.         /* tnBlock  -- block/scope */
  203.  
  204.         struct
  205.         {
  206.             Tree            tnBlkParent;    // parent scope or NULL
  207.             Tree            tnBlkStmt;      // statement list of body
  208.             Tree            tnBlkDecl;      // declaration list or NULL
  209.             unsigned        tnBlkSrcEnd;    // last source line in block
  210.         }
  211.             tnBlock;
  212.  
  213.         /* tnDcl    -- local declaration */
  214.  
  215.         struct
  216.         {
  217.             Tree            tnDclNext;      // next declaration in scope
  218.             Tree            tnDclInfo;      // name w/optional initializer
  219.             SymDef          tnDclSym;       // local symbol (if defined)
  220.         }
  221.             tnDcl;
  222.  
  223.         /* tnSwitch -- switch statement */
  224.  
  225.         struct
  226.         {
  227.             Tree            tnsValue;       // switch value
  228.             Tree            tnsStmt;        // body of the switch
  229.             Tree            tnsCaseList;    // list of case/default labels - head
  230.             Tree            tnsCaseLast;    // list of case/default labels - tail
  231.         }
  232.             tnSwitch;
  233.  
  234.         /* tnCase   -- case/default label */
  235.  
  236.         struct
  237.         {
  238.             Tree            tncNext;        // next label
  239.             Tree            tncValue;       // label value (NULL = default)
  240.             ILblock         tncLabel;       // assigned IL label
  241.         }
  242.             tnCase;
  243.  
  244.         /* tnInit   -- {}-style initializer */
  245.  
  246.         struct
  247.         {
  248.             DefSrcDsc       tniSrcPos;      // initializer's source section
  249.             SymDef          tniCompUnit;    // initializer's compilation unit
  250.         }
  251.             tnInit;
  252.  
  253.         //-----------------------------------------------------------------
  254.         // The flavors that follow only appear within bound expressions:
  255.         //-----------------------------------------------------------------
  256.  
  257.         /* tnLclSym -- local variable */
  258.  
  259.         struct
  260.         {
  261.             SymDef          tnLclSym;       // variable symbol
  262.         }
  263.             tnLclSym;
  264.  
  265.         /* tnVarSym -- global variable or data member */
  266.  
  267.         struct
  268.         {
  269.             SymDef          tnVarSym;       // variable/data member
  270.             Tree            tnVarObj;       // instance pointer or NULL
  271.         }
  272.             tnVarSym;
  273.  
  274.         /* tnFncSym -- function or method */
  275.  
  276.         struct
  277.         {
  278.             SymDef          tnFncSym;       // function symbol
  279.             SymDef          tnFncScp;       // scope for lookup
  280.             Tree            tnFncObj;       // instance pointer or NULL
  281.             Tree            tnFncArgs;      // argument list
  282.         }
  283.             tnFncSym;
  284.  
  285.         /* tnBitFld -- bitfield data member */
  286.  
  287.         struct
  288.         {
  289.             Tree            tnBFinst;       // instance pointer
  290.             SymDef          tnBFmsym;       // data member symbol
  291.             unsigned        tnBFoffs;       // member base offset
  292.             unsigned char   tnBFlen;        // number of bits
  293.             unsigned char   tnBFpos;        // offset of first bit
  294.         }
  295.             tnBitFld;
  296.     };
  297.  
  298.     //---------------------------------------------------------------------
  299.  
  300.     bool            tnOperMayThrow();
  301.  
  302.     //---------------------------------------------------------------------
  303.  
  304.     static
  305.     const   BYTE    tnOperKindTable[TN_COUNT];
  306.  
  307.     static
  308.     unsigned        tnOperKind(treeOps      tnOper)
  309.     {
  310.         assert(tnOper < TN_COUNT);
  311.  
  312.         return  tnOperKindTable[tnOper];
  313.     }
  314.  
  315.     unsigned        tnOperKind()
  316.     {
  317.         assert(tnOper < TN_COUNT);
  318.  
  319.         return  tnOperKindTable[tnOper];
  320.     }
  321.  
  322.     static
  323.     int             tnOperIsConst(treeOps   tnOper)
  324.     {
  325.         return  (tnOperKindTable[tnOper] & TNK_CONST) != 0;
  326.     }
  327.  
  328.     int             tnOperIsConst()
  329.     {
  330.         return  (tnOperKindTable[tnOper] & TNK_CONST) != 0;
  331.     }
  332.  
  333.     static
  334.     int             tnOperIsLeaf(treeOps    tnOper)
  335.     {
  336.         return  (tnOperKindTable[tnOper] & TNK_LEAF ) != 0;
  337.     }
  338.  
  339.     int             tnOperIsLeaf()
  340.     {
  341.         return  (tnOperKindTable[tnOper] & TNK_LEAF ) != 0;
  342.     }
  343.  
  344.     static
  345.     int             tnOperIsCompare(treeOps tnOper)
  346.     {
  347.         return  (tnOperKindTable[tnOper] & TNK_RELOP) != 0;
  348.     }
  349.  
  350.     int             tnOperIsCompare()
  351.     {
  352.         return  (tnOperKindTable[tnOper] & TNK_RELOP) != 0;
  353.     }
  354.  
  355.     static
  356.     int             tnOperIsLogical(treeOps tnOper)
  357.     {
  358.         return  (tnOperKindTable[tnOper] & TNK_LOGOP) != 0;
  359.     }
  360.  
  361.     int             tnOperIsLogical()
  362.     {
  363.         return  (tnOperKindTable[tnOper] & TNK_LOGOP) != 0;
  364.     }
  365.  
  366.     static
  367.     int             tnOperIsUnary(treeOps   tnOper)
  368.     {
  369.         return  (tnOperKindTable[tnOper] & TNK_UNOP ) != 0;
  370.     }
  371.  
  372.     int             tnOperIsUnary()
  373.     {
  374.         return  (tnOperKindTable[tnOper] & TNK_UNOP ) != 0;
  375.     }
  376.  
  377.     static
  378.     int             tnOperIsBinary(treeOps  tnOper)
  379.     {
  380.         return  (tnOperKindTable[tnOper] & TNK_BINOP) != 0;
  381.     }
  382.  
  383.     int             tnOperIsBinary()
  384.     {
  385.         return  (tnOperKindTable[tnOper] & TNK_BINOP) != 0;
  386.     }
  387.  
  388.     static
  389.     int             tnOperIsSimple(treeOps  tnOper)
  390.     {
  391.         return  (tnOperKindTable[tnOper] & TNK_SMPOP) != 0;
  392.     }
  393.  
  394.     int             tnOperIsSimple()
  395.     {
  396.         return  (tnOperKindTable[tnOper] & TNK_SMPOP) != 0;
  397.     }
  398. };
  399.  
  400. /*****************************************************************************/
  401. #endif//_TREENODE_H_
  402. /*****************************************************************************/
  403.