ptreedec.c

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

C
1,078
字号
/****************************************************************************
*
*                            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 "cgfront.h"
#include "ring.h"
#include "initdefs.h"
#include "fnbody.h"
#include "pcheader.h"

#ifndef NDEBUG
    #include "errdefns.h"
#endif

#define PTD_DEFS                                                          \
                            /* PTD_KIND -- kinds of entries             */\
 PTD_DEF( PTD_CTORCOMP     )/* - ctored component (code)                */\
,PTD_DEF( PTD_CTORED_COMP  )/* - ctored component (scope-call)          */\
,PTD_DEF( PTD_DEL_DTORED   )/* - complete dtor of element to be del'ed  */\
,PTD_DEF( PTD_DEL_DTOR_ARR )/* - dtor of array to be deleted            */\
,PTD_DEF( PTD_DEL_DTOR_ELM )/* - dtor of element to be deleted          */\
,PTD_DEF( PTD_DEL_DTOR_SIZE)/* - size of element in object to be del'd  */\
,PTD_DEF( PTD_DTOR_EXPR    )/* - dtorable object in expression          */\
,PTD_DEF( PTD_DTOR_KIND    )/* - dtor kind                              */\
,PTD_DEF( PTD_DTOR_REF     )/* - dtor reference                         */\
,PTD_DEF( PTD_DTOR_SCOPE   )/* - dtorable object in scope               */\
,PTD_DEF( PTD_DTOR_USE     )/* - dtor usage                             */\
,PTD_DEF( PTD_EXPR_CONST   )/* - expression is constant                 */\
,PTD_DEF( PTD_INIT_SYM_END )/* - end of initialization of symbol        */\
,PTD_DEF( PTD_NEW_ALLOC    )/* - signal new allocation                  */\
,PTD_DEF( PTD_NEW_CTOR     )/* - ctoring new'ed expression              */\
,PTD_DEF( PTD_OBJ_OFFSET   )/* - push object: offset                    */\
,PTD_DEF( PTD_OBJ_PUSH     )/* - push object                            */\
,PTD_DEF( PTD_OBJ_POP      )/* - pop object                             */\
,PTD_DEF( PTD_OBJ_SYM      )/* - push object: symbol                    */\
,PTD_DEF( PTD_RETNOPT_VAR  )/* - gen IC_RETNOPT_VAR                     */\
,PTD_DEF( PTD_RETNOPT_END  )/* - gen IC_RETNOPT_END                     */\
,PTD_DEF( PTD_SCOPE_CALL   )/* - call to possible throwable function    */\
,PTD_DEF( PTD_SCOPE_GEN    )/* - force scope to have statement table    */\
,PTD_DEF( PTD_THROW        )/* - throw (or equivalent) in expression    */\
,PTD_DEF( PTD_VB_DELTA     )/* - virtual base delta                     */\
,PTD_DEF( PTD_VB_EXACT     )/* - virtual base exact                     */\
,PTD_DEF( PTD_VB_INDEX     )/* - virtual base index                     */\
,PTD_DEF( PTD_VB_OFFSET    )/* - virtual base offset                    */\
,PTD_DEF( PTD_VF_INDEX     )/* - virtual function index                 */\
,PTD_DEF( PTD_VF_OFFSET    )/* - virtual function offset                */\
,PTD_DEF( PTD_VF_SYM       )/* - virtual function symbol                */\
,PTD_DEF( PTD_OFFSETOF_EXPR)/* - offsetof field name                    */\
,PTD_DEF( PTD_PCH_FREE     )/* - used to mark free PTDs for PCH write   */\
,PTD_DEF( MAX_PTD_KIND )    /* bound for debugging                      */

typedef enum                    // PTD_KIND -- kinds of entries
{
    #define PTD_DEF( a ) a
    PTD_DEFS
    #undef  PTD_DEF
} PTD_KIND;

typedef enum                    // PTD_FMT -- formats of entries
{   PTD_FMT_BASE                // - base only
,   PTD_FMT_SYMBOL              // - symbol
,   PTD_FMT_OFFSET              // - offset
,   PTD_FMT_SIZE                // - size
,   PTD_FMT_TYPE                // - type
,   PTD_FMT_PTREE               // - parse tree
} PTD_FMT;

