fnname.c

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

C
1,410
字号
/****************************************************************************
*
*                            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 <stdarg.h>
#include <stddef.h>
#include <ctype.h>

#include "ppintnam.h"
#include "errdefns.h"
#include "memmgr.h"
#include "class.h"
#include "ppops.h"
#include "vbuf.h"
#include "specname.h"
#include "name.h"
#include "toggle.h"
#include "cgfront.h"
#include "fmttype.h"
#include "initdefs.h"
#include "preproc.h"
#include "pcheader.h"
#include "stats.h"
#include "srcfile.h"
#include "pragdefn.h"

typedef enum {                  // type mangling control
    TM_INCLUDE_FIRST_DIM= 0x01, // - include first dimension in array type mangling
    TM_NO_INITIAL_MOD   = 0x02, // - don't include initial mods
    TM_FIRST_DIM        = 0x80, // * local flag used in appendTypeContinue
    TM_NULL             = 0x00
} tm_control;

static char *operatorNamesStr[] = {
#include "ppopfstr.h"
};
#define MAX_OP_NAMES ARRAY_SIZE( operatorNamesStr )

static CGOP const operatorSameAs[] = {
    #define PPOPOP( s, sa )     delim CO_##sa
    #include "ppopsdef.h"
};

static char *specialNamesStr[] = {
#define SPECNAME_DEFINE
#include "specname.h"
};
#define MAX_SPECIAL_NAMES ARRAY_SIZE( specialNamesStr )

static VBUF mangled_name;       // buffer for working on name
static char *objNameBuff;
static char *specialNames[ MAX_SPECIAL_NAMES ];
static char *operatorNames[ MAX_OP_NAMES + 1 ]; // one more for sentinel

#define MAX_REPLICATE   10
typedef struct replicate_desc {
    char            *ptr;
    size_t          len;
} replicate_desc;
static replicate_desc replicate[MAX_REPLICATE];
static int            next_replicate;

ExtraRptCtr( ctr_lookups );
ExtraRptCtr( ctr_lookups_slow );
ExtraRptCtr( ctr_debug_names );
ExtraRptCtr( ctr_debug_scoped_names );

static void replicateInit( void )
{
    next_replicate = 0;
}

static int replicateSearch( char *name )
{
    int i;
    int len = strlen( name );

#if 0   // fix assertion failures next release
    // demangler will not insert these names into its replicate table
    DbgAssert( name[0] != '$' );
#endif
    for( i = 0 ; i < next_replicate ; i++ ) {
         if( len == replicate[i].len ) {
             if( strcmp( name, replicate[i].ptr ) == 0 ) return( i );
         }
    }
    if( i < MAX_REPLICATE ) {
        replicate[i].len = len;
        replicate[i].ptr = name;
        next_replicate++;
    }
    return( -1 );
}

static uint_32 objNameHash( uint_32 h, char *s )
{
    uint_32 c;
    uint_32 g;

    // don't change this in a patch
    for(;;) {
        /* ( h & ~0x0ffffff ) == 0 is always true here */
        c = *s;
        if( c == 0 ) break;
        h = (h << 4) + c;
        g = h & ~0x0ffffff;
        h ^= g;
        h ^= g >> 24;
        ++s;
    }
    return( h );
}

static TYPE typeLookAhead( TYPE type, type_flag *flags, void **base )
{
    return TypeModExtract( type
                         , flags
                         , base
                         , TC1_NOT_MEM_MODEL | TC1_NOT_ENUM_CHAR );
}

static boolean nameHasPrefix(   // TEST IF NAME HAS A PREFIX
    const char *name,           // - name to be tested
    const char *prefix )        // - prefix
{
    boolean retn;               // - TRUE ==> has prefix

    for( ; ; ++name, ++prefix ) {
        if( *prefix == '\0' ) {
            retn = TRUE;
            break;
        }
        if( *prefix != *name ) {
            retn = FALSE;
            break;
        }
    }
    return retn;
}


