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

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

egtraブランチの内容をマージ。

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