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 + -
显示快捷键?