wbrowse.cpp

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

CPP
2,128
字号
/****************************************************************************
*
*                            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 "wpch.hpp"
#include "handle.hpp"
#include "brmfile.hpp"
#include "reindex.hpp"
#include "decl.hpp"
#include "defn.hpp"
#include "scopes.hpp"
#include "strtable.hpp"
#include "types.hpp"
#include "usage.hpp"
#include "macro.hpp"
#include "wbrowse.hpp"
#include "cache.hpp"
#include "debugprt.hpp"
#include "ppops.hpp"

#define FILE_ERR        "Unable to open %s\n"
#define BAD_CHECKSUM    "%s is not a valid .BRM file.\n"
#define EOF_ERR         "Premature EOF at position %d.\n"
#define UNKNOWN_FLAG    "Unknown record flag %02X at position %d.\n"
#define BAD_PCH_FILE    "The pre-compiled header could not be read."

#define MERGE_ERROR(type,arg1,arg2)  \
        DebugPrinter.DebugMsg(type,arg1,arg2)

Browser *               CurrBrowser;


Browser::Browser()
/**************/
{
    _usages = new UsageList;
    _scopes = new ScopeTable;
    _defns = new DefnList;
    _guards = new DependList;
    _strings = new StringTable;
    _types = new TypeList;
    _decls = new DeclList;
    _macros = new MacroList;

    _declIndex = new ReOrdering;
    _scopeIndex = new ReOrdering;
    _typeIndex = new ReOrdering;
    _stringIndex = new ReOrdering;

    _macrosToSyms = new ReOrdering;

    _defnReIndex = new LList<DefnRec>;
    _typeReIndex = new LList<TypeRec>;
    _usageReIndex = new LList<UsageRec>;

    _buffer = NULL;
    _bufLen = 0;
}


Browser::~Browser()
/***************/
{
    delete _usages;
    delete _scopes;
    delete _defns;
    delete _guards;
    delete _strings;
    delete _types;
    delete _decls;
    delete _macros;
    delete _declIndex;
    delete _scopeIndex;
    delete _typeIndex;
    delete _stringIndex;
    delete _macrosToSyms;
    delete _defnReIndex;
    delete _typeReIndex;
    delete _usageReIndex;

    delete[] _buffer;
}


WBool Browser::LoadOldBrowser( CacheInFile *cache )
/*********************************************/
{
    WBool       result;

    CurrBrowser = this;

    // These first four statements have to be in the given order
    // to ensure that various pointer variables are all set properly
    // after the load.
    result = _types->LoadFrom( cache );
    result = result && _decls->LoadFrom( cache );
    result = result && _scopes->LoadFrom( cache );
    result = result && _usages->LoadFrom( cache );

    result = result && _defns->LoadFrom( cache );
    result = result && _guards->LoadFrom( cache );
    result = result && _strings->LoadFrom( cache );
    result = result && _macros->LoadFrom( cache );

    // flush the re-orderings used by various LoadFrom functions.
    if( result ){
        _scopeIndex->Flush();
        _declIndex->Flush();
        _typeIndex->Flush();
    }

    result = result && _scopeIndex->LoadFrom( cache, "ScopeIndex" );
    result = result && _declIndex->LoadFrom( cache, "DeclIndex" );
    result = result && _typeIndex->LoadFrom( cache, "TypeIndex" );
    result = result && _stringIndex->LoadFrom( cache, "StringIndex" );

    CurrBrowser = NULL;

    // TODO:    more error handling
    return result;
}


WBool Browser::SaveBrowser( CacheOutFile *cache )
/*******************************************/
{
    _usages->SaveTo( cache );
    _scopes->SaveTo( cache );
    _defns->SaveTo( cache );
    _guards->SaveTo( cache );
    _strings->SaveTo( cache );
    _types->SaveTo( cache );
    _decls->SaveTo( cache );
    _macros->SaveTo( cache );
    _scopeIndex->SaveTo( cache, "ScopeIndex" );
    _declIndex->SaveTo( cache, "DeclIndex" );
    _typeIndex->SaveTo( cache, "TypeIndex" );
    _stringIndex->SaveTo( cache, "StringIndex" );

    return TRUE;
}


