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 + -
显示快捷键?