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

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