fmttype.c

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

C
700
字号
/****************************************************************************
*
*                            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 "stringl.h"
#include "stack.h"
#include "memmgr.h"
#include "cgfront.h"
#include "carve.h"
#include "vbuf.h"
#include "dbg.h"
#include "fmtsym.h"
#include "fmttype.h"
#include "name.h"
#include "initdefs.h"

typedef enum {
    LEFT, RIGHT
} FMT_LR;

typedef struct fmt_info FMT_INFO;
struct fmt_info {
    FMT_INFO    *stack;
    TYPE        type;
    unsigned    main_function : 1;
};

typedef struct {
    char        *name;
    type_flag   mask;
} FMT_FLAG_INFO;

#define ENTRY_ERROR             "<error> ",
#define ENTRY_BOOL              "bool ",
#define ENTRY_CHAR              "char ",
#define ENTRY_SCHAR             "signed char ",
#define ENTRY_UCHAR             "unsigned char ",
#define ENTRY_WCHAR             "wchar_t ",
#define ENTRY_SSHORT            "short ",
#define ENTRY_USHORT            "unsigned short ",
#define ENTRY_SINT              "int ",
#define ENTRY_UINT              "unsigned ",
#define ENTRY_SLONG             "long ",
#define ENTRY_ULONG             "unsigned long ",
#define ENTRY_SLONG64           "__int64 ",
#define ENTRY_ULONG64           "unsigned __int64 ",
#define ENTRY_FLOAT             "float ",
#define ENTRY_DOUBLE            "double ",
#define ENTRY_LONG_DOUBLE       "long double ",
#define ENTRY_ENUM              "<enum> ",
#define ENTRY_POINTER           "* ",
#define ENTRY_TYPEDEF           "<typedef> ",
#define ENTRY_CLASS             "<class> ",
#define ENTRY_BITFIELD          "<bitfield> ",
#define ENTRY_FUNCTION          "<function> ",
#define ENTRY_ARRAY             "<array> ",
#define ENTRY_DOT_DOT_DOT       "... ",
#define ENTRY_VOID              "void ",
#define ENTRY_MODIFIER          "<modifier> ",
#define ENTRY_MEMBER_POINTER    "::* ",
#define ENTRY_GENERIC           "? ",

static char *typeName[] = {
    #include "type_arr.h"
};

static char *errFormats[] = {
    #define TFMT_DEF(a,b) b,
    SPECIAL_TYPE_FMTS
    #undef TFMT_DEF
};

static FMT_FLAG_INFO functionFlags[] = {
    { "__loadds ",      TF1_LOADDS },
    { "__saveregs ",    TF1_SAVEREGS },
    { "__interrupt ",   TF1_INTERRUPT },
    { NULL,             TF1_NULL }
};

static FMT_FLAG_INFO modifierFlags[] = {
    { "mutable ",   TF1_MUTABLE },
    { "const ",     TF1_CONST },
    { "volatile ",  TF1_VOLATILE },
    { "__near ",    TF1_NEAR },
    { "__far ",     TF1_FAR },
    { "__far16 ",   TF1_FAR16 },
    { "__huge ",    TF1_HUGE },
    { "__export ",  TF1_DLLEXPORT },
    { "__declspec(dllimport) ",  TF1_DLLIMPORT },
    { "__unaligned ",  TF1_UNALIGNED },
    { NULL,         TF1_NULL }
};

static FMT_FLAG_INFO ushortFlags[] = {
    { "__segment ", TF1_SEGMENT },
    { NULL,         TF1_NULL }
};

static FMT_FLAG_INFO pointerFlags[] = {
    { "& ", TF1_REFERENCE },
    { NULL, TF1_NULL }
};

static FMT_FLAG_INFO classFlags[] = {
    { "<union> ",   TF1_UNION },
    { "<struct> ",  TF1_STRUCT },
    { NULL,         TF1_NULL }
};

static char basedVoid[]         = "void ";
static char basedSelf[]         = "__self ";
static char openBased[]         = "__based( ";
static char closeBased[]        = ") ";
static char openSegname[]       = "__segname( \"";
static char closeSegname[]      = "\" )";
static char openPragma[]        = "__pragma(\"";
static char closePragma[]       = "\") ";
static char openFunction[]      = "( ";
static char closeFunction[]     = ") ";
static char openSquareParen[]   = "[";
static char closeSquareParen[]  = "]";
static char openParen[]         = "(";
static char closeParen[]        = ")";
static char bitfieldSep[]       = " : ";
static char parameterSep[]      = ", ";
static char whiteSpace[]        = " ";
static char nullType[]          = "<null type pointer>";
static char memberPointer[]     = "<member pointer>";

#define BLOCK_FMT       16
static carve_t carveFMT;

FMT_CONTROL FormatTypeDefault = FF_USE_VOID;

static void formatTypeInit( INITFINI* defn )
{
    defn = defn;
    carveFMT = CarveCreate( sizeof( FMT_INFO ), BLOCK_FMT );
}

static void formatTypeFini( INITFINI* defn )
{
    defn = defn;
#ifndef NDEBUG
    CarveVerifyAllGone( carveFMT, "FMT" );
#endif
    CarveDestroy( carveFMT );
}

INITDEFN( type_formatting, formatTypeInit, formatTypeFini )

static void fmtTypeArray( TYPE type, VBUF *pvbuf )
/************************************************/
{
    VBUF    working;
    char    sbuf[ 1 + sizeof( long ) * 2 + 1 ];

    VbufInit( &working );
    VStrNull( &working );
    VStrConcStr( &working, openSquareParen );
    if( type->u.a.array_size > 0 ) {
        ultoa( type->u.a.array_size, sbuf, 10 );
        VStrConcStr( &working, sbuf );
    }
    VStrConcStr( &working, closeSquareParen );
    VStrPrepStr( pvbuf, working.buf );
    VbufFree( &working );
}

