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

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