source: dev/BasicCompiler_Common/Class.cpp@ 59

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

派生クラスから基底クラスへのインスタンスコピーまたは参照を可能にした

File size: 30.9 KB
Line 
1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler32/opcode.h"
7#endif
8
9CDBClass *pobj_DBClass;
10
11CClass *pobj_CompilingClass;
12CClass *pobj_StringClass;
13
14CMember *pCompilingMethod;
15
16
17
18CMember::CMember( CClass *pobj_c, DWORD access, bool isConst, bool isRef, char *buffer, int NowLine ){
19 extern int cp;
20
21 //構文を解析
22 char VarName[VN_SIZE];
23 char init_buf[VN_SIZE];
24 char constract_parameter[VN_SIZE];
25 GetDimentionFormat(buffer,isRef,VarName,SubScripts,&TypeInfo,init_buf,constract_parameter);
26
27 //重複チェック
28 if(pobj_c->DupliCheckAll(VarName)){
29 SetError(15,VarName,cp);
30 }
31
32 if(TypeInfo.type==DEF_OBJECT){
33 if(TypeInfo.u.pobj_Class->IsAbstract()){
34 //抽象クラスだったとき
35 SetError(125,TypeInfo.u.pobj_Class->name,cp);
36 }
37 }
38
39 //メンバ名
40 name=(char *)HeapAlloc(hHeap,0,lstrlen(VarName)+1);
41 lstrcpy(name,VarName);
42
43 //アクセス権
44 dwAccess=access;
45
46 //定数扱いかどうか
47 this->isConst = isConst;
48
49 //参照型かどうか
50 this->isRef = isRef;
51
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 //ソースコードの位置
61 source_code_address=NowLine;
62}
63CMember::CMember(CMember *pobj){
64 //コピーコンストラクタ
65 memset(this,0,sizeof(CMember));
66
67 //name
68 name=(char *)HeapAlloc(hHeap,0,lstrlen(pobj->name)+1);
69 lstrcpy(name,pobj->name);
70
71 //定数扱いかどうか
72 isConst = pobj->isConst;
73
74 //参照型かどうか
75 isRef = pobj->isRef;
76
77 //SubScripts
78 memcpy(SubScripts,pobj->SubScripts,MAX_ARRAYDIM*sizeof(int));
79
80 //TypeInfo
81 TypeInfo=pobj->TypeInfo;
82
83 //ソースコードの位置
84 source_code_address=pobj->source_code_address;
85}
86CMember::CMember(){
87 memset(this,0,sizeof(CMember));
88}
89CMember::~CMember(){
90 HeapDefaultFree(name);
91 if(InitBuf) HeapDefaultFree(InitBuf);
92 if(ConstractParameter) HeapDefaultFree(ConstractParameter);
93}
94
95bool CMember::IsConst(){
96 return isConst;
97}
98bool CMember::IsRef(){
99 return isRef;
100}
101
102int CMember::GetSize(){
103 if( IsRef() ){
104 // 参照型
105 return PTR_SIZE;
106 }
107
108 //メンバサイズを取得
109 return GetTypeSize(TypeInfo.type,TypeInfo.u.lpIndex);
110}
111
112void CMember::InitStaticMember(void){
113 //静的メンバをグローバル領域に作成
114
115 //イテレータをリセット
116 extern CDBClass *pobj_DBClass;
117 pobj_DBClass->Iterator_Reset();
118
119 int back_cp=cp;
120
121 while(pobj_DBClass->Iterator_HasNext()){
122 CClass *pobj_c;
123 pobj_c=pobj_DBClass->Iterator_GetNext();
124
125 foreach( CMember *member, pobj_c->staticMembers ){
126 char temporary[VN_SIZE];
127 sprintf(temporary,"%s.%s",pobj_c->name,member->name);
128 AddGlobalVariable(
129 temporary,
130 member->SubScripts,
131 &member->TypeInfo,
132 GetTypeSize(member->TypeInfo.type,member->TypeInfo.u.lpIndex),
133 member->InitBuf,
134 member->ConstractParameter,
135 0);
136
137 if(member->TypeInfo.type==DEF_OBJECT){
138 //エラー用
139 cp=member->source_code_address;
140
141 CallConstructor(temporary,
142 member->SubScripts,
143 member->TypeInfo,
144 member->ConstractParameter);
145 }
146
147 //ネイティブコードバッファの再確保
148 extern int obp_AllocSize;
149 if(obp_AllocSize<obp+8192){
150 obp_AllocSize+=8192;
151 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize); //matea
152 }
153 }
154 }
155
156 cp=back_cp;
157}
158
159
160
161CMethod::CMethod(CMethod *pobj){
162 //コピーコンストラクタ
163 memset(this,0,sizeof(CMethod));
164
165 psi=pobj->psi;
166
167 bAbstract=pobj->bAbstract;
168
169 bVirtual=pobj->bVirtual;
170}
171CMethod::CMethod(){
172 memset(this,0,sizeof(CMethod));
173}
174CMethod::~CMethod(){
175}
176
177
178
179
180CClass::CClass(const char *name){
181 memset(this,0,sizeof(CClass));
182
183 vtbl_offset=-1;
184
185 this->name=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1);
186 lstrcpy(this->name,name);
187
188 isCompilingConstructor = false;
189 isCompilingDestructor = false;
190}
191CClass::~CClass(){
192 int i;
193
194 //クラス名
195 HeapDefaultFree(name);
196
197 if(ppobj_Member){
198 //メンバ
199 for(i=0;i<iMemberNum;i++){
200 delete ppobj_Member[i];
201 }
202 HeapDefaultFree(ppobj_Member);
203 ppobj_Member=0;
204 }
205
206 //静的メンバ
207 foreach( CMember *member, staticMembers ){
208 delete member;
209 }
210
211 //メソッド
212 foreach( CMethod *method, methods ){
213 delete method;
214 }
215
216 //静的メソッド
217 foreach( CMethod *method, staticMethods ){
218 delete method;
219 }
220}
221void CClass::Inherits( CClass *pInheritsClass ){
222 int i3;
223
224 //メンバをコピー
225 ppobj_Member=(CMember **)HeapReAlloc(
226 hHeap,
227 0,
228 ppobj_Member,
229 pInheritsClass->iMemberNum*sizeof(CMember *));
230 iMemberNum=pInheritsClass->iMemberNum;
231 for(i3=0;i3<pInheritsClass->iMemberNum;i3++){
232 ppobj_Member[i3]=new CMember(pInheritsClass->ppobj_Member[i3]);
233
234 //dwAccess
235 if(pInheritsClass->ppobj_Member[i3]->dwAccess==ACCESS_PRIVATE)
236 ppobj_Member[i3]->dwAccess=ACCESS_NON;
237 else ppobj_Member[i3]->dwAccess=pInheritsClass->ppobj_Member[i3]->dwAccess;
238 }
239
240 //メソッドをコピー
241 foreach( CMethod *baseMethod, pInheritsClass->methods ){
242 CMethod *method = new CMethod( baseMethod );
243
244 //dwAccess
245 if(baseMethod->dwAccess==ACCESS_PRIVATE)
246 method->dwAccess=ACCESS_NON;
247 else method->dwAccess=baseMethod->dwAccess;
248
249 //pobj_Inherits
250 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
251 if(baseMethod->pobj_InheritsClass==0)
252 method->pobj_InheritsClass=pInheritsClass;
253 else
254 method->pobj_InheritsClass=
255 baseMethod->pobj_InheritsClass;
256
257 methods.push_back( method );
258 }
259
260 //仮想関数の数
261 vtbl_num=pInheritsClass->vtbl_num;
262
263 //継承先のクラスをメンバとして保持する
264 pobj_InheritsClass = pInheritsClass;
265}
266void CClass::AddMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer ){
267 ppobj_Member = (CMember **)HeapReAlloc( hHeap, 0, ppobj_Member, ( iMemberNum + 1 ) * sizeof(CMember *) );
268 ppobj_Member[iMemberNum] = new CMember( this, dwAccess, isConst, isRef, buffer );
269 iMemberNum++;
270}
271void CClass::AddStaticMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer, int NowLine ){
272 CMember *member = new CMember( this, dwAccess, isConst, isRef, buffer, NowLine );
273 staticMembers.push_back( member );
274}
275void CClass::AddMethod( SUBINFO *psi,DWORD dwAccess, bool isConst, BOOL bAbstract, BOOL bVirtual ){
276 CMethod *method = new CMethod();
277 method->psi = psi;
278 method->dwAccess = dwAccess;
279 method->isConst = isConst;
280 method->bAbstract = bAbstract;
281 method->bVirtual = bVirtual;
282 method->pobj_InheritsClass = 0;
283
284 methods.push_back( method );
285}
286void CClass::AddStaticMethod(SUBINFO *psi,DWORD dwAccess){
287 CMethod *method = new CMethod();
288 method->psi=psi;
289 method->dwAccess=dwAccess;
290 method->bAbstract=0;
291 method->bVirtual=0;
292 method->pobj_InheritsClass=0;
293
294 staticMethods.push_back( method );
295}
296BOOL CClass::DupliCheckAll(const char *name){
297 //重複チェック
298
299 //メンバ
300 if(DupliCheckMember(name)) return 1;
301
302 //メソッド
303 foreach( CMethod *method, methods ){
304 if( lstrcmp( name, method->psi->name ) == 0 ){
305 return 1;
306 }
307 }
308
309 return 0;
310}
311BOOL CClass::DupliCheckMember(const char *name){
312 //重複チェック
313
314 //メンバ
315 for( int i=0;i<iMemberNum;i++){
316 if(lstrcmp(name,ppobj_Member[i]->name)==0){
317 return 1;
318 }
319 }
320
321 //静的メンバ
322 foreach( CMember *member, staticMembers ){
323 if( lstrcmp( name, member->name ) == 0 ){
324 return 1;
325 }
326 }
327
328 return 0;
329}
330CMethod *CClass::GetMethodInfo( SUBINFO *psi ){
331 for( int i=(int)methods.size()-1; i>=0; i-- ){
332 if( psi == methods[i]->psi ) return methods[i];
333 }
334 return NULL;
335}
336CMethod *CClass::GetStaticMethodInfo( SUBINFO *psi ){
337 for( int i=(int)staticMethods.size()-1; i>=0; i-- ){
338 if( psi == staticMethods[i]->psi ) return staticMethods[i];
339 }
340 return NULL;
341}
342bool CClass::IsExistMethod( const char *name ){
343 foreach( CMethod *method, methods ){
344 if( lstrcmp( method->psi->name, name ) == 0 ) return true;
345 }
346 return false;
347}
348bool CClass::IsExistStaticMethod( const char *name ){
349 foreach( CMethod *method, staticMethods ){
350 if( lstrcmp( method->psi->name, name ) == 0 ) return true;
351 }
352 return false;
353}
354
355void CClass::EnumStaticMethod( const char *methodName, std::vector<SUBINFO *> &subs ) const
356{
357 foreach( CMethod *method, staticMethods ){
358 if(lstrcmp(methodName,method->psi->name)==0){
359 subs.push_back( method->psi );
360 }
361 }
362}
363
364void CClass::EnumMethod( const char *methodName, std::vector<SUBINFO *> &subs ) const
365{
366 //オブジェクトのメンバ関数の場合
367 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
368 for( int i=(int)methods.size()-1; i>=0; i-- ){
369 if(lstrcmp(methodName,methods[i]->psi->name)==0){
370 subs.push_back( methods[i]->psi );
371 }
372 }
373}
374
375void CClass::EnumMethod( const BYTE idOperatorCalc, std::vector<SUBINFO *> &subs ) const
376{
377 //オブジェクトのメンバ関数の場合
378 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
379 for( int i=(int)methods.size()-1; i>=0; i-- ){
380 char *temp;
381 temp=methods[i]->psi->name;
382 if(temp[0]==1&&temp[1]==ESC_OPERATOR){
383 if((BYTE)temp[2]==idOperatorCalc){
384 subs.push_back( methods[i]->psi );
385 }
386 }
387 }
388}
389
390//デフォルト コンストラクタ メソッドを取得
391CMethod *CClass::GetConstructorMethod() const
392{
393 if( ConstructorMemberSubIndex == -1 ) return NULL;
394 return methods[ConstructorMemberSubIndex];
395}
396
397//デフォルト コピーコンストラクタ メソッドを取得
398CMethod *CClass::GetCopyConstructorMethod() const
399{
400 if( CopyConstructorMemberSubIndex == -1 ) return NULL;
401 return methods[CopyConstructorMemberSubIndex];
402}
403
404//デストラクタ メソッドを取得
405CMethod *CClass::GetDestructorMethod() const
406{
407 if( DestructorMemberSubIndex == -1 ) return NULL;
408 return methods[DestructorMemberSubIndex];
409}
410
411
412int CClass::GetFuncNumInVtbl( const SUBINFO *psi ) const
413{
414 int n = 0;
415 foreach( CMethod *method, methods ){
416 if( method->psi == psi ) break;
417 if( method->psi->bVirtual ) n++;
418 }
419 return n;
420}
421LONG_PTR CClass::GetVtblGlobalOffset(void){
422
423 //既に存在する場合はそれを返す
424 if(vtbl_offset!=-1) return vtbl_offset;
425
426
427 //////////////////////////////////////
428 // 存在しないときは新たに生成する
429 //////////////////////////////////////
430
431 SUBINFO **ppsi;
432 ppsi=(SUBINFO **)HeapAlloc(hHeap,0,vtbl_num*sizeof(SUBINFO *));
433
434 //関数テーブルに値をセット
435 int i2 = 0;
436 foreach( CMethod *method, methods ){
437 if(method->bVirtual){
438 method->psi->bUse=1;
439
440 if(method->bAbstract){
441 extern int cp;
442 SetError(300,NULL,cp);
443
444 ppsi[i2]=0;
445 }
446 else ppsi[i2]=method->psi;
447 i2++;
448 }
449 }
450
451 vtbl_offset=dataTable.AddBinary((void *)ppsi,vtbl_num*sizeof(LONG_PTR));
452
453 for( int i=0; i < vtbl_num; i++ ){
454 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
455 }
456
457 HeapDefaultFree(ppsi);
458
459 return vtbl_offset;
460}
461void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
462 if(vtbl_offset==-1) return;
463
464 LONG_PTR *pVtbl;
465 pVtbl=(LONG_PTR *)((char *)dataTable.GetPtr()+vtbl_offset);
466
467 int i;
468 for(i=0;i<vtbl_num;i++){
469 SUBINFO *psi;
470 psi=(SUBINFO *)pVtbl[i];
471 if(!psi) continue;
472 pVtbl[i]=psi->CompileAddress+ImageBase+MemPos_CodeSection;
473 }
474}
475bool CClass::IsAbstract(){
476 //未実装の仮想関数を持つ場合はtrueを返す
477
478 foreach( CMethod *method, methods ){
479 if(method->bVirtual){
480 if(method->bAbstract){
481 return true;
482 }
483 }
484 }
485
486 //コンポジションの関係にあるメンバも検査する
487 for(int i=0;i < iMemberNum;i++){
488 if(ppobj_Member[i]->TypeInfo.type==DEF_OBJECT && ppobj_Member[i]->IsRef() == false){
489 if(ppobj_Member[i]->TypeInfo.u.pobj_Class->IsAbstract())
490 return true;
491 }
492 }
493
494 return false;
495}
496
497// コンストラクタのコンパイルを開始
498void CClass::NotifyStartConstructorCompile(){
499 isCompilingConstructor = true;
500}
501
502//コンストラクタのコンパイルを終了
503void CClass::NotifyFinishConstructorCompile(){
504 isCompilingConstructor = false;
505}
506
507//コンストラクタをコンパイル中かどうかを判別
508bool CClass::IsCompilingConstructor(){
509 return isCompilingConstructor;
510}
511
512//デストラクタのコンパイルを開始
513void CClass::NotifyStartDestructorCompile(){
514 isCompilingDestructor = true;
515}
516
517//デストラクタのコンパイルを終了
518void CClass::NotifyFinishDestructorCompile(){
519 isCompilingDestructor = false;
520}
521
522//デストラクタをコンパイル中かどうかを判別
523bool CClass::IsCompilingDestructor(){
524 return isCompilingDestructor;
525}
526
527
528//自身と等しいクラスかどうかを確認
529bool CClass::IsEquals( CClass *pClass ){
530 if( this == pClass ) return true;
531 return false;
532}
533
534//自身の派生クラスかどうかを確認
535bool CClass::IsSubClass( CClass *pClass ){
536 pClass = pClass->pobj_InheritsClass;
537 while( pClass ){
538 if( this == pClass ) return true;
539 pClass = pClass->pobj_InheritsClass;
540 }
541 return false;
542}
543
544//自身と等しいまたは派生クラスかどうかを確認
545bool CClass::IsEqualsOrSubClass( CClass *pClass ){
546 if( IsEquals( pClass ) ) return true;
547 return IsSubClass( pClass );
548}
549
550
551
552int CDBClass::hash(const char *name){
553 int key;
554
555 for(key=0;*name!='\0';name++){
556 key=((key<<8)+ *name )%MAX_CLASS_HASH;
557 }
558
559 return key;
560}
561
562void CDBClass::DestroyClass(CClass *pobj_c){
563 if(pobj_c->pobj_NextClass){
564 DestroyClass(pobj_c->pobj_NextClass);
565 }
566
567 delete pobj_c;
568}
569
570CDBClass::CDBClass(){
571 memset(this,0,sizeof(CDBClass));
572}
573CDBClass::~CDBClass(){
574 int i;
575 for(i=0;i<MAX_CLASS_HASH;i++){
576 if(pobj_ClassHash[i]) DestroyClass(pobj_ClassHash[i]);
577 }
578
579 if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass);
580}
581
582void CDBClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
583 int i;
584 for(i=0;i<MAX_CLASS_HASH;i++){
585 if(pobj_ClassHash[i]){
586 CClass *pobj_c;
587 pobj_c=pobj_ClassHash[i];
588 while(1){
589 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
590
591 if(pobj_c->pobj_NextClass==0) break;
592 pobj_c=pobj_c->pobj_NextClass;
593 }
594 }
595 }
596}
597
598CClass *CDBClass::check(const char *name){
599 int key;
600 key=hash(name);
601
602 if(pobj_ClassHash[key]){
603 CClass *pobj_c;
604 pobj_c=pobj_ClassHash[key];
605 while(1){
606 if(lstrcmp(name,pobj_c->name)==0){
607 //重複した場合
608 return pobj_c;
609 }
610
611 if(pobj_c->pobj_NextClass==0) break;
612 pobj_c=pobj_c->pobj_NextClass;
613 }
614 }
615 return 0;
616}
617
618CClass *CDBClass::AddClass(const char *name,int NowLine){
619 //////////////////////////////////////////////////////////////////////////
620 // クラスを追加
621 // ※名前のみを登録。その他の情報はSetClassメソッドで!
622 //////////////////////////////////////////////////////////////////////////
623
624 CClass *pobj_c;
625 pobj_c=new CClass(name);
626
627 if(lstrcmp(name,"String")==0){
628 //Stringクラス
629 pobj_StringClass=pobj_c;
630 }
631
632
633 /////////////////////////////////
634 // ハッシュデータに追加
635 /////////////////////////////////
636
637 int key;
638 key=hash(name);
639
640 if(pobj_ClassHash[key]){
641 CClass *pobj_c2;
642 pobj_c2=pobj_ClassHash[key];
643 while(1){
644 if(lstrcmp(name,pobj_c2->name)==0){
645 //重複した場合
646 SetError(15,name,NowLine);
647 return 0;
648 }
649
650 if(pobj_c2->pobj_NextClass==0) break;
651 pobj_c2=pobj_c2->pobj_NextClass;
652 }
653 pobj_c2->pobj_NextClass=pobj_c;
654 }
655 else{
656 pobj_ClassHash[key]=pobj_c;
657 }
658
659 return pobj_c;
660}
661
662void CDBClass::InitNames(void){
663 extern char *basbuf;
664 int i;
665
666 for(i=0;;i++){
667 if(basbuf[i]=='\0') break;
668
669 if(basbuf[i]==1&&(
670 basbuf[i+1]==ESC_CLASS||
671 basbuf[i+1]==ESC_TYPE||
672 basbuf[i+1]==ESC_INTERFACE
673 )){
674 int NowLine;
675 NowLine=i;
676
677 i+=2;
678 //アラインメント修飾子
679 if(_memicmp(basbuf+i,"Align(",6)==0){
680 i+=6;
681 i=JumpStringInPare(basbuf,i)+1;
682 }
683
684 int i2;
685 char temporary[VN_SIZE];
686 for(i2=0;;i++,i2++){
687 if(!IsVariableChar(basbuf[i])){
688 temporary[i2]=0;
689 break;
690 }
691 temporary[i2]=basbuf[i];
692 }
693
694 //クラスを追加
695 pobj_DBClass->AddClass(temporary,NowLine);
696 }
697 }
698}
699
700
701void CDBClass::AddMethod(CClass *pobj_c, DWORD dwAccess, BOOL bStatic, bool isConst, BOOL bAbstract,
702 BOOL bVirtual, BOOL bOverride, char *buffer, int NowLine){
703 int i,i2;
704 char temporary[VN_SIZE];
705
706 i=2;
707 for(i2=0;;i++,i2++){
708 if(buffer[i]=='('||buffer[i]=='\0'){
709 temporary[i2]=0;
710 break;
711 }
712 temporary[i2]=buffer[i];
713 }
714
715
716 //関数ハッシュへ登録
717 SUBINFO *psi;
718 psi=AddSubData(buffer,NowLine,bVirtual,pobj_c,bStatic);
719 if(!psi) return;
720
721
722 ////////////////////////////////////////////////////////////
723 // コンストラクタ、デストラクタの場合の処理
724 ////////////////////////////////////////////////////////////
725 BOOL fConstructor=0,bDestructor=0;
726
727 if(lstrcmp(temporary,pobj_c->name)==0){
728 //コンストラクタの場合
729
730 //標準コンストラクタ(引数なし)
731 if(psi->ParmNum==0) fConstructor=1;
732
733 //コピーコンストラクタ
734 if(psi->ParmNum==1){
735 if(psi->pParmInfo[0].type==DEF_OBJECT&&
736 psi->pParmInfo[0].u.pobj_c==pobj_c) fConstructor=2;
737 }
738
739 //強制的にConst修飾子をつける
740 isConst = true;
741 }
742 else if(temporary[0]=='~'){
743 //デストラクタの場合はその名前が正しいかチェックを行う
744 if(lstrcmp(temporary+1,pobj_c->name)!=0)
745 SetError(117,NULL,NowLine);
746 else
747 bDestructor=1;
748 }
749 if(fConstructor||bDestructor){
750 // コンストラクタ、デストラクタのアクセシビリティをチェック
751 if(dwAccess!=ACCESS_PUBLIC){
752 SetError(116,NULL,NowLine);
753 dwAccess=ACCESS_PUBLIC;
754 }
755
756 //強制的にConst修飾子をつける
757 isConst = true;
758 }
759
760 if( fConstructor == 1 )
761 pobj_c->ConstructorMemberSubIndex = (int)pobj_c->methods.size();
762 else if( fConstructor == 2 )
763 pobj_c->CopyConstructorMemberSubIndex = (int)pobj_c->methods.size();
764 else if( bDestructor )
765 pobj_c->DestructorMemberSubIndex = (int)pobj_c->methods.size();
766
767
768
769 //////////////////
770 // 重複チェック
771 //////////////////
772
773 if(pobj_c->DupliCheckMember(temporary)){
774 SetError(15,temporary,NowLine);
775 return;
776 }
777
778 //メソッド
779 foreach( CMethod *method, pobj_c->methods ){
780 //基底クラスと重複する場合はオーバーライドを行う
781 if(method->pobj_InheritsClass) continue;
782
783 if(lstrcmp(temporary,method->psi->name)==0){
784 if(CompareParameter(
785 method->psi->pParmInfo,method->psi->ParmNum,
786 psi->pParmInfo,psi->ParmNum
787 )==0){
788 //関数名、パラメータ属性が合致したとき
789 SetError(15,psi->name,NowLine);
790 return;
791 }
792 }
793 }
794
795 //仮想関数の場合
796 if(bAbstract) psi->bCompile=1;
797
798 //メソッドのオーバーライド
799 foreach( CMethod *method, pobj_c->methods ){
800 if(lstrcmp(temporary,method->psi->name)==0){
801 if(CompareParameter(
802 method->psi->pParmInfo,method->psi->ParmNum,
803 psi->pParmInfo,psi->ParmNum
804 )==0){
805
806 if(method->psi->bVirtual){
807 //メンバ関数を上書き
808 method->psi=psi;
809 method->bAbstract=0;
810
811 if(!bOverride){
812 SetError(127,NULL,NowLine);
813 }
814 if(method->dwAccess!=dwAccess){
815 SetError(128,NULL,NowLine);
816 }
817 return;
818 }
819 }
820 }
821 }
822
823 if(psi->bVirtual){
824 pobj_c->vtbl_num++;
825 }
826
827 if(bOverride){
828 SetError(12,"Override",NowLine);
829 }
830
831 if(bStatic){
832 pobj_c->AddStaticMethod(psi,dwAccess);
833 }
834 else{
835 pobj_c->AddMethod(psi, dwAccess, isConst, bAbstract, bVirtual);
836 }
837}
838
839BOOL CDBClass::MemberVar_LoopRefCheck(CClass *pobj_c){
840 int i,i2,bRet=1;
841 for(i=0;i<pobj_c->iMemberNum;i++){
842 CMember *pMember = pobj_c->ppobj_Member[i];
843 if(pMember->TypeInfo.type==DEF_OBJECT && pMember->IsRef()==false ){
844 //循環参照でないかをチェック
845 if(pobj_LoopRefCheck->check(pMember->TypeInfo.u.pobj_Class->name)){
846 extern int cp;
847 SetError(124,pMember->TypeInfo.u.pobj_Class->name,cp);
848 return 0;
849 }
850
851 pobj_LoopRefCheck->add(pobj_c->name);
852
853 i2=MemberVar_LoopRefCheck(pMember->TypeInfo.u.pobj_Class);
854 if(bRet==1) bRet=i2;
855
856 pobj_LoopRefCheck->del(pobj_c->name);
857 }
858 }
859
860 return bRet;
861}
862
863void CDBClass::GetClass_recur(const char *lpszInheritsClass){
864 extern char *basbuf;
865 int i,i2,i3,sub_address,top_pos;
866 DWORD dwClassType;
867 DWORD dwAccess;
868 char temporary[8192];
869
870 for(i=0;;i++){
871 if(basbuf[i]=='\0') break;
872
873 CClass *pobj_c;
874
875 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
876 //////////////////////////
877 // インターフェイス
878 //////////////////////////
879
880 top_pos=i;
881
882 i+=2;
883
884 //インターフェイス名を取得
885 GetIdentifierToken( temporary, basbuf, i );
886
887 pobj_c=pobj_DBClass->check(temporary);
888 if(!pobj_c) continue;
889
890 if(lpszInheritsClass){
891 if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){
892 //継承先先読み用
893 continue;
894 }
895 }
896
897 if(pobj_c->ppobj_Member){
898 //既に先読みされているとき
899 continue;
900 }
901
902 //メンバ用メモリを初期化
903 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1);
904 pobj_c->iMemberNum=0;
905
906 pobj_c->ConstructorMemberSubIndex=-1;
907 pobj_c->CopyConstructorMemberSubIndex=-1;
908 pobj_c->DestructorMemberSubIndex=-1;
909
910 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
911 //継承を行う場合
912 for(i+=3,i2=0;;i++,i2++){
913 if(IsCommandDelimitation(basbuf[i])){
914 temporary[i2]=0;
915 break;
916 }
917 temporary[i2]=basbuf[i];
918 }
919
920 if(lstrcmpi(temporary,pobj_c->name)==0){
921 SetError(105,temporary,i);
922 goto Interface_InheritsError;
923 }
924
925 //継承元クラスを取得
926 CClass *pInheritsClass = check(temporary);
927 if( !pInheritsClass ){
928 SetError(106,temporary,i);
929 goto Interface_InheritsError;
930 }
931
932 //ループ継承でないかをチェック
933 if(pobj_LoopRefCheck->check(temporary)){
934 SetError(123,temporary,i);
935 goto Interface_InheritsError;
936 }
937
938 if( pInheritsClass->ppobj_Member == 0 ){
939 //継承先が読み取られていないとき
940 pobj_LoopRefCheck->add(pobj_c->name);
941 GetClass_recur(temporary);
942 pobj_LoopRefCheck->del(pobj_c->name);
943 }
944
945 //継承させる
946 pobj_c->Inherits( pInheritsClass );
947 }
948 else{
949 //継承無し
950 pobj_c->pobj_InheritsClass=0;
951
952 //仮想関数の数を初期化
953 pobj_c->vtbl_num=0;
954 }
955Interface_InheritsError:
956
957 //メンバ変数、関数を取得
958 while(1){
959 i++;
960
961 //エラー
962 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
963 SetError(22,"Interface",i);
964 i--;
965 break;
966 }
967
968 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
969 SetError(111,NULL,i);
970 break;
971 }
972
973 sub_address=i;
974
975 for(i2=0;;i++,i2++){
976 if(IsCommandDelimitation(basbuf[i])){
977 temporary[i2]=0;
978 break;
979 }
980 temporary[i2]=basbuf[i];
981 }
982 if(temporary[0]=='\0'){
983 if(basbuf[i]=='\0'){
984 i--;
985 SetError(22,"Interface",top_pos);
986 break;
987 }
988 continue;
989 }
990
991 //End Interface記述の場合
992 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
993
994 if(!(temporary[0]==1&&(
995 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
996 ))){
997 SetError(1,NULL,i);
998 break;
999 }
1000
1001 //メンバ関数を追加
1002 AddMethod(pobj_c,
1003 ACCESS_PUBLIC, //Publicアクセス権
1004 0, //Static指定なし
1005 false, //Constではない
1006 1, //Abstract
1007 1, //Virtual
1008 0,
1009 temporary,
1010 sub_address
1011 );
1012 }
1013 }
1014
1015 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1016 //////////////////////////
1017 // クラス
1018 //////////////////////////
1019
1020 top_pos=i;
1021
1022 dwClassType=basbuf[i+1];
1023
1024 i+=2;
1025
1026 //アラインメント修飾子
1027 int iAlign=0;
1028 if(_memicmp(basbuf+i,"Align(",6)==0){
1029 i+=6;
1030 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1031 iAlign=atoi(temporary);
1032
1033 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1034 SetError(51,NULL,i);
1035 }
1036
1037
1038 //クラス名を取得
1039 GetIdentifierToken( temporary, basbuf, i );
1040
1041 pobj_c=pobj_DBClass->check(temporary);
1042 if(!pobj_c) continue;
1043
1044 if(lpszInheritsClass){
1045 if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){
1046 //継承先先読み用
1047 continue;
1048 }
1049 }
1050
1051 if(pobj_c->ppobj_Member){
1052 //既に先読みされているとき
1053 continue;
1054 }
1055
1056 pobj_c->iAlign=iAlign;
1057
1058 //メンバ用メモリを初期化
1059 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1);
1060 pobj_c->iMemberNum=0;
1061
1062 pobj_c->ConstructorMemberSubIndex=-1;
1063 pobj_c->CopyConstructorMemberSubIndex=-1;
1064 pobj_c->DestructorMemberSubIndex=-1;
1065
1066 //アクセス制限の初期値をセット
1067 if(dwClassType==ESC_CLASS) dwAccess=ACCESS_PRIVATE;
1068 else dwAccess=ACCESS_PUBLIC;
1069
1070 if( lstrcmp( pobj_c->name, "Object" ) == 0 || dwClassType == ESC_TYPE ){
1071 //継承無し
1072 pobj_c->pobj_InheritsClass=0;
1073
1074 //仮想関数の数を初期化
1075 pobj_c->vtbl_num=0;
1076 }
1077 else{
1078 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1079 //継承を行う場合
1080 for(i+=3,i2=0;;i++,i2++){
1081 if(IsCommandDelimitation(basbuf[i])){
1082 temporary[i2]=0;
1083 break;
1084 }
1085 temporary[i2]=basbuf[i];
1086 }
1087
1088 if(lstrcmpi(temporary,pobj_c->name)==0){
1089 SetError(105,temporary,i);
1090 goto InheritsError;
1091 }
1092 }
1093 else{
1094 //Objectを継承する
1095 lstrcpy( temporary, "Object" );
1096 }
1097
1098 //継承元クラスを取得
1099 CClass *pInheritsClass = check(temporary);
1100 if( !pInheritsClass ){
1101 SetError(106,temporary,i);
1102 goto InheritsError;
1103 }
1104
1105 //ループ継承でないかをチェック
1106 if(pobj_LoopRefCheck->check(temporary)){
1107 SetError(123,temporary,i);
1108 goto InheritsError;
1109 }
1110
1111 if( pInheritsClass->ppobj_Member == 0 ){
1112 //継承先が読み取られていないとき
1113 pobj_LoopRefCheck->add(pobj_c->name);
1114 GetClass_recur(temporary);
1115 pobj_LoopRefCheck->del(pobj_c->name);
1116 }
1117
1118 //継承させる
1119 pobj_c->Inherits( pInheritsClass );
1120 }
1121InheritsError:
1122
1123 //メンバとメソッドを取得
1124 while(1){
1125 i++;
1126
1127 //エラー
1128 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1129 SetError(22,"Class",i);
1130 i--;
1131 break;
1132 }
1133
1134 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1135 SetError(111,NULL,i);
1136 break;
1137 }
1138
1139 //Static修飾子
1140 BOOL bStatic;
1141 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1142 bStatic=1;
1143 i+=2;
1144 }
1145 else bStatic=0;
1146
1147 //Const修飾子
1148 bool isConst = false;
1149 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1150 isConst = true;
1151 i += 2;
1152 }
1153
1154 //Ref修飾子
1155 bool isRef = false;
1156 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_BYREF ){
1157 isRef = true;
1158 i += 2;
1159 }
1160
1161 if(basbuf[i]==1&&(
1162 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1163 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1164 )){
1165 i3=basbuf[i+1];
1166 sub_address=i;
1167 }
1168 else i3=0;
1169
1170 BOOL bVirtual=0,bAbstract=0,bOverride=0;
1171 if(i3==ESC_ABSTRACT){
1172 bAbstract=1;
1173 bVirtual=1;
1174 i+=2;
1175
1176 i3=basbuf[i+1];
1177 }
1178 else if(i3==ESC_VIRTUAL){
1179 bAbstract=0;
1180 bVirtual=1;
1181 i+=2;
1182
1183 i3=basbuf[i+1];
1184 }
1185 else if(i3==ESC_OVERRIDE){
1186 bOverride=1;
1187 bVirtual=1;
1188
1189 i+=2;
1190
1191 i3=basbuf[i+1];
1192 }
1193
1194 for(i2=0;;i++,i2++){
1195 if(IsCommandDelimitation(basbuf[i])){
1196 temporary[i2]=0;
1197 break;
1198 }
1199 temporary[i2]=basbuf[i];
1200 }
1201 if(temporary[0]=='\0'){
1202 if(basbuf[i]=='\0'){
1203
1204 if(dwClassType==ESC_CLASS)
1205 SetError(22,"Class",top_pos);
1206 else
1207 SetError(22,"Type",top_pos);
1208
1209 i--;
1210 break;
1211 }
1212 continue;
1213 }
1214
1215 //End Class記述の場合
1216 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1217 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1218
1219 //アクセスを変更
1220 if(lstrcmpi(temporary,"Private")==0){
1221 dwAccess=ACCESS_PRIVATE;
1222 continue;
1223 }
1224 if(lstrcmpi(temporary,"Public")==0){
1225 dwAccess=ACCESS_PUBLIC;
1226 continue;
1227 }
1228 if(lstrcmpi(temporary,"Protected")==0){
1229 dwAccess=ACCESS_PROTECTED;
1230 continue;
1231 }
1232
1233 extern int cp;
1234 if(i3==0){
1235 if(bStatic){
1236 //静的メンバを追加
1237 cp=i; //エラー用
1238 pobj_c->AddStaticMember( dwAccess, isConst, isRef, temporary, i);
1239 }
1240 else{
1241 //メンバを追加
1242 cp=i; //エラー用
1243 pobj_c->AddMember( dwAccess, isConst, isRef, temporary );
1244
1245
1246 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.type==DEF_OBJECT){
1247 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.u.pobj_Class->ppobj_Member==0){
1248 //参照先が読み取られていないとき
1249 GetClass_recur(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.u.pobj_Class->name);
1250 }
1251 }
1252
1253
1254 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.type==DEF_OBJECT){
1255 //循環参照のチェック
1256 pobj_LoopRefCheck->add(pobj_c->name);
1257 if(!MemberVar_LoopRefCheck(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.u.pobj_Class)){
1258 //エラー回避
1259 pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->TypeInfo.type=DEF_PTR_VOID;
1260 }
1261 pobj_LoopRefCheck->del(pobj_c->name);
1262 }
1263 }
1264 }
1265 else{
1266 // 文法エラーチェック
1267 if( isRef ){
1268 SetError(1,NULL,cp);
1269 }
1270
1271 //メソッドを追加
1272 cp=i; //エラー用
1273 AddMethod(pobj_c,
1274 dwAccess,
1275 bStatic,
1276 isConst,
1277 bAbstract,
1278 bVirtual,
1279 bOverride,
1280 temporary,
1281 sub_address);
1282
1283 if(bAbstract) continue;
1284
1285 for(;;i++){
1286 if(basbuf[i]=='\0'){
1287 i--;
1288 break;
1289 }
1290 if(basbuf[i-1]!='*'&&
1291 basbuf[i]==1&&(
1292 basbuf[i+1]==ESC_SUB||
1293 basbuf[i+1]==ESC_FUNCTION||
1294 basbuf[i+1]==ESC_MACRO||
1295 basbuf[i+1]==ESC_TYPE||
1296 basbuf[i+1]==ESC_CLASS||
1297 basbuf[i+1]==ESC_INTERFACE||
1298 basbuf[i+1]==ESC_ENUM)){
1299 GetDefaultNameFromES(i3,temporary);
1300 SetError(22,temporary,i);
1301 }
1302 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1303 i+=2;
1304 break;
1305 }
1306 }
1307 }
1308 }
1309 }
1310 }
1311}
1312
1313void CDBClass::GetObjectClassInfo(void){
1314 //ループ継承チェック用のクラス
1315 pobj_LoopRefCheck=new CLoopRefCheck();
1316
1317 //クラスを取得
1318 GetClass_recur(0);
1319
1320 delete pobj_LoopRefCheck;
1321 pobj_LoopRefCheck=0;
1322}
1323
1324void CDBClass::StartCompile( SUBINFO *psi ){
1325 pCompilingClass = psi->pobj_ParentClass;
1326 if( pCompilingClass ){
1327 pCompilingMethod = pCompilingClass->GetMethodInfo( psi );
1328 if( !pCompilingMethod ){
1329 pCompilingMethod = pCompilingClass->GetStaticMethodInfo( psi );
1330 if( !pCompilingMethod ){
1331 SetError(300,NULL,cp);
1332 }
1333 }
1334 }
1335 else{
1336 pCompilingMethod = NULL;
1337 }
1338}
1339CClass *CDBClass::GetNowCompilingClass(){
1340 return pCompilingClass;
1341}
1342CMethod *CDBClass::GetNowCompilingMethodInfo(){
1343 return pCompilingMethod;
1344}
1345
1346
1347
1348
1349//////////////////////
1350// イテレータ
1351//////////////////////
1352
1353void CDBClass::Iterator_Reset(void){
1354 if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass);
1355
1356 iIteMaxNum=0;
1357 iIteNextNum=0;
1358 ppobj_IteClass=(CClass **)HeapAlloc(hHeap,0,1);
1359
1360 int i;
1361 for(i=0;i<MAX_CLASS_HASH;i++){
1362 if(pobj_ClassHash[i]){
1363 CClass *pobj_c;
1364 pobj_c=pobj_ClassHash[i];
1365 while(1){
1366 ppobj_IteClass=(CClass **)HeapReAlloc(hHeap,0,ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
1367 ppobj_IteClass[iIteMaxNum]=pobj_c;
1368 iIteMaxNum++;
1369
1370 if(pobj_c->pobj_NextClass==0) break;
1371 pobj_c=pobj_c->pobj_NextClass;
1372 }
1373 }
1374 }
1375}
1376BOOL CDBClass::Iterator_HasNext(void){
1377 if(iIteNextNum<iIteMaxNum) return 1;
1378 return 0;
1379}
1380CClass *CDBClass::Iterator_GetNext(void){
1381 CClass *pobj_c;
1382 pobj_c=ppobj_IteClass[iIteNextNum];
1383 iIteNextNum++;
1384 return pobj_c;
1385}
1386int CDBClass::Iterator_GetMaxCount(void){
1387 return iIteMaxNum;
1388}
Note: See TracBrowser for help on using the repository browser.