subsect.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 429 行 · 第 1/2 页
CPP
429 行
/****************************************************************************
*
* 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 <assert.h>
#include <wcstack.h>
#include <string.hpp>
#include "common.hpp"
#include "cverror.hpp"
#include "subsect.hpp"
WCStack< SymbolStruct*, WCPtrSList<SymbolStruct> > SstAlignSym::symStack;
/*SstGlobalTypes::~SstGlobalTypes()
{
for ( unsigned_16 i = ToTypeIndex(0);
i < ToTypeIndex(_globalTypingInfo.Entries()); i++ ) {
delete */
void SstGlobalTypes::FixUpTypes( const type_index startIndex )
/************************************************************/
{
for ( uint i = startIndex;
i < ToTypeIndex(_globalTypingInfo.Entries()); i++ ) {
_globalTypingInfo[i] -> FixTypeIndex();
}
}
void SstGlobalTypes::ProcessTypes( LFLocalTypeRecord* target )
/************************************************************/
{
WCPtrSListIter<LFTypeRecord> iter(_globalTypingInfo.Find(target));
while ( ++iter ) {
if ( iter.current() -> IsEquivalent( *target ) ) {
return;
}
}
InsertNewType(target);
}
bool SstGlobalTypes::LoadTypes( Retriever& retriever, const module mod )
/**********************************************************************/
{
char* buffer;
unsigned_32 length;
if ( ! retriever.ReadSubsection(buffer,length,sstTypes,mod) ) {
return FALSE;
}
char* end = &buffer[length];
if ( * (unsigned_32 *) buffer != CV4_HEADER ) {
::Warning("invalid header dectected in types.");
}
// skip the header.
buffer += LONG_WORD;
// if it is the first module, just load the types into the global
// table without packing.
if ( mod == 1 ) {
while ( buffer < end ) {
_globalTypingInfo.Insert( new LFGlobalTypeRecord(ToTypeIndex(_globalTypingInfo.Entries()),buffer));
buffer += WORD + * (unsigned_16 *) buffer;
}
TypeMap.Set( CV_FIRST_NONPRIM + _globalTypingInfo.Entries() );
return TRUE;
} else {
while ( buffer < end ) {
_localTypingInfo.Insert( new LFLocalTypeRecord(ToTypeIndex(_localTypingInfo.Entries()),buffer));
buffer += WORD + * (unsigned_16 *) buffer;
}
TypeMap.Reset(_localTypingInfo.Entries());
}
uint oldCount = _globalTypingInfo.Entries();
// Full type packing is not implemented due to its long running time
// when input is relatively big. Here only packs records that can be
// hashed, these records are structs, unions, enums, class. And they
// will likely reference a lot of other records, so partial packing
// is not that bad after all.
WCPtrSListIter<LFTypeRecord> iter(_localTypingInfo._hashRecords);
while ( ++iter ) {
if ( ! TypeMap.IsDone( iter.current() -> TypeIndex() ) ) {
ProcessTypes( iter.current() );
}
}
// Anything that is left will be inserted as a new type into the global
// table.
iter.reset(_localTypingInfo._otherRecords);
while ( ++iter ) {
if ( ! TypeMap.IsDone( iter.current() -> TypeIndex() ) ) {
InsertNewType( iter.current() );
}
}
FixUpTypes(ToTypeIndex(oldCount));
// Selectively destruct the types in the local table. If the type is
// a new type, then only release the memory of a bare LFLocalTypeRecord.
// Otherwise, release the memory of a bare record plus the pointer to
// LFLeafStruct. This is bad style, but can boost performance by not
// having to create a constructor and do a pointer copy only when
// transfer types from the local table to the global table. See the
// LFGlobalTypeRecord declaration for more details.
for ( uint i = CV_FIRST_NONPRIM;
i < ToTypeIndex(_localTypingInfo.Entries()); i++ ) {
if ( ! TypeMap.IsNewType(i) ) {
// If not a new type, release pointer memory as well.
_localTypingInfo[i]->ManualDestruct();
}
// release bare LFLocalTypeRecord memory.
delete _localTypingInfo[i];
}
_localTypingInfo.Clear();
return TRUE;
}
void SstGlobalTypes::Append( LFLocalTypeRecord* typeRecord )
/**********************************************************/
{
_globalTypingInfo.Insert( new LFGlobalTypeRecord (typeRecord));
}
void SstGlobalTypes::Put( ExeMaker& eMaker ) const
{
unsigned_32 offset = 0;
uint i;
eMaker.DumpToExe( (unsigned_32) 0 );
eMaker.DumpToExe( (unsigned_32) _globalTypingInfo.Entries() );
for ( i = ToTypeIndex(0); i < ToTypeIndex(_globalTypingInfo.Entries()); i++ ) {
eMaker.DumpToExe( offset );
offset += _globalTypingInfo[i] -> Length();
}
for ( i = ToTypeIndex(0); i < ToTypeIndex(_globalTypingInfo.Entries()); i++ ) {
_globalTypingInfo[i] -> Put( eMaker );
}
}
uint SymbolSubsection::DumpPageAlign( ExeMaker& eMaker,
const uint padCount,
const unsigned_8 padVal )
/**************************************************************/
{
eMaker.DumpToExe((unsigned_16) (padCount+WORD));
eMaker.DumpToExe((unsigned_16) S_ALIGN);
for ( uint i = 0; i < padCount; i++ ) {
eMaker.DumpToExe(padVal);
}
return ( LONG_WORD + padCount );
}
uint SymbolSubsection::PageAlign( ExeMaker& eMaker,
const uint length,
const unsigned_32 offset )
/*****************************************************************/
{
uint pad = SymbolSubsection::PadCount(length,offset);
if ( pad > 0 ) {
return SymbolSubsection::DumpPageAlign(eMaker,pad);
}
return 0;
}
uint SymbolSubsection::PadCount( const uint length,
const unsigned_32 offset )
/***************************************************************/
{
uint pad = ALIGN_LENGTH - offset % ALIGN_LENGTH;
if ( length > pad ) {
return pad;
}
return 0;
}
void SstAlignSym::InsertOneRecord( SymbolStruct* sym )
/****************************************************/
{
uint pad = SymbolSubsection::PadCount(sym->Length(),_currentOffset);
if ( pad > 0 ) {
_symbolInfo.append( new CSPageAlign(pad) );
_currentOffset += pad + LONG_WORD;
}
sym -> SetOffset( _currentOffset );
_currentOffset += sym -> Length();
_symbolInfo.append( sym );
}
void SstAlignSym::Insert( SymbolStruct* sym )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?