source: dev/BasicCompiler_Common/Class.cpp@ 63

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

CClass::GetSize、CClass::GetMemberOffsetを追加

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