cginfo.c

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

C
1,577
字号
/****************************************************************************
*
*                            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:  Callback functions invoked from cg - communicate
*               auxiliary information to the backend.
*
****************************************************************************/


#include "plusplus.h"

#include "compcfg.h"
#include "tgtenv.h"

#include <process.h>
#include <limits.h>

#include "preproc.h"
#include "cgdata.h"
#include "codegen.h"
#include "errdefns.h"
#include "memmgr.h"
#include "pragdefn.h"
#include "pdefn2.h"
#include "iosupp.h"
#include "segment.h"
#include "cginfo.h"
#include "cgback.h"
#include "rtfuns.h"
#include "rtfuncod.h"
#include "module.h"
#include "srcfile.h"
#include "symdbg.h"
#include "dwarfdbg.h"
#include "extrf.h"
#include "ctexcept.h"
#include "name.h"
#include "cginlibs.h"
#include "cginimps.h"
#include "initdefs.h"
#include "iosupp.h"
#include "cppexit.h"
#include "cgbackut.h"
#include "cginmisc.h"
#include "pragdefn.h"
#include "specfuns.h"
#include "autodept.h"

#if _CPU == 386
    extern struct  inline_funcs Fs_Functions[];   // FS PRAGMAS
#endif

static SYMBOL lastFunctionOutOfMem;

#define _HAS_EXE_MAIN   (  CompFlags.has_main \
                        || CompFlags.has_winmain \
                        )
#define _HAS_DLL_MAIN   ( CompFlags.bd_switch_used \
                        || CompFlags.has_libmain \
                        || CompFlags.has_dllmain \
                        )
#define _HAS_ANY_MAIN   (  _HAS_EXE_MAIN \
                        || _HAS_DLL_MAIN \
                        )

static AUX_INFO *getLangInfo(   // GET LANGUAGE INFO. FOR SYMBOL
    SYMBOL sym )                // - the symbol
;

static void init(               // MODULE INITIALIZATION
    INITFINI* def )             // - definition
{
    def = def;
    CompFlags.low_on_memory_printed = FALSE;
}

INITDEFN( cg_info, init, InitFiniStub )

char *FEName(                   // RETURN THE SYMBOL'S NAME
    SYMBOL sym )
{
    char *sym_name;             // - symbol's name

    if( sym == NULL || sym->name == NULL ) {
        sym_name = "!NULL!";
    } else {
        sym_name = CppNameDebug( sym );
    }
    return( sym_name );
}


