source: dev/trunk/abdev/BasicCompiler_Common/src/Method.cpp @ 352

Last change on this file since 352 was 352, checked in by dai_9181, 16 years ago

基底クラスからインターフェイスメソッドを実装できるようにした。

File size: 4.5 KB
Line 
1#include "stdafx.h"
2
3#include <Class.h>
4
5
6bool DynamicMethod::Override( const UserProc *pUserProc, Prototype::Accessibility accessibility, bool isOverrideModifier )
7{
8    if( this->IsVirtual()
9        && !this->IsAbstract()
10        && isOverrideModifier == false )
11    {
12        // Override修飾子が無い状況で基底クラスの実体メソッドをオーバーライドしようとした
13        SetError(127,NULL,cp);
14    }
15
16    //メンバ関数を上書き
17    this->SetUserProcPtr( pUserProc );
18    this->SetAbstractMark( false );
19
20    if( !this->IsVirtual() )
21    {
22        // オーバーライドミス
23        SetError(136,NULL,cp);
24    }
25    if(this->GetAccessibility() != accessibility )
26    {
27        SetError(128,NULL,cp);
28    }
29
30    return true;
31}
32
33
34StaticMethod::StaticMethod( const StaticMethod &staticMethod )
35{
36    // 静的メソッドがコピーコンストラトされることは想定しない
37    SetError();
38}
39
40Methods::Methods()
41{
42}
43
44// コピーコンストラクタ
45Methods::Methods( const Methods &methods )
46{
47    BOOST_FOREACH( CMethod *pMethod, methods )
48    {
49        this->push_back( new DynamicMethod( dynamic_cast<DynamicMethod &>(*pMethod) ) );
50    }
51}
52
53Methods::~Methods()
54{
55    Methods &methods = *this;
56    BOOST_FOREACH( CMethod *pMethod, methods )
57    {
58        delete pMethod;
59    }
60}
61
62void Methods::Add( UserProc *pUserProc,Prototype::Accessibility accessibility, bool isConst, bool isAbstract, bool isVirtual ){
63    CMethod *pMethod = new DynamicMethod( pUserProc, accessibility, isAbstract, isVirtual, isConst );
64    this->push_back( pMethod );
65    pUserProc->SetMethod( pMethod );
66}
67void Methods::AddStatic(UserProc *pUserProc, Prototype::Accessibility accessibility ){
68    CMethod *pMethod = new StaticMethod( pUserProc, accessibility );
69    this->push_back( pMethod );
70    pUserProc->SetMethod( pMethod );
71}
72
73CMethod *Methods::FindForOverride( const UserProc *pUserProc )
74{
75    //メソッドのオーバーライド
76    Methods &methods = *this;
77    BOOST_FOREACH( CMethod *pMethod, methods )
78    {
79        if( pMethod->GetUserProc().IsEqualForOverride( pUserProc ) )
80        {
81            return pMethod;
82        }
83    }
84    return NULL;
85}
86
87const CMethod *Methods::GetMethodPtr( const UserProc *pUserProc ) const
88{
89    const Methods &methods = *this;
90    for( int i=(int)methods.size()-1; i>=0; i-- ){
91        if( pUserProc == &methods[i]->GetUserProc() ){
92            return methods[i];
93        }
94    }
95    return NULL;
96}
97bool Methods::IsExist( const char *name ) const
98{
99    const Methods &methods = *this;
100    BOOST_FOREACH( const CMethod *pMethod, methods ){
101        if( pMethod->GetUserProc().GetName() == name ) return true;
102    }
103    return false;
104}
105void Methods::Enum( const char *methodName, vector<const UserProc *> &subs ) const
106{
107    //オブジェクトのメンバ関数の場合
108    //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
109    const Methods &methods = *this;
110    for( int i=(int)methods.size()-1; i>=0; i-- ){
111        if( methods[i]->GetUserProc().GetName() == methodName && methods[i]->IsNotUse() == false ){
112            subs.push_back( &methods[i]->GetUserProc() );
113        }
114    }
115}
116void Methods::Enum( BYTE idOperatorCalc, vector<const UserProc *> &subs ) const
117{
118    //オブジェクトのメンバ関数の場合
119    //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
120    const Methods &methods = *this;
121    for( int i=(int)methods.size()-1; i>=0; i-- ){
122        const UserProc &userProc = methods[i]->GetUserProc();
123        const char *temp = userProc.GetName().c_str();
124        if(temp[0]==1&&temp[1]==ESC_OPERATOR){
125            if((BYTE)temp[2]==idOperatorCalc){
126                subs.push_back( &userProc );
127            }
128        }
129    }
130}
131
132int Methods::GetVtblNum() const
133{
134    int count = 0;
135    const Methods &methods = *this;
136    BOOST_FOREACH( const CMethod *pMethod, methods )
137    {
138        if( pMethod->IsVirtual() )
139        {
140            count++;
141        }
142    }
143    return count;
144}
145
146void Methods::GenerateVTablePart( long &vtableDataTableOffset ) const
147{
148    const UserProc **ppsi = (const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
149
150    //関数テーブルに値をセット
151    int i2 = 0;
152    const Methods &methods = *this;
153    BOOST_FOREACH( const CMethod *pMethod, methods ){
154        if(pMethod->IsVirtual()){
155            if( !pMethod->GetUserProc().IsUsing() )
156            {
157                ts((char *)pMethod->GetUserProc().GetFullName().c_str());
158            }
159            pMethod->GetUserProc().Using();
160
161            if(pMethod->IsAbstract()){
162                SetError();
163
164                ppsi[i2]=0;
165            }
166            else{
167                ppsi[i2]=&pMethod->GetUserProc();
168            }
169            i2++;
170        }
171    }
172
173    vtableDataTableOffset = compiler.GetObjectModule().dataTable.AddBinary( (void *)ppsi, GetVtblNum()*sizeof(LONG_PTR) );
174
175    for( int i=0; i < GetVtblNum(); i++ ){
176        pobj_Reloc->AddSchedule_DataSection(static_cast<DWORD>(vtableDataTableOffset+i*sizeof(LONG_PTR)));
177    }
178
179    free(ppsi);
180}
Note: See TracBrowser for help on using the repository browser.