void Browser::CleanUp()
/********************/
{
    {
        DefnRec         *current;

        current = _defnReIndex->First();
        while( current != NULL ){
            current->index = _declIndex->NewId( current->index );
            current = _defnReIndex->Next();
        }
    }
    {
        TypeRec         *current;

        current = _typeReIndex->First();
        while( current != NULL ){
            WAssert( current->typeCode == BRI_TC_Class ||
                    current->typeCode == BRI_TC_Struct ||
                    current->typeCode == BRI_TC_Union ||
                    current->typeCode == BRI_TC_Enum );
            current->ns.symbolID = _declIndex->NewId( current->ns.symbolID );
            current = _typeReIndex->Next();
        }
    }
    {
        UsageRec        *current;

        current = _usageReIndex->First();
        while( current != NULL ){
            if( current->type == BRI_RT_TypeOf ){
                current->typeID = _typeIndex->NewId( current->typeID );
            } else {
                current->targetID = _declIndex->NewId( current->targetID );
            }
            current = _usageReIndex->Next();
        }
    }

    _defnReIndex->Clear();
    _typeReIndex->Clear();
    _usageReIndex->Clear();

    _declIndex->PCHStopUsing();
    _typeIndex->PCHStopUsing();
    _stringIndex->PCHStopUsing();
    _scopeIndex->PCHStopUsing();

    _usages->Reset();
    _defns->AcceptDefns();
}


int Browser::ReadDeclaration(BrmFile &infile)
/******************************************/
{
    static const int    result = sizeof(BRI_SymbolID)
                               + BRI_SIZE_SYMBOLATTRIBUTES
                               + sizeof(BRI_StringID)
                               + sizeof(BRI_TypeID);
    DeclRec *           declRec;
    DeclRec *           firstDecl;
    DeclRec *           otherDecl;
    ScopeRec *          scope;
    BRI_SymbolID        symID;

    if( !_scopes->Ignore() ){
        declRec = new DeclRec;

        // Read the data from the browse file
        infile.Read( &symID, sizeof(BRI_SymbolID), 1 );
        declRec->attribs = (BRI_SymbolAttributes) 0;
        infile.Read( &declRec->attribs, BRI_SIZE_SYMBOLATTRIBUTES, 1 );
        infile.Read( &declRec->nameID, sizeof(BRI_StringID), 1 );
        infile.Read( &declRec->typeID, sizeof(BRI_TypeID), 1 );

        // Re-index vital information now.
        declRec->nameID = _stringIndex->NewId( declRec->nameID );
        declRec->typeID = _typeIndex->NewId( declRec->typeID );

        // Handle symbols with compiler-generated names, like ".@ct"
        scope = _scopes->Current();
        declRec->nameID = renameSym( declRec->nameID,
                                     declRec->typeID,
                                     scope );

        // KLUDGE ALERT!!!!
        // To optimize the search below, each ScopeRec stores an
        // AvlTree of __linked lists of DeclRecs__.  Each linked
        // list contains DeclRecs with the same name...

        // See if this symbol already exists in the current scope
        firstDecl = otherDecl = scope->symbols.Find( declRec->nameID );
        while( otherDecl != NULL ){
            if( otherDecl->typeID == declRec->typeID &&
                (otherDecl->attribs&BRI_SA_TypeMask) ==
                    (declRec->attribs&BRI_SA_TypeMask) ){
                break;
            }
            // Here we use Browser's friend access to DeclRec
            otherDecl = otherDecl->_nextDecl;
        }

        if( otherDecl == NULL ){
            // Add the symbol to the global list and the current scope.
            declRec->index = _declIndex->Change( symID );
            declRec->enclosing = indexOf( scope );
            _decls->Insert( declRec );
            if( firstDecl == NULL ){
                declRec->_nextDecl = NULL;
                scope->symbols.Insert( declRec->nameID, declRec );
            } else {
                declRec->_nextDecl = firstDecl->_nextDecl;
                firstDecl->_nextDecl = declRec;
            }
        } else {
            _declIndex->ChangeTo( symID, otherDecl->index );
            if( otherDecl->attribs & BRI_SA_Temporary ){
                otherDecl->attribs = declRec->attribs;
            }
            delete declRec;
        }
    } else {
        infile.Skip( result );
    }

    return result;
}


