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

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

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

File size: 22.2 KB
RevLine 
[206]1#include "stdafx.h"
[735]2#include <algorithm>
3#include <boost/checked_delete.hpp>
[206]4
[637]5CClass::CClass( const Symbol &symbol, const NamespaceScopesCollection &importedNamespaces )
6 : ClassPrototype( symbol )
[632]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
[637]24CClass::CClass(
25 const Symbol &symbol,
[632]26 const NamespaceScopesCollection &importedNamespaces,
27 ClassType classType,
28 const GenericTypes &formalGenericTypes,
29 const Types &superClassActualTypeParameters,
30 int ConstructorMemberSubIndex,
31 int DestructorMemberSubIndex,
32 int vtblNum,
[672]33 int fixedAlignment,
34 const Types &expandedClassActualTypeParameters )
[637]35 : ClassPrototype( symbol )
[632]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 )
[672]47 , expandedClassActualTypeParameters( expandedClassActualTypeParameters )
[632]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{
[735]77 using std::for_each;
78 using boost::checked_deleter;
[632]79 // 動的メンバ
[735]80 for_each( dynamicMembers.begin(), dynamicMembers.end(), checked_deleter<Member>() );
[632]81 // 静的メンバ
[735]82 for_each( staticMembers.begin(), staticMembers.end(), checked_deleter<Member>() );
[632]83 // インターフェイス
[735]84 for_each( interfaces.begin(), interfaces.end(), checked_deleter<::Interface>() );
[632]85 // テンプレート展開済みのクラス
[735]86 for_each( expandedTemplateClasses.begin(), expandedTemplateClasses.end(), checked_deleter<ExpandedTemplateClass>() );
[632]87}
88
[540]89void CClass::Using() const
90{
91 if( this->IsUsing() )
92 {
93 // 既に使用することになっている
94 return;
95 }
[511]96
[540]97 Prototype::Using();
98
99 // 仮想関数になるメソッドに使用チェックをつける
[728]100 const CClass &_class = *this;
[750]101 foreach( const CMethod *pMethod, _class.GetDynamicMethods() )
[540]102 {
103 if( pMethod->IsVirtual() )
104 {
105 pMethod->GetUserProc().Using();
106 }
107 }
[728]108
109 // インターフェイスメソッドに使用チェックをつける
[750]110 foreach( const ::Interface *pInterface, _class.GetInterfaces() )
[728]111 {
[750]112 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() )
[728]113 {
114 pMethod->GetUserProc().Using();
115 }
116 }
[540]117}
[206]118bool CClass::IsClass() const
[193]119{
[206]120 return classType == CClass::Class;
121}
122bool CClass::IsInterface() const
123{
124 return classType == CClass::Interface;
125}
[370]126bool CClass::IsComInterface() const
127{
128 return classType == CClass::ComInterface;
129}
[206]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//自身の派生クラスかどうかを確認
[447]179bool CClass::IsSubClass( const CClass *pSubClass ) const
[206]180{
[447]181 if( !pSubClass->HasSuperClass() )
[206]182 {
[193]183 return false;
184 }
185
[447]186 const CClass *pTempClass = &pSubClass->GetSuperClass();
[206]187 while( pTempClass ){
188 if( this == pTempClass ) return true;
189 pTempClass = &pTempClass->GetSuperClass();
190 }
191 return false;
[193]192}
193
[206]194//自身と等しいまたは派生クラスかどうかを確認
[447]195bool CClass::IsEqualsOrSubClass( const CClass *pSubClass ) const
[206]196{
[447]197 if( IsEquals( pSubClass ) ) return true;
198 return IsSubClass( pSubClass );
[206]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{
[750]212 foreach( const ::Interface *pInterface, interfaces ){
[346]213 if( pInterfaceClass == &pInterface->GetClass() ){
[206]214 return true;
215 }
216 }
217 return false;
218}
219
[376]220bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine )
221{
[184]222 //メソッドをコピー
[735]223 const Methods& inheritsClassMethods = inheritsClass.GetDynamicMethods();
224 GetDynamicMethods().reserve( inheritsClassMethods.size() );
[750]225 foreach( const CMethod *pBaseMethod, inheritsClassMethods ){
[184]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
[342]245 GetDynamicMethods().push_back( pMethod );
[184]246 }
247
248 //仮想関数の数
249 AddVtblNum( inheritsClass.GetVtblNum() );
250
251 //継承先のクラスをメンバとして保持する
[204]252 SetSuperClass( &inheritsClass );
[299]253 SetSuperClassActualTypeParameters( actualTypeParameters );
[184]254
[351]255 // インターフェイスを引き継ぐ
[735]256 const Interfaces& inheritsClassInterfaces = inheritsClass.GetInterfaces();
257 interfaces.reserve( inheritsClassInterfaces.size() );
[750]258 foreach( const ::Interface *pInterface, inheritsClassInterfaces )
[351]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
[728]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
[561]283void CClass::AddDynamicMember( Member *pMember )
[184]284{
[561]285 dynamicMembers.push_back( pMember );
[184]286}
[561]287void CClass::AddStaticMember( Member *pMember )
288{
289 staticMembers.push_back( pMember );
[184]290}
291
[409]292bool CClass::DupliCheckAll(const char *name) const
293{
[206]294 //重複チェック
295
296 //メンバ
297 if(DupliCheckMember(name)) return 1;
298
299 //メソッド
[750]300 foreach( const CMethod *pMethod, GetDynamicMethods() ){
[735]301 if( name == pMethod->GetUserProc().GetName() ){
[206]302 return 1;
303 }
304 }
305
306 return 0;
307}
[409]308bool CClass::DupliCheckMember(const char *name) const
309{
[206]310 //重複チェック
311
[409]312 if( this->HasSuperClass() )
313 {
314 if( this->GetSuperClass().DupliCheckMember( name ) )
315 {
316 // 基底クラスで重複が発見された
317 return true;
318 }
319 }
320
[206]321 // 動的メンバ
[750]322 foreach( const Member *pMember, dynamicMembers )
[409]323 {
324 if( GetName() == pMember->GetName() )
325 {
326 return true;
[206]327 }
328 }
329
330 // 静的メンバ
[750]331 foreach( Member *pMember, staticMembers ){
[206]332 if( GetName() == pMember->GetName() ){
[409]333 return true;
[206]334 }
335 }
336
[409]337 return false;
[206]338}
339
[561]340const Member *CClass::FindDynamicMember( const char *memberName ) const
[409]341{
342 if( this->HasSuperClass() )
343 {
344 // 基底クラスで検索
[561]345 const Member *result = this->GetSuperClass().FindDynamicMember( memberName );
[409]346 if( result )
347 {
348 return result;
349 }
350 }
351
[750]352 foreach( Member *pMember, GetDynamicMembers() )
[409]353 {
354 if( pMember->GetName() == memberName )
355 {
356 return pMember;
357 }
358 }
359 return NULL;
360}
361
[350]362void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
[347]363{
364 // 動的メソッド
365 GetDynamicMethods().Enum( methodName, subs );
366
367 // インターフェイス メソッド
[750]368 foreach( ::Interface *pInterface, GetInterfaces() )
[347]369 {
370 pInterface->GetDynamicMethods().Enum( methodName, subs );
371 }
372}
[350]373const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
[347]374{
375 // 動的メソッド
376 const CMethod *result = GetDynamicMethods().GetMethodPtr( pUserProc );
377
378 if( !result )
379 {
380 // インターフェイス メソッド
[750]381 foreach( ::Interface *pInterface, GetInterfaces() )
[347]382 {
383 result = pInterface->GetDynamicMethods().GetMethodPtr( pUserProc );
[350]384 if( result )
385 {
386 return result;
387 }
[347]388 }
389 }
390
391 return result;
392}
393
[672]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
[206]410//サイズを取得
411int CClass::GetSize() const
[184]412{
[409]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 {
[735]432 const CClass& super = this->GetSuperClass();
[409]433 // 基底クラスのサイズを追加
[735]434 resultSize += super.GetSize();
[409]435
436 // 基底クラスのアラインメントを取得
[735]437 alignment = super.GetAlignment();
[409]438 }
439 else
440 {
441 // 基底クラスが存在しないとき
442
443 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
444 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
445 }
446 }
447
[750]448 foreach( Member *pMember, dynamicMembers )
[409]449 {
[735]450 const Type& memberType = pMember->GetType();
[409]451 // メンバサイズ
[735]452 int tempMemberSize = memberType.GetSize();
[409]453
454 // 一時アラインメントを算出
455 int tempAlignment = tempMemberSize;
[735]456 if( memberType.IsStruct() )
[409]457 {
458 // メンバが構造体の場合は、メンバのアラインメントを取得
[735]459 tempAlignment = memberType.GetClass().GetAlignment();
[409]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 {
[735]480 if( !memberType.IsStruct() )
[409]481 {
[563]482 throw;
[409]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;
[206]510}
[184]511
[206]512//メンバのオフセットを取得
[409]513int CClass::GetMemberOffset( const char *memberName ) const
[206]514{
[409]515 int resultSize = 0;
[206]516
[232]517 int alignment = 1;
[409]518 if( this->IsStructure() )
[232]519 {
[409]520 // 構造体のとき
521
522 if( this->GetFixedAlignment() )
523 {
524 // アラインメントの固定値が指定されていた場合はそれを取得
525 alignment = this->GetFixedAlignment();
526 }
[232]527 }
[409]528 else
529 {
530 // それ以外
[206]531
[409]532 if( this->HasSuperClass() )
533 {
534 if( this->GetSuperClass().HasDynamicMember( memberName ) )
535 {
536 // 基底クラスのメンバを取得
537 return this->GetSuperClass().GetMemberOffset( memberName );
538 }
[206]539
[409]540 // 基底クラスのサイズを追加
541 resultSize += this->GetSuperClass().GetSize();
[206]542
[409]543 // 基底クラスのアラインメントを取得
544 alignment = this->GetSuperClass().GetAlignment();
[206]545 }
[409]546 else
547 {
548 // 基底クラスが存在しないとき
549
550 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
551 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
[206]552 }
[409]553 }
[206]554
[750]555 foreach( Member *pMember, dynamicMembers )
[409]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();
[206]566 }
567
[409]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 {
[563]588 throw;
[409]589 }
590
591 //メンバを持たない構造体
[206]592 //※何もしない(オフセットの計算をしない)
593 }
594 else{
[409]595 if( resultSize % tempAlignment )
596 {
597 resultSize += tempAlignment - ( resultSize % tempAlignment );
598 }
[206]599 }
600 }
601
602 if(memberName){
603 //メンバ指定がある場合は、オフセットを返す
[409]604 if( pMember->GetName() == memberName )
605 {
606 return resultSize;
[206]607 }
608 }
609
[409]610 // メンバサイズを加算(配列を考慮)
611 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
[206]612 }
613
[409]614 if( alignment )
615 {
616 // 末尾アラインメントを考慮してパディングを追加
617 if( resultSize % alignment )
618 {
619 resultSize += alignment - ( resultSize % alignment );
620 }
[206]621 }
622
[409]623 return resultSize;
[206]624}
625int CClass::GetAlignment() const
626{
[409]627 int alignment = 1;
628 if( this->IsStructure() )
629 {
630 // 構造体のとき
[206]631
[409]632 if( this->GetFixedAlignment() )
633 {
634 // アラインメントの固定値が指定されていた場合はそれを取得
635 return this->GetFixedAlignment();
[206]636 }
[409]637 }
638 else
639 {
640 // それ以外
641
642 if( this->HasSuperClass() )
643 {
644 // 基底クラスのアラインメントを取得
645 alignment = this->GetSuperClass().GetAlignment();
[206]646 }
[409]647 else
648 {
649 // 基底クラスが存在しないとき
[206]650
[409]651 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
652 alignment = PTR_SIZE;
653 }
[206]654 }
655
[750]656 foreach( Member *pMember, dynamicMembers )
[409]657 {
658 int tempAlignment = pMember->GetType().GetSize();
659 if( pMember->GetType().IsStruct() )
660 {
661 // メンバが構造体の場合は、メンバのアラインメントを取得
662 tempAlignment = pMember->GetType().GetClass().GetAlignment();
663 }
[206]664
[409]665 if( alignment < tempAlignment )
666 {
667 // 最大アラインメントを更新
668 alignment = tempAlignment;
669 }
670 }
[206]671
672 return alignment;
673}
[342]674
[348]675void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
[342]676{
[348]677 vtblMasterListIndex = 0;
678
679 vtblIndex = 0;
[750]680 foreach( const CMethod *pMethod, GetDynamicMethods() ){
[342]681 if( &pMethod->GetUserProc() == pUserProc )
682 {
[348]683 return;
[342]684 }
[348]685
686 if( pMethod->IsVirtual() )
687 {
688 vtblIndex++;
689 }
[342]690 }
691
[750]692 foreach( const ::Interface *pInterface, interfaces )
[342]693 {
[348]694 vtblMasterListIndex++;
[342]695
[348]696 vtblIndex = 0;
[750]697 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
[342]698 if( &pMethod->GetUserProc() == pUserProc )
699 {
[348]700 return;
[342]701 }
[348]702
703 if( pMethod->IsVirtual() )
704 {
705 vtblIndex++;
706 }
[342]707 }
708 }
709
[636]710 _ASSERT( false );
[563]711 throw;
[342]712}
[350]713int CClass::GetVtblMasterListIndex( const CClass *pClass ) const
714{
715 int result = 0;
716
[750]717 foreach( const ::Interface *pInterface, interfaces )
[350]718 {
719 result++;
720
721 if( &pInterface->GetClass() == pClass )
722 {
723 return result;
724 }
725 }
726
[636]727 _ASSERT( false );
[563]728 throw;
[350]729}
[345]730long CClass::GetVtblMasterListOffset() const
[206]731{
[342]732 if( vtblMasterListOffset == -1 )
733 {
[636]734 _ASSERT( false );
[563]735 throw;
[342]736 }
[184]737
[342]738 return vtblMasterListOffset;
739}
[206]740bool CClass::IsAbstract() const
741{
742 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
[184]743
[750]744 foreach( const CMethod *pMethod, GetDynamicMethods() ){
[206]745 if(pMethod->IsVirtual()){
746 if(pMethod->IsAbstract()){
747 return true;
748 }
749 }
750 }
751
[351]752 // インターフェイスのvtbl
[750]753 foreach( const ::Interface *pInterface, interfaces )
[351]754 {
[750]755 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
[351]756 if(pMethod->IsVirtual()){
757 if(pMethod->IsAbstract()){
758 return true;
759 }
760 }
761 }
762 }
763
[206]764 return false;
[184]765}
766
[598]767const CClass *Classes::FindEx( const Symbol &symbol ) const
[193]768{
[598]769 if( symbol.GetNamespaceScopes().size() == 0 && symbol.GetName() == "Object" )
[566]770 {
[193]771 return GetObjectClassPtr();
772 }
[598]773 else if( symbol.GetNamespaceScopes().size() == 0 && symbol.GetName() == "String" )
[566]774 {
[193]775 return GetStringClassPtr();
776 }
777
[380]778 std::vector<const CClass *> classes;
[598]779 const CClass *pClass = GetHashArrayElement( symbol.GetName().c_str() );
[270]780 while( pClass )
781 {
[598]782 if( pClass->IsEqualSymbol( symbol.GetNamespaceScopes(), symbol.GetName() ) ){
[270]783 //名前空間とクラス名が一致した
[380]784 classes.push_back( pClass );
[193]785 }
[270]786 pClass = pClass->GetChainNext();
[193]787 }
[380]788 if( classes.size() > 0 )
789 {
790 // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
791 pClass = classes.front();
[193]792
[750]793 foreach( const CClass *pTempClass, classes )
[380]794 {
795 if( pClass->GetNamespaceScopes().size() < pTempClass->GetNamespaceScopes().size() )
796 {
797 pClass = pTempClass;
798 }
799 }
800
801 return pClass;
802 }
803
[193]804 return NULL;
805}
[206]806
[272]807const CClass *Classes::GetStringClassPtr() const
[206]808{
[567]809 if( !pStringClass )
810 {
[272]811 // キャッシュしておく
[598]812 pStringClass = this->FindEx( Symbol( NamespaceScopes( "System" ), "String" ) );
[206]813 }
814 return pStringClass;
815}
[272]816const CClass *Classes::GetObjectClassPtr() const
[206]817{
[567]818 if( !pObjectClass )
819 {
[272]820 // キャッシュしておく
[598]821 pObjectClass = this->FindEx( Symbol( NamespaceScopes( "System" ), "Object" ) );
[206]822 }
823 return pObjectClass;
824}
[349]825const CClass *Classes::GetInterfaceInfoClassPtr() const
826{
[567]827 if( !pInterfaceInfo )
828 {
[349]829 // キャッシュしておく
[598]830 pInterfaceInfo = this->FindEx( Symbol( NamespaceScopes( "ActiveBasic.Core" ), "InterfaceInfo" ) );
[349]831 }
832 return pInterfaceInfo;
833}
[387]834
835std::string CClass::GetStaticDefiningStringAsMemberNames() const
836{
837 std::string result;
838
[750]839 foreach( const Member *pMember, dynamicMembers )
[387]840 {
841 if( result.size() )
842 {
[735]843 result += ',';
[387]844 }
845
[735]846 result += '\"' + pMember->GetName() + '\"';
[387]847 }
848
849 return result;
850}
[412]851std::string CClass::GetStaticDefiningStringAsMemberOffsets() const
852{
853 std::string result;
[387]854
[750]855 foreach( const Member *pMember, dynamicMembers )
[412]856 {
857 if( result.size() )
858 {
[735]859 result += ',';
[412]860 }
861
862 int offset = this->GetMemberOffset( pMember->GetName().c_str() );
863
864 char temporary[255];
[735]865 _itoa( offset, temporary, 16 );
[412]866
867 result += (std::string)"&H" + temporary;
868 }
869
870 return result;
871}
[417]872
873void CClass::GetReferenceOffsetsInitializeBuffer( std::string &referenceOffsetsBuffer, int &numOfReference, int baseOffset ) const
874{
875 const CClass &thisClass = *this;
[750]876 foreach( const Member *pMember, thisClass.GetDynamicMembers() )
[417]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}
[637]901
[640]902bool CClass::Resolve( const ObjectModule &resolver, ResolveErrors &resolveErrors )
[637]903{
[639]904 // 型パラメータ
905 BOOST_FOREACH( GenericType &genericType, formalGenericTypes )
906 {
[640]907 genericType.GetType().Resolve( resolver, resolveErrors );
[639]908 }
909
910 // 基底クラス
911 if( this->pSuperClass )
912 {
913 if( this->pSuperClass->IsNeedResolve() )
914 {
[640]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 }
[639]924 }
925 }
926
927 // 基底クラスの型パラメータ(実パラメータ)
928 BOOST_FOREACH( Type &superClassActualTypeParameter, superClassActualTypeParameters )
929 {
[640]930 superClassActualTypeParameter.Resolve( resolver, resolveErrors );
[639]931 }
932
933 // Blittable型情報
[640]934 blittableType.Resolve( resolver, resolveErrors );
[639]935
936 // 実装するインターフェイス
[750]937 foreach( ::Interface *pInterface, interfaces )
[639]938 {
[640]939 pInterface->Resolve( resolver, resolveErrors );
[639]940 }
941
942 // 動的メンバ
[750]943 foreach( Member *pMember, dynamicMembers )
[639]944 {
[640]945 pMember->Resolve( resolver, resolveErrors );
[639]946 }
947
948 // 静的メンバ
[750]949 foreach( Member *pMember, staticMembers )
[639]950 {
[640]951 pMember->Resolve( resolver, resolveErrors );
[639]952 }
953
954 // 動的メソッド
[750]955 foreach( CMethod *pMethod, GetDynamicMethods() )
[639]956 {
[640]957 pMethod->Resolve( resolver, resolveErrors );
[639]958 }
959
960 // 静的メソッド
[750]961 foreach( CMethod *pMethod, staticMethods )
[639]962 {
[640]963 pMethod->Resolve( resolver, resolveErrors );
[639]964 }
965
966 // テンプレート展開後のクラス
[750]967 foreach( ActiveBasic::Common::Lexical::ExpandedTemplateClass *pExpandedTemplateClass, expandedTemplateClasses )
[639]968 {
[640]969 pExpandedTemplateClass->Resolve( resolver, resolveErrors );
[639]970 }
971
[637]972 return true;
973}
Note: See TracBrowser for help on using the repository browser.