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

Last change on this file since 370 was 370, checked in by dai_9181, 16 years ago

COM修飾子に対応。COMインターフェイスを呼び出せるようにした

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