source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Class.cpp@ 507

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

NamespaceSupporterクラスをab_commonプロジェクトに移動した。

File size: 40.0 KB
RevLine 
[206]1#include "stdafx.h"
2
[266]3#include <Source.h>
[206]4#include <Class.h>
[184]5#include <Compiler.h>
6
7#include "../common.h"
8#ifdef _AMD64_
[485]9#include "../../compiler_x64/opcode.h"
[184]10#else
[484]11#include "../../compiler_x86/opcode.h"
[184]12#endif
13
14
[376]15Interface::Interface( const CClass *pInterfaceClass, const Types &actualTypeParameters )
[344]16 : DynamicMethodsPrototype()
17 , pInterfaceClass( pInterfaceClass )
[343]18 , vtblOffset( -1 )
[376]19 , actualTypeParameters( actualTypeParameters )
[343]20{
21 //メソッドをコピー
22 BOOST_FOREACH( const CMethod *pBaseMethod, pInterfaceClass->GetDynamicMethods() )
23 {
24 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
25
26 // アクセシビリティ
27 if(pBaseMethod->GetAccessibility() == Prototype::Private){
28 pMethod->SetAccessibility( Prototype::None );
29 }
30 else{
31 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
32 }
33
34 //pobj_Inherits
35 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
36 if(pBaseMethod->GetInheritsClassPtr()==0){
37 pMethod->SetInheritsClassPtr( pInterfaceClass );
38 }
39 else{
40 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
41 }
42
[344]43 AddDynamicMethods( pMethod );
[343]44 }
45}
46
[378]47std::string Interface::GetFullNameWithActualGenericTypeParameters() const
48{
49 std::string interfaceName = this->GetClass().GetFullName();
50 if( actualTypeParameters.size() )
51 {
52 std::string actualGenericTypesName;
53 BOOST_FOREACH( const Type &typeParameter, actualTypeParameters )
54 {
55 if( actualGenericTypesName.size() )
56 {
57 actualGenericTypesName += ",";
58 }
59 actualGenericTypesName += typeParameter.ToString();
60 }
[343]61
[378]62 interfaceName += "<" + actualGenericTypesName + ">";
63 }
64 return interfaceName;
65}
66
[206]67bool CClass::IsClass() const
[193]68{
[206]69 return classType == CClass::Class;
70}
71bool CClass::IsInterface() const
72{
73 return classType == CClass::Interface;
74}
[370]75bool CClass::IsComInterface() const
76{
77 return classType == CClass::ComInterface;
78}
[206]79bool CClass::IsEnum() const
80{
81 return classType == CClass::Enum;
82}
83bool CClass::IsDelegate() const
84{
85 return classType == CClass::Delegate;
86}
87bool CClass::IsStructure() const
88{
89 return classType == CClass::Structure;
90}
91
92
93// コンストラクタのコンパイルを開始
94void CClass::NotifyStartConstructorCompile() const
95{
96 isCompilingConstructor = true;
97}
98
99//コンストラクタのコンパイルを終了
100void CClass::NotifyFinishConstructorCompile() const
101{
102 isCompilingConstructor = false;
103}
104
105//コンストラクタをコンパイル中かどうかを判別
106bool CClass::IsCompilingConstructor() const
107{
108 return isCompilingConstructor;
109}
110
111//デストラクタのコンパイルを開始
112void CClass::NotifyStartDestructorCompile() const{
113 isCompilingDestructor = true;
114}
115
116//デストラクタのコンパイルを終了
117void CClass::NotifyFinishDestructorCompile() const{
118 isCompilingDestructor = false;
119}
120
121//デストラクタをコンパイル中かどうかを判別
122bool CClass::IsCompilingDestructor() const
123{
124 return isCompilingDestructor;
125}
126
127//自身の派生クラスかどうかを確認
[447]128bool CClass::IsSubClass( const CClass *pSubClass ) const
[206]129{
[447]130 if( !pSubClass->HasSuperClass() )
[206]131 {
[193]132 return false;
133 }
134
[447]135 const CClass *pTempClass = &pSubClass->GetSuperClass();
[206]136 while( pTempClass ){
137 if( this == pTempClass ) return true;
138 pTempClass = &pTempClass->GetSuperClass();
139 }
140 return false;
[193]141}
142
[206]143//自身と等しいまたは派生クラスかどうかを確認
[447]144bool CClass::IsEqualsOrSubClass( const CClass *pSubClass ) const
[206]145{
[447]146 if( IsEquals( pSubClass ) ) return true;
147 return IsSubClass( pSubClass );
[206]148}
149
150// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
151bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
152{
153 if( IsEquals( &objClass ) ) return true;
154 if( IsSubClass( &objClass ) ) return true;
155 if( objClass.IsSubClass( this ) ) return true;
156 return false;
157}
158
159bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
160{
[346]161 BOOST_FOREACH( const ::Interface *pInterface, interfaces ){
162 if( pInterfaceClass == &pInterface->GetClass() ){
[206]163 return true;
164 }
165 }
166 return false;
167}
168
169bool CClass::Inherits( const char *inheritNames, int nowLine ){
[184]170 int i = 0;
171 bool isInheritsClass = false;
172 while( true ){
173
174 char temporary[VN_SIZE];
175 for( int i2=0;; i++, i2++ ){
176 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
177 temporary[i2] = 0;
178 break;
179 }
180 temporary[i2] = inheritNames[i];
181 }
182
[299]183 // ジェネリクス構文を分解
[297]184 char className[VN_SIZE];
[299]185 Jenga::Common::Strings typeParameterStrings;
186 SplitGenericClassInstance( temporary, className, typeParameterStrings );
[297]187
[299]188 // 型パラメータ文字列から型データを取得
[376]189 Types actualTypeParameters;
[299]190 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
191 {
192 Type type;
193 compiler.StringToType( typeParameterStr, type );
194 actualTypeParameters.push_back( type );
195 }
196
[184]197 //継承元クラスを取得
[297]198 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
[184]199 if( !pInheritsClass ){
[465]200 compiler.errorMessenger.Output(106,className,nowLine);
[184]201 return false;
202 }
203
[370]204 if( pInheritsClass->IsClass() ){
[184]205 // クラスを継承する
206 isInheritsClass = true;
207
[299]208 if( !InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
[184]209 return false;
210 }
211 }
212 else{
[465]213 compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine);
[184]214 return false;
215 }
216
217 if( inheritNames[i] == '\0' ){
218 break;
219 }
220 i++;
221 }
222
223 if( !isInheritsClass ){
224 // クラスを一つも継承していないとき
[299]225 if( !InheritsClass( *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(), Types(), nowLine ) ){
[184]226 return false;
227 }
228 }
229
230 return true;
231}
[376]232bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine )
233{
[184]234 //ループ継承でないかをチェック
[376]235 if( !compiler.GetObjectModule().meta.GetClasses().LoopRefCheck(inheritsClass) )
236 {
[465]237 compiler.errorMessenger.Output(123,inheritsClass.GetName(),nowLine);
[184]238 return false;
239 }
240
241 if( !inheritsClass.IsReady() ){
242 //継承先が読み取られていないとき
[376]243 compiler.GetObjectModule().meta.GetClasses().LookaheadClass(inheritsClass.GetName().c_str());
[184]244 }
245
246 //メソッドをコピー
[342]247 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
[184]248 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
249
250 // アクセシビリティ
251 if(pBaseMethod->GetAccessibility() == Prototype::Private){
252 pMethod->SetAccessibility( Prototype::None );
253 }
254 else{
255 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
256 }
257
258 //pobj_Inherits
259 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
260 if(pBaseMethod->GetInheritsClassPtr()==0){
261 pMethod->SetInheritsClassPtr( &inheritsClass );
262 }
263 else{
264 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
265 }
266
[342]267 GetDynamicMethods().push_back( pMethod );
[184]268 }
269
270 //仮想関数の数
271 AddVtblNum( inheritsClass.GetVtblNum() );
272
273 //継承先のクラスをメンバとして保持する
[204]274 SetSuperClass( &inheritsClass );
[299]275 SetSuperClassActualTypeParameters( actualTypeParameters );
[184]276
[351]277 // インターフェイスを引き継ぐ
278 BOOST_FOREACH( ::Interface *pInterface, inheritsClass.GetInterfaces() )
279 {
280 interfaces.push_back( new ::Interface( *pInterface ) );
281 }
282
[370]283 if( this->IsInterface() && inheritsClass.IsComInterface() )
284 {
285 // COMインターフェイスを継承した場合はCOMインターフェイスにする
286 this->SetClassType( CClass::ComInterface );
[184]287 }
288
289 return true;
290}
[340]291
[376]292bool CClass::Implements( const CClass &interfaceClass, const Types &actualTypeParameters, int nowLine )
[342]293{
[370]294 if( !interfaceClass.IsInterface() && !interfaceClass.IsComInterface() )
[342]295 {
296 // インターフェイスではないとき
[465]297 compiler.errorMessenger.Output(138,interfaceClass.GetName().c_str(),nowLine );
[342]298 return false;
299 }
300
301 if( !interfaceClass.IsReady() ){
302 // インターフェイスが未解析のとき
[376]303 compiler.GetObjectModule().meta.GetClasses().LookaheadClass( interfaceClass.GetName().c_str() );
[342]304 }
305
[376]306 ::Interface *pDestInterface = new ::Interface( &interfaceClass, actualTypeParameters );
[342]307
[351]308 interfaces.push_back( pDestInterface );
309
310
311 /////////////////////////////////////////////////////////////////
[352]312 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
[351]313 /////////////////////////////////////////////////////////////////
314 BOOST_FOREACH( CMethod *pMethod, GetDynamicMethods() )
315 {
[382]316 CMethod *pMethodForOverride = pDestInterface->GetDynamicMethods().FindForOverride( pDestInterface->GetActualTypeParameters(), &pMethod->GetUserProc() );
[351]317 if( pMethodForOverride )
318 {
319 pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
[352]320
321 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
322 pMethod->SetNotUseMark( true );
[351]323 }
324 }
325
326
327 /////////////////////////////////////////////////////////////////
[350]328 // キャストメソッドを追加(内部コードは自動生成すること)
[351]329 /////////////////////////////////////////////////////////////////
[370]330 if( interfaceClass.IsInterface() )
[350]331 {
332 // Function Operator() As ITest
333
334 char temporary[1024];
335 sprintf(temporary,"%c%c%c%c()%c%c%s",
336 1, ESC_FUNCTION,
337 1, ESC_OPERATOR,
338 1, ESC_AS,
[378]339 pDestInterface->GetFullNameWithActualGenericTypeParameters().c_str()
[350]340 );
341
342 this->AddMethod(this,
343 Prototype::Public,
344 0,
345 false, // isConst
346 false, // isAbstract
347 false, // isVirtual
348 false, // isOverride
349 true, // isAutoGeneration
350 temporary,
351 -1
352 );
353 }
354
[351]355
[342]356 return true;
357}
[340]358bool CClass::Implements( const char *interfaceNames, int nowLine )
359{
360 Jenga::Common::Strings paramStrs;
361 SplitParameter( interfaceNames, paramStrs );
[342]362
363 BOOST_FOREACH( const std::string &paramStr, paramStrs )
364 {
[375]365 char className[VN_SIZE];
[376]366 Jenga::Common::Strings typeParameterStrings;
367 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
[375]368
[376]369 Types actualTypeParameters;
370 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
371 {
372 Type type;
373 compiler.StringToType( typeParameterStr, type );
374 actualTypeParameters.push_back( type );
375 }
376
[342]377 //継承元クラスを取得
[375]378 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( className );
[342]379 if( !pInterfaceClass ){
[465]380 compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine);
[342]381 continue;
382 }
[340]383
[342]384 // インターフェイスを継承する
[376]385 Implements( *pInterfaceClass, actualTypeParameters, nowLine );
[342]386 }
387
[340]388 return true;
389}
390
[206]391CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
[184]392{
393 extern int cp;
394
395 //構文を解析
396 char VarName[VN_SIZE];
397 char initBuffer[VN_SIZE];
398 char lpszConstructParameter[VN_SIZE];
[206]399 Subscripts subscripts;
[184]400 Type type;
[206]401 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
[184]402
403 //重複チェック
404 if(this->DupliCheckAll(VarName)){
[465]405 compiler.errorMessenger.Output(15,VarName,cp);
[184]406 }
407
[206]408 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
[184]409 pMember->source_code_address = nowLine;
410 return pMember;
411}
[206]412void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
[184]413 dynamicMembers.push_back(
414 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
415 );
416}
[206]417void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
[184]418 staticMembers.push_back(
419 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
420 );
421}
422
[206]423void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
[350]424 bool isVirtual, bool isOverride, bool isAutoGeneration, char *buffer, int nowLine){
[184]425 int i,i2;
426 char temporary[VN_SIZE];
427
428 i=2;
429 for(i2=0;;i++,i2++){
430 if(buffer[i]=='('||buffer[i]=='\0'){
431 temporary[i2]=0;
432 break;
433 }
434 temporary[i2]=buffer[i];
435 }
436
437
438 //関数ハッシュへ登録
[353]439 char interfaceName[VN_SIZE] = "";
440 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().AddUserProc( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0), interfaceName );
[184]441 if(!pUserProc) return;
442
[350]443 if( isAutoGeneration )
444 {
445 // コード自動生成
446 pUserProc->ThisIsAutoGenerationProc();
447 }
[184]448
[350]449
[184]450 ////////////////////////////////////////////////////////////
451 // コンストラクタ、デストラクタの場合の処理
452 ////////////////////////////////////////////////////////////
453 BOOL fConstructor=0,bDestructor=0;
454
455 if(lstrcmp(temporary,pobj_c->GetName().c_str())==0){
456 //コンストラクタの場合
457
458 //標準コンストラクタ(引数なし)
459 if(pUserProc->Params().size()==0) fConstructor=1;
460
461 //強制的にConst修飾子をつける
462 isConst = true;
463 }
464 else if(temporary[0]=='~'){
465 //デストラクタの場合はその名前が正しいかチェックを行う
466 if(lstrcmp(temporary+1,pobj_c->GetName().c_str())!=0)
[465]467 compiler.errorMessenger.Output(117,NULL,nowLine);
[184]468 else
469 bDestructor=1;
470 }
471 if(fConstructor||bDestructor){
472 // コンストラクタ、デストラクタのアクセシビリティをチェック
473
474 //強制的にConst修飾子をつける
475 isConst = true;
476 }
477
478 if( fConstructor == 1 )
[342]479 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
[184]480 else if( bDestructor )
[342]481 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
[184]482
483
484
485 //////////////////
486 // 重複チェック
487 //////////////////
488
489 if(pobj_c->DupliCheckMember(temporary)){
[465]490 compiler.errorMessenger.Output(15,temporary,nowLine);
[184]491 return;
492 }
493
494 //メソッド
[351]495 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
496 {
[184]497 //基底クラスと重複する場合はオーバーライドを行う
498 if( pMethod->GetInheritsClassPtr() ) continue;
499
[382]500 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
[351]501 {
502 //関数名、パラメータ、戻り値が合致したとき
[465]503 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
[351]504 return;
[184]505 }
506 }
507
508 //仮想関数の場合
509 if( isAbstract ) pUserProc->CompleteCompile();
510
[346]511 // メソッドのオーバーライド
[382]512 CMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
[351]513 if( pMethodForOverride )
[346]514 {
[351]515 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
516 pUserProc->SetMethod( pMethodForOverride );
[346]517 return;
518 }
519 else
520 {
521 // インターフェイス メソッドのオーバーライド
522 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
523 {
[353]524 if( interfaceName[0] )
525 {
526 if( pInterface->GetClass().GetName() != interfaceName )
527 {
528 // 指定されたインターフェイス名と整合しないとき
529 continue;
530 }
531 }
532
[378]533 if( !pInterface->GetClass().IsReady() ){
534 // インターフェイスが未解析のとき
535 compiler.GetObjectModule().meta.GetClasses().LookaheadClass( pInterface->GetClass().GetName().c_str() );
536 }
537
[382]538 CMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
[351]539 if( pMethodForOverride )
[305]540 {
[351]541 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
542 pUserProc->SetMethod( pMethodForOverride );
[305]543 return;
[184]544 }
545 }
546 }
547
[353]548 if( interfaceName[0] )
549 {
[465]550 compiler.errorMessenger.Output(139,interfaceName,nowLine);
[353]551 }
552
[184]553 if( isVirtual ){
554 pobj_c->AddVtblNum( 1 );
555 }
556
557 if( isOverride ){
[465]558 compiler.errorMessenger.Output(12,"Override",nowLine);
[184]559 }
560
561 if(bStatic){
562 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
563 }
564 else{
[342]565 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
[184]566 }
567}
568
[409]569bool CClass::DupliCheckAll(const char *name) const
570{
[206]571 //重複チェック
572
573 //メンバ
574 if(DupliCheckMember(name)) return 1;
575
576 //メソッド
[342]577 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
[206]578 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
579 return 1;
580 }
581 }
582
583 return 0;
584}
[409]585bool CClass::DupliCheckMember(const char *name) const
586{
[206]587 //重複チェック
588
[409]589 if( this->HasSuperClass() )
590 {
591 if( this->GetSuperClass().DupliCheckMember( name ) )
592 {
593 // 基底クラスで重複が発見された
594 return true;
595 }
596 }
597
[206]598 // 動的メンバ
[409]599 BOOST_FOREACH( CMember *pMember, dynamicMembers )
600 {
601 if( GetName() == pMember->GetName() )
602 {
603 return true;
[206]604 }
605 }
606
607 // 静的メンバ
608 BOOST_FOREACH( CMember *pMember, staticMembers ){
609 if( GetName() == pMember->GetName() ){
[409]610 return true;
[206]611 }
612 }
613
[409]614 return false;
[206]615}
616
[409]617const CMember *CClass::FindDynamicMember( const char *memberName ) const
618{
619 if( this->HasSuperClass() )
620 {
621 // 基底クラスで検索
622 const CMember *result = this->GetSuperClass().FindDynamicMember( memberName );
623 if( result )
624 {
625 return result;
626 }
627 }
628
629 BOOST_FOREACH( CMember *pMember, GetDynamicMembers() )
630 {
631 if( pMember->GetName() == memberName )
632 {
633 return pMember;
634 }
635 }
636 return NULL;
637}
638
[350]639void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
[347]640{
641 // 動的メソッド
642 GetDynamicMethods().Enum( methodName, subs );
643
644 // インターフェイス メソッド
645 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
646 {
647 pInterface->GetDynamicMethods().Enum( methodName, subs );
648 }
649}
[350]650const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
[347]651{
652 // 動的メソッド
653 const CMethod *result = GetDynamicMethods().GetMethodPtr( pUserProc );
654
655 if( !result )
656 {
657 // インターフェイス メソッド
658 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
659 {
660 result = pInterface->GetDynamicMethods().GetMethodPtr( pUserProc );
[350]661 if( result )
662 {
663 return result;
664 }
[347]665 }
666 }
667
668 return result;
669}
670
[325]671const ::Delegate &CClass::GetDelegate() const
672{
673 const ::Delegate *dg = compiler.GetObjectModule().meta.GetDelegates().GetHashArrayElement( GetName().c_str() );
674 while( dg )
675 {
676 if( dg->IsEqualSymbol( GetNamespaceScopes(), GetName() ) ){
677 //名前空間とクラス名が一致した
678 return *dg;
679 }
680 dg = dg->GetChainNext();
681 }
682
683 Jenga::Throw( "CClass::GetDelegateメソッドに失敗" );
684 static ::Delegate dummy;
685 return dummy;
686}
687
[206]688//サイズを取得
689int CClass::GetSize() const
[184]690{
[409]691 int resultSize = 0;
692
693 int alignment = 1;
694 if( this->IsStructure() )
695 {
696 // 構造体のとき
697
698 if( this->GetFixedAlignment() )
699 {
700 // アラインメントの固定値が指定されていた場合はそれを取得
701 alignment = this->GetFixedAlignment();
702 }
703 }
704 else
705 {
706 // それ以外
707
708 if( this->HasSuperClass() )
709 {
710 // 基底クラスのサイズを追加
711 resultSize += this->GetSuperClass().GetSize();
712
713 // 基底クラスのアラインメントを取得
714 alignment = this->GetSuperClass().GetAlignment();
715 }
716 else
717 {
718 // 基底クラスが存在しないとき
719
720 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
721 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
722 }
723 }
724
725 BOOST_FOREACH( CMember *pMember, dynamicMembers )
726 {
727 // メンバサイズ
728 int tempMemberSize = pMember->GetType().GetSize();
729
730 // 一時アラインメントを算出
731 int tempAlignment = tempMemberSize;
732 if( pMember->GetType().IsStruct() )
733 {
734 // メンバが構造体の場合は、メンバのアラインメントを取得
735 tempAlignment = pMember->GetType().GetClass().GetAlignment();
736 }
737
738 // アラインメントを考慮してパディングを追加
739 if( GetFixedAlignment() && alignment < tempAlignment )
740 {
741 if( resultSize % alignment )
742 {
743 resultSize += alignment - ( resultSize % alignment );
744 }
745 }
746 else
747 {
748 if( alignment < tempAlignment )
749 {
750 // 最大アラインメントを更新
751 alignment = tempAlignment;
752 }
753
754 if( tempMemberSize == 0 )
755 {
756 if( !pMember->GetType().IsStruct() )
757 {
[465]758 compiler.errorMessenger.OutputFatalError();
[409]759 }
760
761 //メンバを持たない構造体
762 //※何もしない(オフセットの計算をしない)
763 }
764 else{
765 if( resultSize % tempAlignment )
766 {
767 resultSize += tempAlignment - ( resultSize % tempAlignment );
768 }
769 }
770 }
771
772 // メンバサイズを加算(配列を考慮)
773 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
774 }
775
776 if( alignment )
777 {
778 // 末尾アラインメントを考慮してパディングを追加
779 if( resultSize % alignment )
780 {
781 resultSize += alignment - ( resultSize % alignment );
782 }
783 }
784
785 return resultSize;
[206]786}
[184]787
[206]788//メンバのオフセットを取得
[409]789int CClass::GetMemberOffset( const char *memberName ) const
[206]790{
[409]791 int resultSize = 0;
[206]792
[232]793 int alignment = 1;
[409]794 if( this->IsStructure() )
[232]795 {
[409]796 // 構造体のとき
797
798 if( this->GetFixedAlignment() )
799 {
800 // アラインメントの固定値が指定されていた場合はそれを取得
801 alignment = this->GetFixedAlignment();
802 }
[232]803 }
[409]804 else
805 {
806 // それ以外
[206]807
[409]808 if( this->HasSuperClass() )
809 {
810 if( this->GetSuperClass().HasDynamicMember( memberName ) )
811 {
812 // 基底クラスのメンバを取得
813 return this->GetSuperClass().GetMemberOffset( memberName );
814 }
[206]815
[409]816 // 基底クラスのサイズを追加
817 resultSize += this->GetSuperClass().GetSize();
[206]818
[409]819 // 基底クラスのアラインメントを取得
820 alignment = this->GetSuperClass().GetAlignment();
[206]821 }
[409]822 else
823 {
824 // 基底クラスが存在しないとき
825
826 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
827 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
[206]828 }
[409]829 }
[206]830
[409]831 BOOST_FOREACH( CMember *pMember, dynamicMembers )
832 {
833 // メンバサイズ
834 int tempMemberSize = pMember->GetType().GetSize();
835
836 // 一時アラインメントを算出
837 int tempAlignment = tempMemberSize;
838 if( pMember->GetType().IsStruct() )
839 {
840 // メンバが構造体の場合は、メンバのアラインメントを取得
841 tempAlignment = pMember->GetType().GetClass().GetAlignment();
[206]842 }
843
[409]844 // アラインメントを考慮してパディングを追加
845 if( GetFixedAlignment() && alignment < tempAlignment )
846 {
847 if( resultSize % alignment )
848 {
849 resultSize += alignment - ( resultSize % alignment );
850 }
851 }
852 else
853 {
854 if( alignment < tempAlignment )
855 {
856 // 最大アラインメントを更新
857 alignment = tempAlignment;
858 }
859
860 if( tempMemberSize == 0 )
861 {
862 if( !pMember->GetType().IsStruct() )
863 {
[465]864 compiler.errorMessenger.OutputFatalError();
[409]865 }
866
867 //メンバを持たない構造体
[206]868 //※何もしない(オフセットの計算をしない)
869 }
870 else{
[409]871 if( resultSize % tempAlignment )
872 {
873 resultSize += tempAlignment - ( resultSize % tempAlignment );
874 }
[206]875 }
876 }
877
878 if(memberName){
879 //メンバ指定がある場合は、オフセットを返す
[409]880 if( pMember->GetName() == memberName )
881 {
882 return resultSize;
[206]883 }
884 }
885
[409]886 // メンバサイズを加算(配列を考慮)
887 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
[206]888 }
889
[409]890 if( alignment )
891 {
892 // 末尾アラインメントを考慮してパディングを追加
893 if( resultSize % alignment )
894 {
895 resultSize += alignment - ( resultSize % alignment );
896 }
[206]897 }
898
[409]899 return resultSize;
[206]900}
901int CClass::GetAlignment() const
902{
[409]903 int alignment = 1;
904 if( this->IsStructure() )
905 {
906 // 構造体のとき
[206]907
[409]908 if( this->GetFixedAlignment() )
909 {
910 // アラインメントの固定値が指定されていた場合はそれを取得
911 return this->GetFixedAlignment();
[206]912 }
[409]913 }
914 else
915 {
916 // それ以外
917
918 if( this->HasSuperClass() )
919 {
920 // 基底クラスのアラインメントを取得
921 alignment = this->GetSuperClass().GetAlignment();
[206]922 }
[409]923 else
924 {
925 // 基底クラスが存在しないとき
[206]926
[409]927 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
928 alignment = PTR_SIZE;
929 }
[206]930 }
931
[409]932 BOOST_FOREACH( CMember *pMember, dynamicMembers )
933 {
934 int tempAlignment = pMember->GetType().GetSize();
935 if( pMember->GetType().IsStruct() )
936 {
937 // メンバが構造体の場合は、メンバのアラインメントを取得
938 tempAlignment = pMember->GetType().GetClass().GetAlignment();
939 }
[206]940
[409]941 if( alignment < tempAlignment )
942 {
943 // 最大アラインメントを更新
944 alignment = tempAlignment;
945 }
946 }
[206]947
948 return alignment;
949}
[342]950
[348]951void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
[342]952{
[348]953 vtblMasterListIndex = 0;
954
955 vtblIndex = 0;
[342]956 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
957 if( &pMethod->GetUserProc() == pUserProc )
958 {
[348]959 return;
[342]960 }
[348]961
962 if( pMethod->IsVirtual() )
963 {
964 vtblIndex++;
965 }
[342]966 }
967
[346]968 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
[342]969 {
[348]970 vtblMasterListIndex++;
[342]971
[348]972 vtblIndex = 0;
[347]973 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
[342]974 if( &pMethod->GetUserProc() == pUserProc )
975 {
[348]976 return;
[342]977 }
[348]978
979 if( pMethod->IsVirtual() )
980 {
981 vtblIndex++;
982 }
[342]983 }
984 }
985
[465]986 compiler.errorMessenger.OutputFatalError();
[348]987 return;
[342]988}
[350]989int CClass::GetVtblMasterListIndex( const CClass *pClass ) const
990{
991 int result = 0;
992
993 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
994 {
995 result++;
996
997 if( &pInterface->GetClass() == pClass )
998 {
999 return result;
1000 }
1001 }
1002
[465]1003 compiler.errorMessenger.OutputFatalError();
[350]1004 return 0;
1005}
[370]1006long CClass::GetComVtblOffset() const
1007{
1008 return comVtblOffset;
1009}
[345]1010long CClass::GetVtblMasterListOffset() const
[206]1011{
[184]1012 //既に存在する場合はそれを返す
[342]1013 if( vtblMasterListOffset == -1 )
1014 {
[465]1015 compiler.errorMessenger.OutputFatalError();
[342]1016 }
[184]1017
[342]1018 return vtblMasterListOffset;
1019}
[345]1020void CClass::GenerateVTableMasterList( const std::vector<long> &vtableMasterList, long &offset )
[282]1021{
[342]1022 offset = compiler.GetObjectModule().dataTable.AddBinary(
1023 (void *)&vtableMasterList[0],
[345]1024 static_cast<int>(vtableMasterList.size()*sizeof(LONG_PTR))
[342]1025 );
1026}
1027void CClass::GenerateFullVTables()
1028{
[282]1029 if( IsAbstract() )
1030 {
1031 // 抽象クラスは無視
1032 return;
1033 }
1034 if( !IsUsing() )
1035 {
1036 // 使われていないクラスは無視
1037 return;
1038 }
1039
[342]1040 // vtblマスターリストの元データに不要なデータが含まれていたらエラー
1041 if( vtblMasterList.size() )
1042 {
[465]1043 compiler.errorMessenger.OutputFatalError();
[342]1044 }
[282]1045
[342]1046 // 自身のクラスのvtblを生成
[347]1047 GetDynamicMethods().GenerateVTablePart( this->vtbl_offset );
[342]1048 vtblMasterList.push_back( this->vtbl_offset );
[282]1049
[342]1050 // インターフェイスのvtblを生成
[346]1051 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
[342]1052 {
[345]1053 long tempVtblOffset;
[347]1054 pInterface->GetDynamicMethods().GenerateVTablePart( tempVtblOffset );
[342]1055 vtblMasterList.push_back( tempVtblOffset );
[282]1056
[346]1057 pInterface->SetVtblOffset( tempVtblOffset );
[370]1058
1059 if( pInterface->GetClass().IsComInterface() )
1060 {
1061 if( this->comVtblOffset )
1062 {
[465]1063 compiler.errorMessenger.OutputFatalError();
[370]1064 }
1065 this->comVtblOffset = tempVtblOffset;
1066 }
[282]1067 }
1068
[342]1069 // vtblマスターリストを生成
1070 GenerateVTableMasterList( vtblMasterList, this->vtblMasterListOffset );
[282]1071}
[342]1072void CClass::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection )
1073{
[282]1074 if( IsAbstract() )
1075 {
1076 // 抽象クラスは無視
1077 return;
1078 }
1079 if( !IsUsing() )
1080 {
1081 // 使われていないクラスは無視
1082 return;
1083 }
[184]1084 if(vtbl_offset==-1) return;
1085
[342]1086 // 自身のクラスのvtbl
1087 {
1088 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtbl_offset);
[184]1089
[342]1090 for( int i=0; i<GetVtblNum(); i++ ){
1091 const UserProc *pUserProc = (UserProc *)pVtbl[i];
1092 if(!pUserProc) continue;
[263]1093
[342]1094 if( pUserProc->GetBeginOpAddress() == 0
1095 && pUserProc->GetEndOpAddress() == 0 )
1096 {
1097 Jenga::Throw( "未解決の仮想関数が存在する" );
1098 }
1099
1100 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
[282]1101 }
[342]1102 }
[282]1103
[342]1104 // インターフェイスのvtbl
[346]1105 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
[342]1106 {
[347]1107 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + pInterface->GetVtblOffset());
[342]1108
[346]1109 for( int i=0; i<pInterface->GetClass().GetVtblNum(); i++ ){
[342]1110 const UserProc *pUserProc = (UserProc *)pVtbl[i];
1111 if(!pUserProc) continue;
1112
1113 if( pUserProc->GetBeginOpAddress() == 0
1114 && pUserProc->GetEndOpAddress() == 0 )
1115 {
1116 Jenga::Throw( "未解決の仮想関数が存在する" );
1117 }
1118
1119 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
1120 }
[184]1121 }
[342]1122
1123 // vtblマスターリスト
1124 LONG_PTR *pVtblMasterList = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtblMasterListOffset );
1125 for( int i=0; i<static_cast<int>(vtblMasterList.size()); i++ )
1126 {
1127 pVtblMasterList[i] = vtblMasterList[i] + ImageBase + MemPos_DataSection;
1128 }
[184]1129}
[206]1130bool CClass::IsAbstract() const
1131{
1132 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
[184]1133
[342]1134 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
[206]1135 if(pMethod->IsVirtual()){
1136 if(pMethod->IsAbstract()){
1137 return true;
1138 }
1139 }
1140 }
1141
[351]1142 // インターフェイスのvtbl
1143 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1144 {
1145 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
1146 if(pMethod->IsVirtual()){
1147 if(pMethod->IsAbstract()){
1148 return true;
1149 }
1150 }
1151 }
1152 }
1153
[206]1154 return false;
[184]1155}
1156
[206]1157CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
1158 return new CClass(namespaceScopes, importedNamespaces, name);
1159}
[369]1160bool Classes::Insert( CClass *pClass, int nowLine )
[206]1161{
1162 /////////////////////////////////
1163 // ハッシュデータに追加
1164 /////////////////////////////////
1165
[270]1166 if( !Put( pClass ) )
1167 {
[465]1168 compiler.errorMessenger.Output(15,pClass->GetName(), nowLine);
[270]1169 return false;
[206]1170 }
1171 return true;
1172}
1173CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
1174 //////////////////////////////////////////////////////////////////////////
1175 // クラスを追加
1176 // ※名前のみを登録。その他の情報はSetClassメソッドで!
1177 //////////////////////////////////////////////////////////////////////////
1178
1179 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
1180
[369]1181 if( !Insert( pClass, nowLine ) )
[206]1182 {
1183 return NULL;
1184 }
1185
1186 return pClass;
1187}
1188
[282]1189void Classes::GenerateVTables()
1190{
1191 Iterator_Reset();
1192 while( Iterator_HasNext() )
1193 {
1194 CClass *pClass = Iterator_GetNext();
[342]1195 pClass->GenerateFullVTables();
[282]1196 }
1197}
1198
[342]1199void Classes::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection ){
[270]1200 Iterator_Reset();
1201 while( Iterator_HasNext() )
1202 {
1203 CClass *pClass = Iterator_GetNext();
[342]1204 pClass->ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection);
[206]1205 }
1206}
1207
1208
1209void Classes::InitStaticMember(){
[184]1210 //静的メンバをグローバル領域に作成
1211
1212 //イテレータをリセット
1213
1214 extern int cp;
1215 int back_cp=cp;
1216
[270]1217 this->Iterator_Reset();
[184]1218 while(this->Iterator_HasNext()){
1219 CClass &objClass = *this->Iterator_GetNext();
[272]1220 if( objClass.isTargetObjectModule == false )
1221 {
1222 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
1223 continue;
1224 }
[184]1225
1226 // 名前空間をセット
[199]1227 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
[184]1228
[355]1229 DWORD dwFlags = 0;
1230 if( objClass.GetName() == "_System_TypeBase" )
1231 {
1232 // _System_TypeBaseクラスはグローバル、スタティック領域を初期化するためのクラスなのでここでの初期化は除外する
1233 dwFlags |= DIMFLAG_NONCALL_CONSTRACTOR;
1234 }
1235
[406]1236 // コンパイル中クラスとしてセット
1237 compiler.pCompilingClass = &objClass;
1238
1239 const EnumInfo *pEnumInfo = NULL;
1240 if( objClass.IsEnum() )
1241 {
1242 pEnumInfo = compiler.enumInfoCollection.Find( objClass );
1243 }
1244
[184]1245 int i=0;
[406]1246 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() )
1247 {
1248 if( pEnumInfo )
1249 {
1250 cp = pEnumInfo->GetEnumMember( member->GetName() ).GetSourceIndex();
1251 }
1252
[184]1253 char temporary[VN_SIZE];
1254 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
1255 dim(
1256 temporary,
[206]1257 member->GetSubscripts(),
[184]1258 member->GetType(),
1259 member->GetInitializeExpression().c_str(),
1260 member->GetConstructParameter().c_str(),
[355]1261 dwFlags);
[184]1262
1263 i++;
1264 }
[406]1265
1266 compiler.pCompilingClass = NULL;
[184]1267 }
1268
[199]1269 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
[184]1270
1271 cp=back_cp;
1272}
1273
[206]1274void Classes::Compile_System_InitializeUserTypes(){
[184]1275 char temporary[VN_SIZE];
1276
1277 ////////////////////////////////////////////////////////////////////
1278 // クラス登録
1279 ////////////////////////////////////////////////////////////////////
1280
1281 // イテレータをリセット
1282 Iterator_Reset();
1283
1284 while( Iterator_HasNext() ){
1285 const CClass &objClass = *Iterator_GetNext();
1286
1287 if( !objClass.IsUsing() ){
1288 // 未使用のクラスは無視する
1289 continue;
[417]1290 }
[184]1291
[417]1292 std::string referenceOffsetsBuffer;
[184]1293 int numOfReference = 0;
[417]1294 objClass.GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference );
[184]1295
1296 sprintf( temporary
[355]1297 , "Add(%c%c_System_TypeForClass[strNamespace=\"%s\",name=\"%s\",fullName=\"%s\",referenceOffsets=[%s],numOfReference=%d])"
[184]1298 , 1
[355]1299 , ESC_SYSTEM_STATIC_NEW
1300 , objClass.GetNamespaceScopes().ToString().c_str() // 名前空間
1301 , objClass.GetName().c_str() // クラス名
1302 , objClass.GetFullName().c_str() // フルネーム
[417]1303 , referenceOffsetsBuffer.c_str() // 参照メンバオフセット配列
[355]1304 , numOfReference // 参照メンバの個数
[184]1305 );
1306
1307 // コンパイル
1308 ChangeOpcode( temporary );
[355]1309
1310 objClass.SetTypeInfoDataTableOffset(
1311 compiler.GetObjectModule().dataTable.GetLastMadeConstObjectDataTableOffset()
1312 );
[184]1313 }
[355]1314}
1315void Classes::Compile_System_InitializeUserTypesForBaseType()
1316{
1317 extern int cp;
1318 cp = -1;
[184]1319 ////////////////////////////////////////////////////////////////////
1320 // 基底クラスを登録
1321 ////////////////////////////////////////////////////////////////////
1322
[387]1323 char temporary[8192];
[431]1324 sprintf(temporary, "%c%ctempType=Nothing%c%c_System_TypeForClass"
[184]1325 , HIBYTE( COM_DIM )
1326 , LOBYTE( COM_DIM )
1327 , 1
1328 , ESC_AS
1329 );
1330 ChangeOpcode( temporary );
1331
1332 // イテレータをリセット
1333 Iterator_Reset();
1334
1335 while( Iterator_HasNext() ){
1336 const CClass &objClass = *Iterator_GetNext();
1337
1338 if( !objClass.IsUsing() ){
1339 // 未使用のクラスは無視する
1340 continue;
1341 }
1342
[409]1343 if( objClass.HasSuperClass() || objClass.GetDynamicMembers().size() ){
[184]1344 sprintf( temporary
[431]1345 , "tempType=Search(\"%s\") As ActiveBasic.Core._System_TypeForClass"
[355]1346 , objClass.GetFullName().c_str()
[387]1347 );
[184]1348
1349 // コンパイル
[431]1350 MakeMiddleCode( temporary );
[184]1351 ChangeOpcode( temporary );
1352
[431]1353 sprintf( temporary
1354 , "tempType.SetClassInfo(%d,_System_GetComVtbl(%s),_System_GetVtblList(%s),_System_GetDefaultConstructor(%s),_System_GetDestructor(%s))"
1355 , objClass.GetSize()
1356 , objClass.GetFullName().c_str()
1357 , objClass.GetFullName().c_str()
1358 , objClass.GetFullName().c_str()
1359 , objClass.GetFullName().c_str()
1360 , objClass.GetName().c_str()
1361 );
1362
1363 // コンパイル
1364 ChangeOpcode( temporary );
1365
[409]1366 if( objClass.HasSuperClass() )
1367 {
1368 sprintf( temporary
1369 , "tempType.SetBaseType(Search(\"%s\"))"
1370 , objClass.GetSuperClass().GetFullName().c_str()
1371 );
[184]1372
[409]1373 // コンパイル
1374 ChangeOpcode( temporary );
1375 }
[184]1376
[409]1377 if( objClass.GetDynamicMembers().size() )
1378 {
1379 // メンバの型を示すTypeInfoオブジェクトへのDataOffset配列の静的データ定義文字列を取得
1380 sprintf(
1381 temporary,
[412]1382 "tempType.SetMembers([%s],[%s],[%s],%d)",
[409]1383 objClass.GetStaticDefiningStringAsMemberNames().c_str(),
1384 objClass.GetStaticDefiningStringAsMemberTypeInfoNames().c_str(),
[412]1385 objClass.GetStaticDefiningStringAsMemberOffsets().c_str(),
[409]1386 objClass.GetDynamicMembers().size()
1387 );
1388 ChangeOpcode( temporary );
1389 }
[184]1390 }
[387]1391 }
[184]1392}
[193]1393
[206]1394const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
[193]1395{
1396 if( namespaceScopes.size() == 0 && name == "Object" ){
1397 return GetObjectClassPtr();
1398 }
1399 else if( namespaceScopes.size() == 0 && name == "String" ){
1400 return GetStringClassPtr();
1401 }
1402
[380]1403 std::vector<const CClass *> classes;
[270]1404 const CClass *pClass = GetHashArrayElement( name.c_str() );
1405 while( pClass )
1406 {
1407 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1408 //名前空間とクラス名が一致した
[380]1409 classes.push_back( pClass );
[193]1410 }
[270]1411 pClass = pClass->GetChainNext();
[193]1412 }
[380]1413 if( classes.size() > 0 )
1414 {
1415 // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
1416 pClass = classes.front();
[193]1417
[380]1418 BOOST_FOREACH( const CClass *pTempClass, classes )
1419 {
1420 if( pClass->GetNamespaceScopes().size() < pTempClass->GetNamespaceScopes().size() )
1421 {
1422 pClass = pTempClass;
1423 }
1424 }
1425
1426 return pClass;
1427 }
1428
[193]1429 // TypeDefも見る
[265]1430 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
[193]1431 if( index != -1 ){
[265]1432 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
[193]1433 if( type.IsObject() ){
1434 return &type.GetClass();
1435 }
1436 }
1437
1438 return NULL;
1439}
[206]1440const CClass *Classes::Find( const string &fullName ) const
1441{
1442 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1443 char NestName[VN_SIZE] = ""; //入れ子メンバ
1444 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
1445
1446 return Find( NamespaceScopes( AreaName ), NestName );
1447}
1448void Classes::StartCompile( const UserProc *pUserProc ){
1449 const CClass *pParentClass = pUserProc->GetParentClassPtr();
1450 if( pParentClass ){
1451 pParentClass->Using();
1452
[282]1453 // 仮想関数になるメソッドに使用チェックをつける
[342]1454 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
[282]1455 {
1456 if( pMethod->IsVirtual() )
1457 {
1458 pMethod->GetUserProc().Using();
1459 }
1460 }
1461
[350]1462 pCompilingMethod = pParentClass->GetDynamicMethodOrInterfaceMethod( pUserProc );
[206]1463 if( !pCompilingMethod ){
1464 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
1465 if( !pCompilingMethod ){
[465]1466 compiler.errorMessenger.OutputFatalError();
[206]1467 }
1468 }
1469 }
1470 else{
1471 pCompilingMethod = NULL;
1472 }
1473}
1474
[272]1475const CClass *Classes::GetStringClassPtr() const
[206]1476{
1477 if( !pStringClass ){
[272]1478 // キャッシュしておく
1479 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
1480
1481 if( !pStringClass )
1482 {
[465]1483 compiler.errorMessenger.Output(400, "System.String", cp);
[351]1484 static CClass dummy;
1485 return &dummy;
[272]1486 }
1487 return pStringClass;
[206]1488 }
1489 return pStringClass;
1490}
[272]1491const CClass *Classes::GetObjectClassPtr() const
[206]1492{
1493 if( !pObjectClass ){
[272]1494 // キャッシュしておく
1495 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
1496
1497 if( !pObjectClass )
1498 {
[465]1499 compiler.errorMessenger.Output(400, "System.Object", cp);
[351]1500 static CClass dummy;
1501 return &dummy;
[272]1502 }
1503 return pObjectClass;
[206]1504 }
1505 return pObjectClass;
1506}
[349]1507const CClass *Classes::GetInterfaceInfoClassPtr() const
1508{
1509 if( !pInterfaceInfo ){
1510 // キャッシュしておく
1511 pInterfaceInfo = this->Find( "ActiveBasic.Core.InterfaceInfo" );
1512
1513 if( !pInterfaceInfo )
1514 {
[465]1515 compiler.errorMessenger.Output(400, "ActiveBasic.Core.InterfaceInfo", cp);
[351]1516 static CClass dummy;
1517 return &dummy;
[349]1518 }
1519 return pInterfaceInfo;
1520 }
1521 return pInterfaceInfo;
1522}
[387]1523
1524std::string CClass::GetStaticDefiningStringAsMemberNames() const
1525{
1526 std::string result;
1527
1528 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1529 {
1530 if( result.size() )
1531 {
1532 result += ",";
1533 }
1534
1535 result += "\"" + pMember->GetName() + "\"";
1536 }
1537
1538 return result;
1539}
1540std::string CClass::GetStaticDefiningStringAsMemberTypeInfoNames() const
1541{
1542 std::string result;
1543
1544 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1545 {
1546 if( result.size() )
1547 {
1548 result += ",";
1549 }
1550
1551 result += "\"" + compiler.TypeToString( pMember->GetType() ) + "\"";
1552 }
1553
1554 return result;
1555}
[412]1556std::string CClass::GetStaticDefiningStringAsMemberOffsets() const
1557{
1558 std::string result;
[387]1559
[412]1560 BOOST_FOREACH( const CMember *pMember, dynamicMembers )
1561 {
1562 if( result.size() )
1563 {
1564 result += ",";
1565 }
1566
1567 int offset = this->GetMemberOffset( pMember->GetName().c_str() );
1568
1569 char temporary[255];
1570 itoa( offset, temporary, 16 );
1571
1572 result += (std::string)"&H" + temporary;
1573 }
1574
1575 return result;
1576}
[417]1577
1578void CClass::GetReferenceOffsetsInitializeBuffer( std::string &referenceOffsetsBuffer, int &numOfReference, int baseOffset ) const
1579{
1580 const CClass &thisClass = *this;
1581 BOOST_FOREACH( const CMember *pMember, thisClass.GetDynamicMembers() )
1582 {
1583 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() )
1584 {
1585 if( referenceOffsetsBuffer.size() )
1586 {
1587 referenceOffsetsBuffer += ",";
1588 }
1589
1590 char temp[255];
1591 sprintf( temp, "%d", baseOffset + thisClass.GetMemberOffset( pMember->GetName().c_str() ) );
1592 referenceOffsetsBuffer += temp;
1593
1594 numOfReference++;
1595 }
1596 if( pMember->GetType().IsStruct() && !pMember->GetType().IsPointer() )
1597 {
1598 // 構造体の実体をメンバに持つとき
1599 int baseOffset = thisClass.GetMemberOffset( pMember->GetName().c_str() );
1600
1601 // 構造体メンバでGCによるチェックが必要な参照位置を追加
1602 pMember->GetType().GetClass().GetReferenceOffsetsInitializeBuffer( referenceOffsetsBuffer, numOfReference, baseOffset );
1603 }
1604 }
1605}
Note: See TracBrowser for help on using the repository browser.