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
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 // 仮想関数になるメソッドに使用チェックをつける
[728]112 const CClass &_class = *this;
113 BOOST_FOREACH( const CMethod *pMethod, _class.GetDynamicMethods() )
[540]114 {
115 if( pMethod->IsVirtual() )
116 {
117 pMethod->GetUserProc().Using();
118 }
119 }
[728]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 }
[540]129}
[206]130bool CClass::IsClass() const
[193]131{
[206]132 return classType == CClass::Class;
133}
134bool CClass::IsInterface() const
135{
136 return classType == CClass::Interface;
137}
[370]138bool CClass::IsComInterface() const
139{
140 return classType == CClass::ComInterface;
141}
[206]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//自身の派生クラスかどうかを確認
[447]191bool CClass::IsSubClass( const CClass *pSubClass ) const
[206]192{
[447]193 if( !pSubClass->HasSuperClass() )
[206]194 {
[193]195 return false;
196 }
197
[447]198 const CClass *pTempClass = &pSubClass->GetSuperClass();
[206]199 while( pTempClass ){
200 if( this == pTempClass ) return true;
201 pTempClass = &pTempClass->GetSuperClass();
202 }
203 return false;
[193]204}
205
[206]206//自身と等しいまたは派生クラスかどうかを確認
[447]207bool CClass::IsEqualsOrSubClass( const CClass *pSubClass ) const
[206]208{
[447]209 if( IsEquals( pSubClass ) ) return true;
210 return IsSubClass( pSubClass );
[206]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{
[346]224 BOOST_FOREACH( const ::Interface *pInterface, interfaces ){
225 if( pInterfaceClass == &pInterface->GetClass() ){
[206]226 return true;
227 }
228 }
229 return false;
230}
231
[376]232bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine )
233{
[184]234 //メソッドをコピー
[342]235 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
[184]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
[342]255 GetDynamicMethods().push_back( pMethod );
[184]256 }
257
258 //仮想関数の数
259 AddVtblNum( inheritsClass.GetVtblNum() );
260
261 //継承先のクラスをメンバとして保持する
[204]262 SetSuperClass( &inheritsClass );
[299]263 SetSuperClassActualTypeParameters( actualTypeParameters );
[184]264
[351]265 // インターフェイスを引き継ぐ
266 BOOST_FOREACH( ::Interface *pInterface, inheritsClass.GetInterfaces() )
267 {
268 interfaces.push_back( new ::Interface( *pInterface ) );
269 }
270
[370]271 if( this->IsInterface() && inheritsClass.IsComInterface() )
272 {
273 // COMインターフェイスを継承した場合はCOMインターフェイスにする
274 this->SetClassType( CClass::ComInterface );
[184]275 }
276
277 return true;
278}
[340]279
[728]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
[561]291void CClass::AddDynamicMember( Member *pMember )
[184]292{
[561]293 dynamicMembers.push_back( pMember );
[184]294}
[561]295void CClass::AddStaticMember( Member *pMember )
296{
297 staticMembers.push_back( pMember );
[184]298}
299
[409]300bool CClass::DupliCheckAll(const char *name) const
301{
[206]302 //重複チェック
303
304 //メンバ
305 if(DupliCheckMember(name)) return 1;
306
307 //メソッド
[342]308 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
[206]309 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
310 return 1;
311 }
312 }
313
314 return 0;
315}
[409]316bool CClass::DupliCheckMember(const char *name) const
317{
[206]318 //重複チェック
319
[409]320 if( this->HasSuperClass() )
321 {
322 if( this->GetSuperClass().DupliCheckMember( name ) )
323 {
324 // 基底クラスで重複が発見された
325 return true;
326 }
327 }
328
[206]329 // 動的メンバ
[561]330 BOOST_FOREACH( Member *pMember, dynamicMembers )
[409]331 {
332 if( GetName() == pMember->GetName() )
333 {
334 return true;
[206]335 }
336 }
337
338 // 静的メンバ
[561]339 BOOST_FOREACH( Member *pMember, staticMembers ){
[206]340 if( GetName() == pMember->GetName() ){
[409]341 return true;
[206]342 }
343 }
344
[409]345 return false;
[206]346}
347
[561]348const Member *CClass::FindDynamicMember( const char *memberName ) const
[409]349{
350 if( this->HasSuperClass() )
351 {
352 // 基底クラスで検索
[561]353 const Member *result = this->GetSuperClass().FindDynamicMember( memberName );
[409]354 if( result )
355 {
356 return result;
357 }
358 }
359
[561]360 BOOST_FOREACH( Member *pMember, GetDynamicMembers() )
[409]361 {
362 if( pMember->GetName() == memberName )
363 {
364 return pMember;
365 }
366 }
367 return NULL;
368}
369
[350]370void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
[347]371{
372 // 動的メソッド
373 GetDynamicMethods().Enum( methodName, subs );
374
375 // インターフェイス メソッド
376 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
377 {
378 pInterface->GetDynamicMethods().Enum( methodName, subs );
379 }
380}
[350]381const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
[347]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 );
[350]392 if( result )
393 {
394 return result;
395 }
[347]396 }
397 }
398
399 return result;
400}
401
[672]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
[206]418//サイズを取得
419int CClass::GetSize() const
[184]420{
[409]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
[561]455 BOOST_FOREACH( Member *pMember, dynamicMembers )
[409]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 {
[563]488 throw;
[409]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;
[206]516}
[184]517
[206]518//メンバのオフセットを取得
[409]519int CClass::GetMemberOffset( const char *memberName ) const
[206]520{
[409]521 int resultSize = 0;
[206]522
[232]523 int alignment = 1;
[409]524 if( this->IsStructure() )
[232]525 {
[409]526 // 構造体のとき
527
528 if( this->GetFixedAlignment() )
529 {
530 // アラインメントの固定値が指定されていた場合はそれを取得
531 alignment = this->GetFixedAlignment();
532 }
[232]533 }
[409]534 else
535 {
536 // それ以外
[206]537
[409]538 if( this->HasSuperClass() )
539 {
540 if( this->GetSuperClass().HasDynamicMember( memberName ) )
541 {
542 // 基底クラスのメンバを取得
543 return this->GetSuperClass().GetMemberOffset( memberName );
544 }
[206]545
[409]546 // 基底クラスのサイズを追加
547 resultSize += this->GetSuperClass().GetSize();
[206]548
[409]549 // 基底クラスのアラインメントを取得
550 alignment = this->GetSuperClass().GetAlignment();
[206]551 }
[409]552 else
553 {
554 // 基底クラスが存在しないとき
555
556 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
557 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
[206]558 }
[409]559 }
[206]560
[561]561 BOOST_FOREACH( Member *pMember, dynamicMembers )
[409]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();
[206]572 }
573
[409]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 {
[563]594 throw;
[409]595 }
596
597 //メンバを持たない構造体
[206]598 //※何もしない(オフセットの計算をしない)
599 }
600 else{
[409]601 if( resultSize % tempAlignment )
602 {
603 resultSize += tempAlignment - ( resultSize % tempAlignment );
604 }
[206]605 }
606 }
607
608 if(memberName){
609 //メンバ指定がある場合は、オフセットを返す
[409]610 if( pMember->GetName() == memberName )
611 {
612 return resultSize;
[206]613 }
614 }
615
[409]616 // メンバサイズを加算(配列を考慮)
617 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
[206]618 }
619
[409]620 if( alignment )
621 {
622 // 末尾アラインメントを考慮してパディングを追加
623 if( resultSize % alignment )
624 {
625 resultSize += alignment - ( resultSize % alignment );
626 }
[206]627 }
628
[409]629 return resultSize;
[206]630}
631int CClass::GetAlignment() const
632{
[409]633 int alignment = 1;
634 if( this->IsStructure() )
635 {
636 // 構造体のとき
[206]637
[409]638 if( this->GetFixedAlignment() )
639 {
640 // アラインメントの固定値が指定されていた場合はそれを取得
641 return this->GetFixedAlignment();
[206]642 }
[409]643 }
644 else
645 {
646 // それ以外
647
648 if( this->HasSuperClass() )
649 {
650 // 基底クラスのアラインメントを取得
651 alignment = this->GetSuperClass().GetAlignment();
[206]652 }
[409]653 else
654 {
655 // 基底クラスが存在しないとき
[206]656
[409]657 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
658 alignment = PTR_SIZE;
659 }
[206]660 }
661
[561]662 BOOST_FOREACH( Member *pMember, dynamicMembers )
[409]663 {
664 int tempAlignment = pMember->GetType().GetSize();
665 if( pMember->GetType().IsStruct() )
666 {
667 // メンバが構造体の場合は、メンバのアラインメントを取得
668 tempAlignment = pMember->GetType().GetClass().GetAlignment();
669 }
[206]670
[409]671 if( alignment < tempAlignment )
672 {
673 // 最大アラインメントを更新
674 alignment = tempAlignment;
675 }
676 }
[206]677
678 return alignment;
679}
[342]680
[348]681void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
[342]682{
[348]683 vtblMasterListIndex = 0;
684
685 vtblIndex = 0;
[342]686 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
687 if( &pMethod->GetUserProc() == pUserProc )
688 {
[348]689 return;
[342]690 }
[348]691
692 if( pMethod->IsVirtual() )
693 {
694 vtblIndex++;
695 }
[342]696 }
697
[346]698 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
[342]699 {
[348]700 vtblMasterListIndex++;
[342]701
[348]702 vtblIndex = 0;
[347]703 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
[342]704 if( &pMethod->GetUserProc() == pUserProc )
705 {
[348]706 return;
[342]707 }
[348]708
709 if( pMethod->IsVirtual() )
710 {
711 vtblIndex++;
712 }
[342]713 }
714 }
715
[636]716 _ASSERT( false );
[563]717 throw;
[342]718}
[350]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
[636]733 _ASSERT( false );
[563]734 throw;
[350]735}
[345]736long CClass::GetVtblMasterListOffset() const
[206]737{
[342]738 if( vtblMasterListOffset == -1 )
739 {
[636]740 _ASSERT( false );
[563]741 throw;
[342]742 }
[184]743
[342]744 return vtblMasterListOffset;
745}
[206]746bool CClass::IsAbstract() const
747{
748 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
[184]749
[342]750 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
[206]751 if(pMethod->IsVirtual()){
752 if(pMethod->IsAbstract()){
753 return true;
754 }
755 }
756 }
757
[351]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
[206]770 return false;
[184]771}
772
[598]773const CClass *Classes::FindEx( const Symbol &symbol ) const
[193]774{
[598]775 if( symbol.GetNamespaceScopes().size() == 0 && symbol.GetName() == "Object" )
[566]776 {
[193]777 return GetObjectClassPtr();
778 }
[598]779 else if( symbol.GetNamespaceScopes().size() == 0 && symbol.GetName() == "String" )
[566]780 {
[193]781 return GetStringClassPtr();
782 }
783
[380]784 std::vector<const CClass *> classes;
[598]785 const CClass *pClass = GetHashArrayElement( symbol.GetName().c_str() );
[270]786 while( pClass )
787 {
[598]788 if( pClass->IsEqualSymbol( symbol.GetNamespaceScopes(), symbol.GetName() ) ){
[270]789 //名前空間とクラス名が一致した
[380]790 classes.push_back( pClass );
[193]791 }
[270]792 pClass = pClass->GetChainNext();
[193]793 }
[380]794 if( classes.size() > 0 )
795 {
796 // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
797 pClass = classes.front();
[193]798
[380]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
[193]810 return NULL;
811}
[206]812
[272]813const CClass *Classes::GetStringClassPtr() const
[206]814{
[567]815 if( !pStringClass )
816 {
[272]817 // キャッシュしておく
[598]818 pStringClass = this->FindEx( Symbol( NamespaceScopes( "System" ), "String" ) );
[206]819 }
820 return pStringClass;
821}
[272]822const CClass *Classes::GetObjectClassPtr() const
[206]823{
[567]824 if( !pObjectClass )
825 {
[272]826 // キャッシュしておく
[598]827 pObjectClass = this->FindEx( Symbol( NamespaceScopes( "System" ), "Object" ) );
[206]828 }
829 return pObjectClass;
830}
[349]831const CClass *Classes::GetInterfaceInfoClassPtr() const
832{
[567]833 if( !pInterfaceInfo )
834 {
[349]835 // キャッシュしておく
[598]836 pInterfaceInfo = this->FindEx( Symbol( NamespaceScopes( "ActiveBasic.Core" ), "InterfaceInfo" ) );
[349]837 }
838 return pInterfaceInfo;
839}
[387]840
841std::string CClass::GetStaticDefiningStringAsMemberNames() const
842{
843 std::string result;
844
[561]845 BOOST_FOREACH( const Member *pMember, dynamicMembers )
[387]846 {
847 if( result.size() )
848 {
849 result += ",";
850 }
851
852 result += "\"" + pMember->GetName() + "\"";
853 }
854
855 return result;
856}
[412]857std::string CClass::GetStaticDefiningStringAsMemberOffsets() const
858{
859 std::string result;
[387]860
[561]861 BOOST_FOREACH( const Member *pMember, dynamicMembers )
[412]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}
[417]878
879void CClass::GetReferenceOffsetsInitializeBuffer( std::string &referenceOffsetsBuffer, int &numOfReference, int baseOffset ) const
880{
881 const CClass &thisClass = *this;
[561]882 BOOST_FOREACH( const Member *pMember, thisClass.GetDynamicMembers() )
[417]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}
[637]907
[640]908bool CClass::Resolve( const ObjectModule &resolver, ResolveErrors &resolveErrors )
[637]909{
[639]910 // 型パラメータ
911 BOOST_FOREACH( GenericType &genericType, formalGenericTypes )
912 {
[640]913 genericType.GetType().Resolve( resolver, resolveErrors );
[639]914 }
915
916 // 基底クラス
917 if( this->pSuperClass )
918 {
919 if( this->pSuperClass->IsNeedResolve() )
920 {
[640]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 }
[639]930 }
931 }
932
933 // 基底クラスの型パラメータ(実パラメータ)
934 BOOST_FOREACH( Type &superClassActualTypeParameter, superClassActualTypeParameters )
935 {
[640]936 superClassActualTypeParameter.Resolve( resolver, resolveErrors );
[639]937 }
938
939 // Blittable型情報
[640]940 blittableType.Resolve( resolver, resolveErrors );
[639]941
942 // 実装するインターフェイス
943 BOOST_FOREACH( ::Interface *pInterface, interfaces )
944 {
[640]945 pInterface->Resolve( resolver, resolveErrors );
[639]946 }
947
948 // 動的メンバ
949 BOOST_FOREACH( Member *pMember, dynamicMembers )
950 {
[640]951 pMember->Resolve( resolver, resolveErrors );
[639]952 }
953
954 // 静的メンバ
955 BOOST_FOREACH( Member *pMember, staticMembers )
956 {
[640]957 pMember->Resolve( resolver, resolveErrors );
[639]958 }
959
960 // 動的メソッド
961 BOOST_FOREACH( CMethod *pMethod, GetDynamicMethods() )
962 {
[640]963 pMethod->Resolve( resolver, resolveErrors );
[639]964 }
965
966 // 静的メソッド
967 BOOST_FOREACH( CMethod *pMethod, staticMethods )
968 {
[640]969 pMethod->Resolve( resolver, resolveErrors );
[639]970 }
971
972 // テンプレート展開後のクラス
973 BOOST_FOREACH( ActiveBasic::Common::Lexical::ExpandedTemplateClass *pExpandedTemplateClass, expandedTemplateClasses )
974 {
[640]975 pExpandedTemplateClass->Resolve( resolver, resolveErrors );
[639]976 }
977
[637]978 return true;
979}
Note: See TracBrowser for help on using the repository browser.