source: dev/BasicCompiler_Common/Class.cpp@ 56

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

・[Unicode]リテラル文字列のスイッチング
・[Unicode]Char型を文字型として扱うようにする
・[Unicode]SByte型を追加する
に対応。

/unicodeコマンドオプションに対応。

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