analyse.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,397 行 · 第 1/5 页

C
1,397
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


/*
ANALYSE.C -- analyse parsed tree of tokens
          -- issue any semantic errors
          -- convert parse tree into form that can be directly emitted
             using IcEmitExpr
*/

#include "plusplus.h"

#include <stddef.h>

#include "memmgr.h"
#include "stringl.h"
#include "cgfront.h"
#include "cast.h"
#include "fnovload.h"
#include "calldiag.h"
#include "fold.h"
#include "dbg.h"
#include "toggle.h"
#include "errdefns.h"
#include "codegen.h"
#include "defarg.h"
#include "fnbody.h"
#include "context.h"
#include "rtfuncod.h"
#include "ctexcept.h"
#include "objmodel.h"
#include "analtyid.h"
#   include "stats.h"
#ifdef XTRA_RPT
#   include "initdefs.h"
#endif
#ifndef NDEBUG
#include "pragdefn.h"
#endif
#include "mngless.h"

// define action-codes for (operation,operand,operand)-combination actions

typedef enum            // OPAC -- operation actions
{   REQD_INT_LEFT       // - required: integer on left
,   REQD_INT_INTREF_LEFT// - required: integer or integer ref on left
,   REQD_INT_RIGHT      // - required: integer on right
,   REQD_LVALUE_LEFT    // - required: lvalue on left
,   REQD_NOT_ENUM_LEFT  // - required: left must not be enum variable
#if 0
,   REQD_NOT_BOOL_LEFT  // - required: left must not be enum variable
#endif
,   REQD_ENUM_SAME      // - required: if enum, must be same enum
,   REQD_ZERO_LEFT      // - required: left must be 0 integer constant
,   REQD_ZERO_RIGHT     // - required: right must be 0 integer constant
,   REQD_PTR_SCALES_LEFT// - required: left not ptr to fun or void
,   REQD_PTR_SCALES_RIGHT//- required: right not ptr to fun or void
,   REQD_NOT_CONST_LEFT // - required: not constant on left
,   REQD_NOT_CONST_INIT // - required: constant on right ==> constant on left
,   REQD_NOT_ARRAY_LEFT // - required: not array on left
,   REQD_NOT_FUNC_LEFT  // - required: not function on left
,   REQD_NOT_FUNC_RIGHT // - required: not function on right
,   REQD_NOT_MFUN_LEFT  // - required: not this-member on left
,   REQD_NOT_MFUN_RIGHT // - required: not this-member on right
,   REQD_DEFD_CLPTR_LEFT// - required: defined class, when left ptr to class
,   REQD_DEFD_CLPTR_RIGHT//- required: defined class, when right ptr to class
,   REQD_CLASS_LEFT     // - required: defined class on left
,   REQD_CLASS_PTR_LEFT // - required: defined class pointer on left
,   REQD_BOOL_LEFT      // - required: boolean operator on left
,   REQD_BOOL_RIGHT     // - required: boolean operator on right
,   REQD_BOOL_LHS_ASSIGN// - required: lhs of assignment must be bool type
,   REQD_NOT_VOID_INDIRECT // - required: not void on left
,   WARN_ADJ_COMPARES   // - warn if adjacent compares
,   WARN_OPEQ_INT_TRUNC // - warn if @= int value will truncate
,   WARN_INT_TRUNC      // - warn if integer value is truncated
,   WARN_BOOL_ASSIGN_RIGHT // - warn if assignment in right boolean expression
,   WARN_BOOL_ASSIGN_LEFT  // - warn if assignment in left boolean expression
,   WARN_CONST_COND_LEFT   // - warn if constant conditional expr. on left
,   WARN_CONST_COND_RIGHT  // - warn if constant conditional expr. on right
,   WARN_POINTER_ZERO   // - warn if (p >= 0),(p < 0),(0 <= p),(0 > p)
,   WARN_USELESS_CMP    // - warn if compare is always true or false
,   WARN_MINUS_UNSIGNED // - warn if - ( <unsigned operand> )
,   CONV_INIT_REF       // - undo fetch of fetch of an initialization ref.
,   CONV_STAR_ADDR_OF   // - remove *& operations
,   CONV_SWITCH         // - switch operands
,   CONV_CMP_ZERO_LEFT  // - compare-to-zero generated on left
,   CONV_CMP_ZERO_RIGHT // - compare-to-zero generated on right
,   CONV_TO_PTR_DIFF    // - convert expression to ptr difference
,   CONV_STRIP_TYPE     // - strip one level of type informatiom
,   CONV_RVALUE_LEFT    // - get rvalue of left side
,   CONV_RVALUE_RIGHT   // - get rvalue of right side
,   CONV_MEMBER         // - convert right side from (class-qual,id) to member
,   CONV_INDEX          // - do index conversion
,   CONV_TYPE_RIGHT     // - convert type to right type
,   CONV_TYPE_LEFT      // - convert type to left type
,   CONV_AA_COMMON      // - convert to common arithmetic type
,   CONV_PP_COMMON      // - convert to common ptr
,   CONV_PP_ASSIGN      // - convert for ptr assignment
,   CONV_CTOR           // - convert a CTOR specification (5.2.3)
,   CONV_REFERENCE      // - convert a reference
,   CONV_MEANINGLESS    // - expression now meaningless
,   CONV_LOCN_RIGHT     // - set source-info. from right node
,   CONV_BOOL_ASSIGN    // - convert rhs r-value to bool (if necessary)
,   CONV_DYN_CAST       // - dynamic_cast<type>(expr)
,   CONV_CONST_CAST     // - const_cast<type>(expr)
,   CONV_REINT_CAST     // - reinterpret_cast<type>( expr )
,   CONV_STATIC_CAST    // - static_cast<type>( expr )
,   CONV_EXPLICIT_CAST  // - explicit cast
,   STATIC_TEMP_SET     // - set for static init, if required
,   STATIC_TEMP_RESET   // - reset for static init, if required
,   ASSIGN_OTHER        // - do a class, member-ptr assignment
,   INIT_CL_MP          // - do a class/memb-ptr initialization
,   CONV_FUN_MP_LEFT    // - convert left to func memb. ptr, if req'd
,   CONV_FUN_MP_RIGHT   // - convert right to func memb. ptr, if req'd
,   CONV_INIT_BARE      // - convert type(val) to val
,   CONV_FUN_MP_COLON   // - set up for colon memb-ptr extension
,   CONV_FUN_MP_CMP     // - set up for comparison memb-ptr extension
,   CONV_FUN_MP_CHECK   // - check operands for memb-ptr extension
,   RESULT_UN_ARITH     // - set type for unary arithmetic result
,   RESULT_BIN_ARITH    // - set type for binary arithmetic result
,   RESULT_BIN_SHIFT    // - set type for binary shift result
,   RESULT_CMP_ARITH    // - set type for binary arithmetic comparison
,   RESULT_ADDR_OF      // - set result for unary & (address of)
,   RESULT_INCDEC_ARITH // - increment/decrement for arithmetic operand
,   RESULT_PTR_SIZE     // - adjust right by '* sizeof(left)'
,   RESULT_INCDEC_PTR   // - increment/decrement for ptr operand
,   RESULT_QUESTMRK     // - ?: operation
,   RESULT_LVALUE       // - result is lvalue
,   RESULT_INDIRECT     // - result of an indirection
,   RESULT_BOOLEAN      // - result is boolean
,   RESULT_SIZEOF       // - set sizeof result
,   RESULT_OFFSETOF     // - set offsetof result
,   RESULT_CALL         // - call operation
,   RESULT_BARE         // - bare result is meaningful with a side effect
,   RESULT_NEW          // - "NEW" operator
,   RESULT_DLT          // - "DELETE" operator
,   RESULT_COLON_RVALUE // - common rvalue check for arith:arith, ptr:ptr
,   RESULT_COLON_AA     // - arith : arith
,   RESULT_COLON_PP     // - ptr : ptr
,   RESULT_COLON_OTHER  // - other : other ( void : void ), ( class, class )
,   RESULT_COLON        // - general result of ":" operator
,   RESULT_ASSIGN       // - result is assignment
,   RESULT_RETURN       // - result is return value
,   RESULT_RETURN_PA    // - result is return value (arith -> ptr )
,   RESULT_RETURN_AA    // - result is return value (arith -> arith)
,   RESULT_COMMA        // - result of ',' operator
,   RESULT_INIT         // - result of initialization (scalar)
,   RESULT_MINUS_PP     // - result of ptr - ptr
,   RESULT_BITQUEST     // - handle (expr-1?bit-fld-1:bit-fld-2) = expr-2
,   RESULT_TID_EXPR     // - result of typeid( <expr> )
,   RESULT_TID_TYPE     // - result of typeid( <type> )
,   RELOAD_EXPR_BINARY  // - reload type, left, right
,   RELOAD_EXPR_UNARY   // - reload type, left
,   RELOAD_EXPR_TYPE    // - reload type
,   CONV_BASIC_TYPE     // - do a TypedefModifierRemove on the current type
,   RESULT_MEMPTR_QUAL  // - do a .* or ->*
,   RESULT_OTHER_CMP    // - do comparison from member ptr., class
,   RESULT_THROW        // - do a throw
,   RESULT_SEGOP        // - do a :> operation
,   RESULT_SEGNAME      // - handle __segname( "..." )
,   RESULT_COND_EXPR    // - result is binary logical expression
,   RESULT_COND_OPRS    // - result has binary logical expressions
,   RESULT_COND_OPR     // - result has unary logical expression
,   DREF_PTR_LEFT       // - dereference left pointer
,   DREF_PTR_RIGHT      // - dereference right pointer
,   DIAG_FUNC_RIGHT_ONE // - diagnose misuse of function, function ptr (right)
,   DIAG_FUNC_MANY1     // - diagnose misuse of function, function ptr (right)
,   DIAG_FUNC_MANY2     // - diagnose misuse of function, function ptr (right)
,   DIAG_FUNC_LEFT      // - diagnose misuse of function, function ptr (left)
,   DIAG_VOID_LEFT      // - diagnose 'void' left operand
,   DIAG_VOID_RIGHT     // - diagnose 'void' left operand
#if 0
,   DIAG_AUTO_RETURN    // - diagnose return of addr/ref of auto
,   DIAG_AUTO_RETURN_REF// - diagnose return of ref of auto
,   RESULT_RETURN_VAL   // - set return value
,   RESULT_RETURN_VAL_COND // - set return value, if not class
#endif
,   CHECK_RETN_OPT      // - check for return optimization
,   ERR__IMPOSSIBLE     // - error: impossible
,   ERR__NOT_IMPL       // - error: not implemented
,   ERR__BOTH_PTR       // - error: both operands cannot be pointer
,   ERR__SUB_AP         // - error: arithmetic operand minus pointer
,   ERR__ONLY_AR        // - error: only arithmetic operands allowed
,   ERR__ONLY_AP        // - error: only arithmetic or ptr operands
,   ERR__ONLY_IN        // - error: only integral operands allowed
,   ERR__AP_ASSN        // - error: arith = ptr.
,   ERR__NO_PTR         // - error: expression must be pointer
,   ERR__INDEX          // - error: attempt to subscript non-array
,   ERR__PP_INDEX       // - error: attempt to subscript with a ptr index
,   ERR__NOT_FUN        // - error: left expression not a function
,   ERR__SEGOP          // - error: bad operands for ":>"
,   OPAC_END            // - termination action
} OPAC;


