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

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