source: dev/BasicCompiler_Common/Class.cpp@ 64

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

すべてのオブジェクトを参照型に切り替えた。

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