source: dev/BasicCompiler_Common/Class.cpp@ 28

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

・【32ビットコンパイラ】戻り値に実態オブジェクトを持つインデクサを呼び出すと強制終了してしまうバグを修正。
・仮想関数のオーバーロードが正常に動作しないバグを修正。
・純仮想関数(抽象メソッド)が仮想関数でオーバーロードされていると、クラスのインスタンスが生成できてしまうバグを修正。

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