symbol.c

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

C
1,376
字号
/****************************************************************************
*
*                            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 "cgfront.h"
#include "errdefns.h"
#include "ptree.h"
#include "name.h"
#include "defarg.h"
#include "ring.h"
#include "conpool.h"

#define stgClassInSet( s, m )   ((( 1 << (s)->id ) & (m) ) != 0 )

#define SCM_AUTOMATIC   \
        ( 1 << SC_AUTO )        | \
        ( 1 << SC_REGISTER )

#define SCM_CONSTANT            \
        ( 1 << SC_AUTO )        | \
        ( 1 << SC_REGISTER )    | \
        ( 1 << SC_NULL )        | \
        ( 1 << SC_STATIC )      | \
        ( 1 << SC_EXTERN )

#define SCM_NOT_DATA_OR_FUNC    \
        ( 1 << SC_TYPEDEF )     | \
        ( 1 << SC_ACCESS )

#define symIsDataFunction( s )  ( \
        (( (s)->flag & SF_ERROR ) == 0 ) && \
        ( ! stgClassInSet( sym, SCM_NOT_DATA_OR_FUNC ) ) \
        )

#define symIsFuncSym( s ) ( FunctionDeclarationType( (s)->sym_type ) != NULL )
#define symIsDataSym( s ) ( FunctionDeclarationType( (s)->sym_type ) == NULL )

#define symGetScope( sym, scope ) \
    { \
        SYMBOL_NAME sname = sym->name; \
        if( sname != NULL ) { \
            scope = sname->containing; \
        } else { \
            scope = NULL; \
        } \
    }


SCOPE SymScope(                 // GET SCOPE FOR SYMBOL
    SYMBOL sym )                // - the symbol
{
    SCOPE scope;                // - SCOPE for "sym"

    symGetScope( sym, scope );
    return( scope );
}


TYPE SymClass(                  // GET TYPE FOR CLASS CONTAINING A SYMBOL
    SYMBOL sym )                // - the symbol
{
    SCOPE scope;                // - SCOPE for "sym"

    symGetScope( sym, scope );
    if( scope == NULL ) {
        return( NULL );
    }
    return( ScopeClass( scope ) );
}


static SCOPE symClassScope(     // GET SCOPE FOR CLASS CONTAINING SYMBOL
    SYMBOL sym )
{
    SCOPE scope;                // - SCOPE for "sym"

    symGetScope( sym, scope );
    if( scope != NULL ) {
        if( ScopeId( scope ) == SCOPE_CLASS ) {
            return( scope );
        }
    }
    return( NULL );
}


boolean SymIsData(              // TEST IF SYMBOL IS DATA
    SYMBOL sym )                // - the symbol
{
    return symIsDataFunction( sym ) && symIsDataSym( sym );
}


boolean SymIsFunction(          // TEST IF SYMBOL IS A FUNCTION
    SYMBOL sym )                // - the function
{
    return symIsDataFunction( sym ) && symIsFuncSym( sym );
}


boolean SymIsHugeData(          // TEST IF SYMBOL IS HUGE DATA
    SYMBOL sym )                // - the symbol
{
    type_flag flag;

    if( SymIsData( sym ) ) {
        TypeModFlags( sym->sym_type, &flag );
        return(( flag & TF1_HUGE ) != 0 );
    }
    return( FALSE );
}


boolean SymIsInMem(             // TEST IF SYMBOL SHOULD STAY IN MEMORY
    SYMBOL sym )                // - symbol
{
    type_flag flag;

    TypeModFlags( sym->sym_type, &flag );
    return(( flag & TF1_STAY_MEMORY ) != 0 );
}


boolean SymIsClassMember(       // TEST IF SYMBOL IS MEMBER OF A CLASS
    SYMBOL sym )                // - the symbol
{
    return symIsDataFunction( sym ) && symClassScope( sym ) != NULL;
}

boolean SymIsNameSpaceMember(    // TEST IF SYMBOL IS MEMBER OF NAMESPACE
    SYMBOL sym )                // - the symbol
{
    boolean     ret;
    SCOPE       scope;

    ret = FALSE;
    scope = SymScope( sym );
    if( ScopeId( scope ) == SCOPE_FILE ) {
        NAME_SPACE *ns;

        ns = scope->owner.ns;
        if( !ns->global_fs  ){
            ret = TRUE;
        }
    }
    return( ret );
}

boolean SymIsClassDefinition(   // TEST IF SYMBOL IS TYPEDEF FOR A CLASS
    SYMBOL sym )                // - the symbol
{
    TYPE type;                  // - type of class

    if( !SymIsTypedef( sym ) ) {
        return( FALSE );
    }
    type = StructType( sym->sym_type );
    if( type == NULL ) {
        return( FALSE );
    }
    if( !type->u.c.info->defined ) {
        return( FALSE );
    }
    if( sym->name->name != type->u.c.info->name ) {
        return( FALSE );
    }
    if( sym->name->containing != type->u.c.scope->enclosing ) {
        return( FALSE );
    }
    return( TRUE );
}


boolean SymIsInjectedTypedef(   // TEST IF SYMBOL IS INJECTED TYPEDEF
    SYMBOL sym )                // - the symbol
{
    TYPE type;                  // - type of class

    if( !SymIsTypedef( sym ) ) {
        return( FALSE );
    }
    type = StructType( sym->sym_type );
    if( type == NULL ) {
        return( FALSE );
    }
    if( !type->u.c.info->defined ) {
        return( FALSE );
    }
    if( sym->name->name != type->u.c.info->name ) {
        return( FALSE );
    }
    if( sym->name->containing != type->u.c.scope ) {
        return( FALSE );
    }
    return( TRUE );
}


boolean SymIsEnumDefinition(    // TEST IF SYMBOL IS AN ENUMERATION
    SYMBOL sym )                // - the symbol
{
    TYPE type;                  // - type of symbol

    if( !SymIsTypedef( sym ) ) {
        return( FALSE );
    }
    type = EnumType( sym->sym_type );
    if( type == NULL ) {
        return( FALSE );
    }
    if( type->u.t.sym != sym ) {
        return( FALSE );
    }
    return( TRUE );
}


#ifndef NDEBUG
SYMBOL SymDeAlias(              // REDUCE TO NON-ALIASED SYMBOL
    SYMBOL sym )                // - the symbol
{
    if( SymIsAlias( sym ) ) {
        sym = sym->u.alias;
    }
    DbgAssert( ! SymIsAlias( sym ) );
    return( sym );
}
#endif


boolean SymIsAutomatic(         // TEST IF SYMBOL IS AUTOMATIC VARIABLE
    SYMBOL sym )                // - the symbol
{
    sym = SymDeAlias( sym );
    return( stgClassInSet( sym, SCM_AUTOMATIC ) );
}


SYMBOL SymDefaultBase(          // REMOVE DEFAULT ARGUMENTS TO GET BASE SYMBOL
    SYMBOL sym )                // - the symbol
{
    while( SymIsDefArg( sym ) ) {
        sym = sym->thread;
    }
    return sym;
}


boolean SymIsStatic(     // DETERMINE IF SYMBOL IS STATIC
    SYMBOL sym )                // - the symbol
{
    symbol_class id;

    id = SymDefaultBase( sym )->id;
    return ( SC_STATIC == id ) || ( SC_STATIC_FUNCTION_TEMPLATE == id );
}


boolean SymIsStaticMember(      // TEST IF SYMBOL IS STATIC MEMBER
    SYMBOL sym )                // - the symbol
{
    return( SymIsClassMember( sym ) && SymIsStatic( sym ) );
}


boolean SymIsStaticDataMember(  // TEST IF SYMBOL IS STATIC DATA MEMBER
    SYMBOL sym )                // - the symbol
{
    return( SymIsStaticMember( sym ) && symIsDataSym( sym ) );
}


boolean SymIsThisMember(        // TEST IF SYMBOL IS DATA/FUNCTION MEMBER
    SYMBOL sym )                // - the symbol
{
    return SymIsClassMember( sym )
        && ! SymIsStatic( sym )
        && ( sym->id != SC_ENUM );
}


boolean SymIsThisDataMember(    // TEST IF SYMBOL IS THIS DATA MEMBER
    SYMBOL sym )                // - the symbol
{
    return SymIsThisMember( sym ) && symIsDataSym( sym );
}


boolean SymIsFuncMember(        // TEST IF SYMBOL IS A MEMBER FUNCTION
    SYMBOL sym )                // - the symbol
{
    return( SymIsClassMember( sym ) && symIsFuncSym( sym ) );
}


boolean SymIsStaticFuncMember(  // TEST IF SYMBOL IS A STATIC MEMBER FUNC.
    SYMBOL sym )                // - the symbol
{
    return( SymIsFuncMember( sym ) && SymIsStatic( sym ) );
}


boolean SymIsThisFuncMember(    // TEST IF SYMBOL IS A THIS MEMBER FUNC.
    SYMBOL sym )                // - the symbol
{
    return SymIsThisMember( sym ) && symIsFuncSym( sym );
}


boolean SymIsStaticData(        // TEST IF SYMBOL IS STATIC DATA ELEMENT
    SYMBOL sym )                // - the symbol
{
    SCOPE scope;                // - scope for symbol
    boolean retn;               // - TRUE ==> symbol is static data element

    retn = FALSE;
    if( SymIsData( sym ) ) {
        symGetScope( sym, scope );
        if( scope != NULL ) {
            switch( ScopeId( scope ) ) {
              case SCOPE_BLOCK :
              case SCOPE_FILE :
                if( sym->id == SC_STATIC ) {
                    retn = TRUE;
                }
                break;
            }
        }
    }
    return( retn );
}


CLASSINFO *SymClassInfo(        // GET CLASSINFO FOR SYMBOL
    SYMBOL sym )                // - the symbol
{
    return TypeClassInfo( SymClass( sym ) );
}


boolean SymRequiresDtoring(     // TEST IF SYMBOL REQUIRES DTOR-ING
    SYMBOL sym )                // - the symbol
{
    boolean retn;               // - TRUE ==> DTOR required

    if( SymIsData( sym ) ) {
        retn = TypeRequiresDtoring( sym->sym_type );
    } else {
        retn = FALSE;
    }
    return( retn );
}


boolean SymRequiresCtoring(     // TEST IF SYMBOL REQUIRES DTOR-ING
    SYMBOL sym )                // - the symbol
{
    boolean retn;               // - TRUE ==> DTOR required

    if( SymIsData( sym ) ) {
        retn = TypeRequiresCtoring( sym->sym_type );
    } else {
        retn = FALSE;
    }
    return( retn );
}


boolean SymClassCorrupted(      // TEST IF SYMBOL'S CLASS CORRUPTED
    SYMBOL sym )                // - the symbol
{
    TYPE type;                  // - scope's class type

    type = SymClass( sym );
    if( type != NULL ) {
        if( TypeDefined( type ) && ! type->u.c.info->corrupted ) {
            return( FALSE );
        }
    }
    return( TRUE );
}


arg_list *SymFuncArgList(       // GET FUNCTION ARG. LIST
    SYMBOL func )               // - a function SYMBOL
{
    return( TypeArgList( func->sym_type ) );
}


static SYMBOL symAllocate(      // ALOOCATE A NEW SYMBOL
    TYPE type,                  // - symbol type
    symbol_class id,            // - symbol class
    symbol_flag flags )         // - symbol flags
{
    SYMBOL sym = AllocSymbol();
    sym->id = id;
    sym->sym_type = type;
    sym->flag = flags;
    return sym;
}


SYMBOL SymMakeDummy(            // MAKE A DUMMY SYMBOL
    TYPE type,                  // - type of the symbol
    char **name )               // - gets filled in with the name
{
    *name = NameDummy();
    return symAllocate( type, 0, 0 );
}


boolean SymIsTemporary(         // DETERMINE IF INTERNAL SYMBOL
    SYMBOL sym )                // - the symbol
{
    boolean retn;               // - TRUE ==> symbol is internal symbol

    if( ! SymIsData( sym ) ) {
        retn = FALSE;
    } else if( SymIsAnError( sym ) ) {
        retn = TRUE;
    } else if( sym->name->name[0] == NAME_DUMMY_PREFIX_0 ) {
        retn = TRUE;
    } else {
        retn = FALSE;
    }
    return( retn );

⌨️ 快捷键说明

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