static void appendChar(         // APPEND A CHARACTER
    char chr )                  // - the character
{
    VStrConcChr( &mangled_name, chr );
}


static void prependChar(         // PREPEND A CHARACTER
    char chr )                  // - the character
{
    VStrPrepChr( &mangled_name, chr );
}


static void appendStr(          // APPEND A STRING
    char *str )                 // - the string
{
    if( str != NULL ) {
        VStrConcStr( &mangled_name, str );
    }
}

static void appendZZLen(        // CONCATENATE A 'ZZ' length
    unsigned len )              // - the length
{
    char sbuf[16];

    ultoa( len, sbuf, 36 );
    switch( strlen( sbuf ) ){
    case 1:
        appendChar( '0' );
        /* fall through */
    case 2:
        appendStr( sbuf );
        break;
    default:
        CFatal( "internal name length > 36*36" );
        break;
    }
}

static void appendStrWithLen(   // APPEND A STRING FOR LENGTH CHARS
    char *str,                  // - the string
    unsigned len )              // - how many chars to concatenate
{
    while( len != 0 ) {
        appendChar( *str );
        ++str;
        --len;
    }
}

static void prependStr(         // PREPEND A STRING
    char *str )                 // - the string
{
    if( str != NULL ) {
        VStrPrepStr( &mangled_name, str );
    }
}

static void prependLen(         // PREPEND A THE CURRENT STRING LEN
    void )
{
    int len;
    char sbuf[16];              // - buffer

    len = VStrLen( &mangled_name );
    DbgAssert( len == strlen( mangled_name.buf ) );
    ultoa( len, sbuf, 36 );
    switch( strlen( sbuf ) ){
    case 1:
        prependStr( sbuf );
        prependChar( '0' );
        break;
    case 2:
        prependStr( sbuf );
        break;
    default:
        CFatal( "internal name length > 36*36" );
        break;
    }
}

static void appendInt(          // APPEND AN INTEGER
    int val )                   // - value
{
    char sbuf[16];              // - buffer

    ultoa( val, sbuf, 10 );
    appendStr( sbuf );
}

static void appendBase36Int(    // APPEND A BASE 36 INTEGER
    unsigned val )              // - value
{
    char sbuf[16];              // - buffer

    ultoa( val, sbuf, 36 );
    appendStr( sbuf );
}

static void appendReplName(     // APPEND A REPLICATIBLE NAME
    char *id )                  // - the name
{
    int index;

    index = replicateSearch( id );
    if( index >= 0 ) {
        appendChar( index + '0' );
    } else {
        appendStr( id );
        appendStr( IN_NAME_SUFFIX );
    }
}

static void appendNameSpaceName(// APPEND A NAMESPACE NAME
    SCOPE scope )               // - the scope
{
    char *name;

    name = ScopeNameSpaceName( scope );
    if( name != NULL ) {
        if( ScopeIsUnnamedNameSpace( scope ) != NULL ) {
            // we don't want unnamed namespace name in replicate table
            // (demangler never stores anything with '$' prefix in rep table)
            appendChar( IN_CLASS_DELIM );
            appendStr( name );
            appendStr( IN_NAME_SUFFIX );
        } else {
            appendChar( IN_CLASS_DELIM );
            appendReplName( name );
        }
    }
}

static void appendSymName(      // APPEND A SYMBOL's MANGLED NAME
    SYMBOL sym )                // - the symbol
{
    char    *name;

    name = sym->name->name;
    if( nameHasPrefix( name, IN_OP_PREFIX ) ) {
        appendStr( IN_NAME_PREFIX );
        appendStr( &name[ sizeof( IN_NAME_PREFIX ) ] );
    } else {
        appendReplName( name );
    }
}

static void appendScopeMangling(// APPEND CLASS SCOPES
    SCOPE scope );              // - current scope

static void appendScopedSymName(// APPEND A SCOPED SYMBOL NAME
    SYMBOL sym )
{
    appendSymName( sym );
    appendScopeMangling( sym->name->containing );
}

