source: dev/BasicCompiler_Common/Class.cpp@ 101

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

名前空間機能をグローバル関数に適用(作業完了)。

File size: 39.2 KB
RevLine 
[4]1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
[5]6#include "../BasicCompiler32/opcode.h"
[4]7#endif
8
9CDBClass *pobj_DBClass;
10
11CClass *pobj_CompilingClass;
12CClass *pobj_StringClass;
13
[18]14CMember *pCompilingMethod;
15
[4]16
17
[75]18CMember::CMember( CClass *pobj_c, DWORD access, bool isConst, bool isRef, char *buffer, int nowLine ){
[4]19 extern int cp;
20
21 //構文を解析
22 char VarName[VN_SIZE];
23 char init_buf[VN_SIZE];
24 char constract_parameter[VN_SIZE];
[75]25 GetDimentionFormat(buffer,VarName,SubScripts,*this,init_buf,constract_parameter);
[4]26
27 //重複チェック
28 if(pobj_c->DupliCheckAll(VarName)){
29 SetError(15,VarName,cp);
30 }
31
32 //メンバ名
33 name=(char *)HeapAlloc(hHeap,0,lstrlen(VarName)+1);
34 lstrcpy(name,VarName);
35
36 //アクセス権
37 dwAccess=access;
38
[17]39 //定数扱いかどうか
40 this->isConst = isConst;
41
[4]42 //初期データ
43 InitBuf=(char *)HeapAlloc(hHeap,0,lstrlen(init_buf)+1);
44 lstrcpy(InitBuf,init_buf);
45
46 //コンストラクタ用のパラメータ
47 ConstractParameter=(char *)HeapAlloc(hHeap,0,lstrlen(constract_parameter)+1);
48 lstrcpy(ConstractParameter,constract_parameter);
49
50 //ソースコードの位置
[75]51 source_code_address=nowLine;
[4]52}
[75]53CMember::CMember(CMember &member):
54 Type( member )
55{
[4]56
57 //name
[75]58 name=(char *)HeapAlloc(hHeap,0,lstrlen(member.name)+1);
59 lstrcpy(name,member.name);
[4]60
[17]61 //定数扱いかどうか
[75]62 isConst = member.isConst;
[17]63
[4]64 //SubScripts
[75]65 memcpy(SubScripts,member.SubScripts,MAX_ARRAYDIM*sizeof(int));
[4]66
67 //ソースコードの位置
[75]68 source_code_address=member.source_code_address;
[4]69}
70CMember::CMember(){
71 memset(this,0,sizeof(CMember));
72}
73CMember::~CMember(){
74 HeapDefaultFree(name);
75 if(InitBuf) HeapDefaultFree(InitBuf);
76 if(ConstractParameter) HeapDefaultFree(ConstractParameter);
77}
78
[17]79bool CMember::IsConst(){
80 return isConst;
81}
82
[4]83void CMember::InitStaticMember(void){
84 //静的メンバをグローバル領域に作成
85
86 //イテレータをリセット
87 extern CDBClass *pobj_DBClass;
88 pobj_DBClass->Iterator_Reset();
89
90 int back_cp=cp;
91
92 while(pobj_DBClass->Iterator_HasNext()){
93 CClass *pobj_c;
94 pobj_c=pobj_DBClass->Iterator_GetNext();
95
[67]96 int i=0;
[53]97 foreach( CMember *member, pobj_c->staticMembers ){
98 char temporary[VN_SIZE];
99 sprintf(temporary,"%s.%s",pobj_c->name,member->name);
[64]100 dim(
[4]101 temporary,
[53]102 member->SubScripts,
[75]103 *member,
[53]104 member->InitBuf,
105 member->ConstractParameter,
[4]106 0);
107
108 //ネイティブコードバッファの再確保
[89]109 ReallocNativeCodeBuffer();
110
[67]111 i++;
[4]112 }
113 }
114
115 cp=back_cp;
116}
117
118
119
[100]120//コピーコンストラクタ
121CMethod::CMethod(CMethod *pMethod)
122 : pUserProc( pMethod->pUserProc )
123 , dwAccess( pMethod->dwAccess )
124 , bAbstract( pMethod->bAbstract )
125 , bVirtual( pMethod->bVirtual )
126 , isConst( pMethod->isConst )
127 , isStatic( pMethod->isStatic )
128{
129}
[4]130
[100]131CMethod::CMethod( UserProc *pUserProc, DWORD dwAccess, BOOL bAbstract, BOOL bVirtual, bool isConst, bool isStatic )
132 : pUserProc( pUserProc )
133 , dwAccess( dwAccess )
134 , bAbstract( bAbstract )
135 , bVirtual( bVirtual )
136 , isConst( isConst )
137 , isStatic( isStatic )
138 , pobj_InheritsClass( NULL )
139{
[4]140}
141CMethod::~CMethod(){
142}
143
144
145
[101]146CClass::CClass( const NamespaceScopes &namespaceScopes, const char *name ):
147 namespaceScopes( namespaceScopes ),
[90]148 ConstructorMemberSubIndex( 0 ),
149 DestructorMemberSubIndex( 0 ),
150 classType( Class ),
[91]151 isUsing( false ),
[90]152 pobj_InheritsClass( NULL ),
153 ppobj_Member( NULL ),
154 iMemberNum( 0 ),
155 vtbl_num( 0 ),
156 iAlign( 0 ),
157 vtbl_offset( -1 ),
158 isCompilingConstructor( false ),
159 isCompilingDestructor( false ),
160 pobj_NextClass( NULL )
161{
[4]162 this->name=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1);
163 lstrcpy(this->name,name);
164}
165CClass::~CClass(){
166 int i;
167
168 //クラス名
169 HeapDefaultFree(name);
170
171 if(ppobj_Member){
172 //メンバ
173 for(i=0;i<iMemberNum;i++){
174 delete ppobj_Member[i];
175 }
176 HeapDefaultFree(ppobj_Member);
177 ppobj_Member=0;
178 }
179
[53]180 //静的メンバ
181 foreach( CMember *member, staticMembers ){
182 delete member;
[4]183 }
184
[51]185 //メソッド
186 foreach( CMethod *method, methods ){
[50]187 delete method;
[4]188 }
[51]189
190 //静的メソッド
191 foreach( CMethod *method, staticMethods ){
192 delete method;
193 }
[4]194}
[64]195
[101]196bool CClass::IsEqualSymbol() const
197{
198 return false;
199}
200
[91]201bool CClass::IsUsing() const
202{
203 return isUsing;
204}
205void CClass::Using(){
206 isUsing = true;
207}
208
[90]209bool CClass::IsClass() const
210{
211 return classType == CClass::Class;
212}
213bool CClass::IsInterface() const
214{
215 return classType == CClass::Interface;
216}
217bool CClass::IsEnum() const
218{
219 return classType == CClass::Enum;
220}
221bool CClass::IsDelegate() const
222{
223 return classType == CClass::Delegate;
224}
[64]225bool CClass::IsStructure() const
226{
227 return classType == CClass::Structure;
228}
229
[90]230bool CClass::Inherits( CClass &inheritsClass, int nowLine ){
[29]231
[90]232 //ループ継承でないかをチェック
233 if(pobj_LoopRefCheck->check(inheritsClass)){
234 SetError(123,inheritsClass.name,nowLine);
235 return false;
236 }
237
238 if( inheritsClass.ppobj_Member == 0 ){
239 //継承先が読み取られていないとき
240 pobj_LoopRefCheck->add(this->name);
241 pobj_DBClass->GetClass_recur(inheritsClass.name);
242 pobj_LoopRefCheck->del(this->name);
243 }
244
[29]245 //メンバをコピー
246 ppobj_Member=(CMember **)HeapReAlloc(
247 hHeap,
248 0,
249 ppobj_Member,
[90]250 ( iMemberNum + inheritsClass.iMemberNum )*sizeof(CMember *));
251 for(int i3=0;i3<inheritsClass.iMemberNum;i3++){
252 ppobj_Member[iMemberNum]=new CMember( *inheritsClass.ppobj_Member[i3] );
[29]253
254 //dwAccess
[90]255 if(inheritsClass.ppobj_Member[i3]->dwAccess==ACCESS_PRIVATE)
256 ppobj_Member[iMemberNum]->dwAccess=ACCESS_NON;
257 else ppobj_Member[iMemberNum]->dwAccess=inheritsClass.ppobj_Member[i3]->dwAccess;
258
259 iMemberNum++;
[29]260 }
261
262 //メソッドをコピー
[90]263 foreach( CMethod *baseMethod, inheritsClass.methods ){
[51]264 CMethod *method = new CMethod( baseMethod );
[29]265
266 //dwAccess
[51]267 if(baseMethod->dwAccess==ACCESS_PRIVATE)
268 method->dwAccess=ACCESS_NON;
269 else method->dwAccess=baseMethod->dwAccess;
[29]270
271 //pobj_Inherits
272 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
[51]273 if(baseMethod->pobj_InheritsClass==0)
[90]274 method->pobj_InheritsClass=&inheritsClass;
[29]275 else
[51]276 method->pobj_InheritsClass=
277 baseMethod->pobj_InheritsClass;
278
279 methods.push_back( method );
[29]280 }
281
282 //仮想関数の数
[90]283 vtbl_num += inheritsClass.vtbl_num;
[29]284
285 //継承先のクラスをメンバとして保持する
[90]286 pobj_InheritsClass = &inheritsClass;
287
288 return true;
[29]289}
[90]290bool CClass::InheritsInterface( CClass &inheritsInterface, int nowLine ){
291
292 //ループ継承でないかをチェック
293 if(pobj_LoopRefCheck->check(inheritsInterface)){
294 SetError(123,inheritsInterface.name,nowLine);
295 return false;
296 }
297
298 if( inheritsInterface.ppobj_Member == 0 ){
299 //継承先が読み取られていないとき
300 pobj_LoopRefCheck->add(this->name);
301 pobj_DBClass->GetClass_recur(inheritsInterface.name);
302 pobj_LoopRefCheck->del(this->name);
303 }
304
305 //メソッドをコピー
306 foreach( CMethod *baseMethod, inheritsInterface.methods ){
307 CMethod *method = new CMethod( baseMethod );
308
309 //dwAccess
310 if(baseMethod->dwAccess==ACCESS_PRIVATE)
311 method->dwAccess=ACCESS_NON;
312 else method->dwAccess=baseMethod->dwAccess;
313
314 //pobj_Inherits
315 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
316 if(baseMethod->pobj_InheritsClass==0)
317 method->pobj_InheritsClass=&inheritsInterface;
318 else
319 method->pobj_InheritsClass=
320 baseMethod->pobj_InheritsClass;
321
322 methods.push_back( method );
323 }
324
325 //仮想関数の数
326 vtbl_num += inheritsInterface.vtbl_num;
327
328 /*
329 TODO: インターフェイス向けの機構を作る
330 //継承先のクラスをメンバとして保持する
331 pobj_InheritsClass = &inheritsInterface;
332 */
333
334 return true;
335}
[40]336void CClass::AddMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer ){
[17]337 ppobj_Member = (CMember **)HeapReAlloc( hHeap, 0, ppobj_Member, ( iMemberNum + 1 ) * sizeof(CMember *) );
[40]338 ppobj_Member[iMemberNum] = new CMember( this, dwAccess, isConst, isRef, buffer );
[4]339 iMemberNum++;
340}
[75]341void CClass::AddStaticMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer, int nowLine ){
342 CMember *member = new CMember( this, dwAccess, isConst, isRef, buffer, nowLine );
[53]343 staticMembers.push_back( member );
[4]344}
[75]345void CClass::AddMethod( UserProc *pUserProc,DWORD dwAccess, bool isConst, BOOL bAbstract, BOOL bVirtual ){
[100]346 CMethod *method = new CMethod( pUserProc, dwAccess, bAbstract, bVirtual, isConst, false );
[4]347
[51]348 methods.push_back( method );
[75]349
350 // プロシージャオブジェクトと関連付け
351 pUserProc->SetMethod( method );
[4]352}
[75]353void CClass::AddStaticMethod(UserProc *pUserProc,DWORD dwAccess){
[100]354 CMethod *method = new CMethod( pUserProc, dwAccess, FALSE, FALSE, false, true );
[4]355
[51]356 staticMethods.push_back( method );
[75]357
358 // プロシージャオブジェクトと関連付け
359 pUserProc->SetMethod( method );
[4]360}
[46]361BOOL CClass::DupliCheckAll(const char *name){
[4]362 //重複チェック
363
364 //メンバ
365 if(DupliCheckMember(name)) return 1;
366
367 //メソッド
[51]368 foreach( CMethod *method, methods ){
[75]369 if( lstrcmp( name, method->pUserProc->GetName().c_str() ) == 0 ){
[4]370 return 1;
371 }
372 }
373
374 return 0;
375}
[46]376BOOL CClass::DupliCheckMember(const char *name){
[4]377 //重複チェック
378
379 //メンバ
[53]380 for( int i=0;i<iMemberNum;i++){
[4]381 if(lstrcmp(name,ppobj_Member[i]->name)==0){
382 return 1;
383 }
384 }
385
386 //静的メンバ
[53]387 foreach( CMember *member, staticMembers ){
388 if( lstrcmp( name, member->name ) == 0 ){
[4]389 return 1;
390 }
391 }
392
393 return 0;
394}
[75]395CMethod *CClass::GetMethodInfo( UserProc *pUserProc ) const
396{
[51]397 for( int i=(int)methods.size()-1; i>=0; i-- ){
[89]398 if( pUserProc == methods[i]->pUserProc ){
399 return methods[i];
400 }
[18]401 }
[50]402 return NULL;
[18]403}
[75]404CMethod *CClass::GetStaticMethodInfo( UserProc *pUserProc ) const
405{
[51]406 for( int i=(int)staticMethods.size()-1; i>=0; i-- ){
[75]407 if( pUserProc == staticMethods[i]->pUserProc ) return staticMethods[i];
[18]408 }
[50]409 return NULL;
[18]410}
[75]411bool CClass::IsExistMethod( const char *name ) const
412{
[51]413 foreach( CMethod *method, methods ){
[75]414 if( method->pUserProc->GetName() == name ) return true;
[27]415 }
416 return false;
417}
[75]418bool CClass::IsExistStaticMethod( const char *name ) const
419{
[51]420 foreach( CMethod *method, staticMethods ){
[75]421 if( method->pUserProc->GetName() == name ) return true;
[27]422 }
423 return false;
424}
[4]425
[100]426void CClass::EnumStaticMethod( const char *methodName, vector<UserProc *> &subs ) const
[50]427{
[51]428 foreach( CMethod *method, staticMethods ){
[75]429 if( method->pUserProc->GetName() == methodName ){
430 subs.push_back( method->pUserProc );
[50]431 }
432 }
433}
[27]434
[100]435void CClass::EnumMethod( const char *methodName, vector<UserProc *> &subs ) const
[50]436{
437 //オブジェクトのメンバ関数の場合
438 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
[51]439 for( int i=(int)methods.size()-1; i>=0; i-- ){
[75]440 if( methods[i]->pUserProc->GetName() == methodName ){
441 subs.push_back( methods[i]->pUserProc );
[50]442 }
443 }
444}
445
[100]446void CClass::EnumMethod( const BYTE idOperatorCalc, vector<UserProc *> &subs ) const
[50]447{
[51]448 //オブジェクトのメンバ関数の場合
449 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
450 for( int i=(int)methods.size()-1; i>=0; i-- ){
[75]451 UserProc *pUserProc = methods[i]->pUserProc;
452 const char *temp = pUserProc->GetName().c_str();
[50]453 if(temp[0]==1&&temp[1]==ESC_OPERATOR){
454 if((BYTE)temp[2]==idOperatorCalc){
[75]455 subs.push_back( pUserProc );
[50]456 }
457 }
458 }
459}
460
[51]461//デフォルト コンストラクタ メソッドを取得
462CMethod *CClass::GetConstructorMethod() const
463{
464 if( ConstructorMemberSubIndex == -1 ) return NULL;
465 return methods[ConstructorMemberSubIndex];
466}
[50]467
[51]468//デストラクタ メソッドを取得
469CMethod *CClass::GetDestructorMethod() const
470{
471 if( DestructorMemberSubIndex == -1 ) return NULL;
472 return methods[DestructorMemberSubIndex];
473}
474
[63]475//サイズを取得
476int CClass::GetSize() const
477{
478 return GetMemberOffset( NULL, NULL );
479}
[51]480
[63]481//メンバのオフセットを取得
482int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
483{
484 int i,i2,offset;
485
486 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
487 if(vtbl_num) offset=PTR_SIZE;
488 else offset=0;
489
490 int alignment;
491 if(iAlign) alignment=iAlign;
492 else alignment=1;
493
494 int iMaxAlign=0;
495 for(i=0;i<iMemberNum;i++){
496 CMember *pMember = ppobj_Member[i];
497
498 i2 = pMember->GetSize();
499
500 //アラインメントを算出
501 int member_size;
[75]502 if( pMember->IsStruct() ){
[63]503 //メンバクラスのアラインメントを取得
[75]504 member_size=pMember->GetClass().GetAlignment();
[63]505 }
506 else{
507 //メンバサイズを取得
508 member_size=i2;
509 }
510 if(iMaxAlign<member_size) iMaxAlign=member_size;
511
512 //アラインメントを考慮
513 if(iAlign&&iAlign<member_size){
514 if(offset%alignment) offset+=alignment-(offset%alignment);
515 }
516 else{
517 if(alignment<member_size) alignment=member_size;
518
519 if(member_size==0){
520 //メンバを持たないクラス
521 //※何もしない(オフセットの計算をしない)
522 }
523 else{
524 if(offset%member_size) offset+=member_size-(offset%member_size);
525 }
526 }
527
528 if(memberName){
529 //メンバ指定がある場合は、オフセットを返す
530 if(lstrcmp(pMember->name,memberName)==0){
531 if(pMemberNum) *pMemberNum=i;
532 return offset;
533 }
534 }
535
536 //配列を考慮したメンバサイズを取得
537 member_size=i2 * JumpSubScripts(pMember->SubScripts);
538
539 //メンバサイズを加算
540 offset+= member_size;
541 }
542
543 if(iMaxAlign<alignment) alignment=iMaxAlign;
544
545 //アラインメントを考慮
546 if(alignment){
547 if(offset%alignment) offset+=alignment-(offset%alignment);
548 }
549
550 if(pMemberNum) *pMemberNum=i;
551 return offset;
552}
553
554int CClass::GetAlignment() const
555{
556 int i;
557 int alignment,member_size;
558
559 if(vtbl_num) alignment=PTR_SIZE;
560 else alignment=0;
561
562 for(i=0;i<iMemberNum;i++){
563 CMember *pMember = ppobj_Member[i];
564
[75]565 if(pMember->IsStruct()){
[63]566 //メンバクラスのアラインメントを取得
[75]567 member_size=pMember->GetClass().GetAlignment();
[63]568 }
569 else{
570 //メンバサイズを取得
571 member_size = pMember->GetSize();
572 }
573
574 //アラインメントをセット
575 if(alignment<member_size) alignment=member_size;
576 }
577
578 if(alignment==0) return 0;
579
580 if(iAlign) alignment=iAlign;
581
582 return alignment;
583}
584
585
586
[75]587int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
[51]588{
589 int n = 0;
590 foreach( CMethod *method, methods ){
[75]591 if( method->pUserProc == pUserProc ) break;
592 if( method->bVirtual ) n++;
[51]593 }
594 return n;
595}
[4]596LONG_PTR CClass::GetVtblGlobalOffset(void){
[28]597
598 //既に存在する場合はそれを返す
[4]599 if(vtbl_offset!=-1) return vtbl_offset;
600
[28]601
[92]602
[28]603 //////////////////////////////////////
604 // 存在しないときは新たに生成する
605 //////////////////////////////////////
606
[75]607 UserProc **ppsi;
[100]608 ppsi=(UserProc **)HeapAlloc(hHeap,0,vtbl_num*sizeof(GlobalProc *));
[4]609
610 //関数テーブルに値をセット
[51]611 int i2 = 0;
612 foreach( CMethod *method, methods ){
613 if(method->bVirtual){
[75]614 method->pUserProc->Using();
[4]615
[51]616 if(method->bAbstract){
[28]617 extern int cp;
618 SetError(300,NULL,cp);
[4]619
[28]620 ppsi[i2]=0;
[4]621 }
[92]622 else{
623 ppsi[i2]=method->pUserProc;
624 }
[28]625 i2++;
[4]626 }
627 }
628
[56]629 vtbl_offset=dataTable.AddBinary((void *)ppsi,vtbl_num*sizeof(LONG_PTR));
[4]630
[28]631 for( int i=0; i < vtbl_num; i++ ){
[4]632 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
633 }
634
635 HeapDefaultFree(ppsi);
636
637 return vtbl_offset;
638}
639void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
640 if(vtbl_offset==-1) return;
641
642 LONG_PTR *pVtbl;
[56]643 pVtbl=(LONG_PTR *)((char *)dataTable.GetPtr()+vtbl_offset);
[4]644
645 int i;
646 for(i=0;i<vtbl_num;i++){
[100]647 GlobalProc *pUserProc;
648 pUserProc=(GlobalProc *)pVtbl[i];
[75]649 if(!pUserProc) continue;
650 pVtbl[i]=pUserProc->beginOpAddress+ImageBase+MemPos_CodeSection;
[4]651 }
652}
[75]653bool CClass::IsAbstract() const
654{
[96]655 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
[4]656
[51]657 foreach( CMethod *method, methods ){
658 if(method->bVirtual){
659 if(method->bAbstract){
[28]660 return true;
[4]661 }
662 }
663 }
664
[28]665 return false;
[4]666}
667
[17]668// コンストラクタのコンパイルを開始
669void CClass::NotifyStartConstructorCompile(){
670 isCompilingConstructor = true;
671}
[4]672
[17]673//コンストラクタのコンパイルを終了
674void CClass::NotifyFinishConstructorCompile(){
675 isCompilingConstructor = false;
676}
677
678//コンストラクタをコンパイル中かどうかを判別
[75]679bool CClass::IsCompilingConstructor() const
680{
[17]681 return isCompilingConstructor;
682}
683
[18]684//デストラクタのコンパイルを開始
685void CClass::NotifyStartDestructorCompile(){
686 isCompilingDestructor = true;
687}
[17]688
[18]689//デストラクタのコンパイルを終了
690void CClass::NotifyFinishDestructorCompile(){
691 isCompilingDestructor = false;
692}
693
694//デストラクタをコンパイル中かどうかを判別
[75]695bool CClass::IsCompilingDestructor() const
696{
[18]697 return isCompilingDestructor;
698}
699
700
[28]701//自身と等しいクラスかどうかを確認
[75]702bool CClass::IsEquals( const CClass *pClass ) const
703{
[28]704 if( this == pClass ) return true;
705 return false;
706}
707
708//自身の派生クラスかどうかを確認
[75]709bool CClass::IsSubClass( const CClass *pClass ) const
710{
[28]711 pClass = pClass->pobj_InheritsClass;
712 while( pClass ){
713 if( this == pClass ) return true;
714 pClass = pClass->pobj_InheritsClass;
715 }
716 return false;
717}
718
[59]719//自身と等しいまたは派生クラスかどうかを確認
[75]720bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
721{
[59]722 if( IsEquals( pClass ) ) return true;
723 return IsSubClass( pClass );
724}
[28]725
[94]726// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
727bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
728{
729 if( IsEquals( &objClass ) ) return true;
730 if( IsSubClass( &objClass ) ) return true;
731 if( objClass.IsSubClass( this ) ) return true;
732 return false;
733}
[28]734
[59]735
[94]736
[46]737int CDBClass::hash(const char *name){
[4]738 int key;
739
740 for(key=0;*name!='\0';name++){
741 key=((key<<8)+ *name )%MAX_CLASS_HASH;
742 }
743
744 return key;
745}
746
747void CDBClass::DestroyClass(CClass *pobj_c){
748 if(pobj_c->pobj_NextClass){
749 DestroyClass(pobj_c->pobj_NextClass);
750 }
751
752 delete pobj_c;
753}
754
[67]755CDBClass::CDBClass():
756 pStringClass( NULL ),
757 pObjectClass( NULL ),
758 pCompilingClass( NULL ),
759 pCompilingMethod( NULL ),
760 ppobj_IteClass( NULL ),
761 iIteMaxNum( 0 ),
762 iIteNextNum( 0 )
763{
764 memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) );
[4]765}
766CDBClass::~CDBClass(){
767 int i;
768 for(i=0;i<MAX_CLASS_HASH;i++){
769 if(pobj_ClassHash[i]) DestroyClass(pobj_ClassHash[i]);
770 }
771
772 if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass);
773}
774
775void CDBClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
776 int i;
777 for(i=0;i<MAX_CLASS_HASH;i++){
778 if(pobj_ClassHash[i]){
779 CClass *pobj_c;
780 pobj_c=pobj_ClassHash[i];
781 while(1){
782 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
783
784 if(pobj_c->pobj_NextClass==0) break;
785 pobj_c=pobj_c->pobj_NextClass;
786 }
787 }
788 }
789}
790
[46]791CClass *CDBClass::check(const char *name){
[4]792 int key;
793 key=hash(name);
794
795 if(pobj_ClassHash[key]){
796 CClass *pobj_c;
797 pobj_c=pobj_ClassHash[key];
798 while(1){
799 if(lstrcmp(name,pobj_c->name)==0){
800 //重複した場合
801 return pobj_c;
802 }
803
804 if(pobj_c->pobj_NextClass==0) break;
805 pobj_c=pobj_c->pobj_NextClass;
806 }
807 }
[100]808 return NULL;
[4]809}
810
[101]811CClass *CDBClass::AddClass( const NamespaceScopes &namespaceScopes, const char *name,int nowLine){
[4]812 //////////////////////////////////////////////////////////////////////////
813 // クラスを追加
814 // ※名前のみを登録。その他の情報はSetClassメソッドで!
815 //////////////////////////////////////////////////////////////////////////
816
817 CClass *pobj_c;
[101]818 pobj_c=new CClass(namespaceScopes, name);
[4]819
820 if(lstrcmp(name,"String")==0){
821 //Stringクラス
822 pobj_StringClass=pobj_c;
823 }
[67]824 if( lstrcmp( name, "Object" ) == 0 ){
825 pObjectClass = pobj_c;
826 }
[4]827
828
829 /////////////////////////////////
830 // ハッシュデータに追加
831 /////////////////////////////////
832
833 int key;
834 key=hash(name);
835
836 if(pobj_ClassHash[key]){
837 CClass *pobj_c2;
838 pobj_c2=pobj_ClassHash[key];
839 while(1){
840 if(lstrcmp(name,pobj_c2->name)==0){
841 //重複した場合
[75]842 SetError(15,name,nowLine);
[4]843 return 0;
844 }
845
846 if(pobj_c2->pobj_NextClass==0) break;
847 pobj_c2=pobj_c2->pobj_NextClass;
848 }
849 pobj_c2->pobj_NextClass=pobj_c;
850 }
851 else{
852 pobj_ClassHash[key]=pobj_c;
853 }
854
855 return pobj_c;
856}
857
858void CDBClass::InitNames(void){
859 extern char *basbuf;
[101]860 int i, i2;
861 char temporary[VN_SIZE];
[4]862
[101]863 // 名前空間管理
864 NamespaceScopes &namespaceScopes = Smoothie::Lexical::liveingNamespaceScopes;
865 namespaceScopes.clear();
866
[4]867 for(i=0;;i++){
868 if(basbuf[i]=='\0') break;
869
[101]870 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
871 for(i+=2,i2=0;;i2++,i++){
872 if( IsCommandDelimitation( basbuf[i] ) ){
873 temporary[i2]=0;
874 break;
875 }
876 temporary[i2]=basbuf[i];
877 }
878 namespaceScopes.push_back( temporary );
879
880 continue;
881 }
882 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
883 if( namespaceScopes.size() <= 0 ){
884 SetError(12, "End Namespace", i );
885 }
886 else{
887 namespaceScopes.pop_back();
888 }
889
890 i += 2;
891 continue;
892 }
893
[4]894 if(basbuf[i]==1&&(
895 basbuf[i+1]==ESC_CLASS||
896 basbuf[i+1]==ESC_TYPE||
897 basbuf[i+1]==ESC_INTERFACE
898 )){
[75]899 int nowLine;
900 nowLine=i;
[4]901
902 i+=2;
903 //アラインメント修飾子
[76]904 if(memicmp(basbuf+i,"Align(",6)==0){
[4]905 i+=6;
906 i=JumpStringInPare(basbuf,i)+1;
907 }
908
[92]909 bool isEnum = false;
910 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
911 // 列挙型の場合
912 isEnum = true;
913
914 i+=2;
915 }
916
[4]917 int i2;
918 char temporary[VN_SIZE];
919 for(i2=0;;i++,i2++){
920 if(!IsVariableChar(basbuf[i])){
921 temporary[i2]=0;
922 break;
923 }
924 temporary[i2]=basbuf[i];
925 }
926
927 //クラスを追加
[101]928 CClass *pClass = pobj_DBClass->AddClass(namespaceScopes, temporary,nowLine);
[64]929 if( pClass ){
[75]930 if( basbuf[nowLine+1] == ESC_CLASS ){
[92]931 if( isEnum ){
932 pClass->classType = CClass::Enum;
933 }
934 else{
935 pClass->classType = CClass::Class;
936 }
[64]937 }
[75]938 else if( basbuf[nowLine+1] == ESC_INTERFACE ){
[64]939 pClass->classType = CClass::Interface;
940 }
941 else{
942 pClass->classType = CClass::Structure;
943 }
944 }
[4]945 }
946 }
947}
948
949
[18]950void CDBClass::AddMethod(CClass *pobj_c, DWORD dwAccess, BOOL bStatic, bool isConst, BOOL bAbstract,
[75]951 BOOL bVirtual, BOOL bOverride, char *buffer, int nowLine){
[4]952 int i,i2;
953 char temporary[VN_SIZE];
954
955 i=2;
956 for(i2=0;;i++,i2++){
957 if(buffer[i]=='('||buffer[i]=='\0'){
958 temporary[i2]=0;
959 break;
960 }
961 temporary[i2]=buffer[i];
962 }
963
964
965 //関数ハッシュへ登録
[100]966 GlobalProc *pUserProc;
967 pUserProc=AddSubData( NamespaceScopes(), buffer,nowLine,bVirtual,pobj_c, (bStatic!=0) );
[75]968 if(!pUserProc) return;
[4]969
970
971 ////////////////////////////////////////////////////////////
[18]972 // コンストラクタ、デストラクタの場合の処理
[4]973 ////////////////////////////////////////////////////////////
974 BOOL fConstructor=0,bDestructor=0;
975
976 if(lstrcmp(temporary,pobj_c->name)==0){
[18]977 //コンストラクタの場合
978
979 //標準コンストラクタ(引数なし)
[75]980 if(pUserProc->Params().size()==0) fConstructor=1;
[18]981
982 //強制的にConst修飾子をつける
983 isConst = true;
[4]984 }
985 else if(temporary[0]=='~'){
986 //デストラクタの場合はその名前が正しいかチェックを行う
987 if(lstrcmp(temporary+1,pobj_c->name)!=0)
[75]988 SetError(117,NULL,nowLine);
[4]989 else
990 bDestructor=1;
991 }
992 if(fConstructor||bDestructor){
[18]993 // コンストラクタ、デストラクタのアクセシビリティをチェック
994
995 //強制的にConst修飾子をつける
996 isConst = true;
[4]997 }
998
[18]999 if( fConstructor == 1 )
[51]1000 pobj_c->ConstructorMemberSubIndex = (int)pobj_c->methods.size();
[18]1001 else if( bDestructor )
[51]1002 pobj_c->DestructorMemberSubIndex = (int)pobj_c->methods.size();
[4]1003
1004
1005
1006 //////////////////
1007 // 重複チェック
1008 //////////////////
1009
1010 if(pobj_c->DupliCheckMember(temporary)){
[75]1011 SetError(15,temporary,nowLine);
[4]1012 return;
1013 }
1014
[51]1015 //メソッド
1016 foreach( CMethod *method, pobj_c->methods ){
[27]1017 //基底クラスと重複する場合はオーバーライドを行う
[51]1018 if(method->pobj_InheritsClass) continue;
[4]1019
[75]1020 if( method->pUserProc->GetName() == temporary ){
1021 if( Parameter::Equals( method->pUserProc->Params(), pUserProc->Params() ) ){
[4]1022 //関数名、パラメータ属性が合致したとき
[75]1023 SetError(15,pUserProc->GetName().c_str(),nowLine);
[4]1024 return;
1025 }
1026 }
1027 }
1028
1029 //仮想関数の場合
[75]1030 if(bAbstract) pUserProc->CompleteCompile();
[4]1031
[51]1032 //メソッドのオーバーライド
1033 foreach( CMethod *method, pobj_c->methods ){
[75]1034 if( method->pUserProc->GetName() == temporary ){
1035 if( Parameter::Equals( method->pUserProc->Params(), pUserProc->Params() ) ){
[4]1036
[75]1037 if(method->bVirtual){
[4]1038 //メンバ関数を上書き
[75]1039 method->pUserProc=pUserProc;
[51]1040 method->bAbstract=0;
[4]1041
1042 if(!bOverride){
[75]1043 SetError(127,NULL,nowLine);
[4]1044 }
[51]1045 if(method->dwAccess!=dwAccess){
[75]1046 SetError(128,NULL,nowLine);
[4]1047 }
[75]1048
1049 pUserProc->SetMethod( method );
[4]1050 return;
1051 }
1052 }
1053 }
1054 }
1055
[75]1056 if(bVirtual){
[4]1057 pobj_c->vtbl_num++;
1058 }
1059
1060 if(bOverride){
[75]1061 SetError(12,"Override",nowLine);
[4]1062 }
1063
1064 if(bStatic){
[75]1065 pobj_c->AddStaticMethod(pUserProc,dwAccess);
[4]1066 }
1067 else{
[75]1068 pobj_c->AddMethod(pUserProc, dwAccess, isConst, bAbstract, bVirtual);
[4]1069 }
1070}
1071
[75]1072BOOL CDBClass::MemberVar_LoopRefCheck(const CClass &objClass){
[4]1073 int i,i2,bRet=1;
[75]1074 for(i=0;i<objClass.iMemberNum;i++){
1075 const CMember *pMember = objClass.ppobj_Member[i];
[85]1076 if(pMember->IsStruct()){
[4]1077 //循環参照でないかをチェック
[90]1078 if(pobj_LoopRefCheck->check(pMember->GetClass())){
[4]1079 extern int cp;
[75]1080 SetError(124,pMember->GetClass().name,cp);
[4]1081 return 0;
1082 }
1083
[75]1084 pobj_LoopRefCheck->add(objClass.name);
[4]1085
[75]1086 i2=MemberVar_LoopRefCheck(pMember->GetClass());
[4]1087 if(bRet==1) bRet=i2;
1088
[75]1089 pobj_LoopRefCheck->del(objClass.name);
[4]1090 }
1091 }
1092
1093 return bRet;
1094}
1095
[46]1096void CDBClass::GetClass_recur(const char *lpszInheritsClass){
[4]1097 extern char *basbuf;
1098 int i,i2,i3,sub_address,top_pos;
1099 DWORD dwAccess;
1100 char temporary[8192];
1101
1102 for(i=0;;i++){
1103 if(basbuf[i]=='\0') break;
1104
1105 CClass *pobj_c;
1106
1107 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1108 //////////////////////////
1109 // インターフェイス
1110 //////////////////////////
1111
1112 top_pos=i;
1113
1114 i+=2;
1115
1116 //インターフェイス名を取得
[17]1117 GetIdentifierToken( temporary, basbuf, i );
[4]1118
1119 pobj_c=pobj_DBClass->check(temporary);
1120 if(!pobj_c) continue;
1121
1122 if(lpszInheritsClass){
1123 if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){
1124 //継承先先読み用
1125 continue;
1126 }
1127 }
1128
1129 if(pobj_c->ppobj_Member){
1130 //既に先読みされているとき
1131 continue;
1132 }
1133
1134 //メンバ用メモリを初期化
1135 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1);
1136 pobj_c->iMemberNum=0;
1137
1138 pobj_c->ConstructorMemberSubIndex=-1;
1139 pobj_c->DestructorMemberSubIndex=-1;
1140
1141 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1142 //継承を行う場合
1143 for(i+=3,i2=0;;i++,i2++){
1144 if(IsCommandDelimitation(basbuf[i])){
1145 temporary[i2]=0;
1146 break;
1147 }
1148 temporary[i2]=basbuf[i];
1149 }
1150
1151 if(lstrcmpi(temporary,pobj_c->name)==0){
1152 SetError(105,temporary,i);
1153 goto Interface_InheritsError;
1154 }
1155
1156 //継承元クラスを取得
[29]1157 CClass *pInheritsClass = check(temporary);
1158 if( !pInheritsClass ){
[4]1159 SetError(106,temporary,i);
1160 goto Interface_InheritsError;
1161 }
1162
[90]1163 //継承させる
1164 if( !pobj_c->InheritsInterface( *pInheritsClass, i ) ){
[4]1165 goto Interface_InheritsError;
1166 }
1167 }
1168 else{
1169 //継承無し
1170 pobj_c->pobj_InheritsClass=0;
1171
1172 //仮想関数の数を初期化
1173 pobj_c->vtbl_num=0;
1174 }
1175Interface_InheritsError:
1176
1177 //メンバ変数、関数を取得
1178 while(1){
1179 i++;
1180
1181 //エラー
1182 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1183 SetError(22,"Interface",i);
1184 i--;
1185 break;
1186 }
1187
1188 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1189 SetError(111,NULL,i);
1190 break;
1191 }
1192
1193 sub_address=i;
1194
1195 for(i2=0;;i++,i2++){
1196 if(IsCommandDelimitation(basbuf[i])){
1197 temporary[i2]=0;
1198 break;
1199 }
1200 temporary[i2]=basbuf[i];
1201 }
1202 if(temporary[0]=='\0'){
1203 if(basbuf[i]=='\0'){
1204 i--;
1205 SetError(22,"Interface",top_pos);
1206 break;
1207 }
1208 continue;
1209 }
1210
1211 //End Interface記述の場合
1212 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1213
1214 if(!(temporary[0]==1&&(
1215 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1216 ))){
1217 SetError(1,NULL,i);
1218 break;
1219 }
1220
1221 //メンバ関数を追加
[18]1222 AddMethod(pobj_c,
1223 ACCESS_PUBLIC, //Publicアクセス権
1224 0, //Static指定なし
1225 false, //Constではない
1226 1, //Abstract
1227 1, //Virtual
1228 0,
1229 temporary,
1230 sub_address
1231 );
[4]1232 }
1233 }
1234
1235 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1236 //////////////////////////
1237 // クラス
1238 //////////////////////////
1239
1240 top_pos=i;
1241
[64]1242 const DWORD dwClassType=basbuf[i+1];
[4]1243
1244 i+=2;
1245
1246 //アラインメント修飾子
1247 int iAlign=0;
[76]1248 if(memicmp(basbuf+i,"Align(",6)==0){
[4]1249 i+=6;
1250 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1251 iAlign=atoi(temporary);
1252
1253 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1254 SetError(51,NULL,i);
1255 }
1256
[92]1257 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
1258 // 列挙型の場合
1259 i+=2;
1260 }
[4]1261
1262 //クラス名を取得
[17]1263 GetIdentifierToken( temporary, basbuf, i );
[4]1264
1265 pobj_c=pobj_DBClass->check(temporary);
1266 if(!pobj_c) continue;
1267
1268 if(lpszInheritsClass){
1269 if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){
1270 //継承先先読み用
1271 continue;
1272 }
1273 }
1274
1275 if(pobj_c->ppobj_Member){
1276 //既に先読みされているとき
1277 continue;
1278 }
1279
1280 pobj_c->iAlign=iAlign;
1281
1282 //メンバ用メモリを初期化
1283 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1);
1284 pobj_c->iMemberNum=0;
1285
1286 pobj_c->ConstructorMemberSubIndex=-1;
1287 pobj_c->DestructorMemberSubIndex=-1;
1288
1289 //アクセス制限の初期値をセット
1290 if(dwClassType==ESC_CLASS) dwAccess=ACCESS_PRIVATE;
1291 else dwAccess=ACCESS_PUBLIC;
1292
[29]1293 if( lstrcmp( pobj_c->name, "Object" ) == 0 || dwClassType == ESC_TYPE ){
1294 //継承無し
1295 pobj_c->pobj_InheritsClass=0;
1296
1297 //仮想関数の数を初期化
1298 pobj_c->vtbl_num=0;
1299 }
1300 else{
1301 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1302 //継承を行う場合
1303 for(i+=3,i2=0;;i++,i2++){
1304 if(IsCommandDelimitation(basbuf[i])){
1305 temporary[i2]=0;
1306 break;
1307 }
1308 temporary[i2]=basbuf[i];
[4]1309 }
1310
[29]1311 if(lstrcmpi(temporary,pobj_c->name)==0){
1312 SetError(105,temporary,i);
1313 goto InheritsError;
1314 }
[4]1315 }
[29]1316 else{
1317 //Objectを継承する
1318 lstrcpy( temporary, "Object" );
1319 }
[4]1320
1321 //継承元クラスを取得
[29]1322 CClass *pInheritsClass = check(temporary);
1323 if( !pInheritsClass ){
[4]1324 SetError(106,temporary,i);
1325 goto InheritsError;
1326 }
1327
[90]1328 if( pInheritsClass->IsInterface() ){
1329 // クラスを継承していないとき
1330 CClass *pObjectClass = check("Object");
1331 if( !pObjectClass ){
1332 SetError(106,"Object",i);
1333 goto InheritsError;
1334 }
[4]1335
[90]1336 if( !pobj_c->Inherits( *pObjectClass, i ) ){
1337 goto InheritsError;
1338 }
[4]1339 }
1340
[29]1341 //継承させる
[90]1342 if( !pobj_c->Inherits( *pInheritsClass, i ) ){
1343 goto InheritsError;
1344 }
[4]1345 }
1346InheritsError:
1347
[18]1348 //メンバとメソッドを取得
[4]1349 while(1){
1350 i++;
1351
1352 //エラー
1353 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1354 SetError(22,"Class",i);
1355 i--;
1356 break;
1357 }
1358
1359 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1360 SetError(111,NULL,i);
1361 break;
1362 }
1363
1364 //Static修飾子
1365 BOOL bStatic;
1366 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1367 bStatic=1;
1368 i+=2;
1369 }
1370 else bStatic=0;
1371
[17]1372 //Const修飾子
1373 bool isConst = false;
1374 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1375 isConst = true;
1376 i += 2;
1377 }
[64]1378/*
[40]1379 //Ref修飾子
1380 bool isRef = false;
1381 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_BYREF ){
1382 isRef = true;
1383 i += 2;
[64]1384 }*/
[40]1385
[4]1386 if(basbuf[i]==1&&(
1387 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1388 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1389 )){
1390 i3=basbuf[i+1];
1391 sub_address=i;
1392 }
1393 else i3=0;
1394
1395 BOOL bVirtual=0,bAbstract=0,bOverride=0;
1396 if(i3==ESC_ABSTRACT){
1397 bAbstract=1;
1398 bVirtual=1;
1399 i+=2;
1400
1401 i3=basbuf[i+1];
1402 }
1403 else if(i3==ESC_VIRTUAL){
1404 bAbstract=0;
1405 bVirtual=1;
1406 i+=2;
1407
1408 i3=basbuf[i+1];
1409 }
1410 else if(i3==ESC_OVERRIDE){
1411 bOverride=1;
1412 bVirtual=1;
1413
1414 i+=2;
1415
1416 i3=basbuf[i+1];
1417 }
1418
1419 for(i2=0;;i++,i2++){
1420 if(IsCommandDelimitation(basbuf[i])){
1421 temporary[i2]=0;
1422 break;
1423 }
1424 temporary[i2]=basbuf[i];
1425 }
1426 if(temporary[0]=='\0'){
1427 if(basbuf[i]=='\0'){
1428
1429 if(dwClassType==ESC_CLASS)
1430 SetError(22,"Class",top_pos);
1431 else
1432 SetError(22,"Type",top_pos);
1433
1434 i--;
1435 break;
1436 }
1437 continue;
1438 }
1439
1440 //End Class記述の場合
1441 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1442 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1443
1444 //アクセスを変更
1445 if(lstrcmpi(temporary,"Private")==0){
1446 dwAccess=ACCESS_PRIVATE;
1447 continue;
1448 }
1449 if(lstrcmpi(temporary,"Public")==0){
1450 dwAccess=ACCESS_PUBLIC;
1451 continue;
1452 }
1453 if(lstrcmpi(temporary,"Protected")==0){
1454 dwAccess=ACCESS_PROTECTED;
1455 continue;
1456 }
1457
1458 extern int cp;
1459 if(i3==0){
1460 if(bStatic){
1461 //静的メンバを追加
1462 cp=i; //エラー用
[64]1463 pobj_c->AddStaticMember( dwAccess, isConst, false, temporary, i);
[4]1464 }
1465 else{
1466 //メンバを追加
1467 cp=i; //エラー用
[64]1468 pobj_c->AddMember( dwAccess, isConst, false, temporary );
[4]1469
1470
[89]1471 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->IsStruct()){
[75]1472 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass().ppobj_Member==0){
[4]1473 //参照先が読み取られていないとき
[75]1474 GetClass_recur(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass().name);
[4]1475 }
1476 }
1477
1478
[89]1479 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->IsStruct()){
[4]1480 //循環参照のチェック
1481 pobj_LoopRefCheck->add(pobj_c->name);
[75]1482 if(!MemberVar_LoopRefCheck(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass())){
[4]1483 //エラー回避
[75]1484 pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->SetBasicType( DEF_PTR_VOID );
[4]1485 }
1486 pobj_LoopRefCheck->del(pobj_c->name);
1487 }
1488 }
1489 }
1490 else{
1491 //メソッドを追加
1492 cp=i; //エラー用
[18]1493 AddMethod(pobj_c,
1494 dwAccess,
1495 bStatic,
1496 isConst,
1497 bAbstract,
1498 bVirtual,
1499 bOverride,
1500 temporary,
1501 sub_address);
[4]1502
1503 if(bAbstract) continue;
1504
1505 for(;;i++){
1506 if(basbuf[i]=='\0'){
1507 i--;
1508 break;
1509 }
1510 if(basbuf[i-1]!='*'&&
1511 basbuf[i]==1&&(
1512 basbuf[i+1]==ESC_SUB||
1513 basbuf[i+1]==ESC_FUNCTION||
1514 basbuf[i+1]==ESC_MACRO||
1515 basbuf[i+1]==ESC_TYPE||
1516 basbuf[i+1]==ESC_CLASS||
1517 basbuf[i+1]==ESC_INTERFACE||
1518 basbuf[i+1]==ESC_ENUM)){
1519 GetDefaultNameFromES(i3,temporary);
1520 SetError(22,temporary,i);
1521 }
1522 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1523 i+=2;
1524 break;
1525 }
1526 }
1527 }
1528 }
1529 }
1530 }
1531}
1532
[67]1533void CDBClass::GetAllClassInfo(void){
[4]1534 //ループ継承チェック用のクラス
1535 pobj_LoopRefCheck=new CLoopRefCheck();
1536
1537 //クラスを取得
1538 GetClass_recur(0);
1539
1540 delete pobj_LoopRefCheck;
1541 pobj_LoopRefCheck=0;
[89]1542
1543 // イテレータ用のデータを作る
1544 pobj_DBClass->Iterator_Init();
[4]1545}
1546
[89]1547void CDBClass::Compile_System_InitializeUserTypes(){
[90]1548 char temporary[VN_SIZE];
[89]1549
1550 ////////////////////////////////////////////////////////////////////
1551 // クラス登録
1552 ////////////////////////////////////////////////////////////////////
1553
1554 // イテレータをリセット
1555 Iterator_Reset();
1556
1557 while( Iterator_HasNext() ){
[91]1558 const CClass &objClass = *Iterator_GetNext();
[89]1559
[91]1560 if( !objClass.IsUsing() ){
1561 // 未使用のクラスは無視する
1562 continue;
1563 }
1564
[94]1565 char referenceOffsetsBuffer[1024] = "";
1566 int numOfReference = 0;
1567 for( int i=0; i<objClass.iMemberNum; i++ ){
1568 CMember &member = *objClass.ppobj_Member[i];
1569
1570 if( member.IsObject() || member.IsPointer() ){
1571 if( referenceOffsetsBuffer[0] ){
1572 lstrcat( referenceOffsetsBuffer, "," );
1573 }
1574
1575 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1576 "%d",
1577 objClass.GetMemberOffset( member.name ) );
1578
1579 numOfReference++;
1580 }
1581 }
1582
[89]1583 sprintf( temporary
[94]1584 , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))"
[89]1585 , 1
1586 , ESC_NEW
[94]1587 , "" // 名前空間 (TODO: 実装)
1588 , objClass.name // クラス名
1589 , referenceOffsetsBuffer // 参照メンバオフセット配列
1590 , numOfReference // 参照メンバの個数
[89]1591 );
1592
1593 // コンパイル
1594 ChangeOpcode( temporary );
1595
1596 // ネイティブコードバッファの再確保
1597 ReallocNativeCodeBuffer();
1598 }
1599
1600
1601 ////////////////////////////////////////////////////////////////////
[90]1602 // 基底クラスを登録
1603 ////////////////////////////////////////////////////////////////////
1604
1605 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1606 , HIBYTE( COM_DIM )
1607 , LOBYTE( COM_DIM )
1608 , 1
1609 , ESC_AS
1610 );
1611 ChangeOpcode( temporary );
1612
1613 // イテレータをリセット
1614 Iterator_Reset();
1615
1616 while( Iterator_HasNext() ){
[91]1617 const CClass &objClass = *Iterator_GetNext();
[90]1618
[91]1619 if( !objClass.IsUsing() ){
1620 // 未使用のクラスは無視する
1621 continue;
1622 }
1623
1624 if( objClass.pobj_InheritsClass ){
[90]1625 sprintf( temporary
1626 , "tempType=Search(\"%s\",\"%s\")"
1627 , "" // 名前空間 (TODO: 実装)
[91]1628 , objClass.name // クラス名
[90]1629 );
1630
1631 // コンパイル
1632 ChangeOpcode( temporary );
1633
1634 sprintf( temporary
1635 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
1636 , "" // 名前空間 (TODO: 実装)
[91]1637 , objClass.pobj_InheritsClass->name // 基底クラス名
[90]1638 );
1639
1640 // コンパイル
1641 ChangeOpcode( temporary );
1642 }
1643
1644 // ネイティブコードバッファの再確保
1645 ReallocNativeCodeBuffer();
1646 }
1647
1648
1649
1650 ////////////////////////////////////////////////////////////////////
[89]1651 // 継承関係登録
1652 ////////////////////////////////////////////////////////////////////
1653 // TODO: 未完成
1654 /*
1655
1656 // イテレータをリセット
1657 Iterator_Reset();
1658
1659 while( Iterator_HasNext() ){
1660 CClass *pClass = Iterator_GetNext();
1661
1662 sprintf( genBuffer + length
1663 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1664 , "" // クラス名
1665 , pClass->name // クラス名
1666 );
1667 length += lstrlen( genBuffer + length );
1668
1669 while( length + 8192 > max ){
1670 max += 8192;
1671 genBuffer = (char *)realloc( genBuffer, max );
1672 }
1673 }*/
[87]1674}
1675
1676
1677
[67]1678CClass *CDBClass::GetStringClass() const
1679{
1680 if( !pStringClass ){
1681 SetError();
1682 return NULL;
1683 }
1684 return pStringClass;
1685}
1686CClass *CDBClass::GetObjectClass() const
1687{
1688 if( !pObjectClass ){
1689 SetError();
1690 return NULL;
1691 }
1692 return pObjectClass;
1693}
1694
[75]1695void CDBClass::StartCompile( UserProc *pUserProc ){
1696 pCompilingClass = pUserProc->GetParentClassPtr();
[18]1697 if( pCompilingClass ){
[91]1698 pCompilingClass->Using();
1699
[75]1700 pCompilingMethod = pCompilingClass->GetMethodInfo( pUserProc );
[18]1701 if( !pCompilingMethod ){
[75]1702 pCompilingMethod = pCompilingClass->GetStaticMethodInfo( pUserProc );
[18]1703 if( !pCompilingMethod ){
1704 SetError(300,NULL,cp);
1705 }
1706 }
1707 }
1708 else{
1709 pCompilingMethod = NULL;
1710 }
1711}
1712CClass *CDBClass::GetNowCompilingClass(){
1713 return pCompilingClass;
1714}
1715CMethod *CDBClass::GetNowCompilingMethodInfo(){
1716 return pCompilingMethod;
1717}
[4]1718
1719
1720
[18]1721
[4]1722//////////////////////
1723// イテレータ
1724//////////////////////
1725
[89]1726void CDBClass::Iterator_Init(void){
[4]1727 if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass);
1728
1729 iIteMaxNum=0;
1730 iIteNextNum=0;
1731 ppobj_IteClass=(CClass **)HeapAlloc(hHeap,0,1);
1732
1733 int i;
1734 for(i=0;i<MAX_CLASS_HASH;i++){
1735 if(pobj_ClassHash[i]){
1736 CClass *pobj_c;
1737 pobj_c=pobj_ClassHash[i];
1738 while(1){
1739 ppobj_IteClass=(CClass **)HeapReAlloc(hHeap,0,ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
1740 ppobj_IteClass[iIteMaxNum]=pobj_c;
1741 iIteMaxNum++;
1742
1743 if(pobj_c->pobj_NextClass==0) break;
1744 pobj_c=pobj_c->pobj_NextClass;
1745 }
1746 }
1747 }
1748}
[89]1749void CDBClass::Iterator_Reset(void){
1750 iIteNextNum = 0;
1751}
[4]1752BOOL CDBClass::Iterator_HasNext(void){
1753 if(iIteNextNum<iIteMaxNum) return 1;
1754 return 0;
1755}
1756CClass *CDBClass::Iterator_GetNext(void){
1757 CClass *pobj_c;
1758 pobj_c=ppobj_IteClass[iIteNextNum];
1759 iIteNextNum++;
1760 return pobj_c;
1761}
1762int CDBClass::Iterator_GetMaxCount(void){
1763 return iIteMaxNum;
1764}
Note: See TracBrowser for help on using the repository browser.