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
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/SmoothieException.h>
5
6#include <Source.h>
7#include <Class.h>
8#include <Compiler.h>
9#include <NamespaceSupporter.h>
10
11#include "../common.h"
12#ifdef _AMD64_
13#include "../../BasicCompiler64/opcode.h"
14#else
15#include "../../BasicCompiler32/opcode.h"
16#endif
17
18#include <../Enum.h>
19
20
21Interface::Interface( const CClass *pInterfaceClass, const Types &actualTypeParameters )
22 : DynamicMethodsPrototype()
23 , pInterfaceClass( pInterfaceClass )
24 , vtblOffset( -1 )
25 , actualTypeParameters( actualTypeParameters )
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
49 AddDynamicMethods( pMethod );
50 }
51}
52
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 }
67
68 interfaceName += "<" + actualGenericTypesName + ">";
69 }
70 return interfaceName;
71}
72
73bool CClass::IsClass() const
74{
75 return classType == CClass::Class;
76}
77bool CClass::IsInterface() const
78{
79 return classType == CClass::Interface;
80}
81bool CClass::IsComInterface() const
82{
83 return classType == CClass::ComInterface;
84}
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 {
138 return false;
139 }
140
141 const CClass *pTempClass = &pClass->GetSuperClass();
142 while( pTempClass ){
143 if( this == pTempClass ) return true;
144 pTempClass = &pTempClass->GetSuperClass();
145 }
146 return false;
147}
148
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{
167 BOOST_FOREACH( const ::Interface *pInterface, interfaces ){
168 if( pInterfaceClass == &pInterface->GetClass() ){
169 return true;
170 }
171 }
172 return false;
173}
174
175bool CClass::Inherits( const char *inheritNames, int nowLine ){
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
189 // ジェネリクス構文を分解
190 char className[VN_SIZE];
191 Jenga::Common::Strings typeParameterStrings;
192 SplitGenericClassInstance( temporary, className, typeParameterStrings );
193
194 // 型パラメータ文字列から型データを取得
195 Types actualTypeParameters;
196 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
197 {
198 Type type;
199 compiler.StringToType( typeParameterStr, type );
200 actualTypeParameters.push_back( type );
201 }
202
203 //継承元クラスを取得
204 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
205 if( !pInheritsClass ){
206 SmoothieException::Throw(106,className,nowLine);
207 return false;
208 }
209
210 if( pInheritsClass->IsClass() ){
211 // クラスを継承する
212 isInheritsClass = true;
213
214 if( !InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
215 return false;
216 }
217 }
218 else{
219 SetError(135,pInheritsClass->GetFullName().c_str(),nowLine);
220 return false;
221 }
222
223 if( inheritNames[i] == '\0' ){
224 break;
225 }
226 i++;
227 }
228
229 if( !isInheritsClass ){
230 // クラスを一つも継承していないとき
231 if( !InheritsClass( *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(), Types(), nowLine ) ){
232 return false;
233 }
234 }
235
236 return true;
237}
238bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine )
239{
240 //ループ継承でないかをチェック
241 if( !compiler.GetObjectModule().meta.GetClasses().LoopRefCheck(inheritsClass) )
242 {
243 SmoothieException::Throw(123,inheritsClass.GetName(),nowLine);
244 return false;
245 }
246
247 if( !inheritsClass.IsReady() ){
248 //継承先が読み取られていないとき
249 compiler.GetObjectModule().meta.GetClasses().LookaheadClass(inheritsClass.GetName().c_str());
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
264 // メンバのみ、型パラメータを解決する(メソッドのほうは呼び出し時に解決する)
265 if( pMember->GetType().IsTypeParameter() )
266 {
267 pMember->ResetType( actualTypeParameters[pMember->GetType().GetFormalTypeIndex()] );
268 }
269
270 dynamicMembers.push_back( pMember );
271 }
272
273 //メソッドをコピー
274 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
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
294 GetDynamicMethods().push_back( pMethod );
295 }
296
297 //仮想関数の数
298 AddVtblNum( inheritsClass.GetVtblNum() );
299
300 //継承先のクラスをメンバとして保持する
301 SetSuperClass( &inheritsClass );
302 SetSuperClassActualTypeParameters( actualTypeParameters );
303
304 // インターフェイスを引き継ぐ
305 BOOST_FOREACH( ::Interface *pInterface, inheritsClass.GetInterfaces() )
306 {
307 interfaces.push_back( new ::Interface( *pInterface ) );
308 }
309
310 if( this->IsInterface() && inheritsClass.IsComInterface() )
311 {
312 // COMインターフェイスを継承した場合はCOMインターフェイスにする
313 this->SetClassType( CClass::ComInterface );
314 }
315
316 return true;
317}
318
319bool CClass::Implements( const CClass &interfaceClass, const Types &actualTypeParameters, int nowLine )
320{
321 if( !interfaceClass.IsInterface() && !interfaceClass.IsComInterface() )
322 {
323 // インターフェイスではないとき
324 SetError(138,interfaceClass.GetName().c_str(),nowLine );
325 return false;
326 }
327
328 if( !interfaceClass.IsReady() ){
329 // インターフェイスが未解析のとき
330 compiler.GetObjectModule().meta.GetClasses().LookaheadClass( interfaceClass.GetName().c_str() );
331 }
332
333 ::Interface *pDestInterface = new ::Interface( &interfaceClass, actualTypeParameters );
334
335 interfaces.push_back( pDestInterface );
336
337
338 /////////////////////////////////////////////////////////////////
339 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
340 /////////////////////////////////////////////////////////////////
341 BOOST_FOREACH( CMethod *pMethod, GetDynamicMethods() )
342 {
343 CMethod *pMethodForOverride = pDestInterface->GetDynamicMethods().FindForOverride( pDestInterface->GetActualTypeParameters(), &pMethod->GetUserProc() );
344 if( pMethodForOverride )
345 {
346 pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
347
348 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
349 pMethod->SetNotUseMark( true );
350 }
351 }
352
353
354 /////////////////////////////////////////////////////////////////
355 // キャストメソッドを追加(内部コードは自動生成すること)
356 /////////////////////////////////////////////////////////////////
357 if( interfaceClass.IsInterface() )
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,
366 pDestInterface->GetFullNameWithActualGenericTypeParameters().c_str()
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
382
383 return true;
384}
385bool CClass::Implements( const char *interfaceNames, int nowLine )
386{
387 Jenga::Common::Strings paramStrs;
388 SplitParameter( interfaceNames, paramStrs );
389
390 BOOST_FOREACH( const std::string &paramStr, paramStrs )
391 {
392 char className[VN_SIZE];
393 Jenga::Common::Strings typeParameterStrings;
394 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
395
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
404 //継承元クラスを取得
405 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( className );
406 if( !pInterfaceClass ){
407 SetError(106,paramStr.c_str(),nowLine);
408 continue;
409 }
410
411 // インターフェイスを継承する
412 Implements( *pInterfaceClass, actualTypeParameters, nowLine );
413 }
414
415 return true;
416}
417
418CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
419{
420 extern int cp;
421
422 //構文を解析
423 char VarName[VN_SIZE];
424 char initBuffer[VN_SIZE];
425 char lpszConstructParameter[VN_SIZE];
426 Subscripts subscripts;
427 Type type;
428 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
429
430 //重複チェック
431 if(this->DupliCheckAll(VarName)){
432 SetError(15,VarName,cp);
433 }
434
435 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
436 pMember->source_code_address = nowLine;
437 return pMember;
438}
439void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
440 dynamicMembers.push_back(
441 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
442 );
443}
444void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
445 staticMembers.push_back(
446 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
447 );
448}
449
450void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
451 bool isVirtual, bool isOverride, bool isAutoGeneration, char *buffer, int nowLine){
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 //関数ハッシュへ登録
466 char interfaceName[VN_SIZE] = "";
467 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().AddUserProc( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0), interfaceName );
468 if(!pUserProc) return;
469
470 if( isAutoGeneration )
471 {
472 // コード自動生成
473 pUserProc->ThisIsAutoGenerationProc();
474 }
475
476
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 )
506 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
507 else if( bDestructor )
508 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
509
510
511
512 //////////////////
513 // 重複チェック
514 //////////////////
515
516 if(pobj_c->DupliCheckMember(temporary)){
517 SetError(15,temporary,nowLine);
518 return;
519 }
520
521 //メソッド
522 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
523 {
524 //基底クラスと重複する場合はオーバーライドを行う
525 if( pMethod->GetInheritsClassPtr() ) continue;
526
527 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
528 {
529 //関数名、パラメータ、戻り値が合致したとき
530 SetError(15,pUserProc->GetName().c_str(),nowLine);
531 return;
532 }
533 }
534
535 //仮想関数の場合
536 if( isAbstract ) pUserProc->CompleteCompile();
537
538 // メソッドのオーバーライド
539 CMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
540 if( pMethodForOverride )
541 {
542 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
543 pUserProc->SetMethod( pMethodForOverride );
544 return;
545 }
546 else
547 {
548 // インターフェイス メソッドのオーバーライド
549 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
550 {
551 if( interfaceName[0] )
552 {
553 if( pInterface->GetClass().GetName() != interfaceName )
554 {
555 // 指定されたインターフェイス名と整合しないとき
556 continue;
557 }
558 }
559
560 if( !pInterface->GetClass().IsReady() ){
561 // インターフェイスが未解析のとき
562 compiler.GetObjectModule().meta.GetClasses().LookaheadClass( pInterface->GetClass().GetName().c_str() );
563 }
564
565 CMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
566 if( pMethodForOverride )
567 {
568 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
569 pUserProc->SetMethod( pMethodForOverride );
570 return;
571 }
572 }
573 }
574
575 if( interfaceName[0] )
576 {
577 SetError(139,interfaceName,nowLine);
578 }
579
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{
592 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
593 }
594}
595
596bool CClass::DupliCheckAll(const char *name){
597 //重複チェック
598
599 //メンバ
600 if(DupliCheckMember(name)) return 1;
601
602 //メソッド
603 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
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
631void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
632{
633 // 動的メソッド
634 GetDynamicMethods().Enum( methodName, subs );
635
636 // インターフェイス メソッド
637 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
638 {
639 pInterface->GetDynamicMethods().Enum( methodName, subs );
640 }
641}
642const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
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 );
653 if( result )
654 {
655 return result;
656 }
657 }
658 }
659
660 return result;
661}
662
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
680//サイズを取得
681int CClass::GetSize() const
682{
683 return GetMemberOffset( NULL, NULL );
684}
685
686//メンバのオフセットを取得
687int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
688{
689 int i2;
690
691 //仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
692 int offset = IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
693
694 int alignment = 1;
695 if( GetFixedAlignment() )
696 {
697 alignment = GetFixedAlignment();
698 }
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 //アラインメントを考慮
720 if(GetFixedAlignment()&&GetFixedAlignment()<member_size){
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
782 if(GetFixedAlignment()) alignment=GetFixedAlignment();
783
784 return alignment;
785}
786
787void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
788{
789 vtblMasterListIndex = 0;
790
791 vtblIndex = 0;
792 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
793 if( &pMethod->GetUserProc() == pUserProc )
794 {
795 return;
796 }
797
798 if( pMethod->IsVirtual() )
799 {
800 vtblIndex++;
801 }
802 }
803
804 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
805 {
806 vtblMasterListIndex++;
807
808 vtblIndex = 0;
809 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
810 if( &pMethod->GetUserProc() == pUserProc )
811 {
812 return;
813 }
814
815 if( pMethod->IsVirtual() )
816 {
817 vtblIndex++;
818 }
819 }
820 }
821
822 SetError();
823 return;
824}
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}
842long CClass::GetComVtblOffset() const
843{
844 return comVtblOffset;
845}
846long CClass::GetVtblMasterListOffset() const
847{
848 //既に存在する場合はそれを返す
849 if( vtblMasterListOffset == -1 )
850 {
851 SetError();
852 }
853
854 return vtblMasterListOffset;
855}
856void CClass::GenerateVTableMasterList( const std::vector<long> &vtableMasterList, long &offset )
857{
858 offset = compiler.GetObjectModule().dataTable.AddBinary(
859 (void *)&vtableMasterList[0],
860 static_cast<int>(vtableMasterList.size()*sizeof(LONG_PTR))
861 );
862}
863void CClass::GenerateFullVTables()
864{
865 if( IsAbstract() )
866 {
867 // 抽象クラスは無視
868 return;
869 }
870 if( !IsUsing() )
871 {
872 // 使われていないクラスは無視
873 return;
874 }
875
876 // vtblマスターリストの元データに不要なデータが含まれていたらエラー
877 if( vtblMasterList.size() )
878 {
879 SetError();
880 }
881
882 // 自身のクラスのvtblを生成
883 GetDynamicMethods().GenerateVTablePart( this->vtbl_offset );
884 vtblMasterList.push_back( this->vtbl_offset );
885
886 // インターフェイスのvtblを生成
887 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
888 {
889 long tempVtblOffset;
890 pInterface->GetDynamicMethods().GenerateVTablePart( tempVtblOffset );
891 vtblMasterList.push_back( tempVtblOffset );
892
893 pInterface->SetVtblOffset( tempVtblOffset );
894
895 if( pInterface->GetClass().IsComInterface() )
896 {
897 if( this->comVtblOffset )
898 {
899 SetError();
900 }
901 this->comVtblOffset = tempVtblOffset;
902 }
903 }
904
905 // vtblマスターリストを生成
906 GenerateVTableMasterList( vtblMasterList, this->vtblMasterListOffset );
907}
908void CClass::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection )
909{
910 if( IsAbstract() )
911 {
912 // 抽象クラスは無視
913 return;
914 }
915 if( !IsUsing() )
916 {
917 // 使われていないクラスは無視
918 return;
919 }
920 if(vtbl_offset==-1) return;
921
922 // 自身のクラスのvtbl
923 {
924 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtbl_offset);
925
926 for( int i=0; i<GetVtblNum(); i++ ){
927 const UserProc *pUserProc = (UserProc *)pVtbl[i];
928 if(!pUserProc) continue;
929
930 if( pUserProc->GetBeginOpAddress() == 0
931 && pUserProc->GetEndOpAddress() == 0 )
932 {
933 Jenga::Throw( "未解決の仮想関数が存在する" );
934 }
935
936 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
937 }
938 }
939
940 // インターフェイスのvtbl
941 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
942 {
943 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + pInterface->GetVtblOffset());
944
945 for( int i=0; i<pInterface->GetClass().GetVtblNum(); i++ ){
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 }
957 }
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 }
965}
966bool CClass::IsAbstract() const
967{
968 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
969
970 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
971 if(pMethod->IsVirtual()){
972 if(pMethod->IsAbstract()){
973 return true;
974 }
975 }
976 }
977
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
990 return false;
991}
992
993CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
994 return new CClass(namespaceScopes, importedNamespaces, name);
995}
996bool Classes::Insert( CClass *pClass, int nowLine )
997{
998 /////////////////////////////////
999 // ハッシュデータに追加
1000 /////////////////////////////////
1001
1002 if( !Put( pClass ) )
1003 {
1004 SetError(15,pClass->GetName(), nowLine);
1005 return false;
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
1017 if( !Insert( pClass, nowLine ) )
1018 {
1019 return NULL;
1020 }
1021
1022 return pClass;
1023}
1024
1025void Classes::GenerateVTables()
1026{
1027 Iterator_Reset();
1028 while( Iterator_HasNext() )
1029 {
1030 CClass *pClass = Iterator_GetNext();
1031 pClass->GenerateFullVTables();
1032 }
1033}
1034
1035void Classes::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection ){
1036 Iterator_Reset();
1037 while( Iterator_HasNext() )
1038 {
1039 CClass *pClass = Iterator_GetNext();
1040 pClass->ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection);
1041 }
1042}
1043
1044
1045void Classes::InitStaticMember(){
1046 //静的メンバをグローバル領域に作成
1047
1048 //イテレータをリセット
1049
1050 extern int cp;
1051 int back_cp=cp;
1052
1053 this->Iterator_Reset();
1054 while(this->Iterator_HasNext()){
1055 CClass &objClass = *this->Iterator_GetNext();
1056 if( objClass.isTargetObjectModule == false )
1057 {
1058 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
1059 continue;
1060 }
1061
1062 // 名前空間をセット
1063 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
1064
1065 DWORD dwFlags = 0;
1066 if( objClass.GetName() == "_System_TypeBase" )
1067 {
1068 // _System_TypeBaseクラスはグローバル、スタティック領域を初期化するためのクラスなのでここでの初期化は除外する
1069 dwFlags |= DIMFLAG_NONCALL_CONSTRACTOR;
1070 }
1071
1072 // コンパイル中クラスとしてセット
1073 compiler.pCompilingClass = &objClass;
1074
1075 const EnumInfo *pEnumInfo = NULL;
1076 if( objClass.IsEnum() )
1077 {
1078 pEnumInfo = compiler.enumInfoCollection.Find( objClass );
1079 }
1080
1081 int i=0;
1082 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() )
1083 {
1084 if( pEnumInfo )
1085 {
1086 cp = pEnumInfo->GetEnumMember( member->GetName() ).GetSourceIndex();
1087 }
1088
1089 char temporary[VN_SIZE];
1090 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
1091 dim(
1092 temporary,
1093 member->GetSubscripts(),
1094 member->GetType(),
1095 member->GetInitializeExpression().c_str(),
1096 member->GetConstructParameter().c_str(),
1097 dwFlags);
1098
1099 i++;
1100 }
1101
1102 compiler.pCompilingClass = NULL;
1103 }
1104
1105 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
1106
1107 cp=back_cp;
1108}
1109
1110void Classes::Compile_System_InitializeUserTypes(){
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;
1126 }
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
1145 , "Add(%c%c_System_TypeForClass[strNamespace=\"%s\",name=\"%s\",fullName=\"%s\",referenceOffsets=[%s],numOfReference=%d])"
1146 , 1
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 // 参照メンバの個数
1153 );
1154
1155 // コンパイル
1156 ChangeOpcode( temporary );
1157
1158 objClass.SetTypeInfoDataTableOffset(
1159 compiler.GetObjectModule().dataTable.GetLastMadeConstObjectDataTableOffset()
1160 );
1161 }
1162}
1163void Classes::Compile_System_InitializeUserTypesForBaseType()
1164{
1165 extern int cp;
1166 cp = -1;
1167 ////////////////////////////////////////////////////////////////////
1168 // 基底クラスを登録
1169 ////////////////////////////////////////////////////////////////////
1170
1171 char temporary[8192];
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
1191 if( objClass.HasSuperClass() ){
1192 sprintf( temporary
1193 , "tempType=Search(\"%s\")"
1194 , objClass.GetFullName().c_str()
1195 );
1196
1197 // コンパイル
1198 ChangeOpcode( temporary );
1199
1200 sprintf( temporary
1201 , "tempType.SetBaseType(Search(\"%s\"))"
1202 , objClass.GetSuperClass().GetFullName().c_str()
1203 );
1204
1205 // コンパイル
1206 ChangeOpcode( temporary );
1207
1208
1209 // メンバの型を示すTypeInfoオブジェクトへのDataOffset配列の静的データ定義文字列を取得
1210 sprintf(
1211 temporary,
1212 "tempType.SetMembers([%s],[%s],%d)",
1213 objClass.GetStaticDefiningStringAsMemberNames().c_str(),
1214 objClass.GetStaticDefiningStringAsMemberTypeInfoNames().c_str(),
1215 objClass.GetDynamicMembers().size()
1216 );
1217 ChangeOpcode( temporary );
1218 }
1219 }
1220}
1221
1222const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
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
1231 std::vector<const CClass *> classes;
1232 const CClass *pClass = GetHashArrayElement( name.c_str() );
1233 while( pClass )
1234 {
1235 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1236 //名前空間とクラス名が一致した
1237 classes.push_back( pClass );
1238 }
1239 pClass = pClass->GetChainNext();
1240 }
1241 if( classes.size() > 0 )
1242 {
1243 // 複数の名前空間の中に同一のクラス名が存在する場合があるので、アクセス可能で尚且つ階層が一番深いものをチョイスする
1244 pClass = classes.front();
1245
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
1257 // TypeDefも見る
1258 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
1259 if( index != -1 ){
1260 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
1261 if( type.IsObject() ){
1262 return &type.GetClass();
1263 }
1264 }
1265
1266 return NULL;
1267}
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
1281 // 仮想関数になるメソッドに使用チェックをつける
1282 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
1283 {
1284 if( pMethod->IsVirtual() )
1285 {
1286 pMethod->GetUserProc().Using();
1287 }
1288 }
1289
1290 pCompilingMethod = pParentClass->GetDynamicMethodOrInterfaceMethod( pUserProc );
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
1303const CClass *Classes::GetStringClassPtr() const
1304{
1305 if( !pStringClass ){
1306 // キャッシュしておく
1307 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
1308
1309 if( !pStringClass )
1310 {
1311 SetError(400, "System.String", cp);
1312 static CClass dummy;
1313 return &dummy;
1314 }
1315 return pStringClass;
1316 }
1317 return pStringClass;
1318}
1319const CClass *Classes::GetObjectClassPtr() const
1320{
1321 if( !pObjectClass ){
1322 // キャッシュしておく
1323 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
1324
1325 if( !pObjectClass )
1326 {
1327 SetError(400, "System.Object", cp);
1328 static CClass dummy;
1329 return &dummy;
1330 }
1331 return pObjectClass;
1332 }
1333 return pObjectClass;
1334}
1335const CClass *Classes::GetInterfaceInfoClassPtr() const
1336{
1337 if( !pInterfaceInfo ){
1338 // キャッシュしておく
1339 pInterfaceInfo = this->Find( "ActiveBasic.Core.InterfaceInfo" );
1340
1341 if( !pInterfaceInfo )
1342 {
1343 SetError(400, "ActiveBasic.Core.InterfaceInfo", cp);
1344 static CClass dummy;
1345 return &dummy;
1346 }
1347 return pInterfaceInfo;
1348 }
1349 return pInterfaceInfo;
1350}
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.