classlat.cpp

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

CPP
530
字号
 * in the lattice, and if so returns a pointer to it.
 */

ClassLattice * ClassLattice::joinTo( dr_handle hdl, dr_virtuality virt,
                                     dr_access effAccess, int level )
//---------------------------------------------------------------------------
{
    ClassLattice * ret = NULL;
    for( int i = _flatClasses->count(); i > 0 && ret == NULL; i -= 1 ) {
        ClassLattice * test = (*_flatClasses)[ i - 1 ];

        if( test->_handle == hdl ) {
            switch( test->_virtual ) {
            case VIRT_NOT_SET:
                test->_virtual = (VirtLevel) virt;
                ret = test;
                break;
            case VIRT_VIRT:
                if( virt == DR_VIRTUALITY_VIRTUAL || _relaxedVirt ) {
                    if( effAccess < test->_effAccess ) {
                        test->_effAccess = effAccess;
                    }
                    ret = test;
                }
                break;
            default:
                REQUIRE( test->_virtual == VIRT_NOT_VIRT, "classlat::jointo bad _virtual!" );
                if( _relaxedVirt ) {
                    ret = test;
                }
            }
        }
    }

    if( ret != NULL ) {
        if( myabs(ret->_level) < myabs(level) ) {
            ret->adjustLevelsUp( level - ret->_level );
        }
    }
    return ret;
}

/* this method is called when joinTo adjusts the level of an existing
 * latticeNode.  It adjusts all parents all the way up, providing that
 * they are only one level above the child -- otherwise it stops.
 */

void ClassLattice::adjustLevelsUp( int levelDiff )
//------------------------------------------------
{
    for( int i = _bases.count(); i > 0; i -= 1 ) {
        ClassLattice * baseNode = _bases[ i - 1 ]->_class;

        if( baseNode->_level == _level - 1 ) {
            baseNode->adjustLevelsUp( levelDiff );
        } else {
            break;
        }
    }

    _level += levelDiff;
}

static int ClassLattice::baseHook( dr_sym_type, dr_handle handle, char * name,
                                   dr_handle inheritHandle, void * obj )
//----------------------------------------------------------------------------
{
    dr_access        access;
    dr_access        effAccess;
    dr_virtuality    virtuality;
    ClassLattice *   addnode = NULL;
    ClassLattice *   me = (ClassLattice *) obj;

    access = DRGetAccess( inheritHandle );
    virtuality = DRGetVirtuality( inheritHandle );

    if( access > me->_effAccess ) {
        effAccess = access;
    } else {
        effAccess = me->_effAccess;
    }

    addnode = me->joinTo( handle, virtuality, effAccess, me->_level - 1 );

    if( addnode != NULL ) {
        WBRFree( name );
    } else {
        // NYI - _module isn't necessarily what we want it to be!
        addnode = me->newLattice( handle, me->_module, name, me->_flatClasses,
                                  effAccess, virtuality, me->_level - 1 );
    }

    DerivationPtr * ptr = me->newPtr( addnode, access, virtuality );

    me->_bases.add( ptr );

    return TRUE;
}

void ClassLattice::derivedClasses( WVList & symlist )
//---------------------------------------------------
{
    loadDeriveds();
    for( int i = 0; i < _deriveds.count(); i += 1 ) {
        symlist.add( _deriveds[ i ]->_class );
    }
}

void ClassLattice::enumerateDeriveds( BaseCB callback, void * obj )
//-----------------------------------------------------------------
{
    loadDeriveds();
    for( int i = 0; i < _deriveds.count(); i += 1 ) {
        if( !callback( *_deriveds[ i ], obj ) ) break;
    }
}

void ClassLattice::setDeriveds( void )
//------------------------------------
{
    if( !_derivedsLoaded ) {
        for( int nodeCtr = _flatClasses->count(); nodeCtr > 0; nodeCtr-- ) {
            ClassLattice * node = (* _flatClasses )[ nodeCtr - 1 ];
            node->loadBases();

            for( int baseCtr = node->_bases.count(); baseCtr > 0; baseCtr-- ) {
                if( isEqual( node->_bases[ baseCtr - 1 ]->_class ) ) {
                    _deriveds.add( newPtr( node, DR_ACCESS_PUBLIC, DR_VIRTUALITY_NONE ));
                }
            }
        }
        _derivedsLoaded = TRUE;
    }
}

