source: dev/trunk/abdev/BasicCompiler_Common/src/Class.cpp@ 326

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

メソッドの重複チェックで戻り値も判定するよにうにした

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