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

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