ptree.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,173 行 · 第 1/5 页
C
2,173 行
/****************************************************************************
*
* 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!
*
****************************************************************************/
#include "plusplus.h"
#include <stddef.h>
#include "errdefns.h"
#include "watcom.h"
#include "memmgr.h"
#include "stringl.h"
#include "cgfront.h"
#include "fnovload.h"
#include "ppintnam.h"
#include "name.h"
#include "class.h"
#include "carve.h"
#include "vstk.h"
#include "initdefs.h"
#include "stats.h"
#include "floatsup.h"
#include "codegen.h"
#include "pcheader.h"
#include "conpool.h"
#include "defarg.h"
#define MAX_DIGITS 30
#define BLOCK_PTREE 32
static carve_t carvePTREE;
ExtraRptCtr( nodes_defined ); // # nodes currently defined
ExtraRptCtr( nodes_hiwater ); // hi-water mark for above
ExtraRptCtr( total_frees ); // total # PTreeFreeSubtrees
ExtraRptCtr( null_frees ); // # PTreeFreeSubtrees( NULL )
ExtraRptCtr( simple_frees ); // # PTreeFreeSubtrees( node )
// for use by IsLinkerConstant traversal routine
static PTREE linkerConstantSymbolNode;
static target_size_t linkerConstantOffset;
static boolean linkerConstantFlag;
// enumerate OP_CNV_NO_... as 0, 1, 2, ...
//
#define OPCNV( code, contents ) __PASTE( OP_CNV_NO_, code )
enum
#include "ppopscnv.h"
;
#undef OPCNV
// enumerate OPCNV_... as 0x01, 0x02, 0x03, ...
//
#define OPCNV( code, contents ) \
__PASTE( OPCNV_, code ) = ( 1 + __PASTE( OP_CNV_NO_, code ) ) \
<< PTO_CNV_SHIFT
enum
#include "ppopscnv.h"
;
#undef OPCNV
static PTS_FLAG ptreePTSFlags[] = // one for each PTREE node type
#define PTOP( code, bits ) bits
#include "ptreeop.h"
#undef PTOP
;
static PTO_FLAG oper_flags[] ={ // definitions for unary, binary oper.s
#include "ppopsflg.h"
};
static void ptreeInit( // INITIALIZATION
INITFINI* defn ) // - definition
{
defn = defn;
carvePTREE = CarveCreate( sizeof( struct parse_tree_node ), BLOCK_PTREE );
ExtraRptRegisterCtr( &nodes_hiwater
, "high-water mark: PTREE nodes used" );
ExtraRptRegisterCtr( &total_frees, "total # of PTreeFreeSubtrees" );
ExtraRptRegisterCtr( &null_frees, "total # of NULL PTreeFreeSubtrees" );
ExtraRptRegisterCtr( &simple_frees, "total # of simple PTreeFreeSubtrees" );
}
static void ptreeFini( // COMPLETION
INITFINI* defn ) // - definition
{
defn = defn;
#ifndef NDEBUG
CarveVerifyAllGone( carvePTREE, "PTREE" );
#endif
CarveDestroy( carvePTREE );
}
INITDEFN( parse_tree, ptreeInit, ptreeFini )
PTREE PTreeSetLocn( // SET LOCATION IN A PTREE NODE
PTREE tree, // - node
TOKEN_LOCN *locn ) // - location
{
if( ( locn != NULL ) && ( locn->src_file != NULL ) ) {
TokenLocnAssign( tree->locn, *locn );
}
return tree;
}
PTREE PTreeAlloc( void )
/**********************/
{
PTREE tree; // - allocated entry
ExtraRptIncrementCtr( nodes_defined );
ExtraRptHighWater( nodes_defined, nodes_hiwater );
tree = CarveAlloc( carvePTREE );
tree->op = PT_NULL;
tree->cgop = CO_NOP;
tree->id_cgop = CO_NOP;
tree->flags = PTF_NULL;
tree->type = NULL;
tree->sym_name = NULL;
tree->locn.src_file = NULL;
tree->locn.line = 0;
tree->locn.column = 0;
tree->decor = NULL;
return tree;
}
PTREE PTreeAssignReloc( PTREE to, PTREE from, RELOC_LIST *list )
/**************************************************************/
{
PTREE partner;
if( to == NULL ) {
ExtraRptIncrementCtr( nodes_defined );
ExtraRptHighWater( nodes_defined, nodes_hiwater );
to = CarveAlloc( carvePTREE );
}
*to = *from;
switch( to->op ) {
case PT_DUP_EXPR:
if( to->u.dup.subtree[0] != NULL ) {
/* disable former duplicated expression */
from->u.dup.subtree[0] = NULL;
from->u.dup.node = NULL;
/* inform partner about the change */
partner = to->u.dup.node;
partner->u.dup.node = to;
}
break;
case PT_SYMBOL:
to->u.symcg.result = ScopeDupResult( from->u.symcg.result );
break;
}
to->decor = PtdDuplicateReloc( from, list );
return to;
}
PTREE PTreeAssign( PTREE to, PTREE from )
/***************************************/
{
return PTreeAssignReloc( to, from, NULL );
}
PTREE PTreeFree( PTREE tree )
/***************************/
{
CPP_FLOAT *fp_val;
if( tree != NULL ) {
#ifndef NDEBUG
if( tree->op == PT_DUP_EXPR ) {
if( tree->u.dup.subtree[0] != NULL ) {
CFatal( "trying to free a duplicated expr with a dangling reference" );
}
}
#endif
if( tree->decor ) {
PtdFree( tree );
}
if( tree->op == PT_FLOATING_CONSTANT ) {
fp_val = tree->u.floating_constant;
tree->u.floating_constant = NULL;
if( fp_val != NULL ) {
BFFree( fp_val );
}
}
ExtraRptDecrementCtr( nodes_defined );
CarveFree( carvePTREE, tree );
}
return NULL;
}
void PTreeFreeSubtrees( PTREE tree )
/**********************************/
{
ExtraRptIncrementCtr( total_frees );
if( tree == NULL ) {
ExtraRptIncrementCtr( null_frees );
return;
}
if( ptreePTSFlags[ tree->op ] & PTS_OPERATOR ) {
PTreeTraversePostfix( tree, PTreeFree );
} else {
ExtraRptIncrementCtr( simple_frees );
PTreeFree( tree );
}
}
static PTREE makeExpr( ptree_op_t op, CGOP cgop, PTREE sub_1, PTREE sub_2 )
{
PTREE new_tree;
new_tree = PTreeAlloc();
new_tree->op = op;
new_tree->cgop = cgop;
new_tree->u.subtree[0] = sub_1;
new_tree->u.subtree[1] = sub_2;
return new_tree;
}
PTREE PTreeBinary( CGOP cgop, PTREE left, PTREE right )
/*****************************************************/
{
PTREE node = makeExpr( PT_BINARY, cgop, left, right );
if( cgop != CO_COLON_COLON ) {
node->flags |= PTF_LV_CHECKED;
}
return node;
}
PTREE PTreeUnary( CGOP cgop, PTREE expr )
/***************************************/
{
PTREE node = makeExpr( PT_UNARY, cgop, expr, NULL );
node->flags |= PTF_LV_CHECKED;
return node;
}
PTREE PTreeReplaceLeft( PTREE expr, PTREE new_left )
/**************************************************/
{
expr->u.subtree[0] = new_left;
return expr;
}
PTREE PTreeReplaceRight( PTREE expr, PTREE new_right )
/****************************************************/
{
expr->u.subtree[1] = new_right;
return expr;
}
static PTREE strLiteral // MAKE A STRING LITERAL NODE
( STRING_CONSTANT str // - the string
, type_id base ) // - the base type
{
PTREE new_tree;
target_size_t str_len;
str_len = StringAWStrLen( str );
new_tree = PTreeAlloc();
new_tree->op = PT_STRING_CONSTANT;
new_tree->u.string = str;
new_tree->type = MakeArrayOf( str_len, GetBasicType( base ) );
new_tree->flags |= PTF_LVALUE | PTF_LV_CHECKED;
return new_tree;
}
PTREE PTreeLiteral( STRING_CONSTANT str )
/***************************************/
{
return strLiteral( str, TYP_CHAR );
}
PTREE PTreeLiteralWide( STRING_CONSTANT str )
/*******************************************/
{
return strLiteral( str, TYP_WCHAR );
}
PTREE PTreeStringLiteralConcat( PTREE left, PTREE right )
/*******************************************************/
{
STRING_CONSTANT left_str;
STRING_CONSTANT right_str;
STRING_CONSTANT new_str;
TOKEN_LOCN err_locn;
PTREE new_literal;
PTreeExtractLocn( right, &err_locn );
left_str = left->u.string;
right_str = right->u.string;
if( left_str->wide_string != right_str->wide_string ) {
PTreeSetErrLoc( right );
CErr1( ERR_MISMATCHED_WIDE_STRING_CONCATENATION );
}
new_str = StringConcat( left_str, right_str );
if( ! SrcFileAreTLSameLine( &(left->locn), &(right->locn) ) ) {
StringConcatDifferentLines( new_str );
}
if( new_str->wide_string ) {
new_literal = strLiteral( new_str, TYP_WCHAR );
} else {
new_literal = strLiteral( new_str, TYP_CHAR );
}
PTreeSetLocn( new_literal, &err_locn );
PTreeFree( left );
PTreeFree( right );
return new_literal;
}
PTREE PTreeMSSizeofKludge( PTREE type_id )
/****************************************/
{
TYPE tdef;
tdef = type_id->type;
DbgAssert( tdef != NULL );
PTreeFreeSubtrees( type_id );
return( PTreeType( tdef ) );
}
PTREE PTreeTListAppend( PTREE start, PTREE new_tree )
/***************************************************/
{
new_tree->u.type.next = start;
return new_tree;
}
PTREE ThrowsAnything( void )
/**************************/
{
PTREE dot_dot_dot;
dot_dot_dot = PTreeType( GetBasicType( TYP_DOT_DOT_DOT ) );
return PTreeTListAppend( NULL, dot_dot_dot );
}
PTREE PTreeType( TYPE type )
/**************************/
{
PTREE new_tree;
new_tree = PTreeAlloc();
new_tree->op = PT_TYPE;
new_tree->type = type;
new_tree->u.type.next = NULL;
new_tree->u.type.scope = NULL;
new_tree->flags |= PTF_LV_CHECKED;
return new_tree;
}
static PTREE ptreeSetConstantType( PTREE node, type_id id )
{
node->type = GetBasicType( id );
node->flags |= PTF_LV_CHECKED;
return node;
}
static PTREE allocConstant( uint_8 op, type_id id )
{
PTREE new_tree;
new_tree = PTreeAlloc();
new_tree->op = op;
new_tree = ptreeSetConstantType( new_tree, id );
return new_tree;
}
PTREE PTreeBoolConstant( int v )
/******************************/
{
return PTreeIntConstant( v, TYP_BOOL );
}
PTREE PTreeIntConstant( signed long v, type_id id )
/*************************************************/
{
PTREE new_tree;
new_tree = allocConstant( PT_INT_CONSTANT, id );
Int64From32( new_tree->type, v, &new_tree->u.int64_constant );
return new_tree;
}
PTREE PTreeInt64Constant( signed_64 v, type_id id )
/*************************************************/
{
PTREE new_tree;
new_tree = allocConstant( PT_INT_CONSTANT, id );
new_tree->u.int64_constant = v;
return new_tree;
}
static CPP_FLOAT *makeFPRep( char *buff, unsigned len )
{
DbgAssert( buff[len] == '\0' );
return BFCnvSF( buff, buff + len );
}
PTREE PTreeFloatingConstantStr( char *buff, unsigned len, type_id id )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?