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

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

64ビット版でもインターフェイスのベース実装周りをコンパイルできるようにした(インターフェイス機構自体はまだ未完成)

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