source: dev/BasicCompiler_Common/Class.cpp@ 18

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

オブジェクト定数に対応。

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