typesig.c

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

C
499
字号
/****************************************************************************
*
*                            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:  Type signatures.
*
****************************************************************************/

#include "plusplus.h"
#include "cgfront.h"
#include "cgback.h"
#include "ctexcept.h"
#include "ring.h"
#include "carve.h"
#include "cgsegid.h"
#include "errdefns.h"
#include "pcheader.h"
#include "initdefs.h"


//************* temporary ****************

SYMBOL DefaultCtorFind(         // GET SYMBOL FOR DEFAULT CTOR
    TYPE type,                  // - class type
    TOKEN_LOCN* err_locn,       // - error location
    boolean optional )          // - TRUE ==> is optional
{
    unsigned retn;              // - return from attempt to find
    SYMBOL ctor;                // - constructor

    retn = ClassDefaultCtorFind( type, &ctor, err_locn );
    switch( retn ) {
      case CNV_OK :
        break;
      case CNV_IMPOSSIBLE :
        if( optional ) break;
        SetErrLoc( err_locn );
        CErr2p( ERR_NO_DEFAULT_INIT_CTOR, type );
        ctor = NULL;
        break;
      case CNV_AMBIGUOUS :
        if( optional ) break;
        SetErrLoc( err_locn );
        CErr2p( ERR_NO_UNIQUE_DEFAULT_CTOR, type );
        ctor = NULL;
        break;
      case CNV_ERR :
        ctor = NULL;
        break;
#ifndef NDEBUG
      default :
        CFatal( "DefaultCtorFind -- impossible return" );
#endif
    }
    return ctor;
}

//************* temporary ****************

                                // Static Data
static carve_t carveTYPE_SIG;   // - allocations for TYPE_SIGs
static TYPE_SIG *type_sigs;     // - TYPE_SIGs so far

typedef struct                  // ACCINFO -- access information
{   TYPE type;                  // - class type
    TOKEN_LOCN *err_locn;       // - error location
    boolean *err_occurred;      // - TRUE ==> error occurred
    SCOPE access_scope;         // - scope for access
    SCOPE class_scope;          // - scope for class
    TYPE_SIG_ACCESS acc;        // - access type (type signature)
} ACCINFO;


static void typeSigAccessVar(   // ACCESS A DTOR, DEFAULT-CTOR, COPY-CTOR
    TYPE_SIG_ACCESS acc_var,    // - access type (variable)
    SYMBOL *a_sym,              // - addr[ symbol for item accessed ]
    ACCINFO *info )             // - access information
{
    SYMBOL sym;                 // - symbol for routine
    TYPE type;                  // - class type
    TOKEN_LOCN *err_locn;       // - error location
    boolean fill_out;           // - TRUE ==> fill out the entry

    sym = *a_sym;
    if( acc_var & info->acc ) {
        fill_out = info->acc & TSA_FILL_OUT;
        if( fill_out ) {
            SetCurrScope(info->class_scope);
        } else {
            SetCurrScope (info->access_scope);
        }
    } else {
        fill_out = TRUE;
        SetCurrScope(info->class_scope);
    }
    if( ( GetCurrScope() != info->class_scope ) || ( sym == NULL ) ) {
        type = info->type;
        err_locn = info->err_locn;
        switch( acc_var ) {
          case TSA_DTOR :
            sym = DtorFindLocn( type, err_locn );
            break;
          case TSA_DEFAULT_CTOR :
            sym = DefaultCtorFind( type, err_locn, fill_out );
            break;
          case TSA_COPY_CTOR :
            sym = CopyCtorFind( type, err_locn );
            break;
          default :
#ifndef NDEBUG
            CFatal( "typeSigAccessVar -- impossible type" );
#endif
            sym = NULL;
        }
        if( sym == NULL ) {
            if( ! fill_out ) {
                *info->err_occurred = TRUE;
            }
        } else {
            sym = ClassFunMakeAddressable( sym );
            sym->flag |= SF_ADDR_TAKEN;
            if( ! ( info->acc & TSA_NO_REF ) ) {
                if( acc_var & info->acc ) {
                    sym = SymMarkRefed( sym );
                }
            }
            *a_sym = sym;
            CDtorScheduleArgRemap( sym );
        }
    }
}


