thunk.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 487 行 · 第 1/2 页
C
487 行
/****************************************************************************
*
* 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 "cgfront.h"
#include "fnbody.h"
#include "defarg.h"
#include "errdefns.h"
#include "rtngen.h"
#include "objmodel.h"
#include "cgio.h"
static SYMBOL existingThunk( // GET EXISTING THUNK SYMBOL FOR NAME
SCOPE scope, // - scope to look in
char *name ) // - thunk name
{
SYMBOL sym; // - symbol for name
SEARCH_RESULT *result; // - search result
if( ScopeId( scope ) == SCOPE_FILE ) {
result = ScopeFindNaked( scope, name );
} else {
result = ScopeContainsMember( scope, name );
}
if( result != NULL ) {
sym = result->sym_name->name_syms;
ScopeFreeResult( result );
} else {
sym = NULL;
}
return( sym );
}
static unsigned classifyThunk( // GET CLASSIFICATION OF THUNK
SYMBOL sym ) // - original symbol
{
unsigned classification; // - classification of thunk
DbgAssert( ! SymIsThunk( sym ) );
if( SymIsDtor( sym ) ) {
classification = SPECIAL_DTOR_THUNK;
} else if( SymIsOpDel( sym ) ) {
classification = SPECIAL_OP_DEL_THUNK;
} else if( SymIsOpDelar( sym ) ) {
classification = SPECIAL_OP_DELAR_THUNK;
} else if( TypeHasNumArgs( sym->sym_type, 1 ) ) {
DbgAssert( SymIsCtor( sym ) );
classification = SPECIAL_COPY_THUNK;
} else {
DbgAssert( SymIsCtor( sym ) );
classification = SPECIAL_CTOR_THUNK;
}
return classification;
}
static SYMBOL addrThunkSymbol( // GET THUNK SYMBOL FROM ORIGINAL
unsigned classification, // - classification of thunk
SYMBOL sym ) // - original symbol
{
TYPE thunk_type; // - type of new symbol
SYMBOL new_sym; // - the new symbol
SCOPE scope; // - scope for new symbol
char *name; // - name of new symbol
symbol_class thunk_class; // - SC_.. for thunk
switch( classification ) {
case SPECIAL_OP_DEL_THUNK :
case SPECIAL_OP_DELAR_THUNK :
thunk_class = SC_STATIC;
break;
case SPECIAL_DTOR_THUNK :
case SPECIAL_COPY_THUNK :
case SPECIAL_CTOR_THUNK :
thunk_class = SC_MEMBER;
break;
DbgDefault( "addrThunkSymbol -- bad classification" );
}
name = CppSpecialName( classification );
scope = SymScope( sym );
new_sym = existingThunk( scope, name );
if( new_sym == NULL ) {
thunk_type = MakeThunkFunction( sym->sym_type );
new_sym = AllocTypedSymbol( thunk_type );
new_sym->id = thunk_class;
new_sym->flag |= SF_ADDR_THUNK;
new_sym = ScopeInsert( scope, new_sym, name );
SymDeriveThrowBits( new_sym, sym );
}
return new_sym;
}
static void insertArgument( // INSERT AN ARGUMENT
TYPE type ) // - type of argument
{
char *name; // - name of argument
SYMBOL sym; // - new argument
sym = SymMakeDummy( type, &name );
ScopeInsert( GetCurrScope(), sym, name );
}
static void declareThunkArgs( // DECLARE ARG.S FOR THUNK
SYMBOL fn_sym, // - original symbol
TYPE fn_type ) // - type of thunk
{
unsigned num_args; // - # arguments
arg_list *args; // - arguments
TYPE *curr; // - addr[ current argument type ]
if( SymCDtorExtraParm( fn_sym ) ) {
insertArgument( MakeCDtorExtraArgType() );
}
args = fn_type->u.f.args;
for( num_args = args->num_args, curr = args->type_list
; num_args != 0
; ++curr, --num_args ) {
insertArgument( *curr );
}
}
static SCOPE thunkPrologue( // PROLOGUE FOR A SCOPE
SYMBOL thunk_sym, // - thunk symbol
FUNCTION_DATA *data ) // - function data
{
SYMBOL orig; // - original symbol
SCOPE arg_scope; // - scope for arguments
orig = thunk_sym->u.thunk_calls;
thunk_sym->flag |= SF_INITIALIZED;
SetCurrScope (SymScope( thunk_sym ));
ScopeBeginFunction( thunk_sym );
arg_scope = GetCurrScope();
declareThunkArgs( orig, FunctionDeclarationType( orig->sym_type ) );
FunctionBodyStartup( thunk_sym, data, FUNC_NULL );
return arg_scope;
}
static void thunkEpilogue( // THUNK EPILOGUE
SYMBOL thunk_sym, // - thunk symbol
FUNCTION_DATA *data ) // - generation data
{
FunctionBodyShutdown( thunk_sym, data );
ScopeEnd( SCOPE_FUNCTION );
}
static PTREE thunkArgList( // BUILD THUNK ARGUMENT LIST
SCOPE scope ) // - scope for arguments
{
char *ret_name; // - name of return value symbol
PTREE expr; // - argument expression
PTREE list; // - arg. list under construction
SYMBOL stopper; // - stopping value
SYMBOL sym; // - current symbol
unsigned count; // - # in list
OMR arg_model; // - argument calling convention model
TYPE arg_type; // - unmodified argument type from symbol
ret_name = CppSpecialName( SPECIAL_RETURN_VALUE );
stopper = ScopeOrderedStart( scope );
sym = NULL;
list = NULL;
for(;;) {
sym = ScopeOrderedNext( stopper, sym );
if( sym == NULL ) break;
if( sym->name->name != ret_name ) {
arg_type = TypedefModifierRemoveOnly( sym->sym_type );
expr = MakeNodeSymbol( sym );
expr = NodeFetchReference( expr );
arg_model = ObjModelArgument( TypeReferenced( arg_type ) );
if( TypeReference( arg_type ) == NULL && arg_model != OMR_CLASS_REF ) {
expr = NodeRvalue( expr );
}
list = NodeArgument( list, expr );
}
}
list = NodeReverseArgs( &count, list );
return( list );
}
SYMBOL ClassFunMakeAddressable( // MAKE SURE THE FUNCTION CAN BE ADDRESSED
SYMBOL orig_sym ) // - original symbol
{
SYMBOL thunk_sym; // - thunk symbol
unsigned classification; // - classification of thunk
if( orig_sym == NULL ) {
return orig_sym;
}
if( ( orig_sym->id != SC_DEFAULT )
&&( ! TypeHasPragma( orig_sym->sym_type ) ) ) {
type_flag flags;
TypeModFlags( orig_sym->sym_type, &flags );
if( ! ( flags & TF1_DLLIMPORT ) ) {
return orig_sym;
}
}
classification = classifyThunk( orig_sym );
thunk_sym = addrThunkSymbol( classification, orig_sym );
if( NULL == thunk_sym->u.thunk_calls ) {
if( ! SymIsVirtual( orig_sym ) ) {
thunk_sym = SymDeriveThrowBits( thunk_sym, orig_sym );
}
thunk_sym->u.thunk_calls = orig_sym;
RtnGenAddSymbol( RGSYMBOL_GenThunk, thunk_sym );
}
return thunk_sym;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?