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

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