source: dev/BasicCompiler_Common/Class.cpp@ 27

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

静的メンバ、静的メソッド周りを修正。

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