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

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