int Browser::ReadFile(BrmFile &infile)
/***********************************/
{
    int                 result;
    BRI_StringID        filenameID;

    result = sizeof(BRI_StringID);
    // Read the data from the browse file.
    infile.Read( &filenameID, sizeof(BRI_StringID), 1 );
    // Reindex vital information now.
    filenameID = _stringIndex->NewId( filenameID );
    // Change the current file.
    _usages->SetFile( filenameID );

    _guards->StartFile( filenameID );
    if( !_guards->Ignore() ){
        _state = GUARD_SEARCH;
    }

    return result;
}


int Browser::ReadFileEnd(BrmFile &)
/********************************/
{
    _usages->EndFile();
    if( _guards->Ignore() ){
        _guards->EndFile();
    }
    return 0;
}


int Browser::ReadTemplate(BrmFile &infile)
/***************************************/
{
    static const int    result = sizeof(BRI_StringID);
    BRI_StringID        filenameID;

    // Read the data from the browse file
    infile.Read( &filenameID, sizeof(BRI_StringID), 1 );
    filenameID = _stringIndex->NewId( filenameID );
    // Change the current file.
    _usages->SetFile( filenameID );

    if( !_guards->Ignore() ){
        _guards->StartTemplate();
    }

    return result;
}


int Browser::ReadTemplateEnd(BrmFile &)
/************************************/
{
    _usages->EndFile();
    if( !_guards->Ignore() ){
        _guards->EndTemplate();
    }
    return 0;
}


int Browser::ReadScope(BrmFile &infile)
/************************************/
{
    int result = sizeof(BRI_ScopeID)
               + BRI_SIZE_SCOPETYPE
               + sizeof(BRI_TypeID);
    ScopeRec *          scopeRec;
    ScopeRec *          actualScope;
    BRI_StringID        fnName;
    BRI_TypeID          fnType;

    scopeRec = new ScopeRec;

    // Read enough data to determine the size of the record.
    infile.Read( &scopeRec->index, sizeof(BRI_ScopeID), 1 );
    scopeRec->flags = (BRI_ScopeType) 0;
    infile.Read( &scopeRec->flags, BRI_SIZE_SCOPETYPE, 1 );

    if( scopeRec->flags == BRI_ST_Function ){
        result += sizeof(BRI_StringID);
    }

    if( !_scopes->Ignore() ){
        // Add the scope to the scope list.
        if( scopeRec->flags == BRI_ST_Function ){
            infile.Read( &fnName, sizeof(BRI_StringID), 1 );
            infile.Read( &fnType, sizeof(BRI_TypeID), 1 );
            fnName = _stringIndex->NewId( fnName );
            fnType = _typeIndex->NewId( fnType );

            // Handle compiler names like ".@ct"
            fnName = renameSym( fnName, fnType, _scopes->Current() );

            actualScope = _scopes->OpenScope( scopeRec, fnName, fnType );
        } else {
            infile.Read( &scopeRec->symbolID, sizeof(BRI_SymbolID), 1 );
            actualScope = _scopes->OpenScope( scopeRec );
        }
    } else {
        _scopes->OpenDummyScope();
        if( scopeRec->flags == BRI_ST_Function ){
            infile.Skip( sizeof(BRI_StringID) + sizeof(BRI_TypeID) );
        } else {
            infile.Skip( sizeof(BRI_TypeID) );
        }
    }

    return result;
}


int Browser::ReadScopeEnd(BrmFile &)
/*********************************/
{
    _scopes->CloseScope();
    return 0;
}

int Browser::ReadDelta(BrmFile &infile)
/************************************/

⌨️ 快捷键说明

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