scope.c

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

C
2,318
字号
/****************************************************************************
*
*                            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 <stdio.h>
#include <limits.h>

#include "errdefns.h"
#include "memmgr.h"
#include "ring.h"
#include "stack.h"
#include "name.h"
#include "hashtab.h"
#include "carve.h"
#include "cgfront.h"
#include "class.h"
#include "decl.h"
#include "dbg.h"
#include "fnovload.h"
#include "cgsegid.h"
#include "vstk.h"
#include "pstk.h"
#include "pragdefn.h"
#include "yydriver.h"
#include "fnbody.h"
#include "initdefs.h"
#include "pcheader.h"
#include "template.h"
#include "stats.h"
#include "preproc.h"
#include "typesig.h"
#include "brinfo.h"
#include "conpool.h"

#define _ScopeMask( i )         ( 1 << (i) )

#define _IsClassScope( s )      \
        ((s)->id == SCOPE_CLASS)
#define _IsFunctionScope( s )   \
        ((s)->id == SCOPE_FUNCTION)
#define _IsBlockScope( s )   \
        ((s)->id == SCOPE_BLOCK)
#define _IsFileScope( s )   \
        ((s)->id == SCOPE_FILE)

static int hashTableSize[SCOPE_MAX] = {
    #define SCOPE_DEF(a,b) b
    SCOPE_DEFS
    #undef SCOPE_DEF
};

typedef enum file_scope_control {
    FS_GLOBAL           = 0x01,
    FS_UNNAMED          = 0x02,
    FS_NULL             = 0x00
} fs_control;

typedef boolean (*special_name_fn)( SYMBOL_NAME );

typedef struct save_mapping SAVE_MAPPING;
struct save_mapping {
    SAVE_MAPPING        *next;
    SCOPE               from;
    SCOPE               to;
    SYMBOL              sym;
    target_offset_t     map_0;
};

typedef struct base_path BASE_PATH;
struct base_path {
    BASE_PATH           *next;
    BASE_PATH           *prev;
    BASE_CLASS          *base;
    SCOPE               scope;
    inherit_flag        flag;
    unsigned            checked_private : 1;
    unsigned            failed_private : 1;
};

typedef struct symbol_exclude SYMBOL_EXCLUDE;
struct symbol_exclude {
    SYMBOL_EXCLUDE      *next;
    SYMBOL              sym;
};

typedef struct path_cap PATH_CAP;
struct path_cap {
    PATH_CAP            *next;          /* NULL terminated list */
    BASE_PATH           *head;
    BASE_PATH           *tail;
    SCOPE               access_decl;
    SYMBOL_EXCLUDE      *exclude;
    SYMBOL_NAME         sym_name;
    SYMBOL              sym;
    inherit_flag        flag;
    unsigned            throw_away : 1;
    unsigned            across_virtual_base : 1;
};

typedef struct base_stack BASE_STACK;
struct base_stack {
    BASE_STACK          *next;
    BASE_STACK          *parent;
    BASE_CLASS          *base;
    SCOPE               scope;
    SYMBOL              access_changed;
    void                *hold;
    inherit_flag        access_perm;
    unsigned            used : 1;
};

typedef enum {          /* return value for base class walking routines */
    WALK_NORMAL,        /* keep going; nothing special has happened */
    WALK_FINISH,        /* terminate entire walk traversal */
    WALK_ABANDON,       /* abandon this base class and its base classes */
} walk_status;

typedef walk_status (*walk_routine)( BASE_STACK *, void * );

typedef struct {
    SCOPE               derived;
    SCOPE               base;
    unsigned            copies;
    unsigned            virtual_base : 1;
    unsigned            is_derived : 1;
} scope_derived_walk;

typedef struct {
    SCOPE               start;
    GEN_LEAP            *list;
    unsigned            count;
} rtti_leap_walk;

typedef struct {
    char                *name;
    TYPE                found;
} bound_base_walk;

typedef struct {
    SCOPE               found;
    unsigned            copies;
} count_copy_walk;

typedef struct {
    SCOPE               base;
    unsigned            virtual_base : 1;
    unsigned            is_derived : 1;
} derived_walk;

typedef struct {
    PSTK_CTL            common_bases;
    int                 colour;
} common_base_walk;

typedef struct {
    unsigned            depth;
    SCOPE               base;
    unsigned            many_pathes : 1;
} base_depth_walk;

typedef struct {
    void                (*rtn)( SCOPE, void * );
    void                *data;
} all_bases_walk;

typedef struct {
    SCOPE               derived;
    SCOPE               base;
    SCOPE               found;
    SYMBOL              vfn_sym;
    SYMBOL              vfn_override;
    target_offset_t     this_delta;
    target_offset_t     retn_delta;
} vfn_opt_walk;

