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

Last change on this file since 325 was 325, checked in by dai_9181, 17 years ago
File size: 44.5 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 //関数名、パラメータ属性が合致したとき
504 SetError(15,pUserProc->GetName().c_str(),nowLine);
505 return;
506 }
507 }
508 }
509
510 //仮想関数の場合
511 if( isAbstract ) pUserProc->CompleteCompile();
512
513 //メソッドのオーバーライド
514 BOOST_FOREACH( CMethod *pMethod, pobj_c->GetMethods() ){
515 if( pMethod->GetUserProc().GetName() == temporary ){
516 if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) )
517 {
518 //メンバ関数を上書き
519 pMethod->SetUserProcPtr( pUserProc );
520 pMethod->Override();
521
522 if( !pMethod->IsVirtual() )
523 {
524 // オーバーライドミス
525 SetError(136,NULL,cp);
526 }
527 if( !isOverride )
528 {
529 SetError(127,NULL,nowLine);
530 }
531 if(pMethod->GetAccessibility() != accessibility )
532 {
533 SetError(128,NULL,nowLine);
534 }
535
536 pUserProc->SetMethod( pMethod );
537 return;
538 }
539 }
540 }
541
542 if( isVirtual ){
543 pobj_c->AddVtblNum( 1 );
544 }
545
546 if( isOverride ){
547 SetError(12,"Override",nowLine);
548 }
549
550 if(bStatic){
551 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
552 }
553 else{
554 pobj_c->GetMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
555 }
556}
557
558bool CClass::DupliCheckAll(const char *name){
559 //重複チェック
560
561 //メンバ
562 if(DupliCheckMember(name)) return 1;
563
564 //メソッド
565 BOOST_FOREACH( const CMethod *pMethod, methods ){
566 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
567 return 1;
568 }
569 }
570
571 return 0;
572}
573bool CClass::DupliCheckMember(const char *name){
574 //重複チェック
575
576 // 動的メンバ
577 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
578 if( GetName() == pMember->GetName() ){
579 return 1;
580 }
581 }
582
583 // 静的メンバ
584 BOOST_FOREACH( CMember *pMember, staticMembers ){
585 if( GetName() == pMember->GetName() ){
586 return 1;
587 }
588 }
589
590 return 0;
591}
592
593const ::Delegate &CClass::GetDelegate() const
594{
595 const ::Delegate *dg = compiler.GetObjectModule().meta.GetDelegates().GetHashArrayElement( GetName().c_str() );
596 while( dg )
597 {
598 if( dg->IsEqualSymbol( GetNamespaceScopes(), GetName() ) ){
599 //名前空間とクラス名が一致した
600 return *dg;
601 }
602 dg = dg->GetChainNext();
603 }
604
605 Jenga::Throw( "CClass::GetDelegateメソッドに失敗" );
606 static ::Delegate dummy;
607 return dummy;
608}
609
610//サイズを取得
611int CClass::GetSize() const
612{
613 return GetMemberOffset( NULL, NULL );
614}
615
616//メンバのオフセットを取得
617int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
618{
619 int i2;
620
621 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
622 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0;
623
624 int alignment = 1;
625 if( GetFixedAlignment() )
626 {
627 alignment = GetFixedAlignment();
628 }
629
630 int iMaxAlign=0;
631 int i = -1;
632 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
633 i++;
634
635 i2 = pMember->GetType().GetSize();
636
637 //アラインメントを算出
638 int member_size;
639 if( pMember->GetType().IsStruct() ){
640 //メンバクラスのアラインメントを取得
641 member_size=pMember->GetType().GetClass().GetAlignment();
642 }
643 else{
644 //メンバサイズを取得
645 member_size=i2;
646 }
647 if(iMaxAlign<member_size) iMaxAlign=member_size;
648
649 //アラインメントを考慮
650 if(GetFixedAlignment()&&GetFixedAlignment()<member_size){
651 if(offset%alignment) offset+=alignment-(offset%alignment);
652 }
653 else{
654 if(alignment<member_size) alignment=member_size;
655
656 if(member_size==0){
657 //メンバを持たないクラス
658 //※何もしない(オフセットの計算をしない)
659 }
660 else{
661 if(offset%member_size) offset+=member_size-(offset%member_size);
662 }
663 }
664
665 if(memberName){
666 //メンバ指定がある場合は、オフセットを返す
667 if( pMember->GetName() == memberName ){
668 if(pMemberNum) *pMemberNum=i;
669 return offset;
670 }
671 }
672
673 //配列を考慮したメンバサイズを取得
674 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
675
676 //メンバサイズを加算
677 offset+= member_size;
678 }
679
680 if(iMaxAlign<alignment) alignment=iMaxAlign;
681
682 //アラインメントを考慮
683 if(alignment){
684 if(offset%alignment) offset+=alignment-(offset%alignment);
685 }
686
687 if(pMemberNum) *pMemberNum=i;
688 return offset;
689}
690int CClass::GetAlignment() const
691{
692 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
693 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
694
695 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
696 int member_size;
697 if(pMember->GetType().IsStruct()){
698 //メンバクラスのアラインメントを取得
699 member_size=pMember->GetType().GetClass().GetAlignment();
700 }
701 else{
702 //メンバサイズを取得
703 member_size = pMember->GetType().GetSize();
704 }
705
706 //アラインメントをセット
707 if(alignment<member_size) alignment=member_size;
708 }
709
710 if(alignment==0) return 0;
711
712 if(GetFixedAlignment()) alignment=GetFixedAlignment();
713
714 return alignment;
715}
716int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
717{
718 int n = 0;
719 BOOST_FOREACH( const CMethod *pMethod, methods ){
720 if( &pMethod->GetUserProc() == pUserProc ) break;
721 if( pMethod->IsVirtual() ) n++;
722 }
723 return n;
724}
725LONG_PTR CClass::GetVtblGlobalOffset(void) const
726{
727
728 //既に存在する場合はそれを返す
729 if(vtbl_offset!=-1) return vtbl_offset;
730
731
732
733 //////////////////////////////////////
734 // 存在しないときは新たに生成する
735 //////////////////////////////////////
736
737 const UserProc **ppsi;
738 ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
739
740 //関数テーブルに値をセット
741 int i2 = 0;
742 BOOST_FOREACH( const CMethod *pMethod, methods ){
743 if(pMethod->IsVirtual()){
744 pMethod->GetUserProc().Using();
745
746 if(pMethod->IsAbstract()){
747 extern int cp;
748 SmoothieException::Throw(300,NULL,cp);
749
750 ppsi[i2]=0;
751 }
752 else{
753 ppsi[i2]=&pMethod->GetUserProc();
754 }
755 i2++;
756 }
757 }
758
759 vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
760
761 for( int i=0; i < GetVtblNum(); i++ ){
762 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
763 }
764
765 free(ppsi);
766
767 return vtbl_offset;
768}
769void CClass::GenerateVTables()
770{
771 if( IsAbstract() )
772 {
773 // 抽象クラスは無視
774 return;
775 }
776 if( !IsUsing() )
777 {
778 // 使われていないクラスは無視
779 return;
780 }
781
782 const UserProc **ppsi;
783 ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
784
785 //関数テーブルに値をセット
786 int i2 = 0;
787 BOOST_FOREACH( const CMethod *pMethod, methods ){
788 if(pMethod->IsVirtual()){
789 if( !pMethod->GetUserProc().IsUsing() )
790 {
791 ts((char *)pMethod->GetUserProc().GetFullName().c_str());
792 }
793 pMethod->GetUserProc().Using();
794
795 if(pMethod->IsAbstract()){
796 extern int cp;
797 SmoothieException::Throw(300,NULL,cp);
798
799 ppsi[i2]=0;
800 }
801 else{
802 ppsi[i2]=&pMethod->GetUserProc();
803 }
804 i2++;
805 }
806 }
807
808 vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
809
810 for( int i=0; i < GetVtblNum(); i++ ){
811 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
812 }
813
814 free(ppsi);
815}
816void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
817 if( IsAbstract() )
818 {
819 // 抽象クラスは無視
820 return;
821 }
822 if( !IsUsing() )
823 {
824 // 使われていないクラスは無視
825 return;
826 }
827 if(vtbl_offset==-1) return;
828
829 LONG_PTR *pVtbl;
830 pVtbl=(LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr()+vtbl_offset);
831
832 int i;
833 for(i=0;i<GetVtblNum();i++){
834 UserProc *pUserProc;
835 pUserProc=(UserProc *)pVtbl[i];
836 if(!pUserProc) continue;
837
838 if( pUserProc->GetBeginOpAddress() == 0
839 && pUserProc->GetEndOpAddress() == 0 )
840 {
841 Jenga::Throw( "未解決の仮想関数が存在する" );
842 }
843
844 pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection;
845 }
846}
847bool CClass::IsAbstract() const
848{
849 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
850
851 BOOST_FOREACH( const CMethod *pMethod, methods ){
852 if(pMethod->IsVirtual()){
853 if(pMethod->IsAbstract()){
854 return true;
855 }
856 }
857 }
858
859 return false;
860}
861
862CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
863 return new CClass(namespaceScopes, importedNamespaces, name);
864}
865bool Classes::Insert( CClass *pClass )
866{
867 /////////////////////////////////
868 // ハッシュデータに追加
869 /////////////////////////////////
870
871 if( !Put( pClass ) )
872 {
873 SetError(15,pClass->GetName(), cp);
874 return false;
875 }
876 return true;
877}
878CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
879 //////////////////////////////////////////////////////////////////////////
880 // クラスを追加
881 // ※名前のみを登録。その他の情報はSetClassメソッドで!
882 //////////////////////////////////////////////////////////////////////////
883
884 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
885
886 if( !Insert( pClass ) )
887 {
888 return NULL;
889 }
890
891 return pClass;
892}
893
894void Classes::CollectClassesForNameOnly( const BasicSource &source )
895{
896 int i, i2;
897 char temporary[VN_SIZE];
898
899 // 名前空間管理
900 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
901 namespaceScopes.clear();
902
903 // Importsされた名前空間の管理
904 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
905 importedNamespaces.clear();
906
907 for(i=0;;i++){
908 if(source[i]=='\0') break;
909
910 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
911 for(i+=2,i2=0;;i2++,i++){
912 if( IsCommandDelimitation( source[i] ) ){
913 temporary[i2]=0;
914 break;
915 }
916 temporary[i2]=source[i];
917 }
918 namespaceScopes.push_back( temporary );
919
920 continue;
921 }
922 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
923 if( namespaceScopes.size() <= 0 ){
924 SmoothieException::Throw(12, "End Namespace", i );
925 }
926 else{
927 namespaceScopes.pop_back();
928 }
929
930 i += 2;
931 continue;
932 }
933 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
934 for(i+=2,i2=0;;i2++,i++){
935 if( IsCommandDelimitation( source[i] ) ){
936 temporary[i2]=0;
937 break;
938 }
939 temporary[i2]=source[i];
940 }
941 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
942 {
943 SmoothieException::Throw(64,temporary,i );
944 }
945
946 continue;
947 }
948 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
949 importedNamespaces.clear();
950 continue;
951 }
952
953 if(source[i]==1&&(
954 source[i+1]==ESC_CLASS||
955 source[i+1]==ESC_TYPE||
956 source[i+1]==ESC_INTERFACE
957 ))
958 {
959 int nowLine = i;
960 i += 2;
961
962 Type blittableType;
963 if(memicmp(source.GetBuffer()+i,"Align(",6)==0){
964 //アラインメント修飾子
965 i+=6;
966 i=JumpStringInPare(source.GetBuffer(),i)+1;
967 }
968 else if( memicmp( source.GetBuffer() + i, "Blittable(", 10 ) == 0 ){
969 // Blittable修飾子
970 i+=10;
971 i+=GetStringInPare_RemovePare(temporary,source.GetBuffer()+i)+1;
972 compiler.StringToType( temporary, blittableType );
973 }
974
975 bool isEnum = false;
976 bool isDelegate = false;
977 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
978 // 列挙型の場合
979 isEnum = true;
980
981 i += 2;
982 }
983 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
984 {
985 // デリゲートの場合
986 isDelegate = true;
987
988 i += 2;
989 }
990
991 for(i2=0;;i++,i2++){
992 if(!IsVariableChar(source[i])){
993 temporary[i2]=0;
994 break;
995 }
996 temporary[i2]=source[i];
997 }
998
999 //クラスを追加
1000 CClass *pClass = this->Add(namespaceScopes, importedNamespaces, temporary,nowLine);
1001 if( pClass ){
1002 if( source[nowLine+1] == ESC_CLASS ){
1003 if( isEnum )
1004 {
1005 pClass->SetClassType( CClass::Enum );
1006 }
1007 else if( isDelegate )
1008 {
1009 pClass->SetClassType( CClass::Delegate );
1010 }
1011 else{
1012 pClass->SetClassType( CClass::Class );
1013 }
1014 }
1015 else if( source[nowLine+1] == ESC_INTERFACE ){
1016 pClass->SetClassType( CClass::Interface );
1017 }
1018 else{
1019 pClass->SetClassType( CClass::Structure );
1020 }
1021 }
1022
1023 // Blittable型の場合
1024 if( !blittableType.IsNull() ){
1025 pClass->SetBlittableType( blittableType );
1026
1027 // Blittable型として登録
1028 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
1029 }
1030 }
1031 }
1032}
1033
1034void Classes::GenerateVTables()
1035{
1036 Iterator_Reset();
1037 while( Iterator_HasNext() )
1038 {
1039 CClass *pClass = Iterator_GetNext();
1040 pClass->GenerateVTables();
1041 }
1042}
1043
1044void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
1045 Iterator_Reset();
1046 while( Iterator_HasNext() )
1047 {
1048 CClass *pClass = Iterator_GetNext();
1049 pClass->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
1050 }
1051}
1052
1053
1054void Classes::InitStaticMember(){
1055 //静的メンバをグローバル領域に作成
1056
1057 //イテレータをリセット
1058
1059 extern int cp;
1060 int back_cp=cp;
1061
1062 this->Iterator_Reset();
1063 while(this->Iterator_HasNext()){
1064 CClass &objClass = *this->Iterator_GetNext();
1065 if( objClass.isTargetObjectModule == false )
1066 {
1067 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
1068 continue;
1069 }
1070
1071 // 名前空間をセット
1072 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
1073
1074 int i=0;
1075 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() ){
1076 char temporary[VN_SIZE];
1077 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
1078 dim(
1079 temporary,
1080 member->GetSubscripts(),
1081 member->GetType(),
1082 member->GetInitializeExpression().c_str(),
1083 member->GetConstructParameter().c_str(),
1084 0);
1085
1086 i++;
1087 }
1088 }
1089
1090 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
1091
1092 cp=back_cp;
1093}
1094bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){
1095 bool result = true;
1096 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1097 if(pMember->GetType().IsStruct()){
1098 //循環参照でないかをチェック
1099 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
1100 extern int cp;
1101 SetError(124,pMember->GetType().GetClass().GetName(),cp);
1102 return false;
1103 }
1104
1105 pobj_LoopRefCheck->add(objClass.GetName().c_str());
1106
1107 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
1108 if( result )
1109 {
1110 result = tempResult;
1111 }
1112
1113 pobj_LoopRefCheck->del(objClass.GetName().c_str());
1114 }
1115 }
1116
1117 return result;
1118}
1119void Classes::GetClass_recur(const char *lpszInheritsClass){
1120 extern char *basbuf;
1121 int i,i2,i3,sub_address,top_pos;
1122 char temporary[8192];
1123
1124 // 名前空間管理
1125 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1126 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1127 namespaceScopes.clear();
1128
1129 // Importsされた名前空間の管理
1130 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
1131 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
1132
1133 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
1134 const CClass *pBackCompilingClass = compiler.pCompilingClass;
1135
1136 for(i=0;;i++){
1137 if(basbuf[i]=='\0') break;
1138
1139
1140 // 名前空間
1141 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
1142 for(i+=2,i2=0;;i2++,i++){
1143 if( IsCommandDelimitation( basbuf[i] ) ){
1144 temporary[i2]=0;
1145 break;
1146 }
1147 temporary[i2]=basbuf[i];
1148 }
1149 namespaceScopes.push_back( temporary );
1150
1151 continue;
1152 }
1153 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
1154 if( namespaceScopes.size() <= 0 ){
1155 SetError(12, "End Namespace", i );
1156 }
1157 else{
1158 namespaceScopes.pop_back();
1159 }
1160
1161 i += 2;
1162 continue;
1163 }
1164
1165 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
1166 for(i+=2,i2=0;;i2++,i++){
1167 if( IsCommandDelimitation( basbuf[i] ) ){
1168 temporary[i2]=0;
1169 break;
1170 }
1171 temporary[i2]=basbuf[i];
1172 }
1173 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
1174 {
1175 SmoothieException::Throw(64,temporary,i );
1176 }
1177
1178 continue;
1179 }
1180 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
1181 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
1182 continue;
1183 }
1184
1185
1186
1187 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1188 //////////////////////////
1189 // インターフェイス
1190 //////////////////////////
1191
1192 top_pos=i;
1193
1194 i+=2;
1195
1196 //インターフェイス名を取得
1197 GetIdentifierToken( temporary, basbuf, i );
1198
1199 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1200 if(!pobj_c) continue;
1201
1202 if(lpszInheritsClass){
1203 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
1204 //継承先先読み用
1205 continue;
1206 }
1207 }
1208
1209 if(pobj_c->IsReady()){
1210 //既に先読みされているとき
1211 continue;
1212 }
1213
1214 pobj_c->Readed();
1215
1216 pobj_c->SetConstructorMemberSubIndex( -1 );
1217 pobj_c->SetDestructorMemberSubIndex( -1 );
1218
1219 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1220 //継承を行う場合
1221 for(i+=3,i2=0;;i++,i2++){
1222 if(IsCommandDelimitation(basbuf[i])){
1223 temporary[i2]=0;
1224 break;
1225 }
1226 temporary[i2]=basbuf[i];
1227 }
1228
1229 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1230 SetError(105,temporary,i);
1231 goto Interface_InheritsError;
1232 }
1233
1234 //継承元クラスを取得
1235 const Classes &classes = *this;
1236 const CClass *pInheritsClass = classes.Find(temporary);
1237 if( !pInheritsClass ){
1238 SetError(106,temporary,i);
1239 goto Interface_InheritsError;
1240 }
1241
1242 //継承させる
1243 if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){
1244 goto Interface_InheritsError;
1245 }
1246 }
1247 else{
1248 //継承無し
1249 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1250 {
1251 // TODO: ここに来ないことが実証できたらこの分岐は消す
1252 Jenga::Throw( "GetClass_recur内の例外" );
1253 }
1254 }
1255Interface_InheritsError:
1256
1257 //メンバ変数、関数を取得
1258 while(1){
1259 i++;
1260
1261 //エラー
1262 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1263 SetError(22,"Interface",i);
1264 i--;
1265 break;
1266 }
1267
1268 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1269 SetError(111,NULL,i);
1270 break;
1271 }
1272
1273 sub_address=i;
1274
1275 for(i2=0;;i++,i2++){
1276 if(IsCommandDelimitation(basbuf[i])){
1277 temporary[i2]=0;
1278 break;
1279 }
1280 temporary[i2]=basbuf[i];
1281 }
1282 if(temporary[0]=='\0'){
1283 if(basbuf[i]=='\0'){
1284 i--;
1285 SetError(22,"Interface",top_pos);
1286 break;
1287 }
1288 continue;
1289 }
1290
1291 //End Interface記述の場合
1292 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1293
1294 if(!(temporary[0]==1&&(
1295 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1296 ))){
1297 SetError(1,NULL,i);
1298 break;
1299 }
1300
1301 //メンバ関数を追加
1302 pobj_c->AddMethod(pobj_c,
1303 Prototype::Public, //Publicアクセス権
1304 0, //Static指定なし
1305 false, //Constではない
1306 1, //Abstract
1307 1, //Virtual
1308 0,
1309 temporary,
1310 sub_address
1311 );
1312 }
1313 }
1314
1315 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1316 //////////////////////////
1317 // クラス
1318 //////////////////////////
1319
1320 top_pos=i;
1321
1322 const DWORD dwClassType=basbuf[i+1];
1323
1324 i+=2;
1325
1326 int iAlign=0;
1327 if(memicmp(basbuf+i,"Align(",6)==0){
1328 //アラインメント修飾子
1329 i+=6;
1330 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1331 iAlign=atoi(temporary);
1332
1333 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1334 SetError(51,NULL,i);
1335 }
1336 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
1337 // Blittable修飾子
1338 i+=10;
1339 i=JumpStringInPare(basbuf,i)+1;
1340 }
1341
1342 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
1343 {
1344 // 列挙型の場合
1345 i += 2;
1346 }
1347 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
1348 {
1349 // デリゲートの場合
1350 i += 2;
1351 }
1352
1353 //クラス名を取得
1354 GetCommandToken( temporary, basbuf, i );
1355
1356 char className[VN_SIZE];
1357 Jenga::Common::Strings typeParameters;
1358 SplitGenericClassInstance( temporary, className, typeParameters );
1359
1360 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, className) );
1361 if(!pobj_c) continue;
1362
1363 compiler.pCompilingClass = pobj_c;
1364
1365 if(lpszInheritsClass){
1366 if( pobj_c->GetName() != lpszInheritsClass ){
1367 //継承先先読み用
1368 continue;
1369 }
1370 }
1371
1372 if(pobj_c->IsReady()){
1373 //既に先読みされているとき
1374 continue;
1375 }
1376
1377
1378 /////////////////////////////////////////////////////////
1379 // ☆★☆ ジェネリクスサポート ☆★☆
1380 BOOST_FOREACH( const std::string &typeParameter, typeParameters )
1381 {
1382 pobj_c->AddFormalGenericType( GenericType( typeParameter, Type(DEF_OBJECT,*GetObjectClassPtr()) ) );
1383 }
1384 /////////////////////////////////////////////////////////
1385
1386
1387 pobj_c->SetFixedAlignment( iAlign );
1388
1389 pobj_c->Readed();
1390
1391 pobj_c->SetConstructorMemberSubIndex( -1 );
1392 pobj_c->SetDestructorMemberSubIndex( -1 );
1393
1394 //アクセス制限の初期値をセット
1395 Prototype::Accessibility accessibility;
1396 if(dwClassType==ESC_CLASS){
1397 accessibility = Prototype::Private;
1398 }
1399 else{
1400 accessibility = Prototype::Public;
1401 }
1402
1403 if( pobj_c->GetName() == "Object" || dwClassType == ESC_TYPE ){
1404 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1405 {
1406 // TODO: ここに来ないことが実証できたらこの分岐は消す
1407 Jenga::Throw( "GetClass_recur内の例外" );
1408 }
1409 }
1410 else{
1411 bool isInherits = false;
1412 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1413 //継承を行う場合
1414 isInherits = true;
1415
1416 i += 3;
1417 GetCommandToken( temporary, basbuf, i );
1418
1419 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1420 SetError(105,temporary,i);
1421 goto InheritsError;
1422 }
1423 }
1424
1425 if( !isInherits ){
1426 //Objectを継承する
1427 lstrcpy( temporary, "Object" );
1428 }
1429
1430 pobj_c->Inherits( temporary, i );
1431 }
1432InheritsError:
1433
1434 //メンバとメソッドを取得
1435 while(1){
1436 i++;
1437
1438 //エラー
1439 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1440 SetError(22,"Class",i);
1441 i--;
1442 break;
1443 }
1444
1445 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1446 SetError(111,NULL,i);
1447 break;
1448 }
1449
1450 //Static修飾子
1451 BOOL bStatic;
1452 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1453 bStatic=1;
1454 i+=2;
1455 }
1456 else bStatic=0;
1457
1458 //Const修飾子
1459 bool isConst = false;
1460 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1461 isConst = true;
1462 i += 2;
1463 }
1464
1465 if(basbuf[i]==1&&(
1466 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1467 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1468 )){
1469 i3=basbuf[i+1];
1470 sub_address=i;
1471 }
1472 else i3=0;
1473
1474 bool isVirtual = false, isAbstract = false, isOverride = false;
1475 if(i3==ESC_ABSTRACT){
1476 isAbstract=1;
1477 isVirtual=1;
1478 i+=2;
1479
1480 i3=basbuf[i+1];
1481 }
1482 else if(i3==ESC_VIRTUAL){
1483 isAbstract=0;
1484 isVirtual=1;
1485 i+=2;
1486
1487 i3=basbuf[i+1];
1488 }
1489 else if(i3==ESC_OVERRIDE){
1490 isOverride=1;
1491 isVirtual=1;
1492
1493 i+=2;
1494
1495 i3=basbuf[i+1];
1496 }
1497
1498 for(i2=0;;i++,i2++){
1499 if(IsCommandDelimitation(basbuf[i])){
1500 temporary[i2]=0;
1501 break;
1502 }
1503 temporary[i2]=basbuf[i];
1504 }
1505 if(temporary[0]=='\0'){
1506 if(basbuf[i]=='\0'){
1507
1508 if(dwClassType==ESC_CLASS)
1509 SetError(22,"Class",top_pos);
1510 else
1511 SetError(22,"Type",top_pos);
1512
1513 i--;
1514 break;
1515 }
1516 continue;
1517 }
1518
1519 //End Class記述の場合
1520 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1521 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1522
1523 //アクセスを変更
1524 if(lstrcmpi(temporary,"Private")==0){
1525 accessibility = Prototype::Private;
1526 continue;
1527 }
1528 if(lstrcmpi(temporary,"Public")==0){
1529 accessibility = Prototype::Public;
1530 continue;
1531 }
1532 if(lstrcmpi(temporary,"Protected")==0){
1533 accessibility = Prototype::Protected;
1534 continue;
1535 }
1536
1537 extern int cp;
1538 if(i3==0){
1539 if(bStatic){
1540 //静的メンバを追加
1541 cp=i; //エラー用
1542 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
1543 }
1544 else{
1545 //メンバを追加
1546 cp=i; //エラー用
1547 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
1548
1549
1550 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1551 if( !pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().IsReady() ){
1552 //参照先が読み取られていないとき
1553 GetClass_recur(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().GetName().c_str());
1554 }
1555 }
1556
1557
1558 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1559 //循環参照のチェック
1560 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1561 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass())){
1562 //エラー回避
1563 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
1564 type.SetBasicType( DEF_PTR_VOID );
1565 }
1566 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1567 }
1568 }
1569 }
1570 else{
1571 //メソッドを追加
1572 cp=i; //エラー用
1573 pobj_c->AddMethod(pobj_c,
1574 accessibility,
1575 bStatic,
1576 isConst,
1577 isAbstract,
1578 isVirtual,
1579 isOverride,
1580 temporary,
1581 sub_address);
1582
1583 if( isAbstract ) continue;
1584
1585 for(;;i++){
1586 if(basbuf[i]=='\0'){
1587 i--;
1588 break;
1589 }
1590 if(basbuf[i-1]!='*'&&
1591 basbuf[i]==1&&(
1592 basbuf[i+1]==ESC_SUB||
1593 basbuf[i+1]==ESC_FUNCTION||
1594 basbuf[i+1]==ESC_MACRO||
1595 basbuf[i+1]==ESC_TYPE||
1596 basbuf[i+1]==ESC_CLASS||
1597 basbuf[i+1]==ESC_INTERFACE||
1598 basbuf[i+1]==ESC_ENUM)){
1599 GetDefaultNameFromES(i3,temporary);
1600 SetError(22,temporary,i);
1601 }
1602 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1603 i+=2;
1604 break;
1605 }
1606 }
1607 }
1608 }
1609 }
1610 }
1611
1612 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
1613 compiler.pCompilingClass = pBackCompilingClass;
1614
1615 // 名前空間を元に戻す
1616 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1617
1618 // インポートされた名前空間を元に戻す
1619 compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces;
1620}
1621void Classes::GetAllClassInfo(void){
1622 //ループ継承チェック用のクラス
1623 pobj_LoopRefCheck=new CLoopRefCheck();
1624
1625 //クラスを取得
1626 GetClass_recur(0);
1627
1628 delete pobj_LoopRefCheck;
1629 pobj_LoopRefCheck=0;
1630
1631 // イテレータの準備
1632 this->Iterator_Init();
1633}
1634void Classes::Compile_System_InitializeUserTypes(){
1635 char temporary[VN_SIZE];
1636
1637 ////////////////////////////////////////////////////////////////////
1638 // クラス登録
1639 ////////////////////////////////////////////////////////////////////
1640
1641 // イテレータをリセット
1642 Iterator_Reset();
1643
1644 while( Iterator_HasNext() ){
1645 const CClass &objClass = *Iterator_GetNext();
1646
1647 if( !objClass.IsUsing() ){
1648 // 未使用のクラスは無視する
1649 continue;
1650 }
1651
1652 char referenceOffsetsBuffer[1024] = "";
1653 int numOfReference = 0;
1654 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1655 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() ){
1656 if( referenceOffsetsBuffer[0] ){
1657 lstrcat( referenceOffsetsBuffer, "," );
1658 }
1659
1660 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1661 "%d",
1662 objClass.GetMemberOffset( pMember->GetName().c_str() ) );
1663
1664 numOfReference++;
1665 }
1666 }
1667
1668 sprintf( temporary
1669 , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))"
1670 , 1
1671 , ESC_NEW
1672 , "" // 名前空間 (TODO: 実装)
1673 , objClass.GetName().c_str() // クラス名
1674 , referenceOffsetsBuffer // 参照メンバオフセット配列
1675 , numOfReference // 参照メンバの個数
1676 );
1677
1678 // コンパイル
1679 ChangeOpcode( temporary );
1680 }
1681
1682
1683 ////////////////////////////////////////////////////////////////////
1684 // 基底クラスを登録
1685 ////////////////////////////////////////////////////////////////////
1686
1687 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1688 , HIBYTE( COM_DIM )
1689 , LOBYTE( COM_DIM )
1690 , 1
1691 , ESC_AS
1692 );
1693 ChangeOpcode( temporary );
1694
1695 // イテレータをリセット
1696 Iterator_Reset();
1697
1698 while( Iterator_HasNext() ){
1699 const CClass &objClass = *Iterator_GetNext();
1700
1701 if( !objClass.IsUsing() ){
1702 // 未使用のクラスは無視する
1703 continue;
1704 }
1705
1706 if( objClass.HasSuperClass() ){
1707 sprintf( temporary
1708 , "tempType=Search(\"%s\",\"%s\")"
1709 , "" // 名前空間 (TODO: 実装)
1710 , objClass.GetName().c_str() // クラス名
1711 );
1712
1713 // コンパイル
1714 ChangeOpcode( temporary );
1715
1716 sprintf( temporary
1717 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
1718 , "" // 名前空間 (TODO: 実装)
1719 , objClass.GetSuperClass().GetName().c_str() // 基底クラス名
1720 );
1721
1722 // コンパイル
1723 ChangeOpcode( temporary );
1724 }
1725 }
1726
1727
1728
1729 ////////////////////////////////////////////////////////////////////
1730 // 継承関係登録
1731 ////////////////////////////////////////////////////////////////////
1732 // TODO: 未完成
1733 /*
1734
1735 // イテレータをリセット
1736 Iterator_Reset();
1737
1738 while( Iterator_HasNext() ){
1739 CClass *pClass = Iterator_GetNext();
1740
1741 sprintf( genBuffer + length
1742 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1743 , "" // クラス名
1744 , pClass->name // クラス名
1745 );
1746 length += lstrlen( genBuffer + length );
1747
1748 while( length + 8192 > max ){
1749 max += 8192;
1750 genBuffer = (char *)realloc( genBuffer, max );
1751 }
1752 }*/
1753}
1754
1755const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1756{
1757 if( namespaceScopes.size() == 0 && name == "Object" ){
1758 return GetObjectClassPtr();
1759 }
1760 else if( namespaceScopes.size() == 0 && name == "String" ){
1761 return GetStringClassPtr();
1762 }
1763
1764 const CClass *pClass = GetHashArrayElement( name.c_str() );
1765 while( pClass )
1766 {
1767 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1768 //名前空間とクラス名が一致した
1769 return pClass;
1770 }
1771 pClass = pClass->GetChainNext();
1772 }
1773
1774 // TypeDefも見る
1775 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
1776 if( index != -1 ){
1777 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
1778 if( type.IsObject() ){
1779 return &type.GetClass();
1780 }
1781 }
1782
1783 return NULL;
1784}
1785const CClass *Classes::Find( const string &fullName ) const
1786{
1787 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1788 char NestName[VN_SIZE] = ""; //入れ子メンバ
1789 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
1790
1791 return Find( NamespaceScopes( AreaName ), NestName );
1792}
1793void Classes::StartCompile( const UserProc *pUserProc ){
1794 const CClass *pParentClass = pUserProc->GetParentClassPtr();
1795 if( pParentClass ){
1796 pParentClass->Using();
1797
1798 // 仮想関数になるメソッドに使用チェックをつける
1799 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetMethods() )
1800 {
1801 if( pMethod->IsVirtual() )
1802 {
1803 pMethod->GetUserProc().Using();
1804 }
1805 }
1806
1807 pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc );
1808 if( !pCompilingMethod ){
1809 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
1810 if( !pCompilingMethod ){
1811 SmoothieException::Throw(300);
1812 }
1813 }
1814 }
1815 else{
1816 pCompilingMethod = NULL;
1817 }
1818}
1819
1820const CClass *Classes::GetStringClassPtr() const
1821{
1822 if( !pStringClass ){
1823 // キャッシュしておく
1824 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
1825
1826 if( !pStringClass )
1827 {
1828 SmoothieException::Throw();
1829 }
1830 return pStringClass;
1831 }
1832 return pStringClass;
1833}
1834const CClass *Classes::GetObjectClassPtr() const
1835{
1836 if( !pObjectClass ){
1837 // キャッシュしておく
1838 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
1839
1840 if( !pObjectClass )
1841 {
1842 SmoothieException::Throw();
1843 }
1844 return pObjectClass;
1845 }
1846 return pObjectClass;
1847}
Note: See TracBrowser for help on using the repository browser.