// Define action-combinations for (operation,operand,operand) actions.
// These correspond to the non-error codes for OPR_RTN_CODE.

static OPAC opac_BIN_ARITH_I[]  =   {   REQD_INT_LEFT
                                    ,   REQD_INT_RIGHT
                                    ,   CONV_RVALUE_LEFT
                                    ,   CONV_RVALUE_RIGHT
                                    ,   RESULT_BIN_ARITH
                                    ,   CONV_MEANINGLESS
                                    ,   OPAC_END
                                    };

static OPAC opac_BIN_ARITH[]    =   {   CONV_RVALUE_LEFT
                                    ,   CONV_RVALUE_RIGHT
                                    ,   RESULT_BIN_ARITH
                                    ,   CONV_MEANINGLESS
                                    ,   OPAC_END
                                    };

static OPAC opac_MINUS_PP[]     =   {   REQD_PTR_SCALES_LEFT
                                    ,   REQD_PTR_SCALES_RIGHT
                                    ,   DREF_PTR_LEFT
                                    ,   DREF_PTR_RIGHT
                                    ,   RESULT_MINUS_PP
                                    ,   REQD_DEFD_CLPTR_LEFT
                                    ,   CONV_TO_PTR_DIFF
                                    ,   CONV_MEANINGLESS
                                    ,   OPAC_END
                                    };

static OPAC opac_QUESTMRK[]     =   {   DIAG_FUNC_LEFT
                                    ,   CONV_CMP_ZERO_LEFT
                                    ,   WARN_CONST_COND_LEFT
                                    ,   RESULT_QUESTMRK
                                    ,   RESULT_COND_EXPR
                                    ,   OPAC_END
                                    };

static OPAC opac_COLON_AA[]     =   {   RESULT_COLON_RVALUE
                                    ,   RESULT_COLON_AA
                                    ,   RESULT_COLON
                                    ,   RESULT_COND_OPRS
                                    ,   OPAC_END
                                    };

static OPAC opac_COLON_PP[]     =   {   CONV_FUN_MP_COLON
                                    ,   CONV_FUN_MP_CHECK
                                    ,   DIAG_FUNC_LEFT
                                    ,   DIAG_FUNC_RIGHT_ONE
                                    ,   REQD_NOT_MFUN_LEFT
                                    ,   REQD_NOT_MFUN_RIGHT
                                    ,   RESULT_COLON_RVALUE
                                    ,   RESULT_COLON_PP
                                    ,   RELOAD_EXPR_BINARY
                                    ,   RESULT_COLON
                                    ,   RESULT_COND_OPRS

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?