classlat.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 530 行 · 第 1/2 页
CPP
530 行
/****************************************************************************
*
* 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 "assure.h"
#include "module.h"
#include "classlat.h"
#include "classtyp.h"
#include "util.h"
#include "mem.h"
inline int myabs( int a ) { return (a < 0) ? -1 * a : a; }
DerivationPtr::DerivationPtr( ClassLattice * cls, dr_access acc,
dr_virtuality virt )
: _class( cls )
, _virtuality( virt )
, _access( acc )
//--------------------------------------------------------------
{
}
// make a new pointer of my type
virtual DerivationPtr * ClassLattice::newPtr( ClassLattice * cls,
dr_access acc, dr_virtuality virt )
//-------------------------------------------------------------------------
{
return new DerivationPtr( cls, acc, virt );
}
// this constructor is designed to be used by the outside world.
// it creates the root node of the lattice, and the _flatClasses list
ClassLattice::ClassLattice( Symbol * sym, bool relax )
: _handle( sym->getHandle() )
, _module( sym->getModule() )
, _name( WBRStrDup( sym->name() ) )
, _basesLoaded( FALSE )
, _derivedsLoaded( FALSE )
, _effAccess( (dr_access) 0 )
, _virtual( VIRT_NOT_SET )
, _relaxedVirt( relax )
, _level( 0 )
//----------------------------------------------------
{
_flatClasses = new ClassList;
_flatClasses->add( this );
}
// Internal ctor, used to create non-root nodes
ClassLattice::ClassLattice( dr_handle hdl, Module * mod, char * name,
ClassList * vlist, dr_access acc,
dr_virtuality virt, bool relaxVirt, int level )
: _handle( hdl )
, _module( mod )
, _name( name )
, _basesLoaded( FALSE )
, _derivedsLoaded( FALSE )
, _flatClasses( vlist )
, _effAccess( acc )
, _virtual( (VirtLevel)virt )
, _relaxedVirt(relaxVirt)
, _level( level )
//-------------------------------------------------------------------------
{
_flatClasses->add( this );
if( _name == NULL ) { /* OPTME this is expensive */
Symbol * sym = makeSymbol();
_name = WBRStrDup( sym->name() );
delete sym;
}
}
ClassLattice::~ClassLattice( void )
//---------------------------------
{
int i;
WBRFree( _name );
for( i = _bases.count(); i > 0; i -= 1 ) {
delete _bases[ i - 1 ];
}
_bases.reset();
for( i = _deriveds.count(); i > 0; i -= 1 ) {
delete _deriveds[ i - 1 ];
}
_deriveds.reset();
}
ClassLattice * ClassLattice::newLattice( dr_handle hdl, Module * mod,
char * name, ClassList * vlist,
dr_access acc, dr_virtuality virt,
int level )
//-------------------------------------------------------------------------
{
return new ClassLattice( hdl, mod, name, vlist, acc, virt, _relaxedVirt,
level );
}
void ClassLattice::deleteLattice( void )
//--------------------------------------
{
ClassList * list;
list = _flatClasses;
for( int i = list->count(); i > 0; i -= 1 ) {
delete (*list)[ i - 1 ];
}
delete list;
}
char * ClassLattice::name( void ) const
//-------------------------------------
{
ASSERTION( _name != NULL );
return _name;
}
bool ClassLattice::isEqual( WObject const * obj ) const
//-----------------------------------------------------
{
return _handle == ((ClassLattice *)obj)->_handle;
}
Symbol * ClassLattice::makeSymbol( void )
//---------------------------------------
{
char * name = WBRStrDup( _name );
return Symbol::defineSymbol( DR_SYM_CLASS, _handle, 0L, _module, name );
}
void ClassLattice::enumerateBases( BaseCB callback, void * obj )
//--------------------------------------------------------------
{
loadBases();
for( int i = 0; i < _bases.count(); i += 1 ) {
if( !callback( *_bases[ i ], obj ) ) break;
}
}
void ClassLattice::baseClasses( WVList & symlist )
//------------------------------------------------
{
loadBases();
for( int i = 0; i < _bases.count(); i += 1 ) {
symlist.add( _bases[ i ]->_class );
}
}
void ClassLattice::loadBases( void )
//----------------------------------
{
if( !_basesLoaded ) {
_module->setModule();
DRBaseSearch( _handle, this, baseHook );
_basesLoaded = TRUE;
}
}
// joinLattice takes the lowest node of a lattice, and links it to
// another lattice. this function could stand some serious simplification
void ClassLattice::joinLattice( ClassLattice * lattTo )
//-----------------------------------------------------
{
ClassList* list = _flatClasses;
ClassList adjust;
int levelDiff = 0;
bool levelSet = FALSE;
int i;
REQUIRE( lattTo != this, "classlattice::joinlattice -- join to myself" );
for( i = 0; i < list->count(); i += 1 ) {
ClassLattice * node = (*list)[ i ];
if( node != NULL ) {
adjust.add( node );
for( int j = node->_bases.count(); j > 0; j -= 1 ) {
DerivationPtr * basePtr = node->_bases[ j - 1 ];
REQUIRE( node->_flatClasses != lattTo->_flatClasses,
"ClassLattice::JoinLattice tried to join related" );
int index = findClass( *lattTo->_flatClasses, basePtr->_class );
if( index >= 0 ) {
//NYI rely on not having loaded deriveds (otherwise, might kill me!)
REQUIRE( !basePtr->_class->_derivedsLoaded, "joinLattice ack" );
list->replaceAt( findClass( *list, basePtr->_class ), NULL );
if( basePtr->_class != (*lattTo->_flatClasses)[ index ] ) {
delete basePtr->_class;
// this should probably be a separate function
// what it is doing is changing all of the pointers
// from basePtr->_class to the same class in lattTo
for( int k = list->count(); k > 0; k -= 1 ) {
ClassLattice * work = (*list)[ k - 1 ];
if( work != NULL ) {
for( int l = work->_bases.count(); l > 0; l -= 1 ) {
if( work->_bases[ l - 1 ]->_class == basePtr->_class ) {
work->_bases[ l - 1 ]->adjustTo( (*lattTo->_flatClasses)[ index ] );
int tryDiff = work->_bases[ l - 1 ]->_class->_level + 1 - work->_level;
if( !levelSet ) {
levelDiff = tryDiff;
levelSet = TRUE;
} else {
if( tryDiff > levelDiff ) {
levelDiff = tryDiff;
}
}
}
}
}
}
}
}
}
node->_flatClasses = lattTo->_flatClasses;
lattTo->_flatClasses->add( node );
}
}
for( i = adjust.count(); i > 0; i -= 1 ) {
adjust[ i - 1 ]->_level += levelDiff;
}
delete list;
}
/* the hdl parameter is the handle of another symbol. This method checks
* the flatClasses list by handle to see if this symbol is already stored
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?