source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Method.cpp@ 496

Last change on this file since 496 was 465, checked in by dai_9181, 17 years ago

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

File size: 4.7 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 compiler.errorMessenger.Output(127,NULL,cp);
14 }
15
16 //メンバ関数を上書き
17 this->SetUserProcPtr( pUserProc );
18 this->SetAbstractMark( false );
19
20 if( !this->IsVirtual() )
21 {
22 // オーバーライドミス
23 compiler.errorMessenger.Output(136, pUserProc->GetName(), cp);
24 }
25 if(this->GetAccessibility() != accessibility )
26 {
27 compiler.errorMessenger.Output(128,NULL,cp);
28 }
29
30 return true;
31}
32
33
34StaticMethod::StaticMethod( const StaticMethod &staticMethod )
35{
36 // 静的メソッドがコピーコンストラトされることは想定しない
37 compiler.errorMessenger.OutputFatalError();
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 Types &actualTypeParametersForThisMethods, const UserProc *pUserProc )
74{
75 //メソッドのオーバーライド
76 Methods &methods = *this;
77 BOOST_FOREACH( CMethod *pMethod, methods )
78 {
79 if( !pMethod->IsNotUse() && pMethod->GetUserProc().IsEqualForOverride( actualTypeParametersForThisMethods, 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 compiler.errorMessenger.OutputFatalError();
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.