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

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

#171への対応。テンプレート展開後のクラスメソッドの実装で、SizeOf(T)が正常値を返さない不具合を修正(特にTが4バイト未満の型場合)。

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