void ClassLattice::loadDeriveds( void )
//-------------------------------------
{
    if( !_derivedsLoaded ) {
        _module->setModule();
        DRDerivedSearch( _handle, this, deriveHook );
        _derivedsLoaded = TRUE;
    }
}

static int ClassLattice::deriveHook( dr_sym_type, dr_handle handle,
                                     char * name, dr_handle inheritHandle,
                                     void * obj )
//-------------------------------------------------------------------------
{
    ClassLattice *   addnode;
    dr_access        effAccess;
    dr_access        access;
    dr_virtuality    virtuality;
    ClassLattice *   me = (ClassLattice *) obj;

    access = DRGetAccess( inheritHandle );
    virtuality = DRGetVirtuality( inheritHandle );

    if( access > me->_effAccess ) {
        effAccess = access;
    } else {
        effAccess = me->_effAccess;
    }

    addnode = me->joinTo( handle, virtuality, effAccess, me->_level + 1 );

    if( addnode != NULL ) {
        WBRFree( name );
    } else {
        addnode = me->newLattice( handle, me->_module, name, me->_flatClasses,
                                  access, (dr_virtuality) VIRT_NOT_SET,
                                  me->_level + 1 );
    }

    DerivationPtr * ptr = me->ClassLattice::newPtr( addnode, access, virtuality );
    me->_deriveds.add( ptr );

    return TRUE;
}

/*
 * look for cls among derived and base classes, and if found show how it
 * is derived from us / we are derived from it.
 */

char * ClassLattice::derivation( ClassLattice *cls )
//--------------------------------------------------
{
    char            buf[ 18 ];  // long enough for "protected virtual"
    DerivationPtr * ptr;
    int             i;
    bool            found = FALSE;

    for( i = _deriveds.count(); i > 0 && !found; i -= 1 ) {
        ptr = _deriveds[ i - 1 ];
        if( cls == ptr->_class ) {
            found = TRUE;
        }
    }

    for( i = _bases.count(); i > 0 && !found; i -= 1 ) {
        ptr = _bases[ i - 1 ];
        if( cls == ptr->_class ) {
            found = TRUE;
        }
    }

    REQUIRE( found, "ClassLattice::derivation -- couldn't find cls!" );

    switch( ptr->_access ) {
    case DR_ACCESS_PUBLIC:
        strcpy( buf, "public" );
        break;
    case DR_ACCESS_PROTECTED:
        strcpy( buf, "protected" );
        break;
    default:
        REQUIRE( ptr->_access == DR_ACCESS_PRIVATE,
                 "ClassLattice::derivation -- _access out of range!" );
        buf[ 0 ] = '\0';
    }

    if( ptr->_virtuality != DR_VIRTUALITY_NONE ) {
        strcat( buf, " virtual" );
    }
    if( buf[0] != '\0' ) {
        return WBRStrDup( buf );
    }
    return NULL;
}

void ClassLattice::normalizeLevels( void )
//----------------------------------------
{
    int     i;

    if( _flatClasses->count() == 0 )
        return;

    int minimum = (*_flatClasses)[ 0 ]->_level;

    for( i = _flatClasses->count(); i > 0; i -= 1 ) {
        if( (*_flatClasses)[ i - 1 ]->_level < minimum ) {
            minimum = (*_flatClasses)[ i - 1 ]->_level;
        }
    }

    for( i = _flatClasses->count(); i > 0; i -= 1 ) {
        ClassLattice * node = (*_flatClasses)[ i - 1 ];
        node->_level -= minimum;
    }
}

int findClass( ClassList& list, ClassLattice * node )
//---------------------------------------------------
{
    for( int i = list.count(); i > 0; i -= 1 ) {
        if( list[ i - 1 ] && list[ i - 1 ]->isEqual( node ) ) {
            return i - 1;
        }
    }
    return -1;
}

⌨️ 快捷键说明

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