typedef struct {
    CLASS_VBTABLE       *tables;
    SCOPE               start;
    unsigned            already_done : 1;
} vbtable_walk;

typedef struct {
    CLASS_VFTABLE       *tables;
    CLASS_VFTABLE       *curr;
    BASE_STACK          *top;
    BASE_STACK          *parent;
    SCOPE               start;
    SCOPE               final;
    SCOPE               base;
    SCOPE               derived;
    THUNK_ACTION        *thunk;
    VSTK_CTL            disambig;
    unsigned            OK_to_diagnose : 1;
    unsigned            already_done : 1;
    unsigned            thunk_code : 1;
} vftable_walk;

typedef struct {                                /* I - input, O - output */
    SCOPE               start;                  /* I: type of (*p) in "p->C::a" */
    SCOPE               disambiguate;           /* I: C in "p->C::a" */
    SCOPE               ignore;                 /* I: don't search here */
    char                *name;                  /* I: a in "p->C::a" */
    TYPE                type;                   /* I: T in "p->operator T()" */
    TYPE                fn_type;                /* I: type of virtual fn */
    SYMBOL              fn_sym;                 /* I: sym of virtual fn */
    special_name_fn     is_special;             /* I: fn to check for special names */
    unsigned            consider_mask;          /* I: mask to check curr scope */
    BASE_STACK          *top;                   /* T: temp for storing 'top' */
    MSG_NUM             error_msg;              /* O: error message to use */
    MSG_NUM             info_msg;               /* O: info message for above msg */
    SYMBOL              info1;                  /* O: parm for first info msg */
    SYMBOL              info2;                  /* O: parm for second info msg */
    SYMBOL_NAME         vfn_name;               /* O: vfn that shares table */
    FNOV_LIST           *user_conv_list;        /* O: list of user convs in hierarchy */
    PATH_CAP            *paths;                 /* O: paths to name */
    unsigned            path_count;             /* O: # of paths to name */
    inherit_flag        perm;                   /* O: permission of path to name */
    type_flag           this_qualifier;         /* I: T cv-qual *this; cv-qual */
    unsigned            virtual_override : 1;   /* I: find vfns with same name*/
    unsigned            user_conversion : 1;    /* I: find conversion to 'type' */
    unsigned            specific_user_conv : 1; /* I: must find specific conv */
    unsigned            best_user_conv : 1;     /* I: must find best conv */
    unsigned            check_special : 1;      /* I: use is_special() */
    unsigned            no_inherit : 1;         /* I: no base classes searched */
    unsigned            only_inherit : 1;       /* I: only base classes searched */
    unsigned            only_bases : 1;         /* I: direct base classes searched */
    unsigned            ok_to_diagnose : 1;     /* I: flag any errors found */
    unsigned            find_all : 1;           /* I: find all pathes to base */
    unsigned            ignore_access : 1;      /* I: access isn't important */
    unsigned            saw_class : 1;          /* I: class scope was seen */
    unsigned            ambiguous : 1;          /* O: ambiguity detected */
    unsigned            overload_reqd : 1;      /* O: overload affects ambiguity */
    unsigned            use_this : 1;           /* O: access could use "this" */
    unsigned            no_this : 1;            /* O: access can't use "this" */
    unsigned            saw_function : 1;       /* O: function scope was seen */
    unsigned            use_index : 1;          /* O: use index of virtual fn */
    unsigned            return_thunk : 1;       /* O: vfn needs return thunk */
    unsigned            protected_OK : 1;       /* O: protected sym can be accessed */
    unsigned            file_class_done : 1;    /* O: C::id search from file-scope done */
    unsigned            file_ns_done : 1;       /* O: N::id search from file-scope done */
    unsigned            same_table : 1;         /* O: vfn name is in same table */
    unsigned            lookup_error : 1;       /* O: error to report from lookup */
} lookup_walk;

typedef struct access_data {
    BASE_PATH           *path;
    SCOPE               access;
    SCOPE               member;
    SCOPE               located;
    inherit_flag        perm;
    unsigned            protected_OK : 1;
} access_data;

typedef struct qualify_stack QUALIFICATION;
struct qualify_stack {
    QUALIFICATION       *next;
    SCOPE               reset;
    SCOPE               access;
};

SCOPE g_CurrScope;
SCOPE g_FileScope;
SCOPE g_InternalScope;
SYMBOL ChipBugSym;
SYMBOL DFAbbrevSym;
SYMBOL PCHDebugSym;

static char bool_zapped_char;
static char static_assert_zapped_char;

extern SCOPE    GetCurrScope(void)
{
    return g_CurrScope;
}