void FEMessage(                 // MESSAGES FROM CODE-GENERATOR
    msg_class class,            // - message class
    void *parm )                // - parameter
{
    switch( class ) {
    case MSG_SYMBOL_TOO_LONG:
        CErr2p( WARN_MANGLED_NAME_TOO_LONG, (SYMBOL)parm );
        break;
    case MSG_BLIP:
        if( CompFlags.ide_console_output ) {
            if( ! CompFlags.quiet_mode ) {
                putchar( '.' );
                fflush( stdout );
            }
        }
        break;
    case MSG_INFO_FILE:
    case MSG_INFO_PROC:
        if( CompFlags.ide_console_output ) {
            if( ! CompFlags.quiet_mode ) {
                MsgDisplayLine( parm );
            }
        }
        break;
    case MSG_CODE_SIZE:
        if( CompFlags.ide_console_output ) {
            if( ! CompFlags.quiet_mode ) {
                char buffer[16];
                utoa( (unsigned)parm, buffer, 10 );
                MsgDisplayLineArgs( "\rCode size: "
                                  , buffer
                                  , NULL );
            }
        }
        break;
    case MSG_DATA_SIZE:
        break;
    case MSG_ERROR:
        CErr2p( ERR_USER_ERROR_MSG, parm );
        break;
    case MSG_FATAL:
        CErr2p( ERR_FATAL_ERROR, parm );
        CppExit( 1 );         /* exit to DOS do not pass GO */
        break;
    case MSG_BAD_PARM_REGISTER:
        CErr2( ERR_BAD_PARM_REGISTER, (int)parm );
        break;
    case MSG_BAD_RETURN_REGISTER:
        CErr2p( ERR_BAD_RETURN_REGISTER, FEName( (SYMBOL)parm ) );
        break;
    case MSG_SCHEDULER_DIED:
    case MSG_REGALLOC_DIED:
    case MSG_SCOREBOARD_DIED:
        if( ! (GenSwitches & NO_OPTIMIZATION) ) {
            if( lastFunctionOutOfMem != parm ) {
                lastFunctionOutOfMem = parm;
                CErr2p( WARN_CG_MEM_PROC, FEName( (SYMBOL)parm ) );
            }
        }
        break;
    case MSG_PEEPHOLE_FLUSHED:
        if( ! (GenSwitches & NO_OPTIMIZATION) ) {
            if( ! CompFlags.low_on_memory_printed ) {
                CompFlags.low_on_memory_printed = TRUE;
                CErr1( WARN_CG_MEM_PEEPHOLE );
            }
        }
        break;
    case MSG_BACK_END_ERROR:
        CErr2( ERR_BACK_END_ERROR, (int)parm );
        break;
    case MSG_BAD_SAVE:
        CErr2p( ERR_BAD_SAVE, FEName( (SYMBOL)parm ) );
        break;
    case MSG_NO_SEG_REGS:
        CErr2p( ERR_NO_SEG_REGS, FEName( (SYMBOL)parm ) );
        break;
    }
}


char *FEModuleName(             // RETURN MODULE NAME
    void )
{
    return( ModuleName );
}


int FETrue(                     // RETURN TRUE
    void )
{
    return( 1 );
}

int FESymIndex(                 // STUB EXCEPT FOR JAVA
    SYMBOL sym )
{
    return( 0 );
}

int FECodeBytes(                // STUB EXCEPT FOR JAVA
    const char *buffer,
    int len )
{
    return( FALSE );
}

static fe_attr basic_attributes(// GET BASIC ATTRIBUTES
    SYMBOL sym )                // - symbol
{
    fe_attr attr;               // - attribute

    switch( sym->id ) {
    case SC_EXTERN:
        attr = FE_STATIC | FE_GLOBAL | FE_IMPORT ;
        break;
    case SC_PUBLIC:
        attr = FE_STATIC | FE_GLOBAL;
        break;
    case SC_STATIC:
        attr = FE_STATIC | FE_VISIBLE;
        break;
    default :
        attr = 0;
        break;
    }
    return( attr );
}

