source: dev/BasicCompiler_Common/Class.cpp@ 50

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

オーバーロード解決用の関数保持リストを "SUBINFO " ではなく、"vector<SUBINFO *>" に変更した。

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