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

Last change on this file was 829, checked in by イグトランス (egtra), 13 years ago

svn:eol-styleとsvn:mime-type(文字コード指定含む)の設定

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