source: dev/trunk/ab5.0/abdev/ab_common/src/Lexical/Class.cpp@ 779

Last change on this file since 779 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 22.2 KB
Line 
1#include "stdafx.h"
2#include <algorithm>
3#include <boost/checked_delete.hpp>
4
5CClass::CClass( const Symbol &symbol, const NamespaceScopesCollection &importedNamespaces )
6 : ClassPrototype( symbol )
7 , importedNamespaces( importedNamespaces )
8 , classType( Class )
9 , pSuperClass( NULL )
10 , blittableType( Type() )
11 , isReady( false )
12 , fixedAlignment( 0 )
13 , ConstructorMemberSubIndex( -1 )
14 , DestructorMemberSubIndex( -1 )
15 , vtblNum( 0 )
16 , vtbl_offset( -1 )
17 , comVtblOffset( 0 )
18 , isCompilingConstructor( false )
19 , isCompilingDestructor( false )
20 , cacheSize( 0 )
21{
22}
23
24CClass::CClass(
25 const Symbol &symbol,
26 const NamespaceScopesCollection &importedNamespaces,
27 ClassType classType,
28 const GenericTypes &formalGenericTypes,
29 const Types &superClassActualTypeParameters,
30 int ConstructorMemberSubIndex,
31 int DestructorMemberSubIndex,
32 int vtblNum,
33 int fixedAlignment,
34 const Types &expandedClassActualTypeParameters )
35 : ClassPrototype( symbol )
36 , importedNamespaces( importedNamespaces )
37 , classType( classType )
38 , formalGenericTypes( formalGenericTypes )
39 , pSuperClass( NULL )
40 , superClassActualTypeParameters( superClassActualTypeParameters )
41 , blittableType( Type() )
42 , isReady( false )
43 , ConstructorMemberSubIndex( ConstructorMemberSubIndex )
44 , DestructorMemberSubIndex( DestructorMemberSubIndex )
45 , vtblNum( vtblNum )
46 , fixedAlignment( fixedAlignment )
47 , expandedClassActualTypeParameters( expandedClassActualTypeParameters )
48 , vtbl_offset( -1 )
49 , comVtblOffset( 0 )
50 , isCompilingConstructor( false )
51 , isCompilingDestructor( false )
52 , cacheSize( 0 )
53{
54}
55
56CClass::CClass()
57 : ClassPrototype()
58 , importedNamespaces()
59 , classType()
60 , pSuperClass( NULL )
61 , blittableType( Type() )
62 , isReady( false )
63 , fixedAlignment( 0 )
64 , ConstructorMemberSubIndex( -1 )
65 , DestructorMemberSubIndex( -1 )
66 , vtblNum( 0 )
67 , vtbl_offset( -1 )
68 , comVtblOffset( 0 )
69 , isCompilingConstructor( false )
70 , isCompilingDestructor( false )
71 , cacheSize( 0 )
72{
73}
74
75CClass::~CClass()
76{
77 using std::for_each;
78 using boost::checked_deleter;
79 // 動的メンバ
80 for_each( dynamicMembers.begin(), dynamicMembers.end(), checked_deleter<Member>() );
81 // 静的メンバ
82 for_each( staticMembers.begin(), staticMembers.end(), checked_deleter<Member>() );
83 // インターフェイス
84 for_each( interfaces.begin(), interfaces.end(), checked_deleter<::Interface>() );
85 // テンプレート展開済みのクラス
86 for_each( expandedTemplateClasses.begin(), expandedTemplateClasses.end(), checked_deleter<ExpandedTemplateClass>() );
87}
88
89void CClass::Using() const
90{
91 if( this->IsUsing() )
92 {
93 // 既に使用することになっている
94 return;
95 }
96
97 Prototype::Using();
98
99 // 仮想関数になるメソッドに使用チェックをつける
100 const CClass &_class = *this;
101 foreach( const CMethod *pMethod, _class.GetDynamicMethods() )
102 {
103 if( pMethod->IsVirtual() )
104 {
105 pMethod->GetUserProc().Using();
106 }
107 }
108
109 // インターフェイスメソッドに使用チェックをつける
110 foreach( const ::Interface *pInterface, _class.GetInterfaces() )
111 {
112 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() )
113 {
114 pMethod->GetUserProc().Using();
115 }
116 }
117}
118bool CClass::IsClass() const
119{
120 return classType == CClass::Class;
121}
122bool CClass::IsInterface() const
123{
124 return classType == CClass::Interface;
125}
126bool CClass::IsComInterface() const
127{
128 return classType == CClass::ComInterface;
129}
130bool CClass::IsEnum() const
131{
132 return classType == CClass::Enum;
133}
134bool CClass::IsDelegate() const
135{
136 return classType == CClass::Delegate;
137}
138bool CClass::IsStructure() const
139{
140 return classType == CClass::Structure;
141}
142
143
144// コンストラクタのコンパイルを開始
145void CClass::NotifyStartConstructorCompile() const
146{
147 isCompilingConstructor = true;
148}
149
150//コンストラクタのコンパイルを終了
151void CClass::NotifyFinishConstructorCompile() const
152{
153 isCompilingConstructor = false;
154}
155
156//コンストラクタをコンパイル中かどうかを判別
157bool CClass::IsCompilingConstructor() const
158{
159 return isCompilingConstructor;
160}
161
162//デストラクタのコンパイルを開始
163void CClass::NotifyStartDestructorCompile() const{
164 isCompilingDestructor = true;
165}
166
167//デストラクタのコンパイルを終了
168void CClass::NotifyFinishDestructorCompile() const{
169 isCompilingDestructor = false;
170}
171
172//デストラクタをコンパイル中かどうかを判別
173bool CClass::IsCompilingDestructor() const
174{
175 return isCompilingDestructor;
176}
177
178//自身の派生クラスかどうかを確認
179bool CClass::IsSubClass( const CClass *pSubClass ) const
180{
181 if( !pSubClass->HasSuperClass() )
182 {
183 return false;
184 }
185
186 const CClass *pTempClass = &pSubClass->GetSuperClass();
187 while( pTempClass ){
188 if( this == pTempClass ) return true;
189 pTempClass = &pTempClass->GetSuperClass();
190 }
191 return false;
192}
193
194//自身と等しいまたは派生クラスかどうかを確認
195bool CClass::IsEqualsOrSubClass( const CClass *pSubClass ) const
196{
197 if( IsEquals( pSubClass ) ) return true;
198 return IsSubClass( pSubClass );
199}
200
201// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
202bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
203{
204 if( IsEquals( &objClass ) ) return true;
205 if( IsSubClass( &objClass ) ) return true;
206 if( objClass.IsSubClass( this ) ) return true;
207 return false;
208}
209
210bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
211{
212 foreach( const ::Interface *pInterface, interfaces ){
213 if( pInterfaceClass == &pInterface->GetClass() ){
214 return true;
215 }
216 }
217 return false;
218}
219
220bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine )
221{
222 //メソッドをコピー
223 const Methods& inheritsClassMethods = inheritsClass.GetDynamicMethods();
224 GetDynamicMethods().reserve( inheritsClassMethods.size() );
225 foreach( const CMethod *pBaseMethod, inheritsClassMethods ){
226 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
227
228 // アクセシビリティ
229 if(pBaseMethod->GetAccessibility() == Prototype::Private){
230 pMethod->SetAccessibility( Prototype::None );
231 }
232 else{
233 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
234 }
235
236 //pobj_Inherits
237 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
238 if(pBaseMethod->GetInheritsClassPtr()==0){
239 pMethod->SetInheritsClassPtr( &inheritsClass );
240 }
241 else{
242 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
243 }
244
245 GetDynamicMethods().push_back( pMethod );
246 }
247
248 //仮想関数の数
249 AddVtblNum( inheritsClass.GetVtblNum() );
250
251 //継承先のクラスをメンバとして保持する
252 SetSuperClass( &inheritsClass );
253 SetSuperClassActualTypeParameters( actualTypeParameters );
254
255 // インターフェイスを引き継ぐ
256 const Interfaces& inheritsClassInterfaces = inheritsClass.GetInterfaces();
257 interfaces.reserve( inheritsClassInterfaces.size() );
258 foreach( const ::Interface *pInterface, inheritsClassInterfaces )
259 {
260 interfaces.push_back( new ::Interface( *pInterface ) );
261 }
262
263 if( this->IsInterface() && inheritsClass.IsComInterface() )
264 {
265 // COMインターフェイスを継承した場合はCOMインターフェイスにする
266 this->SetClassType( CClass::ComInterface );
267 }
268
269 return true;
270}
271
272bool CClass::InheritsInterface( const CClass &inheritsInterfaceClass, const Types &actualTypeParameters, int nowLine )
273{
274 if( !( this->IsInterface() || this->IsComInterface() ) )
275 {
276 Jenga::Throw( "非インターフェイスに対してCClass::InheritsInterfaceメソッドが呼ばれた" );
277 }
278
279 // インターフェイスを継承する
280 return this->InheritsClass( inheritsInterfaceClass, actualTypeParameters, nowLine );
281}
282
283void CClass::AddDynamicMember( Member *pMember )
284{
285 dynamicMembers.push_back( pMember );
286}
287void CClass::AddStaticMember( Member *pMember )
288{
289 staticMembers.push_back( pMember );
290}
291
292bool CClass::DupliCheckAll(const char *name) const
293{
294 //重複チェック
295
296 //メンバ
297 if(DupliCheckMember(name)) return 1;
298
299 //メソッド
300 foreach( const CMethod *pMethod, GetDynamicMethods() ){
301 if( name == pMethod->GetUserProc().GetName() ){
302 return 1;
303 }
304 }
305
306 return 0;
307}
308bool CClass::DupliCheckMember(const char *name) const
309{
310 //重複チェック
311
312 if( this->HasSuperClass() )
313 {
314 if( this->GetSuperClass().DupliCheckMember( name ) )
315 {
316 // 基底クラスで重複が発見された
317 return true;
318 }
319 }
320
321 // 動的メンバ
322 foreach( const Member *pMember, dynamicMembers )
323 {
324 if( GetName() == pMember->GetName() )
325 {
326 return true;
327 }
328 }
329
330 // 静的メンバ
331 foreach( Member *pMember, staticMembers ){
332 if( GetName() == pMember->GetName() ){
333 return true;
334 }
335 }
336
337 return false;
338}
339
340const Member *CClass::FindDynamicMember( const char *memberName ) const
341{
342 if( this->HasSuperClass() )
343 {
344 // 基底クラスで検索
345 const Member *result = this->GetSuperClass().FindDynamicMember( memberName );
346 if( result )
347 {
348 return result;
349 }
350 }
351
352 foreach( Member *pMember, GetDynamicMembers() )
353 {
354 if( pMember->GetName() == memberName )
355 {
356 return pMember;
357 }
358 }
359 return NULL;
360}
361
362void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
363{
364 // 動的メソッド
365 GetDynamicMethods().Enum( methodName, subs );
366
367 // インターフェイス メソッド
368 foreach( ::Interface *pInterface, GetInterfaces() )
369 {
370 pInterface->GetDynamicMethods().Enum( methodName, subs );
371 }
372}
373const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
374{
375 // 動的メソッド
376 const CMethod *result = GetDynamicMethods().GetMethodPtr( pUserProc );
377
378 if( !result )
379 {
380 // インターフェイス メソッド
381 foreach( ::Interface *pInterface, GetInterfaces() )
382 {
383 result = pInterface->GetDynamicMethods().GetMethodPtr( pUserProc );
384 if( result )
385 {
386 return result;
387 }
388 }
389 }
390
391 return result;
392}
393
394void CClass::ResolveExpandedClassActualTypeParameter( Type &type ) const
395{
396 if( !this->IsExpanded() )
397 {
398 _ASSERTE( false );
399 }
400
401 if( !type.IsTypeParameter() )
402 {
403 // 型パラメータではない場合
404 return;
405 }
406
407 type = expandedClassActualTypeParameters[type.GetFormalTypeIndex()];
408}
409
410//サイズを取得
411int CClass::GetSize() const
412{
413 int resultSize = 0;
414
415 int alignment = 1;
416 if( this->IsStructure() )
417 {
418 // 構造体のとき
419
420 if( this->GetFixedAlignment() )
421 {
422 // アラインメントの固定値が指定されていた場合はそれを取得
423 alignment = this->GetFixedAlignment();
424 }
425 }
426 else
427 {
428 // それ以外
429
430 if( this->HasSuperClass() )
431 {
432 const CClass& super = this->GetSuperClass();
433 // 基底クラスのサイズを追加
434 resultSize += super.GetSize();
435
436 // 基底クラスのアラインメントを取得
437 alignment = super.GetAlignment();
438 }
439 else
440 {
441 // 基底クラスが存在しないとき
442
443 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
444 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
445 }
446 }
447
448 foreach( Member *pMember, dynamicMembers )
449 {
450 const Type& memberType = pMember->GetType();
451 // メンバサイズ
452 int tempMemberSize = memberType.GetSize();
453
454 // 一時アラインメントを算出
455 int tempAlignment = tempMemberSize;
456 if( memberType.IsStruct() )
457 {
458 // メンバが構造体の場合は、メンバのアラインメントを取得
459 tempAlignment = memberType.GetClass().GetAlignment();
460 }
461
462 // アラインメントを考慮してパディングを追加
463 if( GetFixedAlignment() && alignment < tempAlignment )
464 {
465 if( resultSize % alignment )
466 {
467 resultSize += alignment - ( resultSize % alignment );
468 }
469 }
470 else
471 {
472 if( alignment < tempAlignment )
473 {
474 // 最大アラインメントを更新
475 alignment = tempAlignment;
476 }
477
478 if( tempMemberSize == 0 )
479 {
480 if( !memberType.IsStruct() )
481 {
482 throw;
483 }
484
485 //メンバを持たない構造体
486 //※何もしない(オフセットの計算をしない)
487 }
488 else{
489 if( resultSize % tempAlignment )
490 {
491 resultSize += tempAlignment - ( resultSize % tempAlignment );
492 }
493 }
494 }
495
496 // メンバサイズを加算(配列を考慮)
497 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
498 }
499
500 if( alignment )
501 {
502 // 末尾アラインメントを考慮してパディングを追加
503 if( resultSize % alignment )
504 {
505 resultSize += alignment - ( resultSize % alignment );
506 }
507 }
508
509 return resultSize;
510}
511
512//メンバのオフセットを取得
513int CClass::GetMemberOffset( const char *memberName ) const
514{
515 int resultSize = 0;
516
517 int alignment = 1;
518 if( this->IsStructure() )
519 {
520 // 構造体のとき
521
522 if( this->GetFixedAlignment() )
523 {
524 // アラインメントの固定値が指定されていた場合はそれを取得
525 alignment = this->GetFixedAlignment();
526 }
527 }
528 else
529 {
530 // それ以外
531
532 if( this->HasSuperClass() )
533 {
534 if( this->GetSuperClass().HasDynamicMember( memberName ) )
535 {
536 // 基底クラスのメンバを取得
537 return this->GetSuperClass().GetMemberOffset( memberName );
538 }
539
540 // 基底クラスのサイズを追加
541 resultSize += this->GetSuperClass().GetSize();
542
543 // 基底クラスのアラインメントを取得
544 alignment = this->GetSuperClass().GetAlignment();
545 }
546 else
547 {
548 // 基底クラスが存在しないとき
549
550 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
551 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
552 }
553 }
554
555 foreach( Member *pMember, dynamicMembers )
556 {
557 // メンバサイズ
558 int tempMemberSize = pMember->GetType().GetSize();
559
560 // 一時アラインメントを算出
561 int tempAlignment = tempMemberSize;
562 if( pMember->GetType().IsStruct() )
563 {
564 // メンバが構造体の場合は、メンバのアラインメントを取得
565 tempAlignment = pMember->GetType().GetClass().GetAlignment();
566 }
567
568 // アラインメントを考慮してパディングを追加
569 if( GetFixedAlignment() && alignment < tempAlignment )
570 {
571 if( resultSize % alignment )
572 {
573 resultSize += alignment - ( resultSize % alignment );
574 }
575 }
576 else
577 {
578 if( alignment < tempAlignment )
579 {
580 // 最大アラインメントを更新
581 alignment = tempAlignment;
582 }
583
584 if( tempMemberSize == 0 )
585 {
586 if( !pMember->GetType().IsStruct() )
587 {
588 throw;
589 }
590
591 //メンバを持たない構造体
592 //※何もしない(オフセットの計算をしない)
593 }
594 else{
595 if( resultSize % tempAlignment )
596 {
597 resultSize += tempAlignment - ( resultSize % tempAlignment );
598 }
599 }
600 }
601
602 if(memberName){
603 //メンバ指定がある場合は、オフセットを返す
604 if( pMember->GetName() == memberName )
605 {
606 return resultSize;
607 }
608 }
609
610 // メンバサイズを加算(配列を考慮)
611 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
612 }
613
614 if( alignment )
615 {
616 // 末尾アラインメントを考慮してパディングを追加
617 if( resultSize % alignment )
618 {
619 resultSize += alignment - ( resultSize % alignment );
620 }
621 }
622
623 return resultSize;
624}
625int CClass::GetAlignment() const
626{
627 int alignment = 1;
628 if( this->IsStructure() )
629 {
630 // 構造体のとき
631
632 if( this->GetFixedAlignment() )
633 {
634 // アラインメントの固定値が指定されていた場合はそれを取得
635 return this->GetFixedAlignment();
636 }
637 }
638 else
639 {
640 // それ以外
641
642 if( this->HasSuperClass() )
643 {
644 // 基底クラスのアラインメントを取得
645 alignment = this->GetSuperClass().GetAlignment();
646 }
647 else
648 {
649 // 基底クラスが存在しないとき
650
651 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
652 alignment = PTR_SIZE;
653 }
654 }
655
656 foreach( Member *pMember, dynamicMembers )
657 {
658 int tempAlignment = pMember->GetType().GetSize();
659 if( pMember->GetType().IsStruct() )
660 {
661 // メンバが構造体の場合は、メンバのアラインメントを取得
662 tempAlignment = pMember->GetType().GetClass().GetAlignment();
663 }
664
665 if( alignment < tempAlignment )
666 {
667 // 最大アラインメントを更新
668 alignment = tempAlignment;
669 }
670 }
671
672 return alignment;
673}
674
675void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
676{
677 vtblMasterListIndex = 0;
678
679 vtblIndex = 0;
680 foreach( const CMethod *pMethod, GetDynamicMethods() ){
681 if( &pMethod->GetUserProc() == pUserProc )
682 {
683 return;
684 }
685
686 if( pMethod->IsVirtual() )
687 {
688 vtblIndex++;
689 }
690 }
691
692 foreach( const ::Interface *pInterface, interfaces )
693 {
694 vtblMasterListIndex++;
695
696 vtblIndex = 0;
697 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
698 if( &pMethod->GetUserProc() == pUserProc )
699 {
700 return;
701 }
702
703 if( pMethod->IsVirtual() )
704 {
705 vtblIndex++;
706 }
707 }
708 }
709
710 _ASSERT( false );
711 throw;
712}
713int CClass::GetVtblMasterListIndex( const CClass *pClass ) const
714{
715 int result = 0;
716
717 foreach( const ::Interface *pInterface, interfaces )
718 {
719 result++;
720
721 if( &pInterface->GetClass() == pClass )
722 {
723 return result;
724 }
725 }
726
727 _ASSERT( false );
728 throw;
729}
730long CClass::GetVtblMasterListOffset() const
731{
732 if( vtblMasterListOffset == -1 )
733 {
734 _ASSERT( false );
735 throw;
736 }
737
738 return vtblMasterListOffset;
739}
740bool CClass::IsAbstract() const
741{
742 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
743
744 foreach( const CMethod *pMethod, GetDynamicMethods() ){
745 if(pMethod->IsVirtual()){
746 if(pMethod->IsAbstract()){
747 return true;
748 }
749 }
750 }
751
752 // インターフェイスのvtbl
753 foreach( const ::Interface *pInterface, interfaces )
754 {
755 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
756 if(pMethod->IsVirtual()){
757 if(pMethod->IsAbstract()){
758 return true;
759 }
760 }
761 }
762 }
763
764 return false;
765}
766
767const CClass *Classes::FindEx( const Symbol &symbol ) const
768{
769 if( symbol.GetNamespaceScopes().size() == 0 && symbol.GetName() == "Object" )
770 {
771 return GetObjectClassPtr();
772 }
773 else if( symbol.GetNamespaceScopes().size() == 0 && symbol.GetName() == "String" )
774 {
775 return GetStringClassPtr();
776 }
777
778 std::vector<const CClass *> classes;
779 const CClass *pClass = GetHashArrayElement( symbol.GetName().c_str() );
780 while( pClass )
781 {
782 if( pClass->IsEqualSymbol( symbol.GetNamespaceScopes(), symbol.GetName() ) ){
783 //名前空間とクラス名が一致した
784 classes.push_back( pClass );
785 }
786 pClass = pClass->GetChainNext();
787 }
788 if( classes.size() > 0 )
789 {
790 // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
791 pClass = classes.front();
792
793 foreach( const CClass *pTempClass, classes )
794 {
795 if( pClass->GetNamespaceScopes().size() < pTempClass->GetNamespaceScopes().size() )
796 {
797 pClass = pTempClass;
798 }
799 }
800
801 return pClass;
802 }
803
804 return NULL;
805}
806
807const CClass *Classes::GetStringClassPtr() const
808{
809 if( !pStringClass )
810 {
811 // キャッシュしておく
812 pStringClass = this->FindEx( Symbol( NamespaceScopes( "System" ), "String" ) );
813 }
814 return pStringClass;
815}
816const CClass *Classes::GetObjectClassPtr() const
817{
818 if( !pObjectClass )
819 {
820 // キャッシュしておく
821 pObjectClass = this->FindEx( Symbol( NamespaceScopes( "System" ), "Object" ) );
822 }
823 return pObjectClass;
824}
825const CClass *Classes::GetInterfaceInfoClassPtr() const
826{
827 if( !pInterfaceInfo )
828 {
829 // キャッシュしておく
830 pInterfaceInfo = this->FindEx( Symbol( NamespaceScopes( "ActiveBasic.Core" ), "InterfaceInfo" ) );
831 }
832 return pInterfaceInfo;
833}
834
835std::string CClass::GetStaticDefiningStringAsMemberNames() const
836{
837 std::string result;
838
839 foreach( const Member *pMember, dynamicMembers )
840 {
841 if( result.size() )
842 {
843 result += ',';
844 }
845
846 result += '\"' + pMember->GetName() + '\"';
847 }
848
849 return result;
850}
851std::string CClass::GetStaticDefiningStringAsMemberOffsets() const
852{
853 std::string result;
854
855 foreach( const Member *pMember, dynamicMembers )
856 {
857 if( result.size() )
858 {
859 result += ',';
860 }
861
862 int offset = this->GetMemberOffset( pMember->GetName().c_str() );
863
864 char temporary[255];
865 _itoa( offset, temporary, 16 );
866
867 result += (std::string)"&H" + temporary;
868 }
869
870 return result;
871}
872
873void CClass::GetReferenceOffsetsInitializeBuffer( std::string &referenceOffsetsBuffer, int &numOfReference, int baseOffset ) const
874{
875 const CClass &thisClass = *this;
876 foreach( const Member *pMember, thisClass.GetDynamicMembers() )
877 {
878 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() )
879 {
880 if( referenceOffsetsBuffer.size() )
881 {
882 referenceOffsetsBuffer += ",";
883 }
884
885 char temp[255];
886 sprintf( temp, "%d", baseOffset + thisClass.GetMemberOffset( pMember->GetName().c_str() ) );
887 referenceOffsetsBuffer += temp;
888
889 numOfReference++;
890 }
891 if( pMember->GetType().IsStruct() && !pMember->GetType().IsPointer() )
892 {
893 // 構造体の実体をメンバに持つとき
894 int baseOffset = thisClass.GetMemberOffset( pMember->GetName().c_str() );
895
896 // 構造体メンバでGCによるチェックが必要な参照位置を追加
897 pMember->GetType().GetClass().GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference, baseOffset );
898 }
899 }
900}
901
902bool CClass::Resolve( const ObjectModule &resolver, ResolveErrors &resolveErrors )
903{
904 // 型パラメータ
905 BOOST_FOREACH( GenericType &genericType, formalGenericTypes )
906 {
907 genericType.GetType().Resolve( resolver, resolveErrors );
908 }
909
910 // 基底クラス
911 if( this->pSuperClass )
912 {
913 if( this->pSuperClass->IsNeedResolve() )
914 {
915 const CClass *pTempClass = resolver.meta.GetClasses().FindLike( this->pSuperClass );
916 if( pTempClass )
917 {
918 this->pSuperClass = pTempClass;
919 }
920 else
921 {
922 resolveErrors.Add( ResolveError( this->pSuperClass->GetRelationalObjectModuleIndex(), this->pSuperClass->GetFullName() ) );
923 }
924 }
925 }
926
927 // 基底クラスの型パラメータ(実パラメータ)
928 BOOST_FOREACH( Type &superClassActualTypeParameter, superClassActualTypeParameters )
929 {
930 superClassActualTypeParameter.Resolve( resolver, resolveErrors );
931 }
932
933 // Blittable型情報
934 blittableType.Resolve( resolver, resolveErrors );
935
936 // 実装するインターフェイス
937 foreach( ::Interface *pInterface, interfaces )
938 {
939 pInterface->Resolve( resolver, resolveErrors );
940 }
941
942 // 動的メンバ
943 foreach( Member *pMember, dynamicMembers )
944 {
945 pMember->Resolve( resolver, resolveErrors );
946 }
947
948 // 静的メンバ
949 foreach( Member *pMember, staticMembers )
950 {
951 pMember->Resolve( resolver, resolveErrors );
952 }
953
954 // 動的メソッド
955 foreach( CMethod *pMethod, GetDynamicMethods() )
956 {
957 pMethod->Resolve( resolver, resolveErrors );
958 }
959
960 // 静的メソッド
961 foreach( CMethod *pMethod, staticMethods )
962 {
963 pMethod->Resolve( resolver, resolveErrors );
964 }
965
966 // テンプレート展開後のクラス
967 foreach( ActiveBasic::Common::Lexical::ExpandedTemplateClass *pExpandedTemplateClass, expandedTemplateClasses )
968 {
969 pExpandedTemplateClass->Resolve( resolver, resolveErrors );
970 }
971
972 return true;
973}
Note: See TracBrowser for help on using the repository browser.