source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Class.cpp@ 465

Last change on this file since 465 was 465, checked in by dai_9181, 16 years ago

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

File size: 40.1 KB
Line 
1#include "stdafx.h"
2
3#include <Source.h>
4#include <Class.h>
5#include <Compiler.h>
6#include <NamespaceSupporter.h>
7
8#include "../common.h"
9#ifdef _AMD64_
10#include "../../BasicCompiler64/opcode.h"
11#else
12#include "../../BasicCompiler32/opcode.h"
13#endif
14
15
16Interface::Interface( const CClass *pInterfaceClass, const Types &actualTypeParameters )
17 : DynamicMethodsPrototype()
18 , pInterfaceClass( pInterfaceClass )
19 , vtblOffset( -1 )
20 , actualTypeParameters( actualTypeParameters )
21{
22 //メソッドをコピー
23 BOOST_FOREACH( const CMethod *pBaseMethod, pInterfaceClass->GetDynamicMethods() )
24 {
25 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
26
27 // アクセシビリティ
28 if(pBaseMethod->GetAccessibility() == Prototype::Private){
29 pMethod->SetAccessibility( Prototype::None );
30 }
31 else{
32 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
33 }
34
35 //pobj_Inherits
36 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
37 if(pBaseMethod->GetInheritsClassPtr()==0){
38 pMethod->SetInheritsClassPtr( pInterfaceClass );
39 }
40 else{
41 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
42 }
43
44 AddDynamicMethods( pMethod );
45 }
46}
47
48std::string Interface::GetFullNameWithActualGenericTypeParameters() const
49{
50 std::string interfaceName = this->GetClass().GetFullName();
51 if( actualTypeParameters.size() )
52 {
53 std::string actualGenericTypesName;
54 BOOST_FOREACH( const Type &typeParameter, actualTypeParameters )
55 {
56 if( actualGenericTypesName.size() )
57 {
58 actualGenericTypesName += ",";
59 }
60 actualGenericTypesName += typeParameter.ToString();
61 }
62
63 interfaceName += "<" + actualGenericTypesName + ">";
64 }
65 return interfaceName;
66}
67
68bool CClass::IsClass() const
69{
70 return classType == CClass::Class;
71}
72bool CClass::IsInterface() const
73{
74 return classType == CClass::Interface;
75}
76bool CClass::IsComInterface() const
77{
78 return classType == CClass::ComInterface;
79}
80bool CClass::IsEnum() const
81{
82 return classType == CClass::Enum;
83}
84bool CClass::IsDelegate() const
85{
86 return classType == CClass::Delegate;
87}
88bool CClass::IsStructure() const
89{
90 return classType == CClass::Structure;
91}
92
93
94// コンストラクタのコンパイルを開始
95void CClass::NotifyStartConstructorCompile() const
96{
97 isCompilingConstructor = true;
98}
99
100//コンストラクタのコンパイルを終了
101void CClass::NotifyFinishConstructorCompile() const
102{
103 isCompilingConstructor = false;
104}
105
106//コンストラクタをコンパイル中かどうかを判別
107bool CClass::IsCompilingConstructor() const
108{
109 return isCompilingConstructor;
110}
111
112//デストラクタのコンパイルを開始
113void CClass::NotifyStartDestructorCompile() const{
114 isCompilingDestructor = true;
115}
116
117//デストラクタのコンパイルを終了
118void CClass::NotifyFinishDestructorCompile() const{
119 isCompilingDestructor = false;
120}
121
122//デストラクタをコンパイル中かどうかを判別
123bool CClass::IsCompilingDestructor() const
124{
125 return isCompilingDestructor;
126}
127
128//自身の派生クラスかどうかを確認
129bool CClass::IsSubClass( const CClass *pSubClass ) const
130{
131 if( !pSubClass->HasSuperClass() )
132 {
133 return false;
134 }
135
136 const CClass *pTempClass = &pSubClass->GetSuperClass();
137 while( pTempClass ){
138 if( this == pTempClass ) return true;
139 pTempClass = &pTempClass->GetSuperClass();
140 }
141 return false;
142}
143
144//自身と等しいまたは派生クラスかどうかを確認
145bool CClass::IsEqualsOrSubClass( const CClass *pSubClass ) const
146{
147 if( IsEquals( pSubClass ) ) return true;
148 return IsSubClass( pSubClass );
149}
150
151// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
152bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
153{
154 if( IsEquals( &objClass ) ) return true;
155 if( IsSubClass( &objClass ) ) return true;
156 if( objClass.IsSubClass( this ) ) return true;
157 return false;
158}
159
160bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
161{
162 BOOST_FOREACH( const ::Interface *pInterface, interfaces ){
163 if( pInterfaceClass == &pInterface->GetClass() ){
164 return true;
165 }
166 }
167 return false;
168}
169
170bool CClass::Inherits( const char *inheritNames, int nowLine ){
171 int i = 0;
172 bool isInheritsClass = false;
173 while( true ){
174
175 char temporary[VN_SIZE];
176 for( int i2=0;; i++, i2++ ){
177 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
178 temporary[i2] = 0;
179 break;
180 }
181 temporary[i2] = inheritNames[i];
182 }
183
184 // ジェネリクス構文を分解
185 char className[VN_SIZE];
186 Jenga::Common::Strings typeParameterStrings;
187 SplitGenericClassInstance( temporary, className, typeParameterStrings );
188
189 // 型パラメータ文字列から型データを取得
190 Types actualTypeParameters;
191 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
192 {
193 Type type;
194 compiler.StringToType( typeParameterStr, type );
195 actualTypeParameters.push_back( type );
196 }
197
198 //継承元クラスを取得
199 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
200 if( !pInheritsClass ){
201 compiler.errorMessenger.Output(106,className,nowLine);
202 return false;
203 }
204
205 if( pInheritsClass->IsClass() ){
206 // クラスを継承する
207 isInheritsClass = true;
208
209 if( !InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
210 return false;
211 }
212 }
213 else{
214 compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine);
215 return false;
216 }
217
218 if( inheritNames[i] == '\0' ){
219 break;
220 }
221 i++;
222 }
223
224 if( !isInheritsClass ){
225 // クラスを一つも継承していないとき
226 if( !InheritsClass( *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(), Types(), nowLine ) ){
227 return false;
228 }
229 }
230
231 return true;
232}
233bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine )
234{
235 //ループ継承でないかをチェック
236 if( !compiler.GetObjectModule().meta.GetClasses().LoopRefCheck(inheritsClass) )
237 {
238 compiler.errorMessenger.Output(123,inheritsClass.GetName(),nowLine);
239 return false;
240 }
241
242 if( !inheritsClass.IsReady() ){
243 //継承先が読み取られていないとき
244 compiler.GetObjectModule().meta.GetClasses().LookaheadClass(inheritsClass.GetName().c_str());
245 }
246
247 //メソッドをコピー
248 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
249 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
250
251 // アクセシビリティ
252 if(pBaseMethod->GetAccessibility() == Prototype::Private){
253 pMethod->SetAccessibility( Prototype::None );
254 }
255 else{
256 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
257 }
258
259 //pobj_Inherits
260 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
261 if(pBaseMethod->GetInheritsClassPtr()==0){
262 pMethod->SetInheritsClassPtr( &inheritsClass );
263 }
264 else{
265 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
266 }
267
268 GetDynamicMethods().push_back( pMethod );
269 }
270
271 //仮想関数の数
272 AddVtblNum( inheritsClass.GetVtblNum() );
273
274 //継承先のクラスをメンバとして保持する
275 SetSuperClass( &inheritsClass );
276 SetSuperClassActualTypeParameters( actualTypeParameters );
277
278 // インターフェイスを引き継ぐ
279 BOOST_FOREACH( ::Interface *pInterface, inheritsClass.GetInterfaces() )
280 {
281 interfaces.push_back( new ::Interface( *pInterface ) );
282 }
283
284 if( this->IsInterface() && inheritsClass.IsComInterface() )
285 {
286 // COMインターフェイスを継承した場合はCOMインターフェイスにする
287 this->SetClassType( CClass::ComInterface );
288 }
289
290 return true;
291}
292
293bool CClass::Implements( const CClass &interfaceClass, const Types &actualTypeParameters, int nowLine )
294{
295 if( !interfaceClass.IsInterface() && !interfaceClass.IsComInterface() )
296 {
297 // インターフェイスではないとき
298 compiler.errorMessenger.Output(138,interfaceClass.GetName().c_str(),nowLine );
299 return false;
300 }
301
302 if( !interfaceClass.IsReady() ){
303 // インターフェイスが未解析のとき
304 compiler.GetObjectModule().meta.GetClasses().LookaheadClass( interfaceClass.GetName().c_str() );
305 }
306
307 ::Interface *pDestInterface = new ::Interface( &interfaceClass, actualTypeParameters );
308
309 interfaces.push_back( pDestInterface );
310
311
312 /////////////////////////////////////////////////////////////////
313 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
314 /////////////////////////////////////////////////////////////////
315 BOOST_FOREACH( CMethod *pMethod, GetDynamicMethods() )
316 {
317 CMethod *pMethodForOverride = pDestInterface->GetDynamicMethods().FindForOverride( pDestInterface->GetActualTypeParameters(), &pMethod->GetUserProc() );
318 if( pMethodForOverride )
319 {
320 pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
321
322 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
323 pMethod->SetNotUseMark( true );
324 }
325 }
326
327
328 /////////////////////////////////////////////////////////////////
329 // キャストメソッドを追加(内部コードは自動生成すること)
330 /////////////////////////////////////////////////////////////////
331 if( interfaceClass.IsInterface() )
332 {
333 // Function Operator() As ITest
334
335 char temporary[1024];
336 sprintf(temporary,"%c%c%c%c()%c%c%s",
337 1, ESC_FUNCTION,
338 1, ESC_OPERATOR,
339 1, ESC_AS,
340 pDestInterface->GetFullNameWithActualGenericTypeParameters().c_str()
341 );
342
343 this->AddMethod(this,
344 Prototype::Public,
345 0,
346 false, // isConst
347 false, // isAbstract
348 false, // isVirtual
349 false, // isOverride
350 true, // isAutoGeneration
351 temporary,
352 -1
353 );
354 }
355
356
357 return true;
358}
359bool CClass::Implements( const char *interfaceNames, int nowLine )
360{
361 Jenga::Common::Strings paramStrs;
362 SplitParameter( interfaceNames, paramStrs );
363
364 BOOST_FOREACH( const std::string &paramStr, paramStrs )
365 {
366 char className[VN_SIZE];
367 Jenga::Common::Strings typeParameterStrings;
368 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
369
370 Types actualTypeParameters;
371 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
372 {
373 Type type;
374 compiler.StringToType( typeParameterStr, type );
375 actualTypeParameters.push_back( type );
376 }
377
378 //継承元クラスを取得
379 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( className );
380 if( !pInterfaceClass ){
381 compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine);
382 continue;
383 }
384
385 // インターフェイスを継承する
386 Implements( *pInterfaceClass, actualTypeParameters, nowLine );
387 }
388
389 return true;
390}
391
392CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
393{
394 extern int cp;
395
396 //構文を解析
397 char VarName[VN_SIZE];
398 char initBuffer[VN_SIZE];
399 char lpszConstructParameter[VN_SIZE];
400 Subscripts subscripts;
401 Type type;
402 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
403
404 //重複チェック
405 if(this->DupliCheckAll(VarName)){
406 compiler.errorMessenger.Output(15,VarName,cp);
407 }
408
409 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
410 pMember->source_code_address = nowLine;
411 return pMember;
412}
413void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
414 dynamicMembers.push_back(
415 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
416 );
417}
418void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
419 staticMembers.push_back(
420 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
421 );
422}
423
424void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
425 bool isVirtual, bool isOverride, bool isAutoGeneration, char *buffer, int nowLine){
426 int i,i2;
427 char temporary[VN_SIZE];
428
429 i=2;
430 for(i2=0;;i++,i2++){
431 if(buffer[i]=='('||buffer[i]=='\0'){
432 temporary[i2]=0;
433 break;
434 }
435 temporary[i2]=buffer[i];
436 }
437
438
439 //関数ハッシュへ登録
440 char interfaceName[VN_SIZE] = "";
441 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().AddUserProc( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0), interfaceName );
442 if(!pUserProc) return;
443
444 if( isAutoGeneration )
445 {
446 // コード自動生成
447 pUserProc->ThisIsAutoGenerationProc();
448 }
449
450
451 ////////////////////////////////////////////////////////////
452 // コンストラクタ、デストラクタの場合の処理
453 ////////////////////////////////////////////////////////////
454 BOOL fConstructor=0,bDestructor=0;
455
456 if(lstrcmp(temporary,pobj_c->GetName().c_str())==0){
457 //コンストラクタの場合
458
459 //標準コンストラクタ(引数なし)
460 if(pUserProc->Params().size()==0) fConstructor=1;
461
462 //強制的にConst修飾子をつける
463 isConst = true;
464 }
465 else if(temporary[0]=='~'){
466 //デストラクタの場合はその名前が正しいかチェックを行う
467 if(lstrcmp(temporary+1,pobj_c->GetName().c_str())!=0)
468 compiler.errorMessenger.Output(117,NULL,nowLine);
469 else
470 bDestructor=1;
471 }
472 if(fConstructor||bDestructor){
473 // コンストラクタ、デストラクタのアクセシビリティをチェック
474
475 //強制的にConst修飾子をつける
476 isConst = true;
477 }
478
479 if( fConstructor == 1 )
480 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
481 else if( bDestructor )
482 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
483
484
485
486 //////////////////
487 // 重複チェック
488 //////////////////
489
490 if(pobj_c->DupliCheckMember(temporary)){
491 compiler.errorMessenger.Output(15,temporary,nowLine);
492 return;
493 }
494
495 //メソッド
496 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
497 {
498 //基底クラスと重複する場合はオーバーライドを行う
499 if( pMethod->GetInheritsClassPtr() ) continue;
500
501 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
502 {
503 //関数名、パラメータ、戻り値が合致したとき
504 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
505 return;
506 }
507 }
508
509 //仮想関数の場合
510 if( isAbstract ) pUserProc->CompleteCompile();
511
512 // メソッドのオーバーライド
513 CMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
514 if( pMethodForOverride )
515 {
516 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
517 pUserProc->SetMethod( pMethodForOverride );
518 return;
519 }
520 else
521 {
522 // インターフェイス メソッドのオーバーライド
523 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
524 {
525 if( interfaceName[0] )
526 {
527 if( pInterface->GetClass().GetName() != interfaceName )
528 {
529 // 指定されたインターフェイス名と整合しないとき
530 continue;
531 }
532 }
533
534 if( !pInterface->GetClass().IsReady() ){
535 // インターフェイスが未解析のとき
536 compiler.GetObjectModule().meta.GetClasses().LookaheadClass( pInterface->GetClass().GetName().c_str() );
537 }
538
539 CMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
540 if( pMethodForOverride )
541 {
542 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
543 pUserProc->SetMethod( pMethodForOverride );
544 return;
545 }
546 }
547 }
548
549 if( interfaceName[0] )
550 {
551 compiler.errorMessenger.Output(139,interfaceName,nowLine);
552 }
553
554 if( isVirtual ){
555 pobj_c->AddVtblNum( 1 );
556 }
557
558 if( isOverride ){
559 compiler.errorMessenger.Output(12,"Override",nowLine);
560 }
561
562 if(bStatic){
563 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
564 }
565 else{
566 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
567 }
568}
569
570bool CClass::DupliCheckAll(const char *name) const
571{
572 //重複チェック
573
574 //メンバ
575 if(DupliCheckMember(name)) return 1;
576
577 //メソッド
578 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
579 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
580 return 1;
581 }
582 }
583
584 return 0;
585}
586bool CClass::DupliCheckMember(const char *name) const
587{
588 //重複チェック
589
590 if( this->HasSuperClass() )
591 {
592 if( this->GetSuperClass().DupliCheckMember( name ) )
593 {
594 // 基底クラスで重複が発見された
595 return true;
596 }
597 }
598
599 // 動的メンバ
600 BOOST_FOREACH( CMember *pMember, dynamicMembers )
601 {
602 if( GetName() == pMember->GetName() )
603 {
604 return true;
605 }
606 }
607
608 // 静的メンバ
609 BOOST_FOREACH( CMember *pMember, staticMembers ){
610 if( GetName() == pMember->GetName() ){
611 return true;
612 }
613 }
614
615 return false;
616}
617
618const CMember *CClass::FindDynamicMember( const char *memberName ) const
619{
620 if( this->HasSuperClass() )
621 {
622 // 基底クラスで検索
623 const CMember *result = this->GetSuperClass().FindDynamicMember( memberName );
624 if( result )
625 {
626 return result;
627 }
628 }
629
630 BOOST_FOREACH( CMember *pMember, GetDynamicMembers() )
631 {
632 if( pMember->GetName() == memberName )
633 {
634 return pMember;
635 }
636 }
637 return NULL;
638}
639
640void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
641{
642 // 動的メソッド
643 GetDynamicMethods().Enum( methodName, subs );
644
645 // インターフェイス メソッド
646 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
647 {
648 pInterface->GetDynamicMethods().Enum( methodName, subs );
649 }
650}
651const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
652{
653 // 動的メソッド
654 const CMethod *result = GetDynamicMethods().GetMethodPtr( pUserProc );
655
656 if( !result )
657 {
658 // インターフェイス メソッド
659 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
660 {
661 result = pInterface->GetDynamicMethods().GetMethodPtr( pUserProc );
662 if( result )
663 {
664 return result;
665 }
666 }
667 }
668
669 return result;
670}
671
672const ::Delegate &CClass::GetDelegate() const
673{
674 const ::Delegate *dg = compiler.GetObjectModule().meta.GetDelegates().GetHashArrayElement( GetName().c_str() );
675 while( dg )
676 {
677 if( dg->IsEqualSymbol( GetNamespaceScopes(), GetName() ) ){
678 //名前空間とクラス名が一致した
679 return *dg;
680 }
681 dg = dg->GetChainNext();
682 }
683
684 Jenga::Throw( "CClass::GetDelegateメソッドに失敗" );
685 static ::Delegate dummy;
686 return dummy;
687}
688
689//サイズを取得
690int CClass::GetSize() const
691{
692 int resultSize = 0;
693
694 int alignment = 1;
695 if( this->IsStructure() )
696 {
697 // 構造体のとき
698
699 if( this->GetFixedAlignment() )
700 {
701 // アラインメントの固定値が指定されていた場合はそれを取得
702 alignment = this->GetFixedAlignment();
703 }
704 }
705 else
706 {
707 // それ以外
708
709 if( this->HasSuperClass() )
710 {
711 // 基底クラスのサイズを追加
712 resultSize += this->GetSuperClass().GetSize();
713
714 // 基底クラスのアラインメントを取得
715 alignment = this->GetSuperClass().GetAlignment();
716 }
717 else
718 {
719 // 基底クラスが存在しないとき
720
721 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
722 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
723 }
724 }
725
726 BOOST_FOREACH( CMember *pMember, dynamicMembers )
727 {
728 // メンバサイズ
729 int tempMemberSize = pMember->GetType().GetSize();
730
731 // 一時アラインメントを算出
732 int tempAlignment = tempMemberSize;
733 if( pMember->GetType().IsStruct() )
734 {
735 // メンバが構造体の場合は、メンバのアラインメントを取得
736 tempAlignment = pMember->GetType().GetClass().GetAlignment();
737 }
738
739 // アラインメントを考慮してパディングを追加
740 if( GetFixedAlignment() && alignment < tempAlignment )
741 {
742 if( resultSize % alignment )
743 {
744 resultSize += alignment - ( resultSize % alignment );
745 }
746 }
747 else
748 {
749 if( alignment < tempAlignment )
750 {
751 // 最大アラインメントを更新
752 alignment = tempAlignment;
753 }
754
755 if( tempMemberSize == 0 )
756 {
757 if( !pMember->GetType().IsStruct() )
758 {
759 compiler.errorMessenger.OutputFatalError();
760 }
761
762 //メンバを持たない構造体
763 //※何もしない(オフセットの計算をしない)
764 }
765 else{
766 if( resultSize % tempAlignment )
767 {
768 resultSize += tempAlignment - ( resultSize % tempAlignment );
769 }
770 }
771 }
772
773 // メンバサイズを加算(配列を考慮)
774 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
775 }
776
777 if( alignment )
778 {
779 // 末尾アラインメントを考慮してパディングを追加
780 if( resultSize % alignment )
781 {
782 resultSize += alignment - ( resultSize % alignment );
783 }
784 }
785
786 return resultSize;
787}
788
789//メンバのオフセットを取得
790int CClass::GetMemberOffset( const char *memberName ) const
791{
792 int resultSize = 0;
793
794 int alignment = 1;
795 if( this->IsStructure() )
796 {
797 // 構造体のとき
798
799 if( this->GetFixedAlignment() )
800 {
801 // アラインメントの固定値が指定されていた場合はそれを取得
802 alignment = this->GetFixedAlignment();
803 }
804 }
805 else
806 {
807 // それ以外
808
809 if( this->HasSuperClass() )
810 {
811 if( this->GetSuperClass().HasDynamicMember( memberName ) )
812 {
813 // 基底クラスのメンバを取得
814 return this->GetSuperClass().GetMemberOffset( memberName );
815 }
816
817 // 基底クラスのサイズを追加
818 resultSize += this->GetSuperClass().GetSize();
819
820 // 基底クラスのアラインメントを取得
821 alignment = this->GetSuperClass().GetAlignment();
822 }
823 else
824 {
825 // 基底クラスが存在しないとき
826
827 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
828 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
829 }
830 }
831
832 BOOST_FOREACH( CMember *pMember, dynamicMembers )
833 {
834 // メンバサイズ
835 int tempMemberSize = pMember->GetType().GetSize();
836
837 // 一時アラインメントを算出
838 int tempAlignment = tempMemberSize;
839 if( pMember->GetType().IsStruct() )
840 {
841 // メンバが構造体の場合は、メンバのアラインメントを取得
842 tempAlignment = pMember->GetType().GetClass().GetAlignment();
843 }
844
845 // アラインメントを考慮してパディングを追加
846 if( GetFixedAlignment() && alignment < tempAlignment )
847 {
848 if( resultSize % alignment )
849 {
850 resultSize += alignment - ( resultSize % alignment );
851 }
852 }
853 else
854 {
855 if( alignment < tempAlignment )
856 {
857 // 最大アラインメントを更新
858 alignment = tempAlignment;
859 }
860
861 if( tempMemberSize == 0 )
862 {
863 if( !pMember->GetType().IsStruct() )
864 {
865 compiler.errorMessenger.OutputFatalError();
866 }
867
868 //メンバを持たない構造体
869 //※何もしない(オフセットの計算をしない)
870 }
871 else{
872 if( resultSize % tempAlignment )
873 {
874 resultSize += tempAlignment - ( resultSize % tempAlignment );
875 }
876 }
877 }
878
879 if(memberName){
880 //メンバ指定がある場合は、オフセットを返す
881 if( pMember->GetName() == memberName )
882 {
883 return resultSize;
884 }
885 }
886
887 // メンバサイズを加算(配列を考慮)
888 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
889 }
890
891 if( alignment )
892 {
893 // 末尾アラインメントを考慮してパディングを追加
894 if( resultSize % alignment )
895 {
896 resultSize += alignment - ( resultSize % alignment );
897 }
898 }
899
900 return resultSize;
901}
902int CClass::GetAlignment() const
903{
904 int alignment = 1;
905 if( this->IsStructure() )
906 {
907 // 構造体のとき
908
909 if( this->GetFixedAlignment() )
910 {
911 // アラインメントの固定値が指定されていた場合はそれを取得
912 return this->GetFixedAlignment();
913 }
914 }
915 else
916 {
917 // それ以外
918
919 if( this->HasSuperClass() )
920 {
921 // 基底クラスのアラインメントを取得
922 alignment = this->GetSuperClass().GetAlignment();
923 }
924 else
925 {
926 // 基底クラスが存在しないとき
927
928 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
929 alignment = PTR_SIZE;
930 }
931 }
932
933 BOOST_FOREACH( CMember *pMember, dynamicMembers )
934 {
935 int tempAlignment = pMember->GetType().GetSize();
936 if( pMember->GetType().IsStruct() )
937 {
938 // メンバが構造体の場合は、メンバのアラインメントを取得
939 tempAlignment = pMember->GetType().GetClass().GetAlignment();
940 }
941
942 if( alignment < tempAlignment )
943 {
944 // 最大アラインメントを更新
945 alignment = tempAlignment;
946 }
947 }
948
949 return alignment;
950}
951
952void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
953{
954 vtblMasterListIndex = 0;
955
956 vtblIndex = 0;
957 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
958 if( &pMethod->GetUserProc() == pUserProc )
959 {
960 return;
961 }
962
963 if( pMethod->IsVirtual() )
964 {
965 vtblIndex++;
966 }
967 }
968
969 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
970 {
971 vtblMasterListIndex++;
972
973 vtblIndex = 0;
974 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
975 if( &pMethod->GetUserProc() == pUserProc )
976 {
977 return;
978 }
979
980 if( pMethod->IsVirtual() )
981 {
982 vtblIndex++;
983 }
984 }
985 }
986
987 compiler.errorMessenger.OutputFatalError();
988 return;
989}
990int CClass::GetVtblMasterListIndex( const CClass *pClass ) const
991{
992 int result = 0;
993
994 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
995 {
996 result++;
997
998 if( &pInterface->GetClass() == pClass )
999 {
1000 return result;
1001 }
1002 }
1003
1004 compiler.errorMessenger.OutputFatalError();
1005 return 0;
1006}
1007long CClass::GetComVtblOffset() const
1008{
1009 return comVtblOffset;
1010}
1011long CClass::GetVtblMasterListOffset() const
1012{
1013 //既に存在する場合はそれを返す
1014 if( vtblMasterListOffset == -1 )
1015 {
1016 compiler.errorMessenger.OutputFatalError();
1017 }
1018
1019 return vtblMasterListOffset;
1020}
1021void CClass::GenerateVTableMasterList( const std::vector<long> &vtableMasterList, long &offset )
1022{
1023 offset = compiler.GetObjectModule().dataTable.AddBinary(
1024 (void *)&vtableMasterList[0],
1025 static_cast<int>(vtableMasterList.size()*sizeof(LONG_PTR))
1026 );
1027}
1028void CClass::GenerateFullVTables()
1029{
1030 if( IsAbstract() )
1031 {
1032 // 抽象クラスは無視
1033 return;
1034 }
1035 if( !IsUsing() )
1036 {
1037 // 使われていないクラスは無視
1038 return;
1039 }
1040
1041 // vtblマスターリストの元データに不要なデータが含まれていたらエラー
1042 if( vtblMasterList.size() )
1043 {
1044 compiler.errorMessenger.OutputFatalError();
1045 }
1046
1047 // 自身のクラスのvtblを生成
1048 GetDynamicMethods().GenerateVTablePart( this->vtbl_offset );
1049 vtblMasterList.push_back( this->vtbl_offset );
1050
1051 // インターフェイスのvtblを生成
1052 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1053 {
1054 long tempVtblOffset;
1055 pInterface->GetDynamicMethods().GenerateVTablePart( tempVtblOffset );
1056 vtblMasterList.push_back( tempVtblOffset );
1057
1058 pInterface->SetVtblOffset( tempVtblOffset );
1059
1060 if( pInterface->GetClass().IsComInterface() )
1061 {
1062 if( this->comVtblOffset )
1063 {
1064 compiler.errorMessenger.OutputFatalError();
1065 }
1066 this->comVtblOffset = tempVtblOffset;
1067 }
1068 }
1069
1070 // vtblマスターリストを生成
1071 GenerateVTableMasterList( vtblMasterList, this->vtblMasterListOffset );
1072}
1073void CClass::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection )
1074{
1075 if( IsAbstract() )
1076 {
1077 // 抽象クラスは無視
1078 return;
1079 }
1080 if( !IsUsing() )
1081 {
1082 // 使われていないクラスは無視
1083 return;
1084 }
1085 if(vtbl_offset==-1) return;
1086
1087 // 自身のクラスのvtbl
1088 {
1089 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtbl_offset);
1090
1091 for( int i=0; i<GetVtblNum(); i++ ){
1092 const UserProc *pUserProc = (UserProc *)pVtbl[i];
1093 if(!pUserProc) continue;
1094
1095 if( pUserProc->GetBeginOpAddress() == 0
1096 && pUserProc->GetEndOpAddress() == 0 )
1097 {
1098 Jenga::Throw( "未解決の仮想関数が存在する" );
1099 }
1100
1101 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
1102 }
1103 }
1104
1105 // インターフェイスのvtbl
1106 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1107 {
1108 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + pInterface->GetVtblOffset());
1109
1110 for( int i=0; i<pInterface->GetClass().GetVtblNum(); i++ ){
1111 const UserProc *pUserProc = (UserProc *)pVtbl[i];
1112 if(!pUserProc) continue;
1113
1114 if( pUserProc->GetBeginOpAddress() == 0
1115 && pUserProc->GetEndOpAddress() == 0 )
1116 {
1117 Jenga::Throw( "未解決の仮想関数が存在する" );
1118 }
1119
1120 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
1121 }
1122 }
1123
1124 // vtblマスターリスト
1125 LONG_PTR *pVtblMasterList = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtblMasterListOffset );
1126 for( int i=0; i<static_cast<int>(vtblMasterList.size()); i++ )
1127 {
1128 pVtblMasterList[i] = vtblMasterList[i] + ImageBase + MemPos_DataSection;
1129 }
1130}
1131bool CClass::IsAbstract() const
1132{
1133 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
1134
1135 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
1136 if(pMethod->IsVirtual()){
1137 if(pMethod->IsAbstract()){
1138 return true;
1139 }
1140 }
1141 }
1142
1143 // インターフェイスのvtbl
1144 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1145 {
1146 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
1147 if(pMethod->IsVirtual()){
1148 if(pMethod->IsAbstract()){
1149 return true;
1150 }
1151 }
1152 }
1153 }
1154
1155 return false;
1156}
1157
1158CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
1159 return new CClass(namespaceScopes, importedNamespaces, name);
1160}
1161bool Classes::Insert( CClass *pClass, int nowLine )
1162{
1163 /////////////////////////////////
1164 // ハッシュデータに追加
1165 /////////////////////////////////
1166
1167 if( !Put( pClass ) )
1168 {
1169 compiler.errorMessenger.Output(15,pClass->GetName(), nowLine);
1170 return false;
1171 }
1172 return true;
1173}
1174CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
1175 //////////////////////////////////////////////////////////////////////////
1176 // クラスを追加
1177 // ※名前のみを登録。その他の情報はSetClassメソッドで!
1178 //////////////////////////////////////////////////////////////////////////
1179
1180 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
1181
1182 if( !Insert( pClass, nowLine ) )
1183 {
1184 return NULL;
1185 }
1186
1187 return pClass;
1188}
1189
1190void Classes::GenerateVTables()
1191{
1192 Iterator_Reset();
1193 while( Iterator_HasNext() )
1194 {
1195 CClass *pClass = Iterator_GetNext();
1196 pClass->GenerateFullVTables();
1197 }
1198}
1199
1200void Classes::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection ){
1201 Iterator_Reset();
1202 while( Iterator_HasNext() )
1203 {
1204 CClass *pClass = Iterator_GetNext();
1205 pClass->ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection);
1206 }
1207}
1208
1209
1210void Classes::InitStaticMember(){
1211 //静的メンバをグローバル領域に作成
1212
1213 //イテレータをリセット
1214
1215 extern int cp;
1216 int back_cp=cp;
1217
1218 this->Iterator_Reset();
1219 while(this->Iterator_HasNext()){
1220 CClass &objClass = *this->Iterator_GetNext();
1221 if( objClass.isTargetObjectModule == false )
1222 {
1223 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
1224 continue;
1225 }
1226
1227 // 名前空間をセット
1228 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
1229
1230 DWORD dwFlags = 0;
1231 if( objClass.GetName() == "_System_TypeBase" )
1232 {
1233 // _System_TypeBaseクラスはグローバル、スタティック領域を初期化するためのクラスなのでここでの初期化は除外する
1234 dwFlags |= DIMFLAG_NONCALL_CONSTRACTOR;
1235 }
1236
1237 // コンパイル中クラスとしてセット
1238 compiler.pCompilingClass = &objClass;
1239
1240 const EnumInfo *pEnumInfo = NULL;
1241 if( objClass.IsEnum() )
1242 {
1243 pEnumInfo = compiler.enumInfoCollection.Find( objClass );
1244 }
1245
1246 int i=0;
1247 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() )
1248 {
1249 if( pEnumInfo )
1250 {
1251 cp = pEnumInfo->GetEnumMember( member->GetName() ).GetSourceIndex();
1252 }
1253
1254 char temporary[VN_SIZE];
1255 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
1256 dim(
1257 temporary,
1258 member->GetSubscripts(),
1259 member->GetType(),
1260 member->GetInitializeExpression().c_str(),
1261 member->GetConstructParameter().c_str(),
1262 dwFlags);
1263
1264 i++;
1265 }
1266
1267 compiler.pCompilingClass = NULL;
1268 }
1269
1270 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
1271
1272 cp=back_cp;
1273}
1274
1275void Classes::Compile_System_InitializeUserTypes(){
1276 char temporary[VN_SIZE];
1277
1278 ////////////////////////////////////////////////////////////////////
1279 // クラス登録
1280 ////////////////////////////////////////////////////////////////////
1281
1282 // イテレータをリセット
1283 Iterator_Reset();
1284
1285 while( Iterator_HasNext() ){
1286 const CClass &objClass = *Iterator_GetNext();
1287
1288 if( !objClass.IsUsing() ){
1289 // 未使用のクラスは無視する
1290 continue;
1291 }
1292
1293 std::string referenceOffsetsBuffer;
1294 int numOfReference = 0;
1295 objClass.GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference );
1296
1297 sprintf( temporary
1298 , "Add(%c%c_System_TypeForClass[strNamespace=\"%s\",name=\"%s\",fullName=\"%s\",referenceOffsets=[%s],numOfReference=%d])"
1299 , 1
1300 , ESC_SYSTEM_STATIC_NEW
1301 , objClass.GetNamespaceScopes().ToString().c_str() // 名前空間
1302 , objClass.GetName().c_str() // クラス名
1303 , objClass.GetFullName().c_str() // フルネーム
1304 , referenceOffsetsBuffer.c_str() // 参照メンバオフセット配列
1305 , numOfReference // 参照メンバの個数
1306 );
1307
1308 // コンパイル
1309 ChangeOpcode( temporary );
1310
1311 objClass.SetTypeInfoDataTableOffset(
1312 compiler.GetObjectModule().dataTable.GetLastMadeConstObjectDataTableOffset()
1313 );
1314 }
1315}
1316void Classes::Compile_System_InitializeUserTypesForBaseType()
1317{
1318 extern int cp;
1319 cp = -1;
1320 ////////////////////////////////////////////////////////////////////
1321 // 基底クラスを登録
1322 ////////////////////////////////////////////////////////////////////
1323
1324 char temporary[8192];
1325 sprintf(temporary, "%c%ctempType=Nothing%c%c_System_TypeForClass"
1326 , HIBYTE( COM_DIM )
1327 , LOBYTE( COM_DIM )
1328 , 1
1329 , ESC_AS
1330 );
1331 ChangeOpcode( temporary );
1332
1333 // イテレータをリセット
1334 Iterator_Reset();
1335
1336 while( Iterator_HasNext() ){
1337 const CClass &objClass = *Iterator_GetNext();
1338
1339 if( !objClass.IsUsing() ){
1340 // 未使用のクラスは無視する
1341 continue;
1342 }
1343
1344 if( objClass.HasSuperClass() || objClass.GetDynamicMembers().size() ){
1345 sprintf( temporary
1346 , "tempType=Search(\"%s\") As ActiveBasic.Core._System_TypeForClass"
1347 , objClass.GetFullName().c_str()
1348 );
1349
1350 // コンパイル
1351 MakeMiddleCode( temporary );
1352 ChangeOpcode( temporary );
1353
1354 sprintf( temporary
1355 , "tempType.SetClassInfo(%d,_System_GetComVtbl(%s),_System_GetVtblList(%s),_System_GetDefaultConstructor(%s),_System_GetDestructor(%s))"
1356 , objClass.GetSize()
1357 , objClass.GetFullName().c_str()
1358 , objClass.GetFullName().c_str()
1359 , objClass.GetFullName().c_str()
1360 , objClass.GetFullName().c_str()
1361 , objClass.GetName().c_str()
1362 );
1363
1364 // コンパイル
1365 ChangeOpcode( temporary );
1366
1367 if( objClass.HasSuperClass() )
1368 {
1369 sprintf( temporary
1370 , "tempType.SetBaseType(Search(\"%s\"))"
1371 , objClass.GetSuperClass().GetFullName().c_str()
1372 );
1373
1374 // コンパイル
1375 ChangeOpcode( temporary );
1376 }
1377
1378 if( objClass.GetDynamicMembers().size() )
1379 {
1380 // メンバの型を示すTypeInfoオブジェクトへのDataOffset配列の静的データ定義文字列を取得
1381 sprintf(
1382 temporary,
1383 "tempType.SetMembers([%s],[%s],[%s],%d)",
1384 objClass.GetStaticDefiningStringAsMemberNames().c_str(),
1385 objClass.GetStaticDefiningStringAsMemberTypeInfoNames().c_str(),
1386 objClass.GetStaticDefiningStringAsMemberOffsets().c_str(),
1387 objClass.GetDynamicMembers().size()
1388 );
1389 ChangeOpcode( temporary );
1390 }
1391 }
1392 }
1393}
1394
1395const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1396{
1397 if( namespaceScopes.size() == 0 && name == "Object" ){
1398 return GetObjectClassPtr();
1399 }
1400 else if( namespaceScopes.size() == 0 && name == "String" ){
1401 return GetStringClassPtr();
1402 }
1403
1404 std::vector<const CClass *> classes;
1405 const CClass *pClass = GetHashArrayElement( name.c_str() );
1406 while( pClass )
1407 {
1408 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1409 //名前空間とクラス名が一致した
1410 classes.push_back( pClass );
1411 }
1412 pClass = pClass->GetChainNext();
1413 }
1414 if( classes.size() > 0 )
1415 {
1416 // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
1417 pClass = classes.front();
1418
1419 BOOST_FOREACH( const CClass *pTempClass, classes )
1420 {
1421 if( pClass->GetNamespaceScopes().size() < pTempClass->GetNamespaceScopes().size() )
1422 {
1423 pClass = pTempClass;
1424 }
1425 }
1426
1427 return pClass;
1428 }
1429
1430 // TypeDefも見る
1431 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
1432 if( index != -1 ){
1433 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
1434 if( type.IsObject() ){
1435 return &type.GetClass();
1436 }
1437 }
1438
1439 return NULL;
1440}
1441const CClass *Classes::Find( const string &fullName ) const
1442{
1443 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1444 char NestName[VN_SIZE] = ""; //入れ子メンバ
1445 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
1446
1447 return Find( NamespaceScopes( AreaName ), NestName );
1448}
1449void Classes::StartCompile( const UserProc *pUserProc ){
1450 const CClass *pParentClass = pUserProc->GetParentClassPtr();
1451 if( pParentClass ){
1452 pParentClass->Using();
1453
1454 // 仮想関数になるメソッドに使用チェックをつける
1455 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
1456 {
1457 if( pMethod->IsVirtual() )
1458 {
1459 pMethod->GetUserProc().Using();
1460 }
1461 }
1462
1463 pCompilingMethod = pParentClass->GetDynamicMethodOrInterfaceMethod( pUserProc );
1464 if( !pCompilingMethod ){
1465 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
1466 if( !pCompilingMethod ){
1467 compiler.errorMessenger.OutputFatalError();
1468 }
1469 }
1470 }
1471 else{
1472 pCompilingMethod = NULL;
1473 }
1474}
1475
1476const CClass *Classes::GetStringClassPtr() const
1477{
1478 if( !pStringClass ){
1479 // キャッシュしておく
1480 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
1481
1482 if( !pStringClass )
1483 {
1484 compiler.errorMessenger.Output(400, "System.String", cp);
1485 static CClass dummy;
1486 return &dummy;
1487 }
1488 return pStringClass;
1489 }
1490 return pStringClass;
1491}
1492const CClass *Classes::GetObjectClassPtr() const
1493{
1494 if( !pObjectClass ){
1495 // キャッシュしておく
1496 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
1497
1498 if( !pObjectClass )
1499 {
1500 compiler.errorMessenger.Output(400, "System.Object", cp);
1501 static CClass dummy;
1502 return &dummy;
1503 }
1504 return pObjectClass;
1505 }
1506 return pObjectClass;
1507}
1508const CClass *Classes::GetInterfaceInfoClassPtr() const
1509{
1510 if( !pInterfaceInfo ){
1511 // キャッシュしておく
1512 pInterfaceInfo = this->Find( "ActiveBasic.Core.InterfaceInfo" );
1513
1514 if( !pInterfaceInfo )
1515 {
1516 compiler.errorMessenger.Output(400, "ActiveBasic.Core.InterfaceInfo", cp);
1517 static CClass dummy;
1518 return &dummy;
1519 }
1520 return pInterfaceInfo;
1521 }
1522 return pInterfaceInfo;
1523}
1524
1525std::string CClass::GetStaticDefiningStringAsMemberNames() const
1526{
1527 std::string result;
1528
1529 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1530 {
1531 if( result.size() )
1532 {
1533 result += ",";
1534 }
1535
1536 result += "\"" + pMember->GetName() + "\"";
1537 }
1538
1539 return result;
1540}
1541std::string CClass::GetStaticDefiningStringAsMemberTypeInfoNames() const
1542{
1543 std::string result;
1544
1545 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1546 {
1547 if( result.size() )
1548 {
1549 result += ",";
1550 }
1551
1552 result += "\"" + compiler.TypeToString( pMember->GetType() ) + "\"";
1553 }
1554
1555 return result;
1556}
1557std::string CClass::GetStaticDefiningStringAsMemberOffsets() const
1558{
1559 std::string result;
1560
1561 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1562 {
1563 if( result.size() )
1564 {
1565 result += ",";
1566 }
1567
1568 int offset = this->GetMemberOffset( pMember->GetName().c_str() );
1569
1570 char temporary[255];
1571 itoa( offset, temporary, 16 );
1572
1573 result += (std::string)"&H" + temporary;
1574 }
1575
1576 return result;
1577}
1578
1579void CClass::GetReferenceOffsetsInitializeBuffer( std::string &referenceOffsetsBuffer, int &numOfReference, int baseOffset ) const
1580{
1581 const CClass &thisClass = *this;
1582 BOOST_FOREACH( const CMember *pMember, thisClass.GetDynamicMembers() )
1583 {
1584 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() )
1585 {
1586 if( referenceOffsetsBuffer.size() )
1587 {
1588 referenceOffsetsBuffer += ",";
1589 }
1590
1591 char temp[255];
1592 sprintf( temp, "%d", baseOffset + thisClass.GetMemberOffset( pMember->GetName().c_str() ) );
1593 referenceOffsetsBuffer += temp;
1594
1595 numOfReference++;
1596 }
1597 if( pMember->GetType().IsStruct() && !pMember->GetType().IsPointer() )
1598 {
1599 // 構造体の実体をメンバに持つとき
1600 int baseOffset = thisClass.GetMemberOffset( pMember->GetName().c_str() );
1601
1602 // 構造体メンバでGCによるチェックが必要な参照位置を追加
1603 pMember->GetType().GetClass().GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference, baseOffset );
1604 }
1605 }
1606}
Note: See TracBrowser for help on using the repository browser.