source: dev/BasicCompiler_Common/Class.cpp@ 52

Last change on this file since 52 was 51, checked in by dai_9181, 18 years ago

ppobj_Member及びppobj_StaticMemberを廃止し、vectorに統一した(methods及びstaticMethods)。

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