fe_attr FEAttr(                 // GET SYMBOL ATTRIBUTES
    SYMBOL sym )                // - symbol
{
    fe_attr attr;               // - attribute
    fe_attr mask;               // - remove these attributes
    SYMBOL_NAME sym_name;       // - symbol name of symbol
    SCOPE scope;                // - scope of symbol
    char *name;                 // - name of symbol
    TYPE unmod_type;            // - type for symbol
    type_flag mod_flags;        // - modifier flags
    scf_mask scf_info;          // - sym comdat function info

    attr = 0;
    mask = 0;
    name = NULL;
    sym_name = sym->name;
    if( sym_name != NULL ) {
        scope = sym_name->containing;
        if( ScopeEnclosedInUnnamedNameSpace( scope ) ) {
            mask = FE_GLOBAL;
        }
        name = sym_name->name;
        if( name != NULL ) {
            if( IsNameDummy( name ) ) {
                attr |= FE_INTERNAL;
            }
        }
    }
    unmod_type = TypeModFlags( sym->sym_type, &mod_flags );
    if( unmod_type->id == TYP_FUNCTION ) {
        attr |= FE_PROC;
        if( !IsCppNameInterestingDebug( sym ) ){
            attr |= FE_COMPILER;
        }
        if( SymIsInitialized( sym ) ) {
            scf_info = SymComdatFunInfo( sym );
            if( scf_info & SCF_COMDAT ) {
                if( scf_info & SCF_STATIC ) {
                    mask = FE_COMMON | FE_GLOBAL;
                } else {
                    attr |= FE_COMMON;
                }
            }
            if( unmod_type->flag & TF1_NAKED ) {
                attr |= FE_NAKED;
            }
            if( CompFlags.unique_functions ) {
                attr |= FE_UNIQUE;
            }
        } else {
            attr |= FE_IMPORT;
        }
        if( TypeHasEllipsisArg( unmod_type ) ) {
            attr |= FE_VARARGS;
        }
    } else {
        if( SymIsInitialized( sym ) ) {
            if( SymIsComdatData( sym ) ) {
                attr |= FE_COMMON;
            }
        }
        if( mod_flags & TF1_STAY_MEMORY ) {
            attr |= FE_VOLATILE;
        }
        if( mod_flags & TF1_CONST ) {
            attr |= FE_CONSTANT;
        }
        if( mod_flags & TF1_THREAD ) {
            attr |= FE_THREAD_DATA;
        }
        if( ! ( mod_flags & TF1_HUGE ) ) {
            attr |= FE_ONESEG;
        }
    }
    // don't export addressability thunks
    if(( sym->flag & SF_ADDR_THUNK ) == 0 ) {
        if( mod_flags & (TF1_DLLEXPORT|TF1_DLLIMPORT) ) {
            if( SymIsInitialized( sym ) ) {
                if( mod_flags & TF1_DLLEXPORT ) {
                    attr |= FE_DLLEXPORT;
                }
            } else {
                if( mod_flags & TF1_DLLIMPORT ) {
                    // fill vftables with 'S::f' not '__imp_S::f'
                    if( ! SymIsVirtual( sym ) ) {
                        attr |= FE_DLLIMPORT;
                    }
                }
            }
        }
    }
    // change to this: if( sym->flag & SF_CG_ADDR_TAKEN ) {
    if( sym->flag & SF_CG_ADDR_TAKEN ) {
        attr |= FE_ADDR_TAKEN;
    }
    if( SymIsClassMember( sym ) ) {
        if( SymIsStatic( sym ) && IsCppMembPtrOffsetName( name ) ) {
            attr |= FE_UNIQUE;
        }
        if( SymIsInitialized( sym ) ) {
            attr |= FE_STATIC;
            /* only set FE_GLOBAL if it's not an in-class
         * initialization of a const static member */
            if( ! ( sym->flag & SF_IN_CLASS_INIT ) ) {
                attr |= FE_GLOBAL;
            }
        } else {
            attr |= FE_STATIC | FE_GLOBAL | FE_IMPORT ;
        }
    } else {
        attr |= basic_attributes( sym );
    }
    if( mod_flags & TF1_COMMON
     && 0 == mask ) {
        /* should never execute this but just in case ... */
        attr |= FE_COMMON | FE_GLOBAL;
    } else if( attr & FE_COMMON ) {
        attr |= FE_GLOBAL;
    }
    DbgAssert( mask == 0 || ( attr & FE_COMMON ) == 0 );
    attr &= ~mask;
#ifndef NDEBUG
    if( PragDbgToggle.auxinfo ) {
        printf( "FeAttr( %x = %s ) -> %x\n"
              , sym
              , GetMangledName( sym )
              , attr );
    }
#endif
    return( attr );
}


segment_id FESegID(             // GET SEGMENT ID FOR SYMBOL
    SYMBOL sym )                // - symbol
{
    return( CgSegId( sym ) );
}


int FELexLevel(                 // GET LEXICAL LEVEL OF SYMBOL
    SYMBOL sym )                // - the symbol
{
    sym = sym;
    return( 0 );
}


int FEParmType(                 // ARGUMENT PROMOTION ?
    SYMBOL func,                // function being called
    SYMBOL parm,                // parameter being passed

⌨️ 快捷键说明

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