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