static void typeSigAccess(      // HANDLE ACCESS FOR TYPE-SIGNATURE
    TYPE_SIG_ACCESS acc,        // - access type
    TYPE_SIG *sig,              // - current signature
    TOKEN_LOCN* err_locn,       // - error location for access errors
    boolean *error_occurred )   // - to set error indication
{
    ACCINFO info;               // - access information

    if( !( TSA_GEN & acc ) ) {
        info.acc = acc;
        info.type = StructType( sig->type );
        if( info.type != NULL ) {
            info.err_occurred = error_occurred;
            info.err_locn = err_locn;
            info.access_scope = GetCurrScope();
            info.class_scope = TypeScope( info.type );
            typeSigAccessVar( TSA_DTOR,         &sig->dtor,         &info );
            typeSigAccessVar( TSA_DEFAULT_CTOR, &sig->default_ctor, &info );
            typeSigAccessVar( TSA_COPY_CTOR,    &sig->copy_ctor,    &info );
            SetCurrScope(info.access_scope);
        }
    }
}


#define typeSigHdrSize() ( sizeof( TS_HDR ) )

static unsigned typeSigNameSize(// COMPUTE SIZE OF NAME IN TYPE SIGNATURE
    THROBJ thr )                // - category of object
{
    unsigned size;              // - size of mangled name in type signature

    switch( thr ) {
      case THROBJ_SCALAR :
      case THROBJ_PTR_FUN :
      case THROBJ_CLASS :
      case THROBJ_CLASS_VIRT :
        size = CgDataPtrSize();
        break;
      case THROBJ_PTR_SCALAR :
      case THROBJ_PTR_CLASS :
      case THROBJ_REFERENCE :
      case THROBJ_VOID_STAR :
      case THROBJ_ANYTHING :
        size = 0;
        break;
      DbgDefault( "typeSigNameSize -- bad THROBJ_..." );
    }
    return size;
}


TYPE_SIG *TypeSigFind(          // FIND TYPE SIGNATURE
    TYPE_SIG_ACCESS acc,        // - access type
    TYPE type,                  // - type for signature
    TOKEN_LOCN* err_locn,       // - error location for access errors
    boolean *error_occurred )   // - to set error indication
{
    TYPE_SIG *srch;             // - signature for searching
    TYPE_SIG *sig;              // - signature
    SYMBOL sym;                 // - symbol
    unsigned size;              // - size of R/O data
    char *typesig_name;         // - name of type signature
    TYPE typesig_type;          // - type of type signature
    boolean err_this_time;      // - TRUE ==> we have error
    TYPE_SIG_ACCESS acc_ind;    // - indirect access

    err_this_time = FALSE;
    type = TypeCanonicalThr( type );
    sig = NULL;
    RingIterBeg( type_sigs, srch ) {
        if( TypesSameExclude( srch->type, type, TC1_NOT_ENUM_CHAR ) ) {
            sig = srch;
            break;
        }
    } RingIterEnd( srch );
    if( sig == NULL ) {
        THROBJ thr;             // - category of object
        DbgVerify( 0 == ( acc & TSA_GEN )
                 , "TypeSigFind -- no type signature & TSA_GEN" );
        sig = RingCarveAlloc( carveTYPE_SIG, &type_sigs );
        sig->type = type;
        sig->default_ctor = NULL;
        sig->copy_ctor = NULL;
        sig->dtor = NULL;
        sig->sym = NULL;
        sig->base = NULL;
        sig->cgref = FALSE;
        sig->cggen = FALSE;
        sig->free = FALSE;
        thr = ThrowCategory( type );
        if( acc & TSA_INDIRECT ) {
            acc_ind = acc | TSA_INDIRECT_ACCESS;
        } else if( acc & TSA_INDIRECT_ACCESS ) {
            acc_ind = ( acc & ~ TSA_INDIRECT ) | TSA_INDIRECT_GEN;

⌨️ 快捷键说明

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