static char *className(         // GET CLASS' NAME
    TYPE class_type )           // - the class type
{
    CLASSINFO *info;

    info = class_type->u.c.info;
    if( info->name == NULL ) {
        ClassMakeUniqueName( class_type, NULL );
    }
    return( info->name );
}

static void appendClassName(    // APPEND A CLASS' NAME
    TYPE class_type )           // - the class type
{
    appendReplName( className( class_type ) );
}

static void appendBasedMod(     // APPEND A BASED MODIFIER
    type_flag flags,            // - the flags
    void *base )                // - base modifier
{
    STRING_CONSTANT str;

    appendChar( IN_BASED );
    flags &= TF1_BASED;
    switch( flags ) {
    case TF1_BASED_SELF:
        appendChar( IN_BASED_SELF );
        break;
    case TF1_BASED_VOID:
        appendChar( IN_BASED_VOID );
        break;
    case TF1_BASED_STRING:
#ifndef NDEBUG
        if( base == NULL ) {
            CFatal( "invalid based modifier" );
        }
#endif
        appendChar( IN_BASED_STRING );
        str = base;
        appendZZLen( str->len );
        appendStrWithLen( str->string, str->len );
        break;
    case TF1_BASED_FETCH:
#ifndef NDEBUG
        if( base == NULL ) {
            CFatal( "invalid based modifier" );
        }
#endif
        appendChar( IN_BASED_FETCH );
        appendStr( IN_NAME_PREFIX );
        appendScopedSymName( base );
        break;
    case TF1_BASED_ADD:
#ifndef NDEBUG
        if( base == NULL ) {
            CFatal( "invalid based modifier" );
        }
#endif
        appendChar( IN_BASED_ADD );
        appendStr( IN_NAME_PREFIX );
        appendScopedSymName( base );
        break;
#ifndef NDEBUG
    default:
        CFatal( "invalid based modifier" );
#endif
    }
}

static void appendModifier(     // APPEND A MODIFIER
    type_flag flags,            // - the flags
    void *base )                // - base modifier
{
    if( flags & TF1_BASED ) {
        appendBasedMod( flags, base );
    }
    if( flags & TF1_FAR ) {
        appendChar( IN_FAR );
    }
    if( flags & TF1_FAR16 ) {
        appendChar( IN_FAR16 );
    }
    if( flags & TF1_HUGE ) {
        appendChar( IN_HUGE );
    }
    if( flags & TF1_NEAR ) {
        appendChar( IN_NEAR );
    }
    if( flags & TF1_VOLATILE ) {
        appendChar( IN_VOLATILE );
    }
    if( flags & TF1_CONST ) {
        appendChar( IN_CONST );
    }
}

static void appendTypeFlags(    // APPEND TYPE FLAGS
    type_flag flags )           // - the flags
{
    appendModifier( flags, NULL );
}

static void appendTypeContinue( // APPEND A TYPE MANGLING (NO NEAR/FAR PREFIX)
    TYPE type,                  // - type
    char *name,                 // - original name of symbol
    tm_control control )        // - control mask
{
    TYPE *aptr;                 // - arg.s structure
    unsigned acount;            // - arguments count
    type_flag flags;            // - look ahead flags
    void *base;                 // - look ahead base

    control |= TM_FIRST_DIM;
    while( type != NULL ) {
        switch( type->id ) {
        case TYP_BOOL:
            appendChar( IN_BOOL );
            type = TypeError;
            break;
        case TYP_CHAR:
            appendChar( IN_CHAR );
            type = TypeError;
            break;
        case TYP_SCHAR:
            appendChar( IN_SCHAR );
            break;
        case TYP_UCHAR:
            appendChar( IN_UNSIGNED );
            appendChar( IN_UCHAR );
            break;
        case TYP_WCHAR:
            appendChar( IN_WCHAR );
            break;
        case TYP_SSHORT:
            appendChar( IN_SSHORT );
            break;
        case TYP_USHORT:
            appendChar( IN_UNSIGNED );

⌨️ 快捷键说明

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