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

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