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

Last change on this file since 310 was 310, checked in by dai_9181, 17 years ago

GetClass_recurメソッド内でImportsされた名前空間情報が適用されていなかったので適用した。

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