typedef struct ptd_base         PTD_BASE;
typedef struct ptd_symbol       PTD_SYMBOL;
typedef struct ptd_offset       PTD_OFFSET;
typedef struct ptd_size         PTD_SIZE;
typedef struct ptd_type         PTD_TYPE;
typedef struct ptd_ptree        PTD_PTREE;

struct ptd_base                 // PTD_BASE -- base entry
{   PTD* next;                  // - next in list
    PTD_KIND kind;              // - type of entry
    PTD_FMT fmt;                // - format of entry
    unsigned :0;                // - force alignment
};

struct ptd_symbol               // PTD_SYMBOL -- entry containing symbol
{   PTD_BASE base;              // - base
    SYMBOL sym;                 // - symbol
};

struct ptd_type                 // PTD_TYPE -- entry containing type
{   PTD_BASE base;              // - base
    TYPE type;
};

struct ptd_ptree                // PTD_PTREE -- entry containing parse tree
{   PTD_BASE base;              // - base
    PTREE tree;
};

struct ptd_offset               // PTD_OFFSET -- entry containing offset
{   PTD_BASE base;              // - base
    target_offset_t offset;     // - offset
};

struct ptd_size                 // PTD_SIZE -- entry containing size
{   PTD_BASE base;              // - base
    target_size_t size;         // - size
};


union ptd                       // PTD - union of all decorations
{   PTD_BASE base;              // - base
    PTD_SYMBOL symbol;          // - symbol entry
    PTD_OFFSET off;             // - offset entry
    PTD_SIZE size;              // - size entry
    PTD_TYPE type;              // - type entry
    PTD_PTREE ptree;            // - ptree entry
};



static carve_t carvePTD;        // - carve info


static PTD* ptdAlloc            // ALLOCATE AND INITIALIZE BASE ENTRY
    ( PTD** ring                // - expression
    , PTD_KIND kind             // - kind of entry
    , PTD_FMT fmt )             // - format of entry
{
    PTD* ptd;                   // - allocated entry

    ptd = RingCarveAlloc( carvePTD, ring );
    ptd->base.kind = kind;
    ptd->base.fmt = fmt;
    return ptd;
}


static PTREE ptdOffset          // ALLOCATE AN OFFSET ENTRY
    ( PTREE expr                // - expression
    , target_offset_t offset    // - offset
    , PTD_KIND kind )           // - kind of entry
{
    PTD* pto;                   // - new entry

    pto = ptdAlloc( &expr->decor, kind, PTD_FMT_OFFSET );
    pto->off.offset = offset;
    return expr;
}


static PTREE ptdSize            // ALLOCATE A SIZE ENTRY
    ( PTREE expr                // - expression
    , target_size_t size        // - size
    , PTD_KIND kind )           // - kind of entry
{
    PTD* pto;                   // - new entry

    pto = ptdAlloc( &expr->decor, kind, PTD_FMT_SIZE );
    pto->size.size = size;
    return expr;
}


static PTREE ptdType            // ALLOCATE A TYPE ENTRY
    ( PTREE expr                // - expression
    , TYPE type                 // - type to be stashed
    , PTD_KIND kind )           // - kind of entry
{
    PTD* pto;                   // - new entry

    pto = ptdAlloc( &expr->decor, kind, PTD_FMT_TYPE );
    pto->type.type = type;
    return expr;
}


static PTREE ptdBase            // DECORATE WITH BASIC ENTRY
    ( PTREE expr                // - expression
    , PTD_KIND kind )           // - kind of entry
{
    ptdAlloc( &expr->decor, kind, PTD_FMT_BASE );
    return expr;
}


static PTREE ptdSymbol          // DECORATE WITH A SYMBOL
    ( PTREE expr                // - expression
    , SYMBOL sym                // - symbol
    , PTD_KIND kind )           // - kind of decoration
{
    PTD* ptd;                   // - allocated entry

    ptd = ptdAlloc( &expr->decor, kind, PTD_FMT_SYMBOL );
    ptd->symbol.sym = sym;
    return expr;
}


