source: dev/trunk/abdev/BasicCompiler_Common/src/Class.cpp@ 406

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

Enumを大改修。Enumメンバ初期値にリテラル、定数、Enumメンバを指定できるようにした。また、エラー行数を正確に表示可能にした。

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