source: dev/BasicCompiler_Common/Class.cpp@ 92

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

列挙型クラスの自動生成コードを修正した(派生クラスでのToStringメソッドを廃止し、サイズを軽減した)。

File size: 37.8 KB
RevLine 
[4]1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
[5]6#include "../BasicCompiler32/opcode.h"
[4]7#endif
8
9CDBClass *pobj_DBClass;
10
11CClass *pobj_CompilingClass;
12CClass *pobj_StringClass;
13
[18]14CMember *pCompilingMethod;
15
[4]16
17
[75]18CMember::CMember( CClass *pobj_c, DWORD access, bool isConst, bool isRef, char *buffer, int nowLine ){
[4]19 extern int cp;
20
21 //構文を解析
22 char VarName[VN_SIZE];
23 char init_buf[VN_SIZE];
24 char constract_parameter[VN_SIZE];
[75]25 GetDimentionFormat(buffer,VarName,SubScripts,*this,init_buf,constract_parameter);
[4]26
27 //重複チェック
28 if(pobj_c->DupliCheckAll(VarName)){
29 SetError(15,VarName,cp);
30 }
31
[85]32 /*
33 TODO: 消す
34 メンバ定義は抽象クラスでもOK
[75]35 if( IsObject() ){
36 if( GetClass().IsAbstract() ){
[4]37 //抽象クラスだったとき
[75]38 SetError(125,GetClass().name,cp);
[4]39 }
[85]40 }*/
[4]41
42 //メンバ名
43 name=(char *)HeapAlloc(hHeap,0,lstrlen(VarName)+1);
44 lstrcpy(name,VarName);
45
46 //アクセス権
47 dwAccess=access;
48
[17]49 //定数扱いかどうか
50 this->isConst = isConst;
51
[4]52 //初期データ
53 InitBuf=(char *)HeapAlloc(hHeap,0,lstrlen(init_buf)+1);
54 lstrcpy(InitBuf,init_buf);
55
56 //コンストラクタ用のパラメータ
57 ConstractParameter=(char *)HeapAlloc(hHeap,0,lstrlen(constract_parameter)+1);
58 lstrcpy(ConstractParameter,constract_parameter);
59
60 //ソースコードの位置
[75]61 source_code_address=nowLine;
[4]62}
[75]63CMember::CMember(CMember &member):
64 Type( member )
65{
[4]66
67 //name
[75]68 name=(char *)HeapAlloc(hHeap,0,lstrlen(member.name)+1);
69 lstrcpy(name,member.name);
[4]70
[17]71 //定数扱いかどうか
[75]72 isConst = member.isConst;
[17]73
[4]74 //SubScripts
[75]75 memcpy(SubScripts,member.SubScripts,MAX_ARRAYDIM*sizeof(int));
[4]76
77 //ソースコードの位置
[75]78 source_code_address=member.source_code_address;
[4]79}
80CMember::CMember(){
81 memset(this,0,sizeof(CMember));
82}
83CMember::~CMember(){
84 HeapDefaultFree(name);
85 if(InitBuf) HeapDefaultFree(InitBuf);
86 if(ConstractParameter) HeapDefaultFree(ConstractParameter);
87}
88
[17]89bool CMember::IsConst(){
90 return isConst;
91}
92
[4]93void CMember::InitStaticMember(void){
94 //静的メンバをグローバル領域に作成
95
96 //イテレータをリセット
97 extern CDBClass *pobj_DBClass;
98 pobj_DBClass->Iterator_Reset();
99
100 int back_cp=cp;
101
102 while(pobj_DBClass->Iterator_HasNext()){
103 CClass *pobj_c;
104 pobj_c=pobj_DBClass->Iterator_GetNext();
105
[67]106 int i=0;
[53]107 foreach( CMember *member, pobj_c->staticMembers ){
108 char temporary[VN_SIZE];
109 sprintf(temporary,"%s.%s",pobj_c->name,member->name);
[64]110 dim(
[4]111 temporary,
[53]112 member->SubScripts,
[75]113 *member,
[53]114 member->InitBuf,
115 member->ConstractParameter,
[4]116 0);
117
118 //ネイティブコードバッファの再確保
[89]119 ReallocNativeCodeBuffer();
120
[67]121 i++;
[4]122 }
123 }
124
125 cp=back_cp;
126}
127
128
129
130CMethod::CMethod(CMethod *pobj){
131 //コピーコンストラクタ
132 memset(this,0,sizeof(CMethod));
133
[75]134 pUserProc=pobj->pUserProc;
[4]135
136 bAbstract=pobj->bAbstract;
137
138 bVirtual=pobj->bVirtual;
139}
140CMethod::CMethod(){
141 memset(this,0,sizeof(CMethod));
142}
143CMethod::~CMethod(){
144}
145
146
147
[90]148CClass::CClass(const char *name):
149 ConstructorMemberSubIndex( 0 ),
150 DestructorMemberSubIndex( 0 ),
151 classType( Class ),
[91]152 isUsing( false ),
[90]153 pobj_InheritsClass( NULL ),
154 ppobj_Member( NULL ),
155 iMemberNum( 0 ),
156 vtbl_num( 0 ),
157 iAlign( 0 ),
158 vtbl_offset( -1 ),
159 isCompilingConstructor( false ),
160 isCompilingDestructor( false ),
161 pobj_NextClass( NULL )
162{
[4]163 this->name=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1);
164 lstrcpy(this->name,name);
165}
166CClass::~CClass(){
167 int i;
168
169 //クラス名
170 HeapDefaultFree(name);
171
172 if(ppobj_Member){
173 //メンバ
174 for(i=0;i<iMemberNum;i++){
175 delete ppobj_Member[i];
176 }
177 HeapDefaultFree(ppobj_Member);
178 ppobj_Member=0;
179 }
180
[53]181 //静的メンバ
182 foreach( CMember *member, staticMembers ){
183 delete member;
[4]184 }
185
[51]186 //メソッド
187 foreach( CMethod *method, methods ){
[50]188 delete method;
[4]189 }
[51]190
191 //静的メソッド
192 foreach( CMethod *method, staticMethods ){
193 delete method;
194 }
[4]195}
[64]196
[91]197bool CClass::IsUsing() const
198{
199 return isUsing;
200}
201void CClass::Using(){
202 isUsing = true;
203}
204
[90]205bool CClass::IsClass() const
206{
207 return classType == CClass::Class;
208}
209bool CClass::IsInterface() const
210{
211 return classType == CClass::Interface;
212}
213bool CClass::IsEnum() const
214{
215 return classType == CClass::Enum;
216}
217bool CClass::IsDelegate() const
218{
219 return classType == CClass::Delegate;
220}
[64]221bool CClass::IsStructure() const
222{
223 return classType == CClass::Structure;
224}
225
[90]226bool CClass::Inherits( CClass &inheritsClass, int nowLine ){
[29]227
[90]228 //ループ継承でないかをチェック
229 if(pobj_LoopRefCheck->check(inheritsClass)){
230 SetError(123,inheritsClass.name,nowLine);
231 return false;
232 }
233
234 if( inheritsClass.ppobj_Member == 0 ){
235 //継承先が読み取られていないとき
236 pobj_LoopRefCheck->add(this->name);
237 pobj_DBClass->GetClass_recur(inheritsClass.name);
238 pobj_LoopRefCheck->del(this->name);
239 }
240
[29]241 //メンバをコピー
242 ppobj_Member=(CMember **)HeapReAlloc(
243 hHeap,
244 0,
245 ppobj_Member,
[90]246 ( iMemberNum + inheritsClass.iMemberNum )*sizeof(CMember *));
247 for(int i3=0;i3<inheritsClass.iMemberNum;i3++){
248 ppobj_Member[iMemberNum]=new CMember( *inheritsClass.ppobj_Member[i3] );
[29]249
250 //dwAccess
[90]251 if(inheritsClass.ppobj_Member[i3]->dwAccess==ACCESS_PRIVATE)
252 ppobj_Member[iMemberNum]->dwAccess=ACCESS_NON;
253 else ppobj_Member[iMemberNum]->dwAccess=inheritsClass.ppobj_Member[i3]->dwAccess;
254
255 iMemberNum++;
[29]256 }
257
258 //メソッドをコピー
[90]259 foreach( CMethod *baseMethod, inheritsClass.methods ){
[51]260 CMethod *method = new CMethod( baseMethod );
[29]261
262 //dwAccess
[51]263 if(baseMethod->dwAccess==ACCESS_PRIVATE)
264 method->dwAccess=ACCESS_NON;
265 else method->dwAccess=baseMethod->dwAccess;
[29]266
267 //pobj_Inherits
268 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
[51]269 if(baseMethod->pobj_InheritsClass==0)
[90]270 method->pobj_InheritsClass=&inheritsClass;
[29]271 else
[51]272 method->pobj_InheritsClass=
273 baseMethod->pobj_InheritsClass;
274
275 methods.push_back( method );
[29]276 }
277
278 //仮想関数の数
[90]279 vtbl_num += inheritsClass.vtbl_num;
[29]280
281 //継承先のクラスをメンバとして保持する
[90]282 pobj_InheritsClass = &inheritsClass;
283
284 return true;
[29]285}
[90]286bool CClass::InheritsInterface( CClass &inheritsInterface, int nowLine ){
287
288 //ループ継承でないかをチェック
289 if(pobj_LoopRefCheck->check(inheritsInterface)){
290 SetError(123,inheritsInterface.name,nowLine);
291 return false;
292 }
293
294 if( inheritsInterface.ppobj_Member == 0 ){
295 //継承先が読み取られていないとき
296 pobj_LoopRefCheck->add(this->name);
297 pobj_DBClass->GetClass_recur(inheritsInterface.name);
298 pobj_LoopRefCheck->del(this->name);
299 }
300
301 //メソッドをコピー
302 foreach( CMethod *baseMethod, inheritsInterface.methods ){
303 CMethod *method = new CMethod( baseMethod );
304
305 //dwAccess
306 if(baseMethod->dwAccess==ACCESS_PRIVATE)
307 method->dwAccess=ACCESS_NON;
308 else method->dwAccess=baseMethod->dwAccess;
309
310 //pobj_Inherits
311 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
312 if(baseMethod->pobj_InheritsClass==0)
313 method->pobj_InheritsClass=&inheritsInterface;
314 else
315 method->pobj_InheritsClass=
316 baseMethod->pobj_InheritsClass;
317
318 methods.push_back( method );
319 }
320
321 //仮想関数の数
322 vtbl_num += inheritsInterface.vtbl_num;
323
324 /*
325 TODO: インターフェイス向けの機構を作る
326 //継承先のクラスをメンバとして保持する
327 pobj_InheritsClass = &inheritsInterface;
328 */
329
330 return true;
331}
[40]332void CClass::AddMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer ){
[17]333 ppobj_Member = (CMember **)HeapReAlloc( hHeap, 0, ppobj_Member, ( iMemberNum + 1 ) * sizeof(CMember *) );
[40]334 ppobj_Member[iMemberNum] = new CMember( this, dwAccess, isConst, isRef, buffer );
[4]335 iMemberNum++;
336}
[75]337void CClass::AddStaticMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer, int nowLine ){
338 CMember *member = new CMember( this, dwAccess, isConst, isRef, buffer, nowLine );
[53]339 staticMembers.push_back( member );
[4]340}
[75]341void CClass::AddMethod( UserProc *pUserProc,DWORD dwAccess, bool isConst, BOOL bAbstract, BOOL bVirtual ){
[51]342 CMethod *method = new CMethod();
[75]343 method->pUserProc = pUserProc;
[51]344 method->dwAccess = dwAccess;
345 method->isConst = isConst;
346 method->bAbstract = bAbstract;
347 method->bVirtual = bVirtual;
348 method->pobj_InheritsClass = 0;
[4]349
[51]350 methods.push_back( method );
[75]351
352 // プロシージャオブジェクトと関連付け
353 pUserProc->SetMethod( method );
[4]354}
[75]355void CClass::AddStaticMethod(UserProc *pUserProc,DWORD dwAccess){
[50]356 CMethod *method = new CMethod();
[75]357 method->pUserProc=pUserProc;
[50]358 method->dwAccess=dwAccess;
359 method->bAbstract=0;
360 method->bVirtual=0;
361 method->pobj_InheritsClass=0;
[4]362
[51]363 staticMethods.push_back( method );
[75]364
365 // プロシージャオブジェクトと関連付け
366 pUserProc->SetMethod( method );
[4]367}
[46]368BOOL CClass::DupliCheckAll(const char *name){
[4]369 //重複チェック
370
371 //メンバ
372 if(DupliCheckMember(name)) return 1;
373
374 //メソッド
[51]375 foreach( CMethod *method, methods ){
[75]376 if( lstrcmp( name, method->pUserProc->GetName().c_str() ) == 0 ){
[4]377 return 1;
378 }
379 }
380
381 return 0;
382}
[46]383BOOL CClass::DupliCheckMember(const char *name){
[4]384 //重複チェック
385
386 //メンバ
[53]387 for( int i=0;i<iMemberNum;i++){
[4]388 if(lstrcmp(name,ppobj_Member[i]->name)==0){
389 return 1;
390 }
391 }
392
393 //静的メンバ
[53]394 foreach( CMember *member, staticMembers ){
395 if( lstrcmp( name, member->name ) == 0 ){
[4]396 return 1;
397 }
398 }
399
400 return 0;
401}
[75]402CMethod *CClass::GetMethodInfo( UserProc *pUserProc ) const
403{
[51]404 for( int i=(int)methods.size()-1; i>=0; i-- ){
[89]405 if( pUserProc == methods[i]->pUserProc ){
406 return methods[i];
407 }
[18]408 }
[50]409 return NULL;
[18]410}
[75]411CMethod *CClass::GetStaticMethodInfo( UserProc *pUserProc ) const
412{
[51]413 for( int i=(int)staticMethods.size()-1; i>=0; i-- ){
[75]414 if( pUserProc == staticMethods[i]->pUserProc ) return staticMethods[i];
[18]415 }
[50]416 return NULL;
[18]417}
[75]418bool CClass::IsExistMethod( const char *name ) const
419{
[51]420 foreach( CMethod *method, methods ){
[75]421 if( method->pUserProc->GetName() == name ) return true;
[27]422 }
423 return false;
424}
[75]425bool CClass::IsExistStaticMethod( const char *name ) const
426{
[51]427 foreach( CMethod *method, staticMethods ){
[75]428 if( method->pUserProc->GetName() == name ) return true;
[27]429 }
430 return false;
431}
[4]432
[75]433void CClass::EnumStaticMethod( const char *methodName, std::vector<UserProc *> &subs ) const
[50]434{
[51]435 foreach( CMethod *method, staticMethods ){
[75]436 if( method->pUserProc->GetName() == methodName ){
437 subs.push_back( method->pUserProc );
[50]438 }
439 }
440}
[27]441
[75]442void CClass::EnumMethod( const char *methodName, std::vector<UserProc *> &subs ) const
[50]443{
444 //オブジェクトのメンバ関数の場合
445 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
[51]446 for( int i=(int)methods.size()-1; i>=0; i-- ){
[75]447 if( methods[i]->pUserProc->GetName() == methodName ){
448 subs.push_back( methods[i]->pUserProc );
[50]449 }
450 }
451}
452
[75]453void CClass::EnumMethod( const BYTE idOperatorCalc, std::vector<UserProc *> &subs ) const
[50]454{
[51]455 //オブジェクトのメンバ関数の場合
456 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
457 for( int i=(int)methods.size()-1; i>=0; i-- ){
[75]458 UserProc *pUserProc = methods[i]->pUserProc;
459 const char *temp = pUserProc->GetName().c_str();
[50]460 if(temp[0]==1&&temp[1]==ESC_OPERATOR){
461 if((BYTE)temp[2]==idOperatorCalc){
[75]462 subs.push_back( pUserProc );
[50]463 }
464 }
465 }
466}
467
[51]468//デフォルト コンストラクタ メソッドを取得
469CMethod *CClass::GetConstructorMethod() const
470{
471 if( ConstructorMemberSubIndex == -1 ) return NULL;
472 return methods[ConstructorMemberSubIndex];
473}
[50]474
[51]475//デストラクタ メソッドを取得
476CMethod *CClass::GetDestructorMethod() const
477{
478 if( DestructorMemberSubIndex == -1 ) return NULL;
479 return methods[DestructorMemberSubIndex];
480}
481
[63]482//サイズを取得
483int CClass::GetSize() const
484{
485 return GetMemberOffset( NULL, NULL );
486}
[51]487
[63]488//メンバのオフセットを取得
489int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
490{
491 int i,i2,offset;
492
493 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
494 if(vtbl_num) offset=PTR_SIZE;
495 else offset=0;
496
497 int alignment;
498 if(iAlign) alignment=iAlign;
499 else alignment=1;
500
501 int iMaxAlign=0;
502 for(i=0;i<iMemberNum;i++){
503 CMember *pMember = ppobj_Member[i];
504
505 i2 = pMember->GetSize();
506
507 //アラインメントを算出
508 int member_size;
[75]509 if( pMember->IsStruct() ){
[63]510 //メンバクラスのアラインメントを取得
[75]511 member_size=pMember->GetClass().GetAlignment();
[63]512 }
513 else{
514 //メンバサイズを取得
515 member_size=i2;
516 }
517 if(iMaxAlign<member_size) iMaxAlign=member_size;
518
519 //アラインメントを考慮
520 if(iAlign&&iAlign<member_size){
521 if(offset%alignment) offset+=alignment-(offset%alignment);
522 }
523 else{
524 if(alignment<member_size) alignment=member_size;
525
526 if(member_size==0){
527 //メンバを持たないクラス
528 //※何もしない(オフセットの計算をしない)
529 }
530 else{
531 if(offset%member_size) offset+=member_size-(offset%member_size);
532 }
533 }
534
535 if(memberName){
536 //メンバ指定がある場合は、オフセットを返す
537 if(lstrcmp(pMember->name,memberName)==0){
538 if(pMemberNum) *pMemberNum=i;
539 return offset;
540 }
541 }
542
543 //配列を考慮したメンバサイズを取得
544 member_size=i2 * JumpSubScripts(pMember->SubScripts);
545
546 //メンバサイズを加算
547 offset+= member_size;
548 }
549
550 if(iMaxAlign<alignment) alignment=iMaxAlign;
551
552 //アラインメントを考慮
553 if(alignment){
554 if(offset%alignment) offset+=alignment-(offset%alignment);
555 }
556
557 if(pMemberNum) *pMemberNum=i;
558 return offset;
559}
560
561int CClass::GetAlignment() const
562{
563 int i;
564 int alignment,member_size;
565
566 if(vtbl_num) alignment=PTR_SIZE;
567 else alignment=0;
568
569 for(i=0;i<iMemberNum;i++){
570 CMember *pMember = ppobj_Member[i];
571
[75]572 if(pMember->IsStruct()){
[63]573 //メンバクラスのアラインメントを取得
[75]574 member_size=pMember->GetClass().GetAlignment();
[63]575 }
576 else{
577 //メンバサイズを取得
578 member_size = pMember->GetSize();
579 }
580
581 //アラインメントをセット
582 if(alignment<member_size) alignment=member_size;
583 }
584
585 if(alignment==0) return 0;
586
587 if(iAlign) alignment=iAlign;
588
589 return alignment;
590}
591
592
593
[75]594int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
[51]595{
596 int n = 0;
597 foreach( CMethod *method, methods ){
[75]598 if( method->pUserProc == pUserProc ) break;
599 if( method->bVirtual ) n++;
[51]600 }
601 return n;
602}
[4]603LONG_PTR CClass::GetVtblGlobalOffset(void){
[28]604
605 //既に存在する場合はそれを返す
[4]606 if(vtbl_offset!=-1) return vtbl_offset;
607
[28]608
[92]609
[28]610 //////////////////////////////////////
611 // 存在しないときは新たに生成する
612 //////////////////////////////////////
613
[75]614 UserProc **ppsi;
615 ppsi=(UserProc **)HeapAlloc(hHeap,0,vtbl_num*sizeof(UserProc *));
[4]616
617 //関数テーブルに値をセット
[51]618 int i2 = 0;
619 foreach( CMethod *method, methods ){
620 if(method->bVirtual){
[75]621 method->pUserProc->Using();
[4]622
[51]623 if(method->bAbstract){
[28]624 extern int cp;
625 SetError(300,NULL,cp);
[4]626
[28]627 ppsi[i2]=0;
[4]628 }
[92]629 else{
630 ppsi[i2]=method->pUserProc;
631 }
[28]632 i2++;
[4]633 }
634 }
635
[56]636 vtbl_offset=dataTable.AddBinary((void *)ppsi,vtbl_num*sizeof(LONG_PTR));
[4]637
[28]638 for( int i=0; i < vtbl_num; i++ ){
[4]639 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
640 }
641
642 HeapDefaultFree(ppsi);
643
644 return vtbl_offset;
645}
646void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
647 if(vtbl_offset==-1) return;
648
649 LONG_PTR *pVtbl;
[56]650 pVtbl=(LONG_PTR *)((char *)dataTable.GetPtr()+vtbl_offset);
[4]651
652 int i;
653 for(i=0;i<vtbl_num;i++){
[75]654 UserProc *pUserProc;
655 pUserProc=(UserProc *)pVtbl[i];
656 if(!pUserProc) continue;
657 pVtbl[i]=pUserProc->beginOpAddress+ImageBase+MemPos_CodeSection;
[4]658 }
659}
[75]660bool CClass::IsAbstract() const
661{
[51]662 //未実装の仮想関数を持つ場合はtrueを返す
[4]663
[51]664 foreach( CMethod *method, methods ){
665 if(method->bVirtual){
666 if(method->bAbstract){
[28]667 return true;
[4]668 }
669 }
670 }
671
[85]672 /*
673 TODO: 消す
674 これはAB5からは良くなった(参照型になったため)
675
[4]676 //コンポジションの関係にあるメンバも検査する
[28]677 for(int i=0;i < iMemberNum;i++){
[75]678 if(ppobj_Member[i]->IsObject()){
679 if(ppobj_Member[i]->GetClass().IsAbstract())
[28]680 return true;
[4]681 }
682 }
[85]683 */
[4]684
[28]685 return false;
[4]686}
687
[17]688// コンストラクタのコンパイルを開始
689void CClass::NotifyStartConstructorCompile(){
690 isCompilingConstructor = true;
691}
[4]692
[17]693//コンストラクタのコンパイルを終了
694void CClass::NotifyFinishConstructorCompile(){
695 isCompilingConstructor = false;
696}
697
698//コンストラクタをコンパイル中かどうかを判別
[75]699bool CClass::IsCompilingConstructor() const
700{
[17]701 return isCompilingConstructor;
702}
703
[18]704//デストラクタのコンパイルを開始
705void CClass::NotifyStartDestructorCompile(){
706 isCompilingDestructor = true;
707}
[17]708
[18]709//デストラクタのコンパイルを終了
710void CClass::NotifyFinishDestructorCompile(){
711 isCompilingDestructor = false;
712}
713
714//デストラクタをコンパイル中かどうかを判別
[75]715bool CClass::IsCompilingDestructor() const
716{
[18]717 return isCompilingDestructor;
718}
719
720
[28]721//自身と等しいクラスかどうかを確認
[75]722bool CClass::IsEquals( const CClass *pClass ) const
723{
[28]724 if( this == pClass ) return true;
725 return false;
726}
727
728//自身の派生クラスかどうかを確認
[75]729bool CClass::IsSubClass( const CClass *pClass ) const
730{
[28]731 pClass = pClass->pobj_InheritsClass;
732 while( pClass ){
733 if( this == pClass ) return true;
734 pClass = pClass->pobj_InheritsClass;
735 }
736 return false;
737}
738
[59]739//自身と等しいまたは派生クラスかどうかを確認
[75]740bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
741{
[59]742 if( IsEquals( pClass ) ) return true;
743 return IsSubClass( pClass );
744}
[28]745
746
[59]747
[46]748int CDBClass::hash(const char *name){
[4]749 int key;
750
751 for(key=0;*name!='\0';name++){
752 key=((key<<8)+ *name )%MAX_CLASS_HASH;
753 }
754
755 return key;
756}
757
758void CDBClass::DestroyClass(CClass *pobj_c){
759 if(pobj_c->pobj_NextClass){
760 DestroyClass(pobj_c->pobj_NextClass);
761 }
762
763 delete pobj_c;
764}
765
[67]766CDBClass::CDBClass():
767 pStringClass( NULL ),
768 pObjectClass( NULL ),
769 pCompilingClass( NULL ),
770 pCompilingMethod( NULL ),
771 ppobj_IteClass( NULL ),
772 iIteMaxNum( 0 ),
773 iIteNextNum( 0 )
774{
775 memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) );
[4]776}
777CDBClass::~CDBClass(){
778 int i;
779 for(i=0;i<MAX_CLASS_HASH;i++){
780 if(pobj_ClassHash[i]) DestroyClass(pobj_ClassHash[i]);
781 }
782
783 if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass);
784}
785
786void CDBClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
787 int i;
788 for(i=0;i<MAX_CLASS_HASH;i++){
789 if(pobj_ClassHash[i]){
790 CClass *pobj_c;
791 pobj_c=pobj_ClassHash[i];
792 while(1){
793 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
794
795 if(pobj_c->pobj_NextClass==0) break;
796 pobj_c=pobj_c->pobj_NextClass;
797 }
798 }
799 }
800}
801
[46]802CClass *CDBClass::check(const char *name){
[4]803 int key;
804 key=hash(name);
805
806 if(pobj_ClassHash[key]){
807 CClass *pobj_c;
808 pobj_c=pobj_ClassHash[key];
809 while(1){
810 if(lstrcmp(name,pobj_c->name)==0){
811 //重複した場合
812 return pobj_c;
813 }
814
815 if(pobj_c->pobj_NextClass==0) break;
816 pobj_c=pobj_c->pobj_NextClass;
817 }
818 }
819 return 0;
820}
821
[75]822CClass *CDBClass::AddClass(const char *name,int nowLine){
[4]823 //////////////////////////////////////////////////////////////////////////
824 // クラスを追加
825 // ※名前のみを登録。その他の情報はSetClassメソッドで!
826 //////////////////////////////////////////////////////////////////////////
827
828 CClass *pobj_c;
829 pobj_c=new CClass(name);
830
831 if(lstrcmp(name,"String")==0){
832 //Stringクラス
833 pobj_StringClass=pobj_c;
834 }
[67]835 if( lstrcmp( name, "Object" ) == 0 ){
836 pObjectClass = pobj_c;
837 }
[4]838
839
840 /////////////////////////////////
841 // ハッシュデータに追加
842 /////////////////////////////////
843
844 int key;
845 key=hash(name);
846
847 if(pobj_ClassHash[key]){
848 CClass *pobj_c2;
849 pobj_c2=pobj_ClassHash[key];
850 while(1){
851 if(lstrcmp(name,pobj_c2->name)==0){
852 //重複した場合
[75]853 SetError(15,name,nowLine);
[4]854 return 0;
855 }
856
857 if(pobj_c2->pobj_NextClass==0) break;
858 pobj_c2=pobj_c2->pobj_NextClass;
859 }
860 pobj_c2->pobj_NextClass=pobj_c;
861 }
862 else{
863 pobj_ClassHash[key]=pobj_c;
864 }
865
866 return pobj_c;
867}
868
869void CDBClass::InitNames(void){
870 extern char *basbuf;
871 int i;
872
873 for(i=0;;i++){
874 if(basbuf[i]=='\0') break;
875
876 if(basbuf[i]==1&&(
877 basbuf[i+1]==ESC_CLASS||
878 basbuf[i+1]==ESC_TYPE||
879 basbuf[i+1]==ESC_INTERFACE
880 )){
[75]881 int nowLine;
882 nowLine=i;
[4]883
884 i+=2;
885 //アラインメント修飾子
[76]886 if(memicmp(basbuf+i,"Align(",6)==0){
[4]887 i+=6;
888 i=JumpStringInPare(basbuf,i)+1;
889 }
890
[92]891 bool isEnum = false;
892 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
893 // 列挙型の場合
894 isEnum = true;
895
896 i+=2;
897 }
898
[4]899 int i2;
900 char temporary[VN_SIZE];
901 for(i2=0;;i++,i2++){
902 if(!IsVariableChar(basbuf[i])){
903 temporary[i2]=0;
904 break;
905 }
906 temporary[i2]=basbuf[i];
907 }
908
909 //クラスを追加
[75]910 CClass *pClass = pobj_DBClass->AddClass(temporary,nowLine);
[64]911 if( pClass ){
[75]912 if( basbuf[nowLine+1] == ESC_CLASS ){
[92]913 if( isEnum ){
914 pClass->classType = CClass::Enum;
915 }
916 else{
917 pClass->classType = CClass::Class;
918 }
[64]919 }
[75]920 else if( basbuf[nowLine+1] == ESC_INTERFACE ){
[64]921 pClass->classType = CClass::Interface;
922 }
923 else{
924 pClass->classType = CClass::Structure;
925 }
926 }
[4]927 }
928 }
929}
930
931
[18]932void CDBClass::AddMethod(CClass *pobj_c, DWORD dwAccess, BOOL bStatic, bool isConst, BOOL bAbstract,
[75]933 BOOL bVirtual, BOOL bOverride, char *buffer, int nowLine){
[4]934 int i,i2;
935 char temporary[VN_SIZE];
936
937 i=2;
938 for(i2=0;;i++,i2++){
939 if(buffer[i]=='('||buffer[i]=='\0'){
940 temporary[i2]=0;
941 break;
942 }
943 temporary[i2]=buffer[i];
944 }
945
946
947 //関数ハッシュへ登録
[75]948 UserProc *pUserProc;
949 pUserProc=AddSubData(buffer,nowLine,bVirtual,pobj_c, (bStatic!=0) );
950 if(!pUserProc) return;
[4]951
952
953 ////////////////////////////////////////////////////////////
[18]954 // コンストラクタ、デストラクタの場合の処理
[4]955 ////////////////////////////////////////////////////////////
956 BOOL fConstructor=0,bDestructor=0;
957
958 if(lstrcmp(temporary,pobj_c->name)==0){
[18]959 //コンストラクタの場合
960
961 //標準コンストラクタ(引数なし)
[75]962 if(pUserProc->Params().size()==0) fConstructor=1;
[18]963
964 //強制的にConst修飾子をつける
965 isConst = true;
[4]966 }
967 else if(temporary[0]=='~'){
968 //デストラクタの場合はその名前が正しいかチェックを行う
969 if(lstrcmp(temporary+1,pobj_c->name)!=0)
[75]970 SetError(117,NULL,nowLine);
[4]971 else
972 bDestructor=1;
973 }
974 if(fConstructor||bDestructor){
[18]975 // コンストラクタ、デストラクタのアクセシビリティをチェック
976
977 //強制的にConst修飾子をつける
978 isConst = true;
[4]979 }
980
[18]981 if( fConstructor == 1 )
[51]982 pobj_c->ConstructorMemberSubIndex = (int)pobj_c->methods.size();
[18]983 else if( bDestructor )
[51]984 pobj_c->DestructorMemberSubIndex = (int)pobj_c->methods.size();
[4]985
986
987
988 //////////////////
989 // 重複チェック
990 //////////////////
991
992 if(pobj_c->DupliCheckMember(temporary)){
[75]993 SetError(15,temporary,nowLine);
[4]994 return;
995 }
996
[51]997 //メソッド
998 foreach( CMethod *method, pobj_c->methods ){
[27]999 //基底クラスと重複する場合はオーバーライドを行う
[51]1000 if(method->pobj_InheritsClass) continue;
[4]1001
[75]1002 if( method->pUserProc->GetName() == temporary ){
1003 if( Parameter::Equals( method->pUserProc->Params(), pUserProc->Params() ) ){
[4]1004 //関数名、パラメータ属性が合致したとき
[75]1005 SetError(15,pUserProc->GetName().c_str(),nowLine);
[4]1006 return;
1007 }
1008 }
1009 }
1010
1011 //仮想関数の場合
[75]1012 if(bAbstract) pUserProc->CompleteCompile();
[4]1013
[51]1014 //メソッドのオーバーライド
1015 foreach( CMethod *method, pobj_c->methods ){
[75]1016 if( method->pUserProc->GetName() == temporary ){
1017 if( Parameter::Equals( method->pUserProc->Params(), pUserProc->Params() ) ){
[4]1018
[75]1019 if(method->bVirtual){
[4]1020 //メンバ関数を上書き
[75]1021 method->pUserProc=pUserProc;
[51]1022 method->bAbstract=0;
[4]1023
1024 if(!bOverride){
[75]1025 SetError(127,NULL,nowLine);
[4]1026 }
[51]1027 if(method->dwAccess!=dwAccess){
[75]1028 SetError(128,NULL,nowLine);
[4]1029 }
[75]1030
1031 pUserProc->SetMethod( method );
[4]1032 return;
1033 }
1034 }
1035 }
1036 }
1037
[75]1038 if(bVirtual){
[4]1039 pobj_c->vtbl_num++;
1040 }
1041
1042 if(bOverride){
[75]1043 SetError(12,"Override",nowLine);
[4]1044 }
1045
1046 if(bStatic){
[75]1047 pobj_c->AddStaticMethod(pUserProc,dwAccess);
[4]1048 }
1049 else{
[75]1050 pobj_c->AddMethod(pUserProc, dwAccess, isConst, bAbstract, bVirtual);
[4]1051 }
1052}
1053
[75]1054BOOL CDBClass::MemberVar_LoopRefCheck(const CClass &objClass){
[4]1055 int i,i2,bRet=1;
[75]1056 for(i=0;i<objClass.iMemberNum;i++){
1057 const CMember *pMember = objClass.ppobj_Member[i];
[85]1058 if(pMember->IsStruct()){
[4]1059 //循環参照でないかをチェック
[90]1060 if(pobj_LoopRefCheck->check(pMember->GetClass())){
[4]1061 extern int cp;
[75]1062 SetError(124,pMember->GetClass().name,cp);
[4]1063 return 0;
1064 }
1065
[75]1066 pobj_LoopRefCheck->add(objClass.name);
[4]1067
[75]1068 i2=MemberVar_LoopRefCheck(pMember->GetClass());
[4]1069 if(bRet==1) bRet=i2;
1070
[75]1071 pobj_LoopRefCheck->del(objClass.name);
[4]1072 }
1073 }
1074
1075 return bRet;
1076}
1077
[46]1078void CDBClass::GetClass_recur(const char *lpszInheritsClass){
[4]1079 extern char *basbuf;
1080 int i,i2,i3,sub_address,top_pos;
1081 DWORD dwAccess;
1082 char temporary[8192];
1083
1084 for(i=0;;i++){
1085 if(basbuf[i]=='\0') break;
1086
1087 CClass *pobj_c;
1088
1089 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1090 //////////////////////////
1091 // インターフェイス
1092 //////////////////////////
1093
1094 top_pos=i;
1095
1096 i+=2;
1097
1098 //インターフェイス名を取得
[17]1099 GetIdentifierToken( temporary, basbuf, i );
[4]1100
1101 pobj_c=pobj_DBClass->check(temporary);
1102 if(!pobj_c) continue;
1103
1104 if(lpszInheritsClass){
1105 if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){
1106 //継承先先読み用
1107 continue;
1108 }
1109 }
1110
1111 if(pobj_c->ppobj_Member){
1112 //既に先読みされているとき
1113 continue;
1114 }
1115
1116 //メンバ用メモリを初期化
1117 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1);
1118 pobj_c->iMemberNum=0;
1119
1120 pobj_c->ConstructorMemberSubIndex=-1;
1121 pobj_c->DestructorMemberSubIndex=-1;
1122
1123 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1124 //継承を行う場合
1125 for(i+=3,i2=0;;i++,i2++){
1126 if(IsCommandDelimitation(basbuf[i])){
1127 temporary[i2]=0;
1128 break;
1129 }
1130 temporary[i2]=basbuf[i];
1131 }
1132
1133 if(lstrcmpi(temporary,pobj_c->name)==0){
1134 SetError(105,temporary,i);
1135 goto Interface_InheritsError;
1136 }
1137
1138 //継承元クラスを取得
[29]1139 CClass *pInheritsClass = check(temporary);
1140 if( !pInheritsClass ){
[4]1141 SetError(106,temporary,i);
1142 goto Interface_InheritsError;
1143 }
1144
[90]1145 //継承させる
1146 if( !pobj_c->InheritsInterface( *pInheritsClass, i ) ){
[4]1147 goto Interface_InheritsError;
1148 }
1149 }
1150 else{
1151 //継承無し
1152 pobj_c->pobj_InheritsClass=0;
1153
1154 //仮想関数の数を初期化
1155 pobj_c->vtbl_num=0;
1156 }
1157Interface_InheritsError:
1158
1159 //メンバ変数、関数を取得
1160 while(1){
1161 i++;
1162
1163 //エラー
1164 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1165 SetError(22,"Interface",i);
1166 i--;
1167 break;
1168 }
1169
1170 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1171 SetError(111,NULL,i);
1172 break;
1173 }
1174
1175 sub_address=i;
1176
1177 for(i2=0;;i++,i2++){
1178 if(IsCommandDelimitation(basbuf[i])){
1179 temporary[i2]=0;
1180 break;
1181 }
1182 temporary[i2]=basbuf[i];
1183 }
1184 if(temporary[0]=='\0'){
1185 if(basbuf[i]=='\0'){
1186 i--;
1187 SetError(22,"Interface",top_pos);
1188 break;
1189 }
1190 continue;
1191 }
1192
1193 //End Interface記述の場合
1194 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1195
1196 if(!(temporary[0]==1&&(
1197 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1198 ))){
1199 SetError(1,NULL,i);
1200 break;
1201 }
1202
1203 //メンバ関数を追加
[18]1204 AddMethod(pobj_c,
1205 ACCESS_PUBLIC, //Publicアクセス権
1206 0, //Static指定なし
1207 false, //Constではない
1208 1, //Abstract
1209 1, //Virtual
1210 0,
1211 temporary,
1212 sub_address
1213 );
[4]1214 }
1215 }
1216
1217 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1218 //////////////////////////
1219 // クラス
1220 //////////////////////////
1221
1222 top_pos=i;
1223
[64]1224 const DWORD dwClassType=basbuf[i+1];
[4]1225
1226 i+=2;
1227
1228 //アラインメント修飾子
1229 int iAlign=0;
[76]1230 if(memicmp(basbuf+i,"Align(",6)==0){
[4]1231 i+=6;
1232 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1233 iAlign=atoi(temporary);
1234
1235 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1236 SetError(51,NULL,i);
1237 }
1238
[92]1239 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
1240 // 列挙型の場合
1241 i+=2;
1242 }
[4]1243
1244 //クラス名を取得
[17]1245 GetIdentifierToken( temporary, basbuf, i );
[4]1246
1247 pobj_c=pobj_DBClass->check(temporary);
1248 if(!pobj_c) continue;
1249
1250 if(lpszInheritsClass){
1251 if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){
1252 //継承先先読み用
1253 continue;
1254 }
1255 }
1256
1257 if(pobj_c->ppobj_Member){
1258 //既に先読みされているとき
1259 continue;
1260 }
1261
1262 pobj_c->iAlign=iAlign;
1263
1264 //メンバ用メモリを初期化
1265 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1);
1266 pobj_c->iMemberNum=0;
1267
1268 pobj_c->ConstructorMemberSubIndex=-1;
1269 pobj_c->DestructorMemberSubIndex=-1;
1270
1271 //アクセス制限の初期値をセット
1272 if(dwClassType==ESC_CLASS) dwAccess=ACCESS_PRIVATE;
1273 else dwAccess=ACCESS_PUBLIC;
1274
[29]1275 if( lstrcmp( pobj_c->name, "Object" ) == 0 || dwClassType == ESC_TYPE ){
1276 //継承無し
1277 pobj_c->pobj_InheritsClass=0;
1278
1279 //仮想関数の数を初期化
1280 pobj_c->vtbl_num=0;
1281 }
1282 else{
1283 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1284 //継承を行う場合
1285 for(i+=3,i2=0;;i++,i2++){
1286 if(IsCommandDelimitation(basbuf[i])){
1287 temporary[i2]=0;
1288 break;
1289 }
1290 temporary[i2]=basbuf[i];
[4]1291 }
1292
[29]1293 if(lstrcmpi(temporary,pobj_c->name)==0){
1294 SetError(105,temporary,i);
1295 goto InheritsError;
1296 }
[4]1297 }
[29]1298 else{
1299 //Objectを継承する
1300 lstrcpy( temporary, "Object" );
1301 }
[4]1302
1303 //継承元クラスを取得
[29]1304 CClass *pInheritsClass = check(temporary);
1305 if( !pInheritsClass ){
[4]1306 SetError(106,temporary,i);
1307 goto InheritsError;
1308 }
1309
[90]1310 if( pInheritsClass->IsInterface() ){
1311 // クラスを継承していないとき
1312 CClass *pObjectClass = check("Object");
1313 if( !pObjectClass ){
1314 SetError(106,"Object",i);
1315 goto InheritsError;
1316 }
[4]1317
[90]1318 if( !pobj_c->Inherits( *pObjectClass, i ) ){
1319 goto InheritsError;
1320 }
[4]1321 }
1322
[29]1323 //継承させる
[90]1324 if( !pobj_c->Inherits( *pInheritsClass, i ) ){
1325 goto InheritsError;
1326 }
[4]1327 }
1328InheritsError:
1329
[18]1330 //メンバとメソッドを取得
[4]1331 while(1){
1332 i++;
1333
1334 //エラー
1335 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1336 SetError(22,"Class",i);
1337 i--;
1338 break;
1339 }
1340
1341 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1342 SetError(111,NULL,i);
1343 break;
1344 }
1345
1346 //Static修飾子
1347 BOOL bStatic;
1348 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1349 bStatic=1;
1350 i+=2;
1351 }
1352 else bStatic=0;
1353
[17]1354 //Const修飾子
1355 bool isConst = false;
1356 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1357 isConst = true;
1358 i += 2;
1359 }
[64]1360/*
[40]1361 //Ref修飾子
1362 bool isRef = false;
1363 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_BYREF ){
1364 isRef = true;
1365 i += 2;
[64]1366 }*/
[40]1367
[4]1368 if(basbuf[i]==1&&(
1369 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1370 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1371 )){
1372 i3=basbuf[i+1];
1373 sub_address=i;
1374 }
1375 else i3=0;
1376
1377 BOOL bVirtual=0,bAbstract=0,bOverride=0;
1378 if(i3==ESC_ABSTRACT){
1379 bAbstract=1;
1380 bVirtual=1;
1381 i+=2;
1382
1383 i3=basbuf[i+1];
1384 }
1385 else if(i3==ESC_VIRTUAL){
1386 bAbstract=0;
1387 bVirtual=1;
1388 i+=2;
1389
1390 i3=basbuf[i+1];
1391 }
1392 else if(i3==ESC_OVERRIDE){
1393 bOverride=1;
1394 bVirtual=1;
1395
1396 i+=2;
1397
1398 i3=basbuf[i+1];
1399 }
1400
1401 for(i2=0;;i++,i2++){
1402 if(IsCommandDelimitation(basbuf[i])){
1403 temporary[i2]=0;
1404 break;
1405 }
1406 temporary[i2]=basbuf[i];
1407 }
1408 if(temporary[0]=='\0'){
1409 if(basbuf[i]=='\0'){
1410
1411 if(dwClassType==ESC_CLASS)
1412 SetError(22,"Class",top_pos);
1413 else
1414 SetError(22,"Type",top_pos);
1415
1416 i--;
1417 break;
1418 }
1419 continue;
1420 }
1421
1422 //End Class記述の場合
1423 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1424 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1425
1426 //アクセスを変更
1427 if(lstrcmpi(temporary,"Private")==0){
1428 dwAccess=ACCESS_PRIVATE;
1429 continue;
1430 }
1431 if(lstrcmpi(temporary,"Public")==0){
1432 dwAccess=ACCESS_PUBLIC;
1433 continue;
1434 }
1435 if(lstrcmpi(temporary,"Protected")==0){
1436 dwAccess=ACCESS_PROTECTED;
1437 continue;
1438 }
1439
1440 extern int cp;
1441 if(i3==0){
1442 if(bStatic){
1443 //静的メンバを追加
1444 cp=i; //エラー用
[64]1445 pobj_c->AddStaticMember( dwAccess, isConst, false, temporary, i);
[4]1446 }
1447 else{
1448 //メンバを追加
1449 cp=i; //エラー用
[64]1450 pobj_c->AddMember( dwAccess, isConst, false, temporary );
[4]1451
1452
[89]1453 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->IsStruct()){
[75]1454 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass().ppobj_Member==0){
[4]1455 //参照先が読み取られていないとき
[75]1456 GetClass_recur(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass().name);
[4]1457 }
1458 }
1459
1460
[89]1461 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->IsStruct()){
[4]1462 //循環参照のチェック
1463 pobj_LoopRefCheck->add(pobj_c->name);
[75]1464 if(!MemberVar_LoopRefCheck(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass())){
[4]1465 //エラー回避
[75]1466 pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->SetBasicType( DEF_PTR_VOID );
[4]1467 }
1468 pobj_LoopRefCheck->del(pobj_c->name);
1469 }
1470 }
1471 }
1472 else{
1473 //メソッドを追加
1474 cp=i; //エラー用
[18]1475 AddMethod(pobj_c,
1476 dwAccess,
1477 bStatic,
1478 isConst,
1479 bAbstract,
1480 bVirtual,
1481 bOverride,
1482 temporary,
1483 sub_address);
[4]1484
1485 if(bAbstract) continue;
1486
1487 for(;;i++){
1488 if(basbuf[i]=='\0'){
1489 i--;
1490 break;
1491 }
1492 if(basbuf[i-1]!='*'&&
1493 basbuf[i]==1&&(
1494 basbuf[i+1]==ESC_SUB||
1495 basbuf[i+1]==ESC_FUNCTION||
1496 basbuf[i+1]==ESC_MACRO||
1497 basbuf[i+1]==ESC_TYPE||
1498 basbuf[i+1]==ESC_CLASS||
1499 basbuf[i+1]==ESC_INTERFACE||
1500 basbuf[i+1]==ESC_ENUM)){
1501 GetDefaultNameFromES(i3,temporary);
1502 SetError(22,temporary,i);
1503 }
1504 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1505 i+=2;
1506 break;
1507 }
1508 }
1509 }
1510 }
1511 }
1512 }
1513}
1514
[67]1515void CDBClass::GetAllClassInfo(void){
[4]1516 //ループ継承チェック用のクラス
1517 pobj_LoopRefCheck=new CLoopRefCheck();
1518
1519 //クラスを取得
1520 GetClass_recur(0);
1521
1522 delete pobj_LoopRefCheck;
1523 pobj_LoopRefCheck=0;
[89]1524
1525 // イテレータ用のデータを作る
1526 pobj_DBClass->Iterator_Init();
[4]1527}
1528
[89]1529void CDBClass::Compile_System_InitializeUserTypes(){
[90]1530 char temporary[VN_SIZE];
[89]1531
1532 ////////////////////////////////////////////////////////////////////
1533 // クラス登録
1534 ////////////////////////////////////////////////////////////////////
1535
1536 // イテレータをリセット
1537 Iterator_Reset();
1538
1539 while( Iterator_HasNext() ){
[91]1540 const CClass &objClass = *Iterator_GetNext();
[89]1541
[91]1542 if( !objClass.IsUsing() ){
1543 // 未使用のクラスは無視する
1544 continue;
1545 }
1546
[89]1547 sprintf( temporary
1548 , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\"))"
1549 , 1
1550 , ESC_NEW
1551 , "" // 名前空間 (TODO: 実装)
[91]1552 , objClass.name // クラス名
[89]1553 );
1554
1555 // コンパイル
1556 ChangeOpcode( temporary );
1557
1558 // ネイティブコードバッファの再確保
1559 ReallocNativeCodeBuffer();
1560 }
1561
1562
1563 ////////////////////////////////////////////////////////////////////
[90]1564 // 基底クラスを登録
1565 ////////////////////////////////////////////////////////////////////
1566
1567 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1568 , HIBYTE( COM_DIM )
1569 , LOBYTE( COM_DIM )
1570 , 1
1571 , ESC_AS
1572 );
1573 ChangeOpcode( temporary );
1574
1575 // イテレータをリセット
1576 Iterator_Reset();
1577
1578 while( Iterator_HasNext() ){
[91]1579 const CClass &objClass = *Iterator_GetNext();
[90]1580
[91]1581 if( !objClass.IsUsing() ){
1582 // 未使用のクラスは無視する
1583 continue;
1584 }
1585
1586 if( objClass.pobj_InheritsClass ){
[90]1587 sprintf( temporary
1588 , "tempType=Search(\"%s\",\"%s\")"
1589 , "" // 名前空間 (TODO: 実装)
[91]1590 , objClass.name // クラス名
[90]1591 );
1592
1593 // コンパイル
1594 ChangeOpcode( temporary );
1595
1596 sprintf( temporary
1597 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
1598 , "" // 名前空間 (TODO: 実装)
[91]1599 , objClass.pobj_InheritsClass->name // 基底クラス名
[90]1600 );
1601
1602 // コンパイル
1603 ChangeOpcode( temporary );
1604 }
1605
1606 // ネイティブコードバッファの再確保
1607 ReallocNativeCodeBuffer();
1608 }
1609
1610
1611
1612 ////////////////////////////////////////////////////////////////////
[89]1613 // 継承関係登録
1614 ////////////////////////////////////////////////////////////////////
1615 // TODO: 未完成
1616 /*
1617
1618 // イテレータをリセット
1619 Iterator_Reset();
1620
1621 while( Iterator_HasNext() ){
1622 CClass *pClass = Iterator_GetNext();
1623
1624 sprintf( genBuffer + length
1625 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1626 , "" // クラス名
1627 , pClass->name // クラス名
1628 );
1629 length += lstrlen( genBuffer + length );
1630
1631 while( length + 8192 > max ){
1632 max += 8192;
1633 genBuffer = (char *)realloc( genBuffer, max );
1634 }
1635 }*/
[87]1636}
1637
1638
1639
[67]1640CClass *CDBClass::GetStringClass() const
1641{
1642 if( !pStringClass ){
1643 SetError();
1644 return NULL;
1645 }
1646 return pStringClass;
1647}
1648CClass *CDBClass::GetObjectClass() const
1649{
1650 if( !pObjectClass ){
1651 SetError();
1652 return NULL;
1653 }
1654 return pObjectClass;
1655}
1656
[75]1657void CDBClass::StartCompile( UserProc *pUserProc ){
1658 pCompilingClass = pUserProc->GetParentClassPtr();
[18]1659 if( pCompilingClass ){
[91]1660 pCompilingClass->Using();
1661
[75]1662 pCompilingMethod = pCompilingClass->GetMethodInfo( pUserProc );
[18]1663 if( !pCompilingMethod ){
[75]1664 pCompilingMethod = pCompilingClass->GetStaticMethodInfo( pUserProc );
[18]1665 if( !pCompilingMethod ){
1666 SetError(300,NULL,cp);
1667 }
1668 }
1669 }
1670 else{
1671 pCompilingMethod = NULL;
1672 }
1673}
1674CClass *CDBClass::GetNowCompilingClass(){
1675 return pCompilingClass;
1676}
1677CMethod *CDBClass::GetNowCompilingMethodInfo(){
1678 return pCompilingMethod;
1679}
[4]1680
1681
1682
[18]1683
[4]1684//////////////////////
1685// イテレータ
1686//////////////////////
1687
[89]1688void CDBClass::Iterator_Init(void){
[4]1689 if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass);
1690
1691 iIteMaxNum=0;
1692 iIteNextNum=0;
1693 ppobj_IteClass=(CClass **)HeapAlloc(hHeap,0,1);
1694
1695 int i;
1696 for(i=0;i<MAX_CLASS_HASH;i++){
1697 if(pobj_ClassHash[i]){
1698 CClass *pobj_c;
1699 pobj_c=pobj_ClassHash[i];
1700 while(1){
1701 ppobj_IteClass=(CClass **)HeapReAlloc(hHeap,0,ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
1702 ppobj_IteClass[iIteMaxNum]=pobj_c;
1703 iIteMaxNum++;
1704
1705 if(pobj_c->pobj_NextClass==0) break;
1706 pobj_c=pobj_c->pobj_NextClass;
1707 }
1708 }
1709 }
1710}
[89]1711void CDBClass::Iterator_Reset(void){
1712 iIteNextNum = 0;
1713}
[4]1714BOOL CDBClass::Iterator_HasNext(void){
1715 if(iIteNextNum<iIteMaxNum) return 1;
1716 return 0;
1717}
1718CClass *CDBClass::Iterator_GetNext(void){
1719 CClass *pobj_c;
1720 pobj_c=ppobj_IteClass[iIteNextNum];
1721 iIteNextNum++;
1722 return pobj_c;
1723}
1724int CDBClass::Iterator_GetMaxCount(void){
1725 return iIteMaxNum;
1726}
Note: See TracBrowser for help on using the repository browser.