static PTREE ptdPTree           // DECORATE WITH A PTREE
    ( PTREE expr                // - expression
    , PTREE tree                // - parse tree
    , PTD_KIND kind )           // - kind of decoration
{
    PTD* ptd;                   // - allocated entry

    ptd = ptdAlloc( &expr->decor, kind, PTD_FMT_PTREE );
    ptd->ptree.tree = tree;
    return expr;
}


PTREE PtdFree                   // FREE ENTRIES FOR A PARSE TREE NODE
    ( PTREE expr )              // - parse tree node
{
    RingCarveFree( carvePTD, &expr->decor );
    return expr;
}


PTD* PtdDuplicateReloc          // DUPLICATE DECORATION, RELOC SYMBOLS
    ( PTREE src                 // - source PTREE
    , RELOC_LIST *reloc_list )  // - relocation list
{
    PTD* ring;                  // - ring to be used
    PTD* curr;                  // - current entry
    PTD* copy;                  // - copied entry

    ring = NULL;
    RingIterBeg( src->decor, curr ) {
        copy = ptdAlloc( &ring, curr->base.kind, curr->base.fmt );
        switch( curr->base.fmt ) {
          case PTD_FMT_BASE :
            break;
          case PTD_FMT_SYMBOL :
            if( reloc_list == NULL ) {
                copy->symbol.sym = curr->symbol.sym;
            } else {
                copy->symbol.sym = SymReloc( curr->symbol.sym, reloc_list );
            }
            break;
          case PTD_FMT_TYPE :
            copy->type.type = curr->type.type;
            break;
          case PTD_FMT_OFFSET :
            copy->off.offset = curr->off.offset;
            break;
          case PTD_FMT_SIZE :
            copy->size.size = curr->size.size;
            break;
          DbgDefault( "PtdDuplicate -- bad format" );
        }
    } RingIterEnd( curr );
    return ring;
}

PTD* PtdDuplicate               // DUPLICATE DECORATION
    ( PTREE src )               // - source PTREE
{
    return( PtdDuplicateReloc( src, NULL ) );
}


PTREE PtdInsert                 // INSERT A DECORATION RING
    ( PTREE expr                // - expression
    , PTD* ring )               // - ring of decoration
{
    if( NULL == expr->decor ) {
        expr->decor = ring;
    } else if( NULL != ring ) {
        PTD* first = ring->base.next;
        ring->base.next = expr->decor->base.next;
        expr->decor->base.next = first;
    }
    return expr;
}


static SYMBOL dtorForType       // LOCATE DTOR FOR TYPE
    ( TYPE type )               // - elemental type
{
    SYMBOL dtor;                // - NULL or DTOR for type

    type = StructType( type );
    if( NULL == type ) {
        dtor = NULL;
    } else if( TypeReallyDtorable( type ) ) {
        dtor = RoDtorFindType( type );
    } else {
        dtor = NULL;
    }
    return dtor;
}


PTREE PtdRetnOptVar             // DECORATE WITH IC_RETNOPT_VAR
    ( PTREE expr                // - expression
    , SYMBOL var )              // - symbol which could be optimized away
{
    if( FnRetnOpt() ) {
        if( expr == NULL ) {
            CgFrontCodePtr( IC_RETNOPT_VAR, var );
            expr = NULL;
        } else {
            expr = ptdSymbol( expr, var, PTD_RETNOPT_VAR );
        }
    }
    return expr;
}


PTREE PtdRetnOptEnd             // DECORATE WITH IC_RETNOPT_END
    ( PTREE expr )              // - expression
{
    if( FnRetnOpt() ) {
        if( expr == NULL ) {
            CgFrontCode( IC_RETNOPT_END );
            expr = NULL;
        } else {
            expr = ptdBase( expr, PTD_RETNOPT_END );
        }
    }
    return expr;
}


PTREE PtdDtorUseSym             // DECORATE WITH DTOR USAGE (SYMBOL)
    ( PTREE expr                // - expression
    , SYMBOL dtor )             // - destructor symbol
{
    if( dtor != NULL ) {
        dtor->flag |= SF_REFERENCED;
        expr = FunctionCalled( expr, dtor );
        expr = ptdSymbol( expr, dtor, PTD_DTOR_USE );

⌨️ 快捷键说明

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