source: dev/BasicCompiler_Common/Class.cpp@ 71

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

Parameter.cpp→ParamImpl.cpp
CParameter→ParamImpl

Type.cpp、Type.hを用意した。

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