#include "stdafx.h" #include bool DynamicMethod::Override( const UserProc *pUserProc, Prototype::Accessibility accessibility, bool isOverrideModifier ) { if( this->IsVirtual() && !this->IsAbstract() && isOverrideModifier == false ) { // Override修飾子が無い状況で基底クラスの実体メソッドをオーバーライドしようとした compiler.errorMessenger.Output(127,NULL,cp); } //メンバ関数を上書き this->SetUserProcPtr( pUserProc ); this->SetAbstractMark( false ); if( !this->IsVirtual() ) { // オーバーライドミス compiler.errorMessenger.Output(136, pUserProc->GetName(), cp); } if(this->GetAccessibility() != accessibility ) { compiler.errorMessenger.Output(128,NULL,cp); } return true; } StaticMethod::StaticMethod( const StaticMethod &staticMethod ) { // 静的メソッドがコピーコンストラトされることは想定しない compiler.errorMessenger.OutputFatalError(); } Methods::Methods() { } // コピーコンストラクタ Methods::Methods( const Methods &methods ) { BOOST_FOREACH( CMethod *pMethod, methods ) { this->push_back( new DynamicMethod( dynamic_cast(*pMethod) ) ); } } Methods::~Methods() { Methods &methods = *this; BOOST_FOREACH( CMethod *pMethod, methods ) { delete pMethod; } } void Methods::Add( UserProc *pUserProc,Prototype::Accessibility accessibility, bool isConst, bool isAbstract, bool isVirtual ){ CMethod *pMethod = new DynamicMethod( pUserProc, accessibility, isAbstract, isVirtual, isConst ); this->push_back( pMethod ); pUserProc->SetMethod( pMethod ); } void Methods::AddStatic(UserProc *pUserProc, Prototype::Accessibility accessibility ){ CMethod *pMethod = new StaticMethod( pUserProc, accessibility ); this->push_back( pMethod ); pUserProc->SetMethod( pMethod ); } CMethod *Methods::FindForOverride( const Types &actualTypeParametersForThisMethods, const UserProc *pUserProc ) { //メソッドのオーバーライド Methods &methods = *this; BOOST_FOREACH( CMethod *pMethod, methods ) { if( !pMethod->IsNotUse() && pMethod->GetUserProc().IsEqualForOverride( actualTypeParametersForThisMethods, pUserProc ) ) { return pMethod; } } return NULL; } const CMethod *Methods::GetMethodPtr( const UserProc *pUserProc ) const { const Methods &methods = *this; for( int i=(int)methods.size()-1; i>=0; i-- ){ if( pUserProc == &methods[i]->GetUserProc() ){ return methods[i]; } } return NULL; } bool Methods::IsExist( const char *name ) const { const Methods &methods = *this; BOOST_FOREACH( const CMethod *pMethod, methods ){ if( pMethod->GetUserProc().GetName() == name ) return true; } return false; } void Methods::Enum( const char *methodName, std::vector &subs ) const { //オブジェクトのメンバ関数の場合 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う const Methods &methods = *this; for( int i=(int)methods.size()-1; i>=0; i-- ){ if( methods[i]->GetUserProc().GetName() == methodName && methods[i]->IsNotUse() == false ){ subs.push_back( &methods[i]->GetUserProc() ); } } } void Methods::Enum( BYTE idOperatorCalc, std::vector &subs ) const { //オブジェクトのメンバ関数の場合 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う const Methods &methods = *this; for( int i=(int)methods.size()-1; i>=0; i-- ){ const UserProc &userProc = methods[i]->GetUserProc(); const char *temp = userProc.GetName().c_str(); if(temp[0]==1&&temp[1]==ESC_OPERATOR){ if((BYTE)temp[2]==idOperatorCalc){ subs.push_back( &userProc ); } } } } int Methods::GetVtblNum() const { int count = 0; const Methods &methods = *this; BOOST_FOREACH( const CMethod *pMethod, methods ) { if( pMethod->IsVirtual() ) { count++; } } return count; } void Methods::GenerateVTablePart( long &vtableDataTableOffset ) const { const UserProc **ppsi = (const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *)); //関数テーブルに値をセット int i2 = 0; const Methods &methods = *this; BOOST_FOREACH( const CMethod *pMethod, methods ){ if(pMethod->IsVirtual()){ if( !pMethod->GetUserProc().IsUsing() ) { //ts((char *)pMethod->GetUserProc().GetFullName().c_str()); } pMethod->GetUserProc().Using(); if(pMethod->IsAbstract()){ compiler.errorMessenger.OutputFatalError(); ppsi[i2]=0; } else{ ppsi[i2]=&pMethod->GetUserProc(); } i2++; } } vtableDataTableOffset = compiler.GetObjectModule().dataTable.AddBinary( (void *)ppsi, GetVtblNum()*sizeof(LONG_PTR) ); for( int i=0; i < GetVtblNum(); i++ ){ pobj_Reloc->AddSchedule_DataSection(static_cast(vtableDataTableOffset+i*sizeof(LONG_PTR))); } free(ppsi); }