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

Last change on this file since 728 was 728, checked in by dai, 16 years ago

#200への対応。ジェネリックインターフェイスを実装したジェネリッククラスのテンプレート展開に対応。

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