extern SCOPE    SetCurrScope(SCOPE newScope)
{
    SCOPE oldScope = g_CurrScope;
    g_CurrScope = newScope;

#ifndef NDEBUG
    if( PragDbgToggle.dump_scopes )
    {
        printf("Set new scope to 0x%.08X\n", newScope);
        if(newScope)
        {
            printf("===============================================================================\n");
            DumpScope(newScope);
            printf("===============================================================================\n");
        }
    }
#endif

    return oldScope;
}

extern SCOPE    GetFileScope(void)
{
    return g_FileScope;
}

extern SCOPE    SetFileScope(SCOPE newScope)
{
    SCOPE oldScope = g_FileScope;
    g_FileScope = newScope;
    return oldScope;
}

extern SCOPE    GetInternalScope(void)
{
    return g_InternalScope;
}

extern SCOPE    SetInternalScope(SCOPE newScope)
{
    SCOPE oldScope = g_InternalScope;
    g_InternalScope = newScope;
    return oldScope;
}



#define BLOCK_SYM_REGION        64
#define BLOCK_USING_NS          64
#define BLOCK_NAME_SPACE        64
#define BLOCK_SCOPE             64
#define BLOCK_SYMBOL            64
#define BLOCK_SYMBOL_NAME       64
#define BLOCK_BASE_STACK        16
#define BLOCK_BASE_PATH         16
#define BLOCK_PATH_CAP          16
#define BLOCK_SEARCH_RESULT     16
#define BLOCK_GEN_LEAP          16
#define BLOCK_QUALIFICATION     16
#define BLOCK_SYMBOL_EXCLUDE    16
static carve_t carveSYM_REGION;
static carve_t carveUSING_NS;
static carve_t carveNAME_SPACE;
static carve_t carveSCOPE;
static carve_t carveSYMBOL;
static carve_t carveSYMBOL_NAME;
static carve_t carveBASE_STACK;
static carve_t carveBASE_PATH;
static carve_t carvePATH_CAP;
static carve_t carveSEARCH_RESULT;
static carve_t carveGEN_LEAP;
static carve_t carveQUALIFICATION;
static carve_t carveSYMBOL_EXCLUDE;

ExtraRptCtr( syms_defined );
ExtraRptCtr( scopes_alloced );
ExtraRptCtr( scopes_kept );
ExtraRptCtr( scopes_searched );
ExtraRptCtr( scopes_closed );
ExtraRptCtr( nonempty_scopes_closed );
ExtraRptCtr( cnv_total );
ExtraRptCtr( cnv_quick );
ExtraRptCtr( cnv_found );

static SAVE_MAPPING *mappingList;       // member pointer mapping array list
static char *uniqueNameSpaceName;       // name for unique namespaces
static NAME_SPACE *allNameSpaces;       // list of all namespaces

static inherit_flag verifyAccess( access_data * );
static inherit_flag checkBaseAccess( SCOPE, SCOPE, derived_status );

#ifndef NDEBUG
static void printScopeName( SCOPE scope, char *suffix )
{
    char *name;

    switch( scope->id ) {
    case SCOPE_CLASS:
        name = ScopeClass( scope )->u.c.info->name;
        if( name == NULL ) {
            name = "**un-named**";
        }
        printf( "%s ", name );
        break;
    case SCOPE_FILE:
        name = ScopeNameSpaceFormatName( scope );
        if( name == NULL ) {
            printf( "FILE " );
        } else {
            printf( "%s ", name );
        }
        break;
    case SCOPE_FUNCTION:
        printf( "%s() ", ScopeFunction( scope )->name->name );
        break;
    case SCOPE_BLOCK:
        printf( "{} " );
        break;
    default:
        printf( "SCOPE(%02x) ", scope->id );
    }
    if( suffix != NULL ) {
        fputs( suffix, stdout );
    }
}

static void printSymbolName( SYMBOL sym )
{
    printScopeName( SymScope( sym ), NULL );
    printf( ":: %s ", sym->name->name );
}

static void dumpThunk( THUNK_ACTION *thunk )
{
    SYMBOL sym;

    if( ! PragDbgToggle.dump_vftables ) {
        return;
    }
    printf( "thunk:" );
    if( thunk->last_entry ) {
        printf( " last_entry" );
    }
    if( thunk->possible_ambiguity ) {
        printf( " possible_ambiguity" );
    }
    if( ScopePureVirtualThunk( thunk ) != NULL ) {
        printf( " pure_virtual" );
    }
    putchar( '\n' );
    printf( "- " );
    sym = thunk->sym;
    printSymbolName( sym );
    putchar( '\n' );
    if( thunk->delta ) {
        printf( "- this -= %xh\n", thunk->delta );
    }
    if( thunk->ctor_disp ) {

⌨️ 快捷键说明

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