static boolean willPrintBased( type_flag flags )
/**********************************************/
{
    return( ( flags & TF1_BASED ) != TF1_NULL );
}

static void fmtTypeBased( TYPE type, VBUF *pvbuf )
/************************************************/
{
    type_flag   flags;
    VBUF        working;

    if( !willPrintBased( type->flag ) ) {
        return;
    }
    flags = type->flag & TF1_BASED;
    VStrConcStr( pvbuf, openBased );
    switch( flags ) {
    case TF1_BASED_STRING:
        VStrConcStr( pvbuf, openSegname );
        VStrConcStr( pvbuf, ((STRING_CONSTANT)(type->u.m.base))->string );
        VStrConcStr( pvbuf, closeSegname );
        break;
    case TF1_BASED_VOID:
        VStrConcStr( pvbuf, basedVoid );
        break;
    case TF1_BASED_SELF:
        VStrConcStr( pvbuf, basedSelf );
        break;
    case TF1_BASED_FETCH:
        FormatSym( (SYMBOL)type->u.m.base, &working );
        VStrConcStr( pvbuf, working.buf );
        VStrConcStr( pvbuf, whiteSpace );
        VbufFree( &working );
        break;
    case TF1_BASED_ADD:
        FormatSym( (SYMBOL)type->u.m.base, &working );
        VStrConcStr( pvbuf, working.buf );
        VStrConcStr( pvbuf, whiteSpace );
        VbufFree( &working );
        break;
    }
    VStrConcStr( pvbuf, closeBased );
}

static void fmtNicePragma( AUX_INFO *pragma, VBUF *pvbuf )
/********************************************************/
{
    char *id;

    if( pragma == NULL ) {
        return;
    }
    if( PragmaName( pragma, &id ) ) {
        if( id != NULL ) {
            VStrConcStr( pvbuf, id );
            VStrConcStr( pvbuf, whiteSpace );
        }
    } else {
        if( id != NULL ) {
            VStrConcStr( pvbuf, openPragma );
            VStrConcStr( pvbuf, id );
            VStrConcStr( pvbuf, closePragma );
        }
    }
}

static void fmtTypePragma( TYPE type, VBUF *pvbuf )
/*************************************************/
{
    AUX_INFO *pragma;

    if( type->id == TYP_MODIFIER ) {
        pragma = type->u.m.pragma;
    } else {
        pragma = type->u.f.pragma;
    }
    fmtNicePragma( pragma, pvbuf );
}

static void fmtTypeBitfield( TYPE type, VBUF *pvbuf )
/***************************************************/
{
    VBUF    working;
    char    sbuf[ 1 + sizeof( long ) * 2 + 1 ];

    VbufInit( &working );
    VStrNull( &working );
    VStrConcStr( &working, bitfieldSep );
    ultoa( type->u.b.field_width, sbuf, 10 );
    VStrConcStr( &working, sbuf );
    VStrConcStr( &working, whiteSpace );
    VStrPrepStr( pvbuf, working.buf );
    VbufFree( &working );
}

static char *getArgName( unsigned index )
{
    char *name;
    SYMBOL sym;

    name = NULL;
    sym = ScopeFuncParm( index );
    if( sym != NULL ) {
        name = sym->name->name;
        if( IsNameDummy( name ) ) {
            name = NULL;
        }
    }
    return( name );
}

static void fmtTypeArgument( TYPE arg_type, unsigned arg_index, VBUF *pvbuf, FMT_CONTROL control )
{
    FMT_CONTROL arg_control;
    VBUF arg_prefix;
    VBUF arg_suffix;
    char *name;

    arg_control = FormatTypeDefault | control;
    arg_control &= ~FF_ARG_NAMES;
    FormatFunctionType( arg_type, &arg_prefix, &arg_suffix, 0, arg_control );
    if( arg_prefix.buf != NULL ) {
        VStrConcStr( pvbuf, arg_prefix.buf );
    }
    if( control & FF_ARG_NAMES ) {
        name = getArgName( arg_index );
        if( name != NULL ) {
            VStrConcStr( pvbuf, name );
        }
    }
    if( arg_suffix.buf != NULL ) {
        VStrConcStr( pvbuf, arg_suffix.buf );
    }
    VbufFree( &arg_prefix );
    VbufFree( &arg_suffix );
}

static void fmtTypeFlag( type_flag flag, VBUF *pvbuf,
/***************************************************/
    FMT_FLAG_INFO *flag_info )
{
    unsigned    i;
    type_flag   mask;

    for( i = 0 ; flag_info[i].name != NULL ; i++ ) {
        mask = flag_info[i].mask;
        if( (flag & mask) == mask ) {
            VStrConcStr( pvbuf, flag_info[i].name );
        }
    }
}

⌨️ 快捷键说明

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