source: dev/BasicCompiler_Common/Class.cpp@ 51

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

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

File size: 31.6 KB
RevLine 
[4]1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
[5]6#include "../BasicCompiler32/opcode.h"
[4]7#endif
8
9CDBClass *pobj_DBClass;
10
11CClass *pobj_CompilingClass;
12CClass *pobj_StringClass;
13
[18]14CMember *pCompilingMethod;
15
[4]16int AddDataTable(char *buffer,int length);
17
18
19
[40]20CMember::CMember( CClass *pobj_c, DWORD access, bool isConst, bool isRef, char *buffer, int NowLine ){
[4]21 extern int cp;
22
23 //構文を解析
24 char VarName[VN_SIZE];
25 char init_buf[VN_SIZE];
26 char constract_parameter[VN_SIZE];
[40]27 GetDimentionFormat(buffer,isRef,VarName,SubScripts,&TypeInfo,init_buf,constract_parameter);
[4]28
29 //重複チェック
30 if(pobj_c->DupliCheckAll(VarName)){
31 SetError(15,VarName,cp);
32 }
33
34 if(TypeInfo.type==DEF_OBJECT){
[28]35 if(TypeInfo.u.pobj_Class->IsAbstract()){
[4]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
[17]48 //定数扱いかどうか
49 this->isConst = isConst;
50
[40]51 //参照型かどうか
52 this->isRef = isRef;
53
[4]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
[17]73 //定数扱いかどうか
74 isConst = pobj->isConst;
75
[40]76 //参照型かどうか
77 isRef = pobj->isRef;
78
[4]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
[17]97bool CMember::IsConst(){
98 return isConst;
99}
[40]100bool CMember::IsRef(){
101 return isRef;
102}
[17]103
[40]104int CMember::GetSize(){
105 if( IsRef() ){
106 // 参照型
107 return PTR_SIZE;
108 }
109
110 //メンバサイズを取得
111 return GetTypeSize(TypeInfo.type,TypeInfo.u.lpIndex);
112}
113
[4]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
[50]144 CallConstructor(temporary,
[4]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
[46]183CClass::CClass(const char *name){
[4]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);
[17]190
[18]191 isCompilingConstructor = false;
192 isCompilingDestructor = false;
[4]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
[51]218 //メソッド
219 foreach( CMethod *method, methods ){
[50]220 delete method;
[4]221 }
[51]222
223 //静的メソッド
224 foreach( CMethod *method, staticMethods ){
225 delete method;
226 }
[4]227}
[29]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 //メソッドをコピー
[51]248 foreach( CMethod *baseMethod, pInheritsClass->methods ){
249 CMethod *method = new CMethod( baseMethod );
[29]250
251 //dwAccess
[51]252 if(baseMethod->dwAccess==ACCESS_PRIVATE)
253 method->dwAccess=ACCESS_NON;
254 else method->dwAccess=baseMethod->dwAccess;
[29]255
256 //pobj_Inherits
257 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
[51]258 if(baseMethod->pobj_InheritsClass==0)
259 method->pobj_InheritsClass=pInheritsClass;
[29]260 else
[51]261 method->pobj_InheritsClass=
262 baseMethod->pobj_InheritsClass;
263
264 methods.push_back( method );
[29]265 }
266
267 //仮想関数の数
268 vtbl_num=pInheritsClass->vtbl_num;
269
270 //継承先のクラスをメンバとして保持する
271 pobj_InheritsClass = pInheritsClass;
272}
[40]273void CClass::AddMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer ){
[17]274 ppobj_Member = (CMember **)HeapReAlloc( hHeap, 0, ppobj_Member, ( iMemberNum + 1 ) * sizeof(CMember *) );
[40]275 ppobj_Member[iMemberNum] = new CMember( this, dwAccess, isConst, isRef, buffer );
[4]276 iMemberNum++;
277}
[40]278void CClass::AddStaticMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer, int NowLine ){
[4]279 ppobj_StaticMember=(CMember **)HeapReAlloc(hHeap,0,ppobj_StaticMember,(iStaticMemberNum+1)*sizeof(CMember *));
[40]280 ppobj_StaticMember[iStaticMemberNum]=new CMember( this, dwAccess, isConst, isRef, buffer, NowLine );
[4]281 iStaticMemberNum++;
282}
[18]283void CClass::AddMethod( SUBINFO *psi,DWORD dwAccess, bool isConst, BOOL bAbstract, BOOL bVirtual ){
[51]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;
[4]291
[51]292 methods.push_back( method );
[4]293}
294void CClass::AddStaticMethod(SUBINFO *psi,DWORD dwAccess){
[50]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;
[4]301
[51]302 staticMethods.push_back( method );
[4]303}
[46]304BOOL CClass::DupliCheckAll(const char *name){
[4]305 //重複チェック
306
307 //メンバ
308 if(DupliCheckMember(name)) return 1;
309
310 //メソッド
[51]311 foreach( CMethod *method, methods ){
312 if( lstrcmp( name, method->psi->name ) == 0 ){
[4]313 return 1;
314 }
315 }
316
317 return 0;
318}
[46]319BOOL CClass::DupliCheckMember(const char *name){
[4]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}
[18]340CMethod *CClass::GetMethodInfo( SUBINFO *psi ){
[51]341 for( int i=(int)methods.size()-1; i>=0; i-- ){
342 if( psi == methods[i]->psi ) return methods[i];
[18]343 }
[50]344 return NULL;
[18]345}
346CMethod *CClass::GetStaticMethodInfo( SUBINFO *psi ){
[51]347 for( int i=(int)staticMethods.size()-1; i>=0; i-- ){
348 if( psi == staticMethods[i]->psi ) return staticMethods[i];
[18]349 }
[50]350 return NULL;
[18]351}
[46]352bool CClass::IsExistMethod( const char *name ){
[51]353 foreach( CMethod *method, methods ){
354 if( lstrcmp( method->psi->name, name ) == 0 ) return true;
[27]355 }
356 return false;
357}
[46]358bool CClass::IsExistStaticMethod( const char *name ){
[51]359 foreach( CMethod *method, staticMethods ){
[50]360 if( lstrcmp( method->psi->name, name ) == 0 ) return true;
[27]361 }
362 return false;
363}
[4]364
[50]365void CClass::EnumStaticMethod( const char *methodName, std::vector<SUBINFO *> &subs ) const
366{
[51]367 foreach( CMethod *method, staticMethods ){
[50]368 if(lstrcmp(methodName,method->psi->name)==0){
369 subs.push_back( method->psi );
370 }
371 }
372}
[27]373
[50]374void CClass::EnumMethod( const char *methodName, std::vector<SUBINFO *> &subs ) const
375{
376 //オブジェクトのメンバ関数の場合
377 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
[51]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 );
[50]381 }
382 }
383}
384
385void CClass::EnumMethod( const BYTE idOperatorCalc, std::vector<SUBINFO *> &subs ) const
386{
[51]387 //オブジェクトのメンバ関数の場合
388 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
389 for( int i=(int)methods.size()-1; i>=0; i-- ){
[50]390 char *temp;
[51]391 temp=methods[i]->psi->name;
[50]392 if(temp[0]==1&&temp[1]==ESC_OPERATOR){
393 if((BYTE)temp[2]==idOperatorCalc){
[51]394 subs.push_back( methods[i]->psi );
[50]395 }
396 }
397 }
398}
399
[51]400//デフォルト コンストラクタ メソッドを取得
401CMethod *CClass::GetConstructorMethod() const
402{
403 if( ConstructorMemberSubIndex == -1 ) return NULL;
404 return methods[ConstructorMemberSubIndex];
405}
[50]406
[51]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
[4]422LONG_PTR CClass::AddVtblDataTable(SUBINFO **ppsi,int length){
423 return AddDataTable((char *)ppsi,length);
424}
[51]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}
[4]434LONG_PTR CClass::GetVtblGlobalOffset(void){
[28]435
436 //既に存在する場合はそれを返す
[4]437 if(vtbl_offset!=-1) return vtbl_offset;
438
[28]439
440 //////////////////////////////////////
441 // 存在しないときは新たに生成する
442 //////////////////////////////////////
443
[4]444 SUBINFO **ppsi;
445 ppsi=(SUBINFO **)HeapAlloc(hHeap,0,vtbl_num*sizeof(SUBINFO *));
446
447 //関数テーブルに値をセット
[51]448 int i2 = 0;
449 foreach( CMethod *method, methods ){
450 if(method->bVirtual){
451 method->psi->bUse=1;
[4]452
[51]453 if(method->bAbstract){
[28]454 extern int cp;
455 SetError(300,NULL,cp);
[4]456
[28]457 ppsi[i2]=0;
[4]458 }
[51]459 else ppsi[i2]=method->psi;
[28]460 i2++;
[4]461 }
462 }
463
464 vtbl_offset=AddDataTable((char *)ppsi,vtbl_num*sizeof(LONG_PTR));
465
[28]466 for( int i=0; i < vtbl_num; i++ ){
[4]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}
[28]489bool CClass::IsAbstract(){
[51]490 //未実装の仮想関数を持つ場合はtrueを返す
[4]491
[51]492 foreach( CMethod *method, methods ){
493 if(method->bVirtual){
494 if(method->bAbstract){
[28]495 return true;
[4]496 }
497 }
498 }
499
500 //コンポジションの関係にあるメンバも検査する
[28]501 for(int i=0;i < iMemberNum;i++){
[40]502 if(ppobj_Member[i]->TypeInfo.type==DEF_OBJECT && ppobj_Member[i]->IsRef() == false){
[28]503 if(ppobj_Member[i]->TypeInfo.u.pobj_Class->IsAbstract())
504 return true;
[4]505 }
506 }
507
[28]508 return false;
[4]509}
510
[17]511// コンストラクタのコンパイルを開始
512void CClass::NotifyStartConstructorCompile(){
513 isCompilingConstructor = true;
514}
[4]515
[17]516//コンストラクタのコンパイルを終了
517void CClass::NotifyFinishConstructorCompile(){
518 isCompilingConstructor = false;
519}
520
521//コンストラクタをコンパイル中かどうかを判別
522bool CClass::IsCompilingConstructor(){
523 return isCompilingConstructor;
524}
525
[18]526//デストラクタのコンパイルを開始
527void CClass::NotifyStartDestructorCompile(){
528 isCompilingDestructor = true;
529}
[17]530
[18]531//デストラクタのコンパイルを終了
532void CClass::NotifyFinishDestructorCompile(){
533 isCompilingDestructor = false;
534}
535
536//デストラクタをコンパイル中かどうかを判別
537bool CClass::IsCompilingDestructor(){
538 return isCompilingDestructor;
539}
540
541
[28]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
[46]560int CDBClass::hash(const char *name){
[4]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
[46]606CClass *CDBClass::check(const char *name){
[4]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
[46]626CClass *CDBClass::AddClass(const char *name,int NowLine){
[4]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 //アラインメント修飾子
[5]687 if(_memicmp(basbuf+i,"Align(",6)==0){
[4]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
[18]709void CDBClass::AddMethod(CClass *pobj_c, DWORD dwAccess, BOOL bStatic, bool isConst, BOOL bAbstract,
710 BOOL bVirtual, BOOL bOverride, char *buffer, int NowLine){
[4]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 ////////////////////////////////////////////////////////////
[18]731 // コンストラクタ、デストラクタの場合の処理
[4]732 ////////////////////////////////////////////////////////////
733 BOOL fConstructor=0,bDestructor=0;
734
735 if(lstrcmp(temporary,pobj_c->name)==0){
[18]736 //コンストラクタの場合
737
738 //標準コンストラクタ(引数なし)
[31]739 if(psi->ParmNum==0) fConstructor=1;
[18]740
741 //コピーコンストラクタ
[31]742 if(psi->ParmNum==1){
[4]743 if(psi->pParmInfo[1].type==DEF_OBJECT&&
744 psi->pParmInfo[1].u.pobj_c==pobj_c) fConstructor=2;
745 }
[18]746
747 //強制的にConst修飾子をつける
748 isConst = true;
[4]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){
[18]758 // コンストラクタ、デストラクタのアクセシビリティをチェック
[4]759 if(dwAccess!=ACCESS_PUBLIC){
760 SetError(116,NULL,NowLine);
761 dwAccess=ACCESS_PUBLIC;
762 }
[18]763
764 //強制的にConst修飾子をつける
765 isConst = true;
[4]766 }
767
[18]768 if( fConstructor == 1 )
[51]769 pobj_c->ConstructorMemberSubIndex = (int)pobj_c->methods.size();
[18]770 else if( fConstructor == 2 )
[51]771 pobj_c->CopyConstructorMemberSubIndex = (int)pobj_c->methods.size();
[18]772 else if( bDestructor )
[51]773 pobj_c->DestructorMemberSubIndex = (int)pobj_c->methods.size();
[4]774
775
776
777 //////////////////
778 // 重複チェック
779 //////////////////
780
781 if(pobj_c->DupliCheckMember(temporary)){
782 SetError(15,temporary,NowLine);
783 return;
784 }
785
[51]786 //メソッド
787 foreach( CMethod *method, pobj_c->methods ){
[27]788 //基底クラスと重複する場合はオーバーライドを行う
[51]789 if(method->pobj_InheritsClass) continue;
[4]790
[51]791 if(lstrcmp(temporary,method->psi->name)==0){
[4]792 if(CompareParameter(
[51]793 method->psi->pParmInfo,method->psi->ParmNum,
[4]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
[51]806 //メソッドのオーバーライド
807 foreach( CMethod *method, pobj_c->methods ){
808 if(lstrcmp(temporary,method->psi->name)==0){
[4]809 if(CompareParameter(
[51]810 method->psi->pParmInfo,method->psi->ParmNum,
[4]811 psi->pParmInfo,psi->ParmNum
812 )==0){
813
[51]814 if(method->psi->bVirtual){
[4]815 //メンバ関数を上書き
[51]816 method->psi=psi;
817 method->bAbstract=0;
[4]818
819 if(!bOverride){
820 SetError(127,NULL,NowLine);
821 }
[51]822 if(method->dwAccess!=dwAccess){
[4]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{
[18]843 pobj_c->AddMethod(psi, dwAccess, isConst, bAbstract, bVirtual);
[4]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++){
[40]850 CMember *pMember = pobj_c->ppobj_Member[i];
851 if(pMember->TypeInfo.type==DEF_OBJECT && pMember->IsRef()==false ){
[4]852 //循環参照でないかをチェック
[40]853 if(pobj_LoopRefCheck->check(pMember->TypeInfo.u.pobj_Class->name)){
[4]854 extern int cp;
[40]855 SetError(124,pMember->TypeInfo.u.pobj_Class->name,cp);
[4]856 return 0;
857 }
858
859 pobj_LoopRefCheck->add(pobj_c->name);
860
[40]861 i2=MemberVar_LoopRefCheck(pMember->TypeInfo.u.pobj_Class);
[4]862 if(bRet==1) bRet=i2;
863
864 pobj_LoopRefCheck->del(pobj_c->name);
865 }
866 }
867
868 return bRet;
869}
870
[46]871void CDBClass::GetClass_recur(const char *lpszInheritsClass){
[4]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 //インターフェイス名を取得
[17]893 GetIdentifierToken( temporary, basbuf, i );
[4]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 //継承元クラスを取得
[29]936 CClass *pInheritsClass = check(temporary);
937 if( !pInheritsClass ){
[4]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
[29]948 if( pInheritsClass->ppobj_Member == 0 ){
[4]949 //継承先が読み取られていないとき
950 pobj_LoopRefCheck->add(pobj_c->name);
951 GetClass_recur(temporary);
952 pobj_LoopRefCheck->del(pobj_c->name);
953 }
954
[29]955 //継承させる
956 pobj_c->Inherits( pInheritsClass );
[4]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 //メンバ関数を追加
[18]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 );
[4]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;
[5]1038 if(_memicmp(basbuf+i,"Align(",6)==0){
[4]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 //クラス名を取得
[17]1049 GetIdentifierToken( temporary, basbuf, i );
[4]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
[29]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];
[4]1098 }
1099
[29]1100 if(lstrcmpi(temporary,pobj_c->name)==0){
1101 SetError(105,temporary,i);
1102 goto InheritsError;
1103 }
[4]1104 }
[29]1105 else{
1106 //Objectを継承する
1107 lstrcpy( temporary, "Object" );
1108 }
[4]1109
1110 //継承元クラスを取得
[29]1111 CClass *pInheritsClass = check(temporary);
1112 if( !pInheritsClass ){
[4]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
[29]1123 if( pInheritsClass->ppobj_Member == 0 ){
[4]1124 //継承先が読み取られていないとき
1125 pobj_LoopRefCheck->add(pobj_c->name);
1126 GetClass_recur(temporary);
1127 pobj_LoopRefCheck->del(pobj_c->name);
1128 }
1129
[29]1130 //継承させる
1131 pobj_c->Inherits( pInheritsClass );
[4]1132 }
1133InheritsError:
1134
[18]1135 //メンバとメソッドを取得
[4]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
[17]1159 //Const修飾子
1160 bool isConst = false;
1161 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1162 isConst = true;
1163 i += 2;
1164 }
1165
[40]1166 //Ref修飾子
1167 bool isRef = false;
1168 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_BYREF ){
1169 isRef = true;
1170 i += 2;
1171 }
1172
[4]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; //エラー用
[40]1250 pobj_c->AddStaticMember( dwAccess, isConst, isRef, temporary, i);
[4]1251 }
1252 else{
1253 //メンバを追加
1254 cp=i; //エラー用
[40]1255 pobj_c->AddMember( dwAccess, isConst, isRef, temporary );
[4]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{
[40]1278 // 文法エラーチェック
1279 if( isRef ){
1280 SetError(1,NULL,cp);
1281 }
1282
[4]1283 //メソッドを追加
1284 cp=i; //エラー用
[18]1285 AddMethod(pobj_c,
1286 dwAccess,
1287 bStatic,
1288 isConst,
1289 bAbstract,
1290 bVirtual,
1291 bOverride,
1292 temporary,
1293 sub_address);
[4]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
[18]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}
[4]1357
1358
1359
[18]1360
[4]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.