source: dev/BasicCompiler_Common/Class.cpp@ 53

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

ppobj_StaticMemberを廃止し、vectorに統一した(staticMember)。

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
16int AddDataTable(char *buffer,int length);
17
18
19
20CMember::CMember( CClass *pobj_c, DWORD access, bool isConst, bool isRef, char *buffer, int NowLine ){
21 extern int cp;
22
23 //構文を解析
24 char VarName[VN_SIZE];
25 char init_buf[VN_SIZE];
26 char constract_parameter[VN_SIZE];
27 GetDimentionFormat(buffer,isRef,VarName,SubScripts,&TypeInfo,init_buf,constract_parameter);
28
29 //重複チェック
30 if(pobj_c->DupliCheckAll(VarName)){
31 SetError(15,VarName,cp);
32 }
33
34 if(TypeInfo.type==DEF_OBJECT){
35 if(TypeInfo.u.pobj_Class->IsAbstract()){
36 //抽象クラスだったとき
37 SetError(125,TypeInfo.u.pobj_Class->name,cp);
38 }
39 }
40
41 //メンバ名
42 name=(char *)HeapAlloc(hHeap,0,lstrlen(VarName)+1);
43 lstrcpy(name,VarName);
44
45 //アクセス権
46 dwAccess=access;
47
48 //定数扱いかどうか
49 this->isConst = isConst;
50
51 //参照型かどうか
52 this->isRef = isRef;
53
54 //初期データ
55 InitBuf=(char *)HeapAlloc(hHeap,0,lstrlen(init_buf)+1);
56 lstrcpy(InitBuf,init_buf);
57
58 //コンストラクタ用のパラメータ
59 ConstractParameter=(char *)HeapAlloc(hHeap,0,lstrlen(constract_parameter)+1);
60 lstrcpy(ConstractParameter,constract_parameter);
61
62 //ソースコードの位置
63 source_code_address=NowLine;
64}
65CMember::CMember(CMember *pobj){
66 //コピーコンストラクタ
67 memset(this,0,sizeof(CMember));
68
69 //name
70 name=(char *)HeapAlloc(hHeap,0,lstrlen(pobj->name)+1);
71 lstrcpy(name,pobj->name);
72
73 //定数扱いかどうか
74 isConst = pobj->isConst;
75
76 //参照型かどうか
77 isRef = pobj->isRef;
78
79 //SubScripts
80 memcpy(SubScripts,pobj->SubScripts,MAX_ARRAYDIM*sizeof(int));
81
82 //TypeInfo
83 TypeInfo=pobj->TypeInfo;
84
85 //ソースコードの位置
86 source_code_address=pobj->source_code_address;
87}
88CMember::CMember(){
89 memset(this,0,sizeof(CMember));
90}
91CMember::~CMember(){
92 HeapDefaultFree(name);
93 if(InitBuf) HeapDefaultFree(InitBuf);
94 if(ConstractParameter) HeapDefaultFree(ConstractParameter);
95}
96
97bool CMember::IsConst(){
98 return isConst;
99}
100bool CMember::IsRef(){
101 return isRef;
102}
103
104int CMember::GetSize(){
105 if( IsRef() ){
106 // 参照型
107 return PTR_SIZE;
108 }
109
110 //メンバサイズを取得
111 return GetTypeSize(TypeInfo.type,TypeInfo.u.lpIndex);
112}
113
114void CMember::InitStaticMember(void){
115 //静的メンバをグローバル領域に作成
116
117 //イテレータをリセット
118 extern CDBClass *pobj_DBClass;
119 pobj_DBClass->Iterator_Reset();
120
121 int back_cp=cp;
122
123 while(pobj_DBClass->Iterator_HasNext()){
124 CClass *pobj_c;
125 pobj_c=pobj_DBClass->Iterator_GetNext();
126
127 foreach( CMember *member, pobj_c->staticMembers ){
128 char temporary[VN_SIZE];
129 sprintf(temporary,"%s.%s",pobj_c->name,member->name);
130 AddGlobalVariable(
131 temporary,
132 member->SubScripts,
133 &member->TypeInfo,
134 GetTypeSize(member->TypeInfo.type,member->TypeInfo.u.lpIndex),
135 member->InitBuf,
136 member->ConstractParameter,
137 0);
138
139 if(member->TypeInfo.type==DEF_OBJECT){
140 //エラー用
141 cp=member->source_code_address;
142
143 CallConstructor(temporary,
144 member->SubScripts,
145 member->TypeInfo,
146 member->ConstractParameter);
147 }
148
149 //ネイティブコードバッファの再確保
150 extern int obp_AllocSize;
151 if(obp_AllocSize<obp+8192){
152 obp_AllocSize+=8192;
153 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize); //matea
154 }
155 }
156 }
157
158 cp=back_cp;
159}
160
161
162
163CMethod::CMethod(CMethod *pobj){
164 //コピーコンストラクタ
165 memset(this,0,sizeof(CMethod));
166
167 psi=pobj->psi;
168
169 bAbstract=pobj->bAbstract;
170
171 bVirtual=pobj->bVirtual;
172}
173CMethod::CMethod(){
174 memset(this,0,sizeof(CMethod));
175}
176CMethod::~CMethod(){
177}
178
179
180
181
182CClass::CClass(const char *name){
183 memset(this,0,sizeof(CClass));
184
185 vtbl_offset=-1;
186
187 this->name=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1);
188 lstrcpy(this->name,name);
189
190 isCompilingConstructor = false;
191 isCompilingDestructor = false;
192}
193CClass::~CClass(){
194 int i;
195
196 //クラス名
197 HeapDefaultFree(name);
198
199 if(ppobj_Member){
200 //メンバ
201 for(i=0;i<iMemberNum;i++){
202 delete ppobj_Member[i];
203 }
204 HeapDefaultFree(ppobj_Member);
205 ppobj_Member=0;
206 }
207
208 //静的メンバ
209 foreach( CMember *member, staticMembers ){
210 delete member;
211 }
212
213 //メソッド
214 foreach( CMethod *method, methods ){
215 delete method;
216 }
217
218 //静的メソッド
219 foreach( CMethod *method, staticMethods ){
220 delete method;
221 }
222}
223void CClass::Inherits( CClass *pInheritsClass ){
224 int i3;
225
226 //メンバをコピー
227 ppobj_Member=(CMember **)HeapReAlloc(
228 hHeap,
229 0,
230 ppobj_Member,
231 pInheritsClass->iMemberNum*sizeof(CMember *));
232 iMemberNum=pInheritsClass->iMemberNum;
233 for(i3=0;i3<pInheritsClass->iMemberNum;i3++){
234 ppobj_Member[i3]=new CMember(pInheritsClass->ppobj_Member[i3]);
235
236 //dwAccess
237 if(pInheritsClass->ppobj_Member[i3]->dwAccess==ACCESS_PRIVATE)
238 ppobj_Member[i3]->dwAccess=ACCESS_NON;
239 else ppobj_Member[i3]->dwAccess=pInheritsClass->ppobj_Member[i3]->dwAccess;
240 }
241
242 //メソッドをコピー
243 foreach( CMethod *baseMethod, pInheritsClass->methods ){
244 CMethod *method = new CMethod( baseMethod );
245
246 //dwAccess
247 if(baseMethod->dwAccess==ACCESS_PRIVATE)
248 method->dwAccess=ACCESS_NON;
249 else method->dwAccess=baseMethod->dwAccess;
250
251 //pobj_Inherits
252 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
253 if(baseMethod->pobj_InheritsClass==0)
254 method->pobj_InheritsClass=pInheritsClass;
255 else
256 method->pobj_InheritsClass=
257 baseMethod->pobj_InheritsClass;
258
259 methods.push_back( method );
260 }
261
262 //仮想関数の数
263 vtbl_num=pInheritsClass->vtbl_num;
264
265 //継承先のクラスをメンバとして保持する
266 pobj_InheritsClass = pInheritsClass;
267}
268void CClass::AddMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer ){
269 ppobj_Member = (CMember **)HeapReAlloc( hHeap, 0, ppobj_Member, ( iMemberNum + 1 ) * sizeof(CMember *) );
270 ppobj_Member[iMemberNum] = new CMember( this, dwAccess, isConst, isRef, buffer );
271 iMemberNum++;
272}
273void CClass::AddStaticMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer, int NowLine ){
274 CMember *member = new CMember( this, dwAccess, isConst, isRef, buffer, NowLine );
275 staticMembers.push_back( member );
276}
277void CClass::AddMethod( SUBINFO *psi,DWORD dwAccess, bool isConst, BOOL bAbstract, BOOL bVirtual ){
278 CMethod *method = new CMethod();
279 method->psi = psi;
280 method->dwAccess = dwAccess;
281 method->isConst = isConst;
282 method->bAbstract = bAbstract;
283 method->bVirtual = bVirtual;
284 method->pobj_InheritsClass = 0;
285
286 methods.push_back( method );
287}
288void CClass::AddStaticMethod(SUBINFO *psi,DWORD dwAccess){
289 CMethod *method = new CMethod();
290 method->psi=psi;
291 method->dwAccess=dwAccess;
292 method->bAbstract=0;
293 method->bVirtual=0;
294 method->pobj_InheritsClass=0;
295
296 staticMethods.push_back( method );
297}
298BOOL CClass::DupliCheckAll(const char *name){
299 //重複チェック
300
301 //メンバ
302 if(DupliCheckMember(name)) return 1;
303
304 //メソッド
305 foreach( CMethod *method, methods ){
306 if( lstrcmp( name, method->psi->name ) == 0 ){
307 return 1;
308 }
309 }
310
311 return 0;
312}
313BOOL CClass::DupliCheckMember(const char *name){
314 //重複チェック
315
316 //メンバ
317 for( int i=0;i<iMemberNum;i++){
318 if(lstrcmp(name,ppobj_Member[i]->name)==0){
319 return 1;
320 }
321 }
322
323 //静的メンバ
324 foreach( CMember *member, staticMembers ){
325 if( lstrcmp( name, member->name ) == 0 ){
326 return 1;
327 }
328 }
329
330 return 0;
331}
332CMethod *CClass::GetMethodInfo( SUBINFO *psi ){
333 for( int i=(int)methods.size()-1; i>=0; i-- ){
334 if( psi == methods[i]->psi ) return methods[i];
335 }
336 return NULL;
337}
338CMethod *CClass::GetStaticMethodInfo( SUBINFO *psi ){
339 for( int i=(int)staticMethods.size()-1; i>=0; i-- ){
340 if( psi == staticMethods[i]->psi ) return staticMethods[i];
341 }
342 return NULL;
343}
344bool CClass::IsExistMethod( const char *name ){
345 foreach( CMethod *method, methods ){
346 if( lstrcmp( method->psi->name, name ) == 0 ) return true;
347 }
348 return false;
349}
350bool CClass::IsExistStaticMethod( const char *name ){
351 foreach( CMethod *method, staticMethods ){
352 if( lstrcmp( method->psi->name, name ) == 0 ) return true;
353 }
354 return false;
355}
356
357void CClass::EnumStaticMethod( const char *methodName, std::vector<SUBINFO *> &subs ) const
358{
359 foreach( CMethod *method, staticMethods ){
360 if(lstrcmp(methodName,method->psi->name)==0){
361 subs.push_back( method->psi );
362 }
363 }
364}
365
366void CClass::EnumMethod( const char *methodName, std::vector<SUBINFO *> &subs ) const
367{
368 //オブジェクトのメンバ関数の場合
369 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
370 for( int i=(int)methods.size()-1; i>=0; i-- ){
371 if(lstrcmp(methodName,methods[i]->psi->name)==0){
372 subs.push_back( methods[i]->psi );
373 }
374 }
375}
376
377void CClass::EnumMethod( const BYTE idOperatorCalc, std::vector<SUBINFO *> &subs ) const
378{
379 //オブジェクトのメンバ関数の場合
380 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
381 for( int i=(int)methods.size()-1; i>=0; i-- ){
382 char *temp;
383 temp=methods[i]->psi->name;
384 if(temp[0]==1&&temp[1]==ESC_OPERATOR){
385 if((BYTE)temp[2]==idOperatorCalc){
386 subs.push_back( methods[i]->psi );
387 }
388 }
389 }
390}
391
392//デフォルト コンストラクタ メソッドを取得
393CMethod *CClass::GetConstructorMethod() const
394{
395 if( ConstructorMemberSubIndex == -1 ) return NULL;
396 return methods[ConstructorMemberSubIndex];
397}
398
399//デフォルト コピーコンストラクタ メソッドを取得
400CMethod *CClass::GetCopyConstructorMethod() const
401{
402 if( CopyConstructorMemberSubIndex == -1 ) return NULL;
403 return methods[CopyConstructorMemberSubIndex];
404}
405
406//デストラクタ メソッドを取得
407CMethod *CClass::GetDestructorMethod() const
408{
409 if( DestructorMemberSubIndex == -1 ) return NULL;
410 return methods[DestructorMemberSubIndex];
411}
412
413
414LONG_PTR CClass::AddVtblDataTable(SUBINFO **ppsi,int length){
415 return AddDataTable((char *)ppsi,length);
416}
417int CClass::GetFuncNumInVtbl( const SUBINFO *psi ) const
418{
419 int n = 0;
420 foreach( CMethod *method, methods ){
421 if( method->psi == psi ) break;
422 if( method->psi->bVirtual ) n++;
423 }
424 return n;
425}
426LONG_PTR CClass::GetVtblGlobalOffset(void){
427
428 //既に存在する場合はそれを返す
429 if(vtbl_offset!=-1) return vtbl_offset;
430
431
432 //////////////////////////////////////
433 // 存在しないときは新たに生成する
434 //////////////////////////////////////
435
436 SUBINFO **ppsi;
437 ppsi=(SUBINFO **)HeapAlloc(hHeap,0,vtbl_num*sizeof(SUBINFO *));
438
439 //関数テーブルに値をセット
440 int i2 = 0;
441 foreach( CMethod *method, methods ){
442 if(method->bVirtual){
443 method->psi->bUse=1;
444
445 if(method->bAbstract){
446 extern int cp;
447 SetError(300,NULL,cp);
448
449 ppsi[i2]=0;
450 }
451 else ppsi[i2]=method->psi;
452 i2++;
453 }
454 }
455
456 vtbl_offset=AddDataTable((char *)ppsi,vtbl_num*sizeof(LONG_PTR));
457
458 for( int i=0; i < vtbl_num; i++ ){
459 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
460 }
461
462 HeapDefaultFree(ppsi);
463
464 return vtbl_offset;
465}
466void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
467 if(vtbl_offset==-1) return;
468
469 extern char *DataTable;
470 LONG_PTR *pVtbl;
471 pVtbl=(LONG_PTR *)(DataTable+vtbl_offset);
472
473 int i;
474 for(i=0;i<vtbl_num;i++){
475 SUBINFO *psi;
476 psi=(SUBINFO *)pVtbl[i];
477 if(!psi) continue;
478 pVtbl[i]=psi->CompileAddress+ImageBase+MemPos_CodeSection;
479 }
480}
481bool CClass::IsAbstract(){
482 //未実装の仮想関数を持つ場合はtrueを返す
483
484 foreach( CMethod *method, methods ){
485 if(method->bVirtual){
486 if(method->bAbstract){
487 return true;
488 }
489 }
490 }
491
492 //コンポジションの関係にあるメンバも検査する
493 for(int i=0;i < iMemberNum;i++){
494 if(ppobj_Member[i]->TypeInfo.type==DEF_OBJECT && ppobj_Member[i]->IsRef() == false){
495 if(ppobj_Member[i]->TypeInfo.u.pobj_Class->IsAbstract())
496 return true;
497 }
498 }
499
500 return false;
501}
502
503// コンストラクタのコンパイルを開始
504void CClass::NotifyStartConstructorCompile(){
505 isCompilingConstructor = true;
506}
507
508//コンストラクタのコンパイルを終了
509void CClass::NotifyFinishConstructorCompile(){
510 isCompilingConstructor = false;
511}
512
513//コンストラクタをコンパイル中かどうかを判別
514bool CClass::IsCompilingConstructor(){
515 return isCompilingConstructor;
516}
517
518//デストラクタのコンパイルを開始
519void CClass::NotifyStartDestructorCompile(){
520 isCompilingDestructor = true;
521}
522
523//デストラクタのコンパイルを終了
524void CClass::NotifyFinishDestructorCompile(){
525 isCompilingDestructor = false;
526}
527
528//デストラクタをコンパイル中かどうかを判別
529bool CClass::IsCompilingDestructor(){
530 return isCompilingDestructor;
531}
532
533
534//自身と等しいクラスかどうかを確認
535bool CClass::IsEquals( CClass *pClass ){
536 if( this == pClass ) return true;
537 return false;
538}
539
540//自身の派生クラスかどうかを確認
541bool CClass::IsSubClass( CClass *pClass ){
542 pClass = pClass->pobj_InheritsClass;
543 while( pClass ){
544 if( this == pClass ) return true;
545 pClass = pClass->pobj_InheritsClass;
546 }
547 return false;
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[1].type==DEF_OBJECT&&
736 psi->pParmInfo[1].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.