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

Last change on this file since 374 was 374, checked in by dai_9181, 16 years ago
File size: 50.9 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/SmoothieException.h>
5#include <jenga/include/smoothie/LexicalAnalysis.h>
6
7#include <Source.h>
8#include <Class.h>
9#include <Compiler.h>
10#include <NamespaceSupporter.h>
11
12#include "../common.h"
13#ifdef _AMD64_
14#include "../../BasicCompiler64/opcode.h"
15#else
16#include "../../BasicCompiler32/opcode.h"
17#endif
18
19
20class CLoopRefCheck{
21 char **names;
22 int num;
23 void init(){
24 int i;
25 for(i=0;i<num;i++){
26 free(names[i]);
27 }
28 free(names);
29 }
30public:
31 CLoopRefCheck()
32 {
33 names=(char **)malloc(1);
34 num=0;
35 }
36 ~CLoopRefCheck()
37 {
38 init();
39 }
40 void add(const char *lpszInheritsClass)
41 {
42 names=(char **)realloc(names,(num+1)*sizeof(char *));
43 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
44 lstrcpy(names[num],lpszInheritsClass);
45 num++;
46 }
47 void del(const char *lpszInheritsClass)
48 {
49 int i;
50 for(i=0;i<num;i++){
51 if(lstrcmp(names[i],lpszInheritsClass)==0){
52 free(names[i]);
53 break;
54 }
55 }
56 if(i!=num){
57 num--;
58 for(;i<num;i++){
59 names[i]=names[i+1];
60 }
61 }
62 }
63 BOOL check(const CClass &inheritsClass) const
64 {
65 //ループ継承チェック
66 int i;
67 for(i=0;i<num;i++){
68 if( inheritsClass.GetName() == names[i] ){
69 return 1;
70 }
71 }
72 return 0;
73 }
74};
75CLoopRefCheck *pobj_LoopRefCheck;
76
77
78Interface::Interface( const CClass *pInterfaceClass )
79 : DynamicMethodsPrototype()
80 , pInterfaceClass( pInterfaceClass )
81 , vtblOffset( -1 )
82{
83 //メソッドをコピー
84 BOOST_FOREACH( const CMethod *pBaseMethod, pInterfaceClass->GetDynamicMethods() )
85 {
86 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
87
88 // アクセシビリティ
89 if(pBaseMethod->GetAccessibility() == Prototype::Private){
90 pMethod->SetAccessibility( Prototype::None );
91 }
92 else{
93 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
94 }
95
96 //pobj_Inherits
97 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
98 if(pBaseMethod->GetInheritsClassPtr()==0){
99 pMethod->SetInheritsClassPtr( pInterfaceClass );
100 }
101 else{
102 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
103 }
104
105 AddDynamicMethods( pMethod );
106 }
107}
108
109
110bool CClass::IsClass() const
111{
112 return classType == CClass::Class;
113}
114bool CClass::IsInterface() const
115{
116 return classType == CClass::Interface;
117}
118bool CClass::IsComInterface() const
119{
120 return classType == CClass::ComInterface;
121}
122bool CClass::IsEnum() const
123{
124 return classType == CClass::Enum;
125}
126bool CClass::IsDelegate() const
127{
128 return classType == CClass::Delegate;
129}
130bool CClass::IsStructure() const
131{
132 return classType == CClass::Structure;
133}
134
135
136// コンストラクタのコンパイルを開始
137void CClass::NotifyStartConstructorCompile() const
138{
139 isCompilingConstructor = true;
140}
141
142//コンストラクタのコンパイルを終了
143void CClass::NotifyFinishConstructorCompile() const
144{
145 isCompilingConstructor = false;
146}
147
148//コンストラクタをコンパイル中かどうかを判別
149bool CClass::IsCompilingConstructor() const
150{
151 return isCompilingConstructor;
152}
153
154//デストラクタのコンパイルを開始
155void CClass::NotifyStartDestructorCompile() const{
156 isCompilingDestructor = true;
157}
158
159//デストラクタのコンパイルを終了
160void CClass::NotifyFinishDestructorCompile() const{
161 isCompilingDestructor = false;
162}
163
164//デストラクタをコンパイル中かどうかを判別
165bool CClass::IsCompilingDestructor() const
166{
167 return isCompilingDestructor;
168}
169
170//自身の派生クラスかどうかを確認
171bool CClass::IsSubClass( const CClass *pClass ) const
172{
173 if( !pClass->HasSuperClass() )
174 {
175 return false;
176 }
177
178 const CClass *pTempClass = &pClass->GetSuperClass();
179 while( pTempClass ){
180 if( this == pTempClass ) return true;
181 pTempClass = &pTempClass->GetSuperClass();
182 }
183 return false;
184}
185
186//自身と等しいまたは派生クラスかどうかを確認
187bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
188{
189 if( IsEquals( pClass ) ) return true;
190 return IsSubClass( pClass );
191}
192
193// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
194bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
195{
196 if( IsEquals( &objClass ) ) return true;
197 if( IsSubClass( &objClass ) ) return true;
198 if( objClass.IsSubClass( this ) ) return true;
199 return false;
200}
201
202bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
203{
204 BOOST_FOREACH( const ::Interface *pInterface, interfaces ){
205 if( pInterfaceClass == &pInterface->GetClass() ){
206 return true;
207 }
208 }
209 return false;
210}
211
212bool CClass::Inherits( const char *inheritNames, int nowLine ){
213 int i = 0;
214 bool isInheritsClass = false;
215 while( true ){
216
217 char temporary[VN_SIZE];
218 for( int i2=0;; i++, i2++ ){
219 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
220 temporary[i2] = 0;
221 break;
222 }
223 temporary[i2] = inheritNames[i];
224 }
225
226 // ジェネリクス構文を分解
227 char className[VN_SIZE];
228 Jenga::Common::Strings typeParameterStrings;
229 SplitGenericClassInstance( temporary, className, typeParameterStrings );
230
231 // 型パラメータ文字列から型データを取得
232 std::vector<Type> actualTypeParameters;
233 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
234 {
235 Type type;
236 compiler.StringToType( typeParameterStr, type );
237 actualTypeParameters.push_back( type );
238 }
239
240 //継承元クラスを取得
241 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
242 if( !pInheritsClass ){
243 SmoothieException::Throw(106,className,nowLine);
244 return false;
245 }
246
247 if( pInheritsClass->IsClass() ){
248 // クラスを継承する
249 isInheritsClass = true;
250
251 if( !InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
252 return false;
253 }
254 }
255 else{
256 SetError(135,pInheritsClass->GetFullName().c_str(),nowLine);
257 return false;
258 }
259
260 if( inheritNames[i] == '\0' ){
261 break;
262 }
263 i++;
264 }
265
266 if( !isInheritsClass ){
267 // クラスを一つも継承していないとき
268 if( !InheritsClass( *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(), Types(), nowLine ) ){
269 return false;
270 }
271 }
272
273 return true;
274}
275bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine ){
276
277 //ループ継承でないかをチェック
278 if(pobj_LoopRefCheck->check(inheritsClass)){
279 SmoothieException::Throw(123,inheritsClass.GetName(),nowLine);
280 return false;
281 }
282
283 if( !inheritsClass.IsReady() ){
284 //継承先が読み取られていないとき
285 pobj_LoopRefCheck->add(this->GetName().c_str());
286 compiler.GetObjectModule().meta.GetClasses().GetClass_recur(inheritsClass.GetName().c_str());
287 pobj_LoopRefCheck->del(this->GetName().c_str());
288 }
289
290 //メンバをコピー
291 BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.GetDynamicMembers() ){
292 CMember *pMember = new CMember( *inheritsClassDynamicMember );
293
294 // アクセシビリティ
295 if( inheritsClassDynamicMember->IsPrivate() ){
296 pMember->SetAccessibility( Prototype::None );
297 }
298 else{
299 pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() );
300 }
301
302 // メンバのみ、型パラメータを解決する(メソッドのほうは呼び出し時に解決する)
303 if( pMember->GetType().IsTypeParameter() )
304 {
305 pMember->ResetType( actualTypeParameters[pMember->GetType().GetFormalTypeIndex()] );
306 }
307
308 dynamicMembers.push_back( pMember );
309 }
310
311 //メソッドをコピー
312 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetDynamicMethods() ){
313 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
314
315 // アクセシビリティ
316 if(pBaseMethod->GetAccessibility() == Prototype::Private){
317 pMethod->SetAccessibility( Prototype::None );
318 }
319 else{
320 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
321 }
322
323 //pobj_Inherits
324 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
325 if(pBaseMethod->GetInheritsClassPtr()==0){
326 pMethod->SetInheritsClassPtr( &inheritsClass );
327 }
328 else{
329 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
330 }
331
332 GetDynamicMethods().push_back( pMethod );
333 }
334
335 //仮想関数の数
336 AddVtblNum( inheritsClass.GetVtblNum() );
337
338 //継承先のクラスをメンバとして保持する
339 SetSuperClass( &inheritsClass );
340 SetSuperClassActualTypeParameters( actualTypeParameters );
341
342 // インターフェイスを引き継ぐ
343 BOOST_FOREACH( ::Interface *pInterface, inheritsClass.GetInterfaces() )
344 {
345 interfaces.push_back( new ::Interface( *pInterface ) );
346 }
347
348 if( this->IsInterface() && inheritsClass.IsComInterface() )
349 {
350 // COMインターフェイスを継承した場合はCOMインターフェイスにする
351 this->SetClassType( CClass::ComInterface );
352 }
353
354 return true;
355}
356
357bool CClass::Implements( const CClass &interfaceClass, int nowLine )
358{
359 if( !interfaceClass.IsInterface() && !interfaceClass.IsComInterface() )
360 {
361 // インターフェイスではないとき
362 SetError(138,interfaceClass.GetName().c_str(),nowLine );
363 return false;
364 }
365
366 if( !interfaceClass.IsReady() ){
367 // インターフェイスが未解析のとき
368 pobj_LoopRefCheck->add(this->GetName().c_str());
369 compiler.GetObjectModule().meta.GetClasses().GetClass_recur(interfaceClass.GetName().c_str());
370 pobj_LoopRefCheck->del(this->GetName().c_str());
371 }
372
373 ::Interface *pDestInterface = new ::Interface( &interfaceClass );
374
375 interfaces.push_back( pDestInterface );
376
377
378 /////////////////////////////////////////////////////////////////
379 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
380 /////////////////////////////////////////////////////////////////
381 BOOST_FOREACH( CMethod *pMethod, GetDynamicMethods() )
382 {
383 CMethod *pMethodForOverride = pDestInterface->GetDynamicMethods().FindForOverride( &pMethod->GetUserProc() );
384 if( pMethodForOverride )
385 {
386 pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
387
388 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
389 pMethod->SetNotUseMark( true );
390 }
391 }
392
393
394 /////////////////////////////////////////////////////////////////
395 // キャストメソッドを追加(内部コードは自動生成すること)
396 /////////////////////////////////////////////////////////////////
397 if( interfaceClass.IsInterface() )
398 {
399 // Function Operator() As ITest
400
401 char temporary[1024];
402 sprintf(temporary,"%c%c%c%c()%c%c%s",
403 1, ESC_FUNCTION,
404 1, ESC_OPERATOR,
405 1, ESC_AS,
406 interfaceClass.GetName().c_str()
407 );
408
409 this->AddMethod(this,
410 Prototype::Public,
411 0,
412 false, // isConst
413 false, // isAbstract
414 false, // isVirtual
415 false, // isOverride
416 true, // isAutoGeneration
417 temporary,
418 -1
419 );
420 }
421
422
423 return true;
424}
425bool CClass::Implements( const char *interfaceNames, int nowLine )
426{
427 Jenga::Common::Strings paramStrs;
428 SplitParameter( interfaceNames, paramStrs );
429
430 BOOST_FOREACH( const std::string &paramStr, paramStrs )
431 {
432 //継承元クラスを取得
433 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( paramStr.c_str() );
434 if( !pInterfaceClass ){
435 SetError(106,paramStr.c_str(),nowLine);
436 continue;
437 }
438
439 // インターフェイスを継承する
440 Implements( *pInterfaceClass, nowLine );
441 }
442
443 return true;
444}
445
446CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
447{
448 extern int cp;
449
450 //構文を解析
451 char VarName[VN_SIZE];
452 char initBuffer[VN_SIZE];
453 char lpszConstructParameter[VN_SIZE];
454 Subscripts subscripts;
455 Type type;
456 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
457
458 //重複チェック
459 if(this->DupliCheckAll(VarName)){
460 SetError(15,VarName,cp);
461 }
462
463 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
464 pMember->source_code_address = nowLine;
465 return pMember;
466}
467void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
468 dynamicMembers.push_back(
469 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
470 );
471}
472void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
473 staticMembers.push_back(
474 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
475 );
476}
477
478void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
479 bool isVirtual, bool isOverride, bool isAutoGeneration, char *buffer, int nowLine){
480 int i,i2;
481 char temporary[VN_SIZE];
482
483 i=2;
484 for(i2=0;;i++,i2++){
485 if(buffer[i]=='('||buffer[i]=='\0'){
486 temporary[i2]=0;
487 break;
488 }
489 temporary[i2]=buffer[i];
490 }
491
492
493 //関数ハッシュへ登録
494 char interfaceName[VN_SIZE] = "";
495 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().AddUserProc( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0), interfaceName );
496 if(!pUserProc) return;
497
498 if( isAutoGeneration )
499 {
500 // コード自動生成
501 pUserProc->ThisIsAutoGenerationProc();
502 }
503
504
505 ////////////////////////////////////////////////////////////
506 // コンストラクタ、デストラクタの場合の処理
507 ////////////////////////////////////////////////////////////
508 BOOL fConstructor=0,bDestructor=0;
509
510 if(lstrcmp(temporary,pobj_c->GetName().c_str())==0){
511 //コンストラクタの場合
512
513 //標準コンストラクタ(引数なし)
514 if(pUserProc->Params().size()==0) fConstructor=1;
515
516 //強制的にConst修飾子をつける
517 isConst = true;
518 }
519 else if(temporary[0]=='~'){
520 //デストラクタの場合はその名前が正しいかチェックを行う
521 if(lstrcmp(temporary+1,pobj_c->GetName().c_str())!=0)
522 SetError(117,NULL,nowLine);
523 else
524 bDestructor=1;
525 }
526 if(fConstructor||bDestructor){
527 // コンストラクタ、デストラクタのアクセシビリティをチェック
528
529 //強制的にConst修飾子をつける
530 isConst = true;
531 }
532
533 if( fConstructor == 1 )
534 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
535 else if( bDestructor )
536 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
537
538
539
540 //////////////////
541 // 重複チェック
542 //////////////////
543
544 if(pobj_c->DupliCheckMember(temporary)){
545 SetError(15,temporary,nowLine);
546 return;
547 }
548
549 //メソッド
550 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
551 {
552 //基底クラスと重複する場合はオーバーライドを行う
553 if( pMethod->GetInheritsClassPtr() ) continue;
554
555 if( pMethod->GetUserProc().IsEqualForOverride( pUserProc ) )
556 {
557 //関数名、パラメータ、戻り値が合致したとき
558 SetError(15,pUserProc->GetName().c_str(),nowLine);
559 return;
560 }
561 }
562
563 //仮想関数の場合
564 if( isAbstract ) pUserProc->CompleteCompile();
565
566 // メソッドのオーバーライド
567 CMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pUserProc );
568 if( pMethodForOverride )
569 {
570 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
571 pUserProc->SetMethod( pMethodForOverride );
572 return;
573 }
574 else
575 {
576 // インターフェイス メソッドのオーバーライド
577 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
578 {
579 if( interfaceName[0] )
580 {
581 if( pInterface->GetClass().GetName() != interfaceName )
582 {
583 // 指定されたインターフェイス名と整合しないとき
584 continue;
585 }
586 }
587
588 CMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pUserProc );
589 if( pMethodForOverride )
590 {
591 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
592 pUserProc->SetMethod( pMethodForOverride );
593 return;
594 }
595 }
596 }
597
598 if( interfaceName[0] )
599 {
600 SetError(139,interfaceName,nowLine);
601 }
602
603 if( isVirtual ){
604 pobj_c->AddVtblNum( 1 );
605 }
606
607 if( isOverride ){
608 SetError(12,"Override",nowLine);
609 }
610
611 if(bStatic){
612 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
613 }
614 else{
615 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
616 }
617}
618
619bool CClass::DupliCheckAll(const char *name){
620 //重複チェック
621
622 //メンバ
623 if(DupliCheckMember(name)) return 1;
624
625 //メソッド
626 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
627 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
628 return 1;
629 }
630 }
631
632 return 0;
633}
634bool CClass::DupliCheckMember(const char *name){
635 //重複チェック
636
637 // 動的メンバ
638 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
639 if( GetName() == pMember->GetName() ){
640 return 1;
641 }
642 }
643
644 // 静的メンバ
645 BOOST_FOREACH( CMember *pMember, staticMembers ){
646 if( GetName() == pMember->GetName() ){
647 return 1;
648 }
649 }
650
651 return 0;
652}
653
654void CClass::EnumDynamicMethodsOrInterfaceMethods( const char *methodName, std::vector<const UserProc *> &subs ) const
655{
656 // 動的メソッド
657 GetDynamicMethods().Enum( methodName, subs );
658
659 // インターフェイス メソッド
660 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
661 {
662 pInterface->GetDynamicMethods().Enum( methodName, subs );
663 }
664}
665const CMethod *CClass::GetDynamicMethodOrInterfaceMethod( const UserProc *pUserProc ) const
666{
667 // 動的メソッド
668 const CMethod *result = GetDynamicMethods().GetMethodPtr( pUserProc );
669
670 if( !result )
671 {
672 // インターフェイス メソッド
673 BOOST_FOREACH( ::Interface *pInterface, GetInterfaces() )
674 {
675 result = pInterface->GetDynamicMethods().GetMethodPtr( pUserProc );
676 if( result )
677 {
678 return result;
679 }
680 }
681 }
682
683 return result;
684}
685
686const ::Delegate &CClass::GetDelegate() const
687{
688 const ::Delegate *dg = compiler.GetObjectModule().meta.GetDelegates().GetHashArrayElement( GetName().c_str() );
689 while( dg )
690 {
691 if( dg->IsEqualSymbol( GetNamespaceScopes(), GetName() ) ){
692 //名前空間とクラス名が一致した
693 return *dg;
694 }
695 dg = dg->GetChainNext();
696 }
697
698 Jenga::Throw( "CClass::GetDelegateメソッドに失敗" );
699 static ::Delegate dummy;
700 return dummy;
701}
702
703//サイズを取得
704int CClass::GetSize() const
705{
706 return GetMemberOffset( NULL, NULL );
707}
708
709//メンバのオフセットを取得
710int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
711{
712 int i2;
713
714 //仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加
715 int offset = IsExistVirtualFunctions() ? PTR_SIZE*2 : 0;
716
717 int alignment = 1;
718 if( GetFixedAlignment() )
719 {
720 alignment = GetFixedAlignment();
721 }
722
723 int iMaxAlign=0;
724 int i = -1;
725 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
726 i++;
727
728 i2 = pMember->GetType().GetSize();
729
730 //アラインメントを算出
731 int member_size;
732 if( pMember->GetType().IsStruct() ){
733 //メンバクラスのアラインメントを取得
734 member_size=pMember->GetType().GetClass().GetAlignment();
735 }
736 else{
737 //メンバサイズを取得
738 member_size=i2;
739 }
740 if(iMaxAlign<member_size) iMaxAlign=member_size;
741
742 //アラインメントを考慮
743 if(GetFixedAlignment()&&GetFixedAlignment()<member_size){
744 if(offset%alignment) offset+=alignment-(offset%alignment);
745 }
746 else{
747 if(alignment<member_size) alignment=member_size;
748
749 if(member_size==0){
750 //メンバを持たないクラス
751 //※何もしない(オフセットの計算をしない)
752 }
753 else{
754 if(offset%member_size) offset+=member_size-(offset%member_size);
755 }
756 }
757
758 if(memberName){
759 //メンバ指定がある場合は、オフセットを返す
760 if( pMember->GetName() == memberName ){
761 if(pMemberNum) *pMemberNum=i;
762 return offset;
763 }
764 }
765
766 //配列を考慮したメンバサイズを取得
767 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
768
769 //メンバサイズを加算
770 offset+= member_size;
771 }
772
773 if(iMaxAlign<alignment) alignment=iMaxAlign;
774
775 //アラインメントを考慮
776 if(alignment){
777 if(offset%alignment) offset+=alignment-(offset%alignment);
778 }
779
780 if(pMemberNum) *pMemberNum=i;
781 return offset;
782}
783int CClass::GetAlignment() const
784{
785 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
786 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
787
788 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
789 int member_size;
790 if(pMember->GetType().IsStruct()){
791 //メンバクラスのアラインメントを取得
792 member_size=pMember->GetType().GetClass().GetAlignment();
793 }
794 else{
795 //メンバサイズを取得
796 member_size = pMember->GetType().GetSize();
797 }
798
799 //アラインメントをセット
800 if(alignment<member_size) alignment=member_size;
801 }
802
803 if(alignment==0) return 0;
804
805 if(GetFixedAlignment()) alignment=GetFixedAlignment();
806
807 return alignment;
808}
809
810void CClass::GetVtblMasterListIndexAndVtblIndex( const UserProc *pUserProc, int &vtblMasterListIndex, int &vtblIndex ) const
811{
812 vtblMasterListIndex = 0;
813
814 vtblIndex = 0;
815 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
816 if( &pMethod->GetUserProc() == pUserProc )
817 {
818 return;
819 }
820
821 if( pMethod->IsVirtual() )
822 {
823 vtblIndex++;
824 }
825 }
826
827 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
828 {
829 vtblMasterListIndex++;
830
831 vtblIndex = 0;
832 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
833 if( &pMethod->GetUserProc() == pUserProc )
834 {
835 return;
836 }
837
838 if( pMethod->IsVirtual() )
839 {
840 vtblIndex++;
841 }
842 }
843 }
844
845 SetError();
846 return;
847}
848int CClass::GetVtblMasterListIndex( const CClass *pClass ) const
849{
850 int result = 0;
851
852 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
853 {
854 result++;
855
856 if( &pInterface->GetClass() == pClass )
857 {
858 return result;
859 }
860 }
861
862 SetError();
863 return 0;
864}
865long CClass::GetComVtblOffset() const
866{
867 return comVtblOffset;
868}
869long CClass::GetVtblMasterListOffset() const
870{
871 //既に存在する場合はそれを返す
872 if( vtblMasterListOffset == -1 )
873 {
874 SetError();
875 }
876
877 return vtblMasterListOffset;
878}
879void CClass::GenerateVTableMasterList( const std::vector<long> &vtableMasterList, long &offset )
880{
881 offset = compiler.GetObjectModule().dataTable.AddBinary(
882 (void *)&vtableMasterList[0],
883 static_cast<int>(vtableMasterList.size()*sizeof(LONG_PTR))
884 );
885}
886void CClass::GenerateFullVTables()
887{
888 if( IsAbstract() )
889 {
890 // 抽象クラスは無視
891 return;
892 }
893 if( !IsUsing() )
894 {
895 // 使われていないクラスは無視
896 return;
897 }
898
899 // vtblマスターリストの元データに不要なデータが含まれていたらエラー
900 if( vtblMasterList.size() )
901 {
902 SetError();
903 }
904
905 // 自身のクラスのvtblを生成
906 GetDynamicMethods().GenerateVTablePart( this->vtbl_offset );
907 vtblMasterList.push_back( this->vtbl_offset );
908
909 // インターフェイスのvtblを生成
910 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
911 {
912 long tempVtblOffset;
913 pInterface->GetDynamicMethods().GenerateVTablePart( tempVtblOffset );
914 vtblMasterList.push_back( tempVtblOffset );
915
916 pInterface->SetVtblOffset( tempVtblOffset );
917
918 if( pInterface->GetClass().IsComInterface() )
919 {
920 if( this->comVtblOffset )
921 {
922 SetError();
923 }
924 this->comVtblOffset = tempVtblOffset;
925 }
926 }
927
928 // vtblマスターリストを生成
929 GenerateVTableMasterList( vtblMasterList, this->vtblMasterListOffset );
930}
931void CClass::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection )
932{
933 if( IsAbstract() )
934 {
935 // 抽象クラスは無視
936 return;
937 }
938 if( !IsUsing() )
939 {
940 // 使われていないクラスは無視
941 return;
942 }
943 if(vtbl_offset==-1) return;
944
945 // 自身のクラスのvtbl
946 {
947 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtbl_offset);
948
949 for( int i=0; i<GetVtblNum(); i++ ){
950 const UserProc *pUserProc = (UserProc *)pVtbl[i];
951 if(!pUserProc) continue;
952
953 if( pUserProc->GetBeginOpAddress() == 0
954 && pUserProc->GetEndOpAddress() == 0 )
955 {
956 Jenga::Throw( "未解決の仮想関数が存在する" );
957 }
958
959 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
960 }
961 }
962
963 // インターフェイスのvtbl
964 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
965 {
966 LONG_PTR *pVtbl = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + pInterface->GetVtblOffset());
967
968 for( int i=0; i<pInterface->GetClass().GetVtblNum(); i++ ){
969 const UserProc *pUserProc = (UserProc *)pVtbl[i];
970 if(!pUserProc) continue;
971
972 if( pUserProc->GetBeginOpAddress() == 0
973 && pUserProc->GetEndOpAddress() == 0 )
974 {
975 Jenga::Throw( "未解決の仮想関数が存在する" );
976 }
977
978 pVtbl[i] = pUserProc->GetBeginOpAddress() + ImageBase + MemPos_CodeSection;
979 }
980 }
981
982 // vtblマスターリスト
983 LONG_PTR *pVtblMasterList = (LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr() + vtblMasterListOffset );
984 for( int i=0; i<static_cast<int>(vtblMasterList.size()); i++ )
985 {
986 pVtblMasterList[i] = vtblMasterList[i] + ImageBase + MemPos_DataSection;
987 }
988}
989bool CClass::IsAbstract() const
990{
991 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
992
993 BOOST_FOREACH( const CMethod *pMethod, GetDynamicMethods() ){
994 if(pMethod->IsVirtual()){
995 if(pMethod->IsAbstract()){
996 return true;
997 }
998 }
999 }
1000
1001 // インターフェイスのvtbl
1002 BOOST_FOREACH( const ::Interface *pInterface, interfaces )
1003 {
1004 BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
1005 if(pMethod->IsVirtual()){
1006 if(pMethod->IsAbstract()){
1007 return true;
1008 }
1009 }
1010 }
1011 }
1012
1013 return false;
1014}
1015
1016CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
1017 return new CClass(namespaceScopes, importedNamespaces, name);
1018}
1019bool Classes::Insert( CClass *pClass, int nowLine )
1020{
1021 /////////////////////////////////
1022 // ハッシュデータに追加
1023 /////////////////////////////////
1024
1025 if( !Put( pClass ) )
1026 {
1027 SetError(15,pClass->GetName(), nowLine);
1028 return false;
1029 }
1030 return true;
1031}
1032CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
1033 //////////////////////////////////////////////////////////////////////////
1034 // クラスを追加
1035 // ※名前のみを登録。その他の情報はSetClassメソッドで!
1036 //////////////////////////////////////////////////////////////////////////
1037
1038 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
1039
1040 if( !Insert( pClass, nowLine ) )
1041 {
1042 return NULL;
1043 }
1044
1045 return pClass;
1046}
1047
1048void Classes::CollectClassesForNameOnly( const BasicSource &source )
1049{
1050 int i, i2;
1051 char temporary[VN_SIZE];
1052
1053 // 名前空間管理
1054 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1055 namespaceScopes.clear();
1056
1057 // Importsされた名前空間の管理
1058 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
1059 importedNamespaces.clear();
1060
1061 for(i=0;;i++){
1062 if(source[i]=='\0') break;
1063
1064 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
1065 for(i+=2,i2=0;;i2++,i++){
1066 if( IsCommandDelimitation( source[i] ) ){
1067 temporary[i2]=0;
1068 break;
1069 }
1070 temporary[i2]=source[i];
1071 }
1072 namespaceScopes.push_back( temporary );
1073
1074 continue;
1075 }
1076 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
1077 if( namespaceScopes.size() <= 0 ){
1078 SmoothieException::Throw(12, "End Namespace", i );
1079 }
1080 else{
1081 namespaceScopes.pop_back();
1082 }
1083
1084 i += 2;
1085 continue;
1086 }
1087 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
1088 for(i+=2,i2=0;;i2++,i++){
1089 if( IsCommandDelimitation( source[i] ) ){
1090 temporary[i2]=0;
1091 break;
1092 }
1093 temporary[i2]=source[i];
1094 }
1095 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
1096 {
1097 SmoothieException::Throw(64,temporary,i );
1098 }
1099
1100 continue;
1101 }
1102 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
1103 importedNamespaces.clear();
1104 continue;
1105 }
1106
1107 if(source[i]==1&&(
1108 source[i+1]==ESC_CLASS||
1109 source[i+1]==ESC_TYPE||
1110 source[i+1]==ESC_INTERFACE
1111 ))
1112 {
1113 int nowLine = i;
1114 i += 2;
1115
1116 Type blittableType;
1117 if(memicmp(source.GetBuffer()+i,"Align(",6)==0){
1118 //アラインメント修飾子
1119 i+=6;
1120 i=JumpStringInPare(source.GetBuffer(),i)+1;
1121 }
1122 else if( memicmp( source.GetBuffer() + i, "Blittable(", 10 ) == 0 ){
1123 // Blittable修飾子
1124 i+=10;
1125 i+=GetStringInPare_RemovePare(temporary,source.GetBuffer()+i)+1;
1126 compiler.StringToType( temporary, blittableType );
1127 }
1128
1129 bool isEnum = false;
1130 bool isDelegate = false;
1131 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
1132 // 列挙型の場合
1133 isEnum = true;
1134
1135 i += 2;
1136 }
1137 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
1138 {
1139 // デリゲートの場合
1140 isDelegate = true;
1141
1142 i += 2;
1143 }
1144
1145 for(i2=0;;i++,i2++){
1146 if(!IsVariableChar(source[i])){
1147 temporary[i2]=0;
1148 break;
1149 }
1150 temporary[i2]=source[i];
1151 }
1152
1153 //クラスを追加
1154 CClass *pClass = this->Add(namespaceScopes, importedNamespaces, temporary,nowLine);
1155 if( pClass ){
1156 if( source[nowLine+1] == ESC_CLASS ){
1157 if( isEnum )
1158 {
1159 pClass->SetClassType( CClass::Enum );
1160 }
1161 else if( isDelegate )
1162 {
1163 pClass->SetClassType( CClass::Delegate );
1164 }
1165 else{
1166 pClass->SetClassType( CClass::Class );
1167 }
1168 }
1169 else if( source[nowLine+1] == ESC_INTERFACE ){
1170 pClass->SetClassType( CClass::Interface );
1171 }
1172 else{
1173 pClass->SetClassType( CClass::Structure );
1174 }
1175 }
1176
1177 // Blittable型の場合
1178 if( !blittableType.IsNull() ){
1179 pClass->SetBlittableType( blittableType );
1180
1181 // Blittable型として登録
1182 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
1183 }
1184 }
1185 }
1186}
1187
1188void Classes::GenerateVTables()
1189{
1190 Iterator_Reset();
1191 while( Iterator_HasNext() )
1192 {
1193 CClass *pClass = Iterator_GetNext();
1194 pClass->GenerateFullVTables();
1195 }
1196}
1197
1198void Classes::ActionVtblSchedule( LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection, LONG_PTR MemPos_DataSection ){
1199 Iterator_Reset();
1200 while( Iterator_HasNext() )
1201 {
1202 CClass *pClass = Iterator_GetNext();
1203 pClass->ActionVtblSchedule( ImageBase, MemPos_CodeSection, MemPos_DataSection);
1204 }
1205}
1206
1207
1208void Classes::InitStaticMember(){
1209 //静的メンバをグローバル領域に作成
1210
1211 //イテレータをリセット
1212
1213 extern int cp;
1214 int back_cp=cp;
1215
1216 this->Iterator_Reset();
1217 while(this->Iterator_HasNext()){
1218 CClass &objClass = *this->Iterator_GetNext();
1219 if( objClass.isTargetObjectModule == false )
1220 {
1221 // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため)
1222 continue;
1223 }
1224
1225 // 名前空間をセット
1226 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
1227
1228 DWORD dwFlags = 0;
1229 if( objClass.GetName() == "_System_TypeBase" )
1230 {
1231 // _System_TypeBaseクラスはグローバル、スタティック領域を初期化するためのクラスなのでここでの初期化は除外する
1232 dwFlags |= DIMFLAG_NONCALL_CONSTRACTOR;
1233 }
1234
1235 int i=0;
1236 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() ){
1237 char temporary[VN_SIZE];
1238 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
1239 dim(
1240 temporary,
1241 member->GetSubscripts(),
1242 member->GetType(),
1243 member->GetInitializeExpression().c_str(),
1244 member->GetConstructParameter().c_str(),
1245 dwFlags);
1246
1247 i++;
1248 }
1249 }
1250
1251 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
1252
1253 cp=back_cp;
1254}
1255bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){
1256 bool result = true;
1257 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1258 if(pMember->GetType().IsStruct()){
1259 //循環参照でないかをチェック
1260 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
1261 extern int cp;
1262 SetError(124,pMember->GetType().GetClass().GetName(),cp);
1263 return false;
1264 }
1265
1266 pobj_LoopRefCheck->add(objClass.GetName().c_str());
1267
1268 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
1269 if( result )
1270 {
1271 result = tempResult;
1272 }
1273
1274 pobj_LoopRefCheck->del(objClass.GetName().c_str());
1275 }
1276 }
1277
1278 return result;
1279}
1280void Classes::GetClass_recur(const char *lpszInheritsClass){
1281 extern char *basbuf;
1282 int i,i2,i3,sub_address,top_pos;
1283 char temporary[8192];
1284
1285 // 名前空間管理
1286 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1287 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1288 namespaceScopes.clear();
1289
1290 // Importsされた名前空間の管理
1291 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
1292 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
1293
1294 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
1295 const CClass *pBackCompilingClass = compiler.pCompilingClass;
1296
1297 for(i=0;;i++){
1298 if(basbuf[i]=='\0') break;
1299
1300
1301 // 名前空間
1302 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
1303 for(i+=2,i2=0;;i2++,i++){
1304 if( IsCommandDelimitation( basbuf[i] ) ){
1305 temporary[i2]=0;
1306 break;
1307 }
1308 temporary[i2]=basbuf[i];
1309 }
1310 namespaceScopes.push_back( temporary );
1311
1312 continue;
1313 }
1314 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
1315 if( namespaceScopes.size() <= 0 ){
1316 SetError(12, "End Namespace", i );
1317 }
1318 else{
1319 namespaceScopes.pop_back();
1320 }
1321
1322 i += 2;
1323 continue;
1324 }
1325
1326 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
1327 for(i+=2,i2=0;;i2++,i++){
1328 if( IsCommandDelimitation( basbuf[i] ) ){
1329 temporary[i2]=0;
1330 break;
1331 }
1332 temporary[i2]=basbuf[i];
1333 }
1334 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
1335 {
1336 SmoothieException::Throw(64,temporary,i );
1337 }
1338
1339 continue;
1340 }
1341 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
1342 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
1343 continue;
1344 }
1345
1346
1347
1348 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1349 //////////////////////////
1350 // インターフェイス
1351 //////////////////////////
1352
1353 top_pos=i;
1354
1355 i+=2;
1356
1357 //インターフェイス名を取得
1358 GetCommandToken( temporary, basbuf, i );
1359
1360 char className[VN_SIZE];
1361 Jenga::Common::Strings typeParameters;
1362 SplitGenericClassInstance( temporary, className, typeParameters );
1363
1364 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1365 if(!pobj_c) continue;
1366
1367 if(lpszInheritsClass){
1368 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
1369 //継承先先読み用
1370 continue;
1371 }
1372 }
1373
1374 if(pobj_c->IsReady()){
1375 //既に先読みされているとき
1376 continue;
1377 }
1378
1379 /////////////////////////////////////////////////////////
1380 // ☆★☆ ジェネリクスサポート ☆★☆
1381 BOOST_FOREACH( const std::string &typeParameter, typeParameters )
1382 {
1383 pobj_c->AddFormalGenericType( GenericType( typeParameter, Type(DEF_OBJECT,*GetObjectClassPtr()) ) );
1384 }
1385 /////////////////////////////////////////////////////////
1386
1387 pobj_c->Readed();
1388
1389 pobj_c->SetConstructorMemberSubIndex( -1 );
1390 pobj_c->SetDestructorMemberSubIndex( -1 );
1391
1392 if( memcmp( basbuf+i+1, "__COM", 5 ) == 0 && IsCommandDelimitation( basbuf[i+1+5] ) )
1393 {
1394 // COMインターフェイス
1395 pobj_c->SetClassType( CClass::ComInterface );
1396
1397 i += 6;
1398 }
1399
1400 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1401 //継承を行う場合
1402 for(i+=3,i2=0;;i++,i2++){
1403 if(IsCommandDelimitation(basbuf[i])){
1404 temporary[i2]=0;
1405 break;
1406 }
1407 temporary[i2]=basbuf[i];
1408 }
1409
1410 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1411 SetError(105,temporary,i);
1412 goto Interface_InheritsError;
1413 }
1414
1415 //継承元クラスを取得
1416 const Classes &classes = *this;
1417 const CClass *pInheritsClass = classes.Find(temporary);
1418 if( !pInheritsClass ){
1419 SetError(106,temporary,i);
1420 goto Interface_InheritsError;
1421 }
1422
1423 //継承させる
1424 if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){
1425 goto Interface_InheritsError;
1426 }
1427 }
1428 else{
1429 //継承無し
1430 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1431 {
1432 // TODO: ここに来ないことが実証できたらこの分岐は消す
1433 Jenga::Throw( "GetClass_recur内の例外" );
1434 }
1435 }
1436Interface_InheritsError:
1437
1438 //メンバ変数、関数を取得
1439 while(1){
1440 i++;
1441
1442 //エラー
1443 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1444 SetError(22,"Interface",i);
1445 i--;
1446 break;
1447 }
1448
1449 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1450 SetError(111,NULL,i);
1451 break;
1452 }
1453 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
1454 {
1455 SetError(137, NULL, i );
1456 break;
1457 }
1458
1459 sub_address=i;
1460
1461 for(i2=0;;i++,i2++){
1462 if(IsCommandDelimitation(basbuf[i])){
1463 temporary[i2]=0;
1464 break;
1465 }
1466 temporary[i2]=basbuf[i];
1467 }
1468 if(temporary[0]=='\0'){
1469 if(basbuf[i]=='\0'){
1470 i--;
1471 SetError(22,"Interface",top_pos);
1472 break;
1473 }
1474 continue;
1475 }
1476
1477 //End Interface記述の場合
1478 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1479
1480 if(!(temporary[0]==1&&(
1481 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1482 ))){
1483 SetError(1,NULL,i);
1484 break;
1485 }
1486
1487 //メンバ関数を追加
1488 pobj_c->AddMethod(pobj_c,
1489 Prototype::Public, //Publicアクセス権
1490 0, // bStatic
1491 false, // isConst
1492 true, // isAbstract
1493 true, // isVirtual
1494 false, // isOverride
1495 false, // isAutoGeneration
1496 temporary,
1497 sub_address
1498 );
1499 }
1500 }
1501
1502 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1503 //////////////////////////
1504 // クラス
1505 //////////////////////////
1506
1507 top_pos=i;
1508
1509 const DWORD dwClassType=basbuf[i+1];
1510
1511 i+=2;
1512
1513 int iAlign=0;
1514 if(memicmp(basbuf+i,"Align(",6)==0){
1515 //アラインメント修飾子
1516 i+=6;
1517 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1518 iAlign=atoi(temporary);
1519
1520 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1521 SetError(51,NULL,i);
1522 }
1523 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
1524 // Blittable修飾子
1525 i+=10;
1526 i=JumpStringInPare(basbuf,i)+1;
1527 }
1528
1529 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
1530 {
1531 // 列挙型の場合
1532 i += 2;
1533 }
1534 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
1535 {
1536 // デリゲートの場合
1537 i += 2;
1538 }
1539
1540 //クラス名を取得
1541 GetCommandToken( temporary, basbuf, i );
1542
1543 char className[VN_SIZE];
1544 Jenga::Common::Strings typeParameters;
1545 SplitGenericClassInstance( temporary, className, typeParameters );
1546
1547 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, className) );
1548 if(!pobj_c) continue;
1549
1550 compiler.pCompilingClass = pobj_c;
1551
1552 if(lpszInheritsClass){
1553 if( pobj_c->GetName() != lpszInheritsClass ){
1554 //継承先先読み用
1555 continue;
1556 }
1557 }
1558
1559 if(pobj_c->IsReady()){
1560 //既に先読みされているとき
1561 continue;
1562 }
1563
1564
1565 /////////////////////////////////////////////////////////
1566 // ☆★☆ ジェネリクスサポート ☆★☆
1567 BOOST_FOREACH( const std::string &typeParameter, typeParameters )
1568 {
1569 pobj_c->AddFormalGenericType( GenericType( typeParameter, Type(DEF_OBJECT,*GetObjectClassPtr()) ) );
1570 }
1571 /////////////////////////////////////////////////////////
1572
1573
1574 pobj_c->SetFixedAlignment( iAlign );
1575
1576 pobj_c->Readed();
1577
1578 pobj_c->SetConstructorMemberSubIndex( -1 );
1579 pobj_c->SetDestructorMemberSubIndex( -1 );
1580
1581 //アクセス制限の初期値をセット
1582 Prototype::Accessibility accessibility;
1583 if(dwClassType==ESC_CLASS){
1584 accessibility = Prototype::Private;
1585 }
1586 else{
1587 accessibility = Prototype::Public;
1588 }
1589
1590 if( pobj_c->GetName() == "Object"
1591 || dwClassType == ESC_TYPE )
1592 {
1593 // 何も継承しない
1594
1595 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1596 {
1597 // TODO: ここに来ないことが実証できたらこの分岐は消す
1598 Jenga::Throw( "GetClass_recur内の例外" );
1599 }
1600 }
1601 else{
1602 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS)
1603 {
1604 // クラス継承先が指定されているとき
1605 i += 3;
1606 GetCommandToken( temporary, basbuf, i );
1607
1608 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1609 SetError(105,temporary,i);
1610 goto InheritsError;
1611 }
1612 }
1613 else
1614 {
1615 // 何の指定もないときはObjectクラスを継承する
1616 lstrcpy( temporary, "Object" );
1617 }
1618 pobj_c->Inherits( temporary, i );
1619
1620 if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS )
1621 {
1622 // インターフェイス実装を行う場合
1623 i += 3;
1624 GetCommandToken( temporary, basbuf, i );
1625
1626 pobj_c->Implements( temporary, i );
1627 }
1628 }
1629InheritsError:
1630
1631 //メンバとメソッドを取得
1632 while(1){
1633 i++;
1634
1635 //エラー
1636 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1637 SetError(22,"Class",i);
1638 i--;
1639 break;
1640 }
1641
1642 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1643 SetError(111,NULL,i);
1644 break;
1645 }
1646 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
1647 {
1648 SetError(137, NULL, i );
1649 break;
1650 }
1651
1652 //Static修飾子
1653 BOOL bStatic;
1654 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1655 bStatic=1;
1656 i+=2;
1657 }
1658 else bStatic=0;
1659
1660 //Const修飾子
1661 bool isConst = false;
1662 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1663 isConst = true;
1664 i += 2;
1665 }
1666
1667 if(basbuf[i]==1&&(
1668 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1669 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1670 )){
1671 i3=basbuf[i+1];
1672 sub_address=i;
1673 }
1674 else i3=0;
1675
1676 bool isVirtual = false, isAbstract = false, isOverride = false;
1677 if(i3==ESC_ABSTRACT){
1678 isAbstract=1;
1679 isVirtual=1;
1680 i+=2;
1681
1682 i3=basbuf[i+1];
1683 }
1684 else if(i3==ESC_VIRTUAL){
1685 isAbstract=0;
1686 isVirtual=1;
1687 i+=2;
1688
1689 i3=basbuf[i+1];
1690 }
1691 else if(i3==ESC_OVERRIDE){
1692 isOverride=1;
1693 isVirtual=1;
1694
1695 i+=2;
1696
1697 i3=basbuf[i+1];
1698 }
1699
1700 for(i2=0;;i++,i2++){
1701 if(IsCommandDelimitation(basbuf[i])){
1702 temporary[i2]=0;
1703 break;
1704 }
1705 temporary[i2]=basbuf[i];
1706 }
1707 if(temporary[0]=='\0'){
1708 if(basbuf[i]=='\0'){
1709
1710 if(dwClassType==ESC_CLASS)
1711 SetError(22,"Class",top_pos);
1712 else
1713 SetError(22,"Type",top_pos);
1714
1715 i--;
1716 break;
1717 }
1718 continue;
1719 }
1720
1721 //End Class記述の場合
1722 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1723 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1724
1725 //アクセスを変更
1726 if(lstrcmpi(temporary,"Private")==0){
1727 accessibility = Prototype::Private;
1728 continue;
1729 }
1730 if(lstrcmpi(temporary,"Public")==0){
1731 accessibility = Prototype::Public;
1732 continue;
1733 }
1734 if(lstrcmpi(temporary,"Protected")==0){
1735 accessibility = Prototype::Protected;
1736 continue;
1737 }
1738
1739 extern int cp;
1740 if(i3==0){
1741 if(bStatic){
1742 //静的メンバを追加
1743 cp=i; //エラー用
1744 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
1745 }
1746 else{
1747 //メンバを追加
1748 cp=i; //エラー用
1749 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
1750
1751
1752 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1753 if( !pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().IsReady() ){
1754 //参照先が読み取られていないとき
1755 GetClass_recur(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().GetName().c_str());
1756 }
1757 }
1758
1759
1760 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1761 //循環参照のチェック
1762 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1763 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass())){
1764 //エラー回避
1765 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
1766 type.SetBasicType( DEF_PTR_VOID );
1767 }
1768 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1769 }
1770 }
1771 }
1772 else{
1773 //メソッドを追加
1774 cp=i; //エラー用
1775 pobj_c->AddMethod(pobj_c,
1776 accessibility,
1777 bStatic,
1778 isConst,
1779 isAbstract,
1780 isVirtual,
1781 isOverride,
1782 false,
1783 temporary,
1784 sub_address);
1785
1786 if( isAbstract ) continue;
1787
1788 for(;;i++){
1789 if(basbuf[i]=='\0'){
1790 i--;
1791 break;
1792 }
1793 if(basbuf[i-1]!='*'&&
1794 basbuf[i]==1&&(
1795 basbuf[i+1]==ESC_SUB||
1796 basbuf[i+1]==ESC_FUNCTION||
1797 basbuf[i+1]==ESC_MACRO||
1798 basbuf[i+1]==ESC_TYPE||
1799 basbuf[i+1]==ESC_CLASS||
1800 basbuf[i+1]==ESC_INTERFACE||
1801 basbuf[i+1]==ESC_ENUM)){
1802 GetDefaultNameFromES(i3,temporary);
1803 SetError(22,temporary,i);
1804 }
1805 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1806 i+=2;
1807 break;
1808 }
1809 }
1810 }
1811 }
1812 }
1813 }
1814
1815 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
1816 compiler.pCompilingClass = pBackCompilingClass;
1817
1818 // 名前空間を元に戻す
1819 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1820
1821 // インポートされた名前空間を元に戻す
1822 compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces;
1823}
1824void Classes::GetAllClassInfo(void){
1825 //ループ継承チェック用のクラス
1826 pobj_LoopRefCheck=new CLoopRefCheck();
1827
1828 //クラスを取得
1829 GetClass_recur(0);
1830
1831 delete pobj_LoopRefCheck;
1832 pobj_LoopRefCheck=0;
1833
1834 // イテレータの準備
1835 this->Iterator_Init();
1836}
1837void Classes::Compile_System_InitializeUserTypes(){
1838 char temporary[VN_SIZE];
1839
1840 ////////////////////////////////////////////////////////////////////
1841 // クラス登録
1842 ////////////////////////////////////////////////////////////////////
1843
1844 // イテレータをリセット
1845 Iterator_Reset();
1846
1847 while( Iterator_HasNext() ){
1848 const CClass &objClass = *Iterator_GetNext();
1849
1850 if( !objClass.IsUsing() ){
1851 // 未使用のクラスは無視する
1852 continue;
1853 }
1854
1855 char referenceOffsetsBuffer[1024] = "";
1856 int numOfReference = 0;
1857 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1858 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() ){
1859 if( referenceOffsetsBuffer[0] ){
1860 lstrcat( referenceOffsetsBuffer, "," );
1861 }
1862
1863 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1864 "%d",
1865 objClass.GetMemberOffset( pMember->GetName().c_str() ) );
1866
1867 numOfReference++;
1868 }
1869 }
1870
1871 sprintf( temporary
1872 , "Add(%c%c_System_TypeForClass[strNamespace=\"%s\",name=\"%s\",fullName=\"%s\",referenceOffsets=[%s],numOfReference=%d])"
1873 , 1
1874 , ESC_SYSTEM_STATIC_NEW
1875 , objClass.GetNamespaceScopes().ToString().c_str() // 名前空間
1876 , objClass.GetName().c_str() // クラス名
1877 , objClass.GetFullName().c_str() // フルネーム
1878 , referenceOffsetsBuffer // 参照メンバオフセット配列
1879 , numOfReference // 参照メンバの個数
1880 );
1881
1882 // コンパイル
1883 ChangeOpcode( temporary );
1884
1885 objClass.SetTypeInfoDataTableOffset(
1886 compiler.GetObjectModule().dataTable.GetLastMadeConstObjectDataTableOffset()
1887 );
1888 }
1889}
1890void Classes::Compile_System_InitializeUserTypesForBaseType()
1891{
1892 extern int cp;
1893 cp = -1;
1894 ////////////////////////////////////////////////////////////////////
1895 // 基底クラスを登録
1896 ////////////////////////////////////////////////////////////////////
1897
1898 char temporary[VN_SIZE];
1899 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1900 , HIBYTE( COM_DIM )
1901 , LOBYTE( COM_DIM )
1902 , 1
1903 , ESC_AS
1904 );
1905 ChangeOpcode( temporary );
1906
1907 // イテレータをリセット
1908 Iterator_Reset();
1909
1910 while( Iterator_HasNext() ){
1911 const CClass &objClass = *Iterator_GetNext();
1912
1913 if( !objClass.IsUsing() ){
1914 // 未使用のクラスは無視する
1915 continue;
1916 }
1917
1918 if( objClass.HasSuperClass() ){
1919 sprintf( temporary
1920 , "tempType=Search(\"%s\")"
1921 , objClass.GetFullName().c_str()
1922 );
1923
1924 // コンパイル
1925 ChangeOpcode( temporary );
1926
1927 sprintf( temporary
1928 , "tempType.SetBaseType(Search(\"%s\"))"
1929 , objClass.GetSuperClass().GetFullName().c_str()
1930 );
1931
1932 // コンパイル
1933 ChangeOpcode( temporary );
1934 }
1935 }
1936
1937
1938
1939 ////////////////////////////////////////////////////////////////////
1940 // 継承関係登録
1941 ////////////////////////////////////////////////////////////////////
1942 // TODO: 未完成
1943 /*
1944
1945 // イテレータをリセット
1946 Iterator_Reset();
1947
1948 while( Iterator_HasNext() ){
1949 CClass *pClass = Iterator_GetNext();
1950
1951 sprintf( genBuffer + length
1952 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1953 , "" // クラス名
1954 , pClass->name // クラス名
1955 );
1956 length += lstrlen( genBuffer + length );
1957
1958 while( length + 8192 > max ){
1959 max += 8192;
1960 genBuffer = (char *)realloc( genBuffer, max );
1961 }
1962 }*/
1963}
1964
1965const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1966{
1967 if( namespaceScopes.size() == 0 && name == "Object" ){
1968 return GetObjectClassPtr();
1969 }
1970 else if( namespaceScopes.size() == 0 && name == "String" ){
1971 return GetStringClassPtr();
1972 }
1973
1974 const CClass *pClass = GetHashArrayElement( name.c_str() );
1975 while( pClass )
1976 {
1977 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1978 //名前空間とクラス名が一致した
1979 return pClass;
1980 }
1981 pClass = pClass->GetChainNext();
1982 }
1983
1984 // TypeDefも見る
1985 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
1986 if( index != -1 ){
1987 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
1988 if( type.IsObject() ){
1989 return &type.GetClass();
1990 }
1991 }
1992
1993 return NULL;
1994}
1995const CClass *Classes::Find( const string &fullName ) const
1996{
1997 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1998 char NestName[VN_SIZE] = ""; //入れ子メンバ
1999 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
2000
2001 return Find( NamespaceScopes( AreaName ), NestName );
2002}
2003void Classes::StartCompile( const UserProc *pUserProc ){
2004 const CClass *pParentClass = pUserProc->GetParentClassPtr();
2005 if( pParentClass ){
2006 pParentClass->Using();
2007
2008 // 仮想関数になるメソッドに使用チェックをつける
2009 BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetDynamicMethods() )
2010 {
2011 if( pMethod->IsVirtual() )
2012 {
2013 pMethod->GetUserProc().Using();
2014 }
2015 }
2016
2017 pCompilingMethod = pParentClass->GetDynamicMethodOrInterfaceMethod( pUserProc );
2018 if( !pCompilingMethod ){
2019 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
2020 if( !pCompilingMethod ){
2021 SmoothieException::Throw(300);
2022 }
2023 }
2024 }
2025 else{
2026 pCompilingMethod = NULL;
2027 }
2028}
2029
2030const CClass *Classes::GetStringClassPtr() const
2031{
2032 if( !pStringClass ){
2033 // キャッシュしておく
2034 pStringClass = this->Find( NamespaceScopes( "System" ), "String" );
2035
2036 if( !pStringClass )
2037 {
2038 SetError(400, "System.String", cp);
2039 static CClass dummy;
2040 return &dummy;
2041 }
2042 return pStringClass;
2043 }
2044 return pStringClass;
2045}
2046const CClass *Classes::GetObjectClassPtr() const
2047{
2048 if( !pObjectClass ){
2049 // キャッシュしておく
2050 pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" );
2051
2052 if( !pObjectClass )
2053 {
2054 SetError(400, "System.Object", cp);
2055 static CClass dummy;
2056 return &dummy;
2057 }
2058 return pObjectClass;
2059 }
2060 return pObjectClass;
2061}
2062const CClass *Classes::GetInterfaceInfoClassPtr() const
2063{
2064 if( !pInterfaceInfo ){
2065 // キャッシュしておく
2066 pInterfaceInfo = this->Find( "ActiveBasic.Core.InterfaceInfo" );
2067
2068 if( !pInterfaceInfo )
2069 {
2070 SetError(400, "ActiveBasic.Core.InterfaceInfo", cp);
2071 static CClass dummy;
2072 return &dummy;
2073 }
2074 return pInterfaceInfo;
2075 }
2076 return pInterfaceInfo;
2077}
Note: See TracBrowser for help on using the repository browser.