source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Class.cpp@ 536

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

Compiler::pCompilingClassメンバをprivateにし、setter/getterにあたるメソッドを用意した。

File size: 26.0 KB
Line 
1#include "stdafx.h"
2
3#include <Source.h>
4#include <Class.h>
5#include <Compiler.h>
6
7#include "../common.h"
8#ifdef _AMD64_
9#include "../../compiler_x64/opcode.h"
10#else
11#include "../../compiler_x86/opcode.h"
12#endif
13
14using namespace ActiveBasic::Compiler;
15
16
17class CLoopRefCheck{
18 char **names;
19 int num;
20 void init(){
21 int i;
22 for(i=0;i<num;i++){
23 free(names[i]);
24 }
25 free(names);
26 }
27public:
28 CLoopRefCheck()
29 {
30 names=(char **)malloc(1);
31 num=0;
32 }
33 ~CLoopRefCheck()
34 {
35 init();
36 }
37 void add(const char *lpszInheritsClass)
38 {
39 names=(char **)realloc(names,(num+1)*sizeof(char *));
40 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
41 lstrcpy(names[num],lpszInheritsClass);
42 num++;
43 }
44 void del(const char *lpszInheritsClass)
45 {
46 int i;
47 for(i=0;i<num;i++){
48 if(lstrcmp(names[i],lpszInheritsClass)==0){
49 free(names[i]);
50 break;
51 }
52 }
53 if(i!=num){
54 num--;
55 for(;i<num;i++){
56 names[i]=names[i+1];
57 }
58 }
59 }
60 BOOL check(const CClass &inheritsClass) const
61 {
62 //ループ継承チェック
63 int i;
64 for(i=0;i<num;i++){
65 if( inheritsClass.GetName() == names[i] ){
66 return 1;
67 }
68 }
69 return 0;
70 }
71};
72CLoopRefCheck *pobj_LoopRefCheck;
73
74bool MemberVar_LoopRefCheck(const CClass &objClass){
75 if( objClass.HasSuperClass() )
76 {
77 // 基底クラスをチェック
78 if( MemberVar_LoopRefCheck( objClass.GetSuperClass() ) == false )
79 {
80 return false;
81 }
82 }
83
84 bool result = true;
85 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
86 if(pMember->GetType().IsStruct()){
87 //循環参照でないかをチェック
88 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
89 extern int cp;
90 compiler.errorMessenger.Output(124,pMember->GetType().GetClass().GetName(),cp);
91 return false;
92 }
93
94 pobj_LoopRefCheck->add(objClass.GetName().c_str());
95
96 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
97 if( result )
98 {
99 result = tempResult;
100 }
101
102 pobj_LoopRefCheck->del(objClass.GetName().c_str());
103 }
104 }
105
106 return result;
107}
108
109void LexicalAnalyzer::AddMethod(CClass *pobj_c, UserProc *pUserProc, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
110 bool isVirtual, bool isOverride, const char *interfaceName, bool isAutoGeneration, int nowLine)
111{
112 if( isAutoGeneration )
113 {
114 // コード自動生成
115 pUserProc->ThisIsAutoGenerationProc();
116 }
117
118
119 ////////////////////////////////////////////////////////////
120 // コンストラクタ、デストラクタの場合の処理
121 ////////////////////////////////////////////////////////////
122 BOOL fConstructor=0,bDestructor=0;
123
124 if( pUserProc->GetName() == pobj_c->GetName() ){
125 //コンストラクタの場合
126
127 //標準コンストラクタ(引数なし)
128 if(pUserProc->Params().size()==0) fConstructor=1;
129
130 //強制的にConst修飾子をつける
131 isConst = true;
132 }
133 else if(pUserProc->GetName()[0]=='~'){
134 //デストラクタの場合はその名前が正しいかチェックを行う
135 if(lstrcmp(pUserProc->GetName().c_str()+1,pobj_c->GetName().c_str())!=0)
136 compiler.errorMessenger.Output(117,NULL,nowLine);
137 else
138 bDestructor=1;
139 }
140 if(fConstructor||bDestructor){
141 // コンストラクタ、デストラクタのアクセシビリティをチェック
142
143 //強制的にConst修飾子をつける
144 isConst = true;
145 }
146
147 if( fConstructor == 1 )
148 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
149 else if( bDestructor )
150 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
151
152
153
154 //////////////////
155 // 重複チェック
156 //////////////////
157
158 if(pobj_c->DupliCheckMember( pUserProc->GetName().c_str() )){
159 compiler.errorMessenger.Output(15,pUserProc->GetName(),nowLine);
160 return;
161 }
162
163 //メソッド
164 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
165 {
166 //基底クラスと重複する場合はオーバーライドを行う
167 if( pMethod->GetInheritsClassPtr() ) continue;
168
169 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
170 {
171 //関数名、パラメータ、戻り値が合致したとき
172 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
173 return;
174 }
175 }
176
177 //仮想関数の場合
178 if( isAbstract ) pUserProc->CompleteCompile();
179
180 // メソッドのオーバーライド
181 CMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
182 if( pMethodForOverride )
183 {
184 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
185 pUserProc->SetMethod( pMethodForOverride );
186 return;
187 }
188 else
189 {
190 // インターフェイス メソッドのオーバーライド
191 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
192 {
193 if( interfaceName[0] )
194 {
195 if( pInterface->GetClass().GetName() != interfaceName )
196 {
197 // 指定されたインターフェイス名と整合しないとき
198 continue;
199 }
200 }
201
202 if( !pInterface->GetClass().IsReady() ){
203 // インターフェイスが未解析のとき
204 LexicalAnalyzer::LookaheadClass(
205 pInterface->GetClass().GetName().c_str(),
206 compiler.GetObjectModule().meta.GetClasses()
207 );
208 }
209
210 CMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
211 if( pMethodForOverride )
212 {
213 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
214 pUserProc->SetMethod( pMethodForOverride );
215 return;
216 }
217 }
218 }
219
220 if( interfaceName[0] )
221 {
222 compiler.errorMessenger.Output(139,interfaceName,nowLine);
223 }
224
225 if( isVirtual ){
226 pobj_c->AddVtblNum( 1 );
227 }
228
229 if( isOverride ){
230 compiler.errorMessenger.Output(12,"Override",nowLine);
231 }
232
233 if(bStatic){
234 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
235 }
236 else{
237 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
238 }
239}
240
241bool LexicalAnalyzer::Inherits( CClass &currentClass, const char *inheritNames, int nowLine ){
242 int i = 0;
243 bool isInheritsClass = false;
244 while( true ){
245
246 char temporary[VN_SIZE];
247 for( int i2=0;; i++, i2++ ){
248 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
249 temporary[i2] = 0;
250 break;
251 }
252 temporary[i2] = inheritNames[i];
253 }
254
255 // ジェネリクス構文を分解
256 char className[VN_SIZE];
257 Jenga::Common::Strings typeParameterStrings;
258 SplitGenericClassInstance( temporary, className, typeParameterStrings );
259
260 // 型パラメータ文字列から型データを取得
261 Types actualTypeParameters;
262 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
263 {
264 Type type;
265 compiler.StringToType( typeParameterStr, type );
266 actualTypeParameters.push_back( type );
267 }
268
269 //継承元クラスを取得
270 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
271 if( !pInheritsClass ){
272 compiler.errorMessenger.Output(106,className,nowLine);
273 return false;
274 }
275
276 if( pInheritsClass->IsClass() ){
277 // クラスを継承する
278 isInheritsClass = true;
279
280 //ループ継承でないかをチェック
281 if( !LexicalAnalyzer::LoopRefCheck(*pInheritsClass) )
282 {
283 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),nowLine);
284 return false;
285 }
286
287 if( !pInheritsClass->IsReady() ){
288 //継承先が読み取られていないとき
289 LexicalAnalyzer::LookaheadClass(
290 pInheritsClass->GetName().c_str(),
291 compiler.GetObjectModule().meta.GetClasses()
292 );
293 }
294
295 if( !currentClass.InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
296 return false;
297 }
298 }
299 else{
300 compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine);
301 return false;
302 }
303
304 if( inheritNames[i] == '\0' ){
305 break;
306 }
307 i++;
308 }
309
310 if( !isInheritsClass ){
311 const CClass *pObjectClass = compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
312 //ループ継承でないかをチェック
313 if( !LexicalAnalyzer::LoopRefCheck( *pObjectClass ) )
314 {
315 compiler.errorMessenger.Output(123,pObjectClass->GetName(),nowLine);
316 return false;
317 }
318
319 if( !pObjectClass->IsReady() ){
320 //継承先が読み取られていないとき
321 LexicalAnalyzer::LookaheadClass(
322 pObjectClass->GetName().c_str(),
323 compiler.GetObjectModule().meta.GetClasses()
324 );
325 }
326
327 // クラスを一つも継承していないとき
328 if( !currentClass.InheritsClass( *pObjectClass, Types(), nowLine ) ){
329 return false;
330 }
331 }
332
333 return true;
334}
335
336bool LexicalAnalyzer::Implements( CClass &currentClass, const char *interfaceNames, int nowLine )
337{
338 Jenga::Common::Strings paramStrs;
339 SplitParameter( interfaceNames, paramStrs );
340
341 BOOST_FOREACH( const std::string &paramStr, paramStrs )
342 {
343 char className[VN_SIZE];
344 Jenga::Common::Strings typeParameterStrings;
345 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
346
347 Types actualTypeParameters;
348 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
349 {
350 Type type;
351 compiler.StringToType( typeParameterStr, type );
352 actualTypeParameters.push_back( type );
353 }
354
355 //継承元クラスを取得
356 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( className );
357 if( !pInterfaceClass ){
358 compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine);
359 continue;
360 }
361
362 if( !pInterfaceClass->IsReady() ){
363 // インターフェイスが未解析のとき
364 LexicalAnalyzer::LookaheadClass(
365 pInterfaceClass->GetName().c_str(),
366 compiler.GetObjectModule().meta.GetClasses()
367 );
368 }
369
370 // インターフェイスを継承する
371 currentClass.Implements( *pInterfaceClass, actualTypeParameters, nowLine );
372 }
373
374 return true;
375}
376
377void GetClass_recur( const char *lpszInheritsClass, Classes &classes )
378{
379 extern char *basbuf;
380 int i,i2,i3,sub_address,top_pos;
381 char temporary[8192];
382
383 // 名前空間管理
384 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
385 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
386 namespaceScopes.clear();
387
388 // Importsされた名前空間の管理
389 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
390 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
391
392 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
393 const CClass *pBackCompilingClass = compiler.IsCompilingClass()
394 ? &compiler.GetCompilingClass()
395 : NULL;
396
397 for(i=0;;i++){
398 if(basbuf[i]=='\0') break;
399
400
401 // 名前空間
402 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
403 for(i+=2,i2=0;;i2++,i++){
404 if( IsCommandDelimitation( basbuf[i] ) ){
405 temporary[i2]=0;
406 break;
407 }
408 temporary[i2]=basbuf[i];
409 }
410 namespaceScopes.push_back( temporary );
411
412 continue;
413 }
414 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
415 if( namespaceScopes.size() <= 0 ){
416 compiler.errorMessenger.Output(12, "End Namespace", i );
417 }
418 else{
419 namespaceScopes.pop_back();
420 }
421
422 i += 2;
423 continue;
424 }
425
426 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
427 for(i+=2,i2=0;;i2++,i++){
428 if( IsCommandDelimitation( basbuf[i] ) ){
429 temporary[i2]=0;
430 break;
431 }
432 temporary[i2]=basbuf[i];
433 }
434 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
435 {
436 compiler.errorMessenger.Output(64,temporary,i );
437 }
438
439 continue;
440 }
441 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
442 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
443 continue;
444 }
445
446
447
448 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
449 //////////////////////////
450 // インターフェイス
451 //////////////////////////
452
453 top_pos=i;
454
455 i+=2;
456
457 //インターフェイス名を取得
458 GetCommandToken( temporary, basbuf, i );
459
460 char className[VN_SIZE];
461 Jenga::Common::Strings typeParameters;
462 Jenga::Common::Strings typeParameterBaseClassNames;
463 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
464
465 CClass *pobj_c = const_cast<CClass *>( classes.Find(namespaceScopes, className) );
466 if(!pobj_c) continue;
467
468 compiler.SetCompilingClass( pobj_c );
469
470 if(lpszInheritsClass){
471 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
472 //継承先先読み用
473 continue;
474 }
475 }
476
477 if(pobj_c->IsReady()){
478 //既に先読みされているとき
479 continue;
480 }
481
482 /////////////////////////////////////////////////////////
483 // ☆★☆ ジェネリクスサポート ☆★☆
484 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
485 {
486 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
487 if( typeParameterBaseClassNames[i2].size() )
488 {
489 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
490 {
491 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
492 }
493 else if( !baseType.IsObject() )
494 {
495 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
496 }
497 }
498
499 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
500 }
501 /////////////////////////////////////////////////////////
502
503 pobj_c->Readed();
504
505 pobj_c->SetConstructorMemberSubIndex( -1 );
506 pobj_c->SetDestructorMemberSubIndex( -1 );
507
508 if( memcmp( basbuf+i+1, "__COM", 5 ) == 0 && IsCommandDelimitation( basbuf[i+1+5] ) )
509 {
510 // COMインターフェイス
511 pobj_c->SetClassType( CClass::ComInterface );
512
513 i += 6;
514 }
515
516 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
517 //継承を行う場合
518 for(i+=3,i2=0;;i++,i2++){
519 if(IsCommandDelimitation(basbuf[i])){
520 temporary[i2]=0;
521 break;
522 }
523 temporary[i2]=basbuf[i];
524 }
525
526 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
527 compiler.errorMessenger.Output(105,temporary,i);
528 goto Interface_InheritsError;
529 }
530
531 //継承元クラスを取得
532 const CClass *pInheritsClass = classes.Find(temporary);
533 if( !pInheritsClass ){
534 compiler.errorMessenger.Output(106,temporary,i);
535 goto Interface_InheritsError;
536 }
537
538 //ループ継承でないかをチェック
539 if( !LexicalAnalyzer::LoopRefCheck( *pInheritsClass ) )
540 {
541 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),i);
542 goto Interface_InheritsError;
543 }
544
545 //継承させる
546 if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){
547 goto Interface_InheritsError;
548 }
549 }
550 else{
551 //継承無し
552 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
553 {
554 // TODO: ここに来ないことが実証できたらこの分岐は消す
555 Jenga::Throw( "GetClass_recur内の例外" );
556 }
557 }
558Interface_InheritsError:
559
560 //メンバ変数、関数を取得
561 while(1){
562 i++;
563
564 //エラー
565 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
566 compiler.errorMessenger.Output(22,"Interface",i);
567 i--;
568 break;
569 }
570
571 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
572 compiler.errorMessenger.Output(111,NULL,i);
573 break;
574 }
575 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
576 {
577 compiler.errorMessenger.Output(137, NULL, i );
578 break;
579 }
580
581 sub_address=i;
582
583 for(i2=0;;i++,i2++){
584 if(IsCommandDelimitation(basbuf[i])){
585 temporary[i2]=0;
586 break;
587 }
588 temporary[i2]=basbuf[i];
589 }
590 if(temporary[0]=='\0'){
591 if(basbuf[i]=='\0'){
592 i--;
593 compiler.errorMessenger.Output(22,"Interface",top_pos);
594 break;
595 }
596 continue;
597 }
598
599 //End Interface記述の場合
600 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
601
602 if(!(temporary[0]==1&&(
603 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
604 ))){
605 compiler.errorMessenger.Output(1,NULL,i);
606 break;
607 }
608
609 //関数ハッシュへ登録
610 char interfaceName[VN_SIZE] = "";
611 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,true,pobj_c, false, interfaceName );
612 if( pUserProc )
613 {
614 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, i );
615
616 //メンバ関数を追加
617 LexicalAnalyzer::AddMethod(pobj_c,
618 pUserProc,
619 Prototype::Public, //Publicアクセス権
620 0, // bStatic
621 false, // isConst
622 true, // isAbstract
623 true, // isVirtual
624 false, // isOverride
625 interfaceName,
626 false, // isAutoGeneration
627 sub_address
628 );
629 }
630 }
631 }
632
633 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
634 //////////////////////////
635 // クラス
636 //////////////////////////
637
638 top_pos=i;
639
640 const DWORD dwClassType=basbuf[i+1];
641
642 i+=2;
643
644 int iAlign=0;
645 if(memicmp(basbuf+i,"Align(",6)==0){
646 //アラインメント修飾子
647 i+=6;
648 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
649 iAlign=atoi(temporary);
650
651 if( dwClassType != ESC_TYPE )
652 {
653 compiler.errorMessenger.Output(140,NULL,i);
654 }
655
656 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
657 compiler.errorMessenger.Output(51,NULL,i);
658 }
659 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
660 // Blittable修飾子
661 i+=10;
662 i=JumpStringInPare(basbuf,i)+1;
663
664 if( dwClassType != ESC_CLASS )
665 {
666 compiler.errorMessenger.Output(141,NULL,i);
667 }
668 }
669
670 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
671 {
672 // 列挙型の場合
673 i += 2;
674 }
675 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
676 {
677 // デリゲートの場合
678 i += 2;
679 }
680
681 //クラス名を取得
682 GetCommandToken( temporary, basbuf, i );
683
684 char className[VN_SIZE];
685 Jenga::Common::Strings typeParameters;
686 Jenga::Common::Strings typeParameterBaseClassNames;
687 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
688
689 CClass *pobj_c = const_cast<CClass *>( classes.Find(namespaceScopes, className) );
690 if(!pobj_c) continue;
691
692 compiler.SetCompilingClass( pobj_c );
693
694 if(lpszInheritsClass){
695 if( pobj_c->GetName() != lpszInheritsClass ){
696 //継承先先読み用
697 continue;
698 }
699 }
700
701 if( lstrcmp(className,"Control")==0)
702 {
703 int test=0;
704 }
705
706 if(pobj_c->IsReady()){
707 //既に先読みされているとき
708 continue;
709 }
710
711
712 /////////////////////////////////////////////////////////
713 // ☆★☆ ジェネリクスサポート ☆★☆
714 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
715 {
716 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
717 if( typeParameterBaseClassNames[i2].size() )
718 {
719 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
720 {
721 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
722 }
723 else if( !baseType.IsObject() )
724 {
725 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
726 }
727 }
728
729 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
730 }
731 /////////////////////////////////////////////////////////
732
733
734 pobj_c->SetFixedAlignment( iAlign );
735
736 pobj_c->Readed();
737
738 pobj_c->SetConstructorMemberSubIndex( -1 );
739 pobj_c->SetDestructorMemberSubIndex( -1 );
740
741 //アクセス制限の初期値をセット
742 Prototype::Accessibility accessibility;
743 if(dwClassType==ESC_CLASS){
744 accessibility = Prototype::Private;
745 }
746 else{
747 accessibility = Prototype::Public;
748 }
749
750 if( pobj_c->GetName() == "Object"
751 || dwClassType == ESC_TYPE )
752 {
753 // 何も継承しない
754
755 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
756 {
757 // TODO: ここに来ないことが実証できたらこの分岐は消す
758 Jenga::Throw( "GetClass_recur内の例外" );
759 }
760 }
761 else{
762 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS)
763 {
764 // クラス継承先が指定されているとき
765 i += 3;
766 GetCommandToken( temporary, basbuf, i );
767
768 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
769 compiler.errorMessenger.Output(105,temporary,i);
770 goto InheritsError;
771 }
772 }
773 else
774 {
775 // 何の指定もないときはObjectクラスを継承する
776 lstrcpy( temporary, "Object" );
777 }
778 LexicalAnalyzer::Inherits( *pobj_c, temporary, i );
779
780 if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS )
781 {
782 // インターフェイス実装を行う場合
783 i += 3;
784 GetCommandToken( temporary, basbuf, i );
785
786 LexicalAnalyzer::Implements( *pobj_c, temporary, i );
787 }
788 }
789InheritsError:
790
791 //メンバとメソッドを取得
792 while(1){
793 i++;
794
795 //エラー
796 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
797 compiler.errorMessenger.Output(22,"Class",i);
798 i--;
799 break;
800 }
801
802 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
803 compiler.errorMessenger.Output(111,NULL,i);
804 break;
805 }
806 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
807 {
808 compiler.errorMessenger.Output(137, NULL, i );
809 break;
810 }
811
812 //Static修飾子
813 BOOL bStatic;
814 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
815 bStatic=1;
816 i+=2;
817 }
818 else bStatic=0;
819
820 //Const修飾子
821 bool isConst = false;
822 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
823 isConst = true;
824 i += 2;
825 }
826
827 if(basbuf[i]==1&&(
828 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
829 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
830 )){
831 i3=basbuf[i+1];
832 sub_address=i;
833 }
834 else i3=0;
835
836 bool isVirtual = false, isAbstract = false, isOverride = false;
837 if(i3==ESC_ABSTRACT){
838 isAbstract=1;
839 isVirtual=1;
840 i+=2;
841
842 i3=basbuf[i+1];
843 }
844 else if(i3==ESC_VIRTUAL){
845 isAbstract=0;
846 isVirtual=1;
847 i+=2;
848
849 i3=basbuf[i+1];
850 }
851 else if(i3==ESC_OVERRIDE){
852 isOverride=1;
853 isVirtual=1;
854
855 i+=2;
856
857 i3=basbuf[i+1];
858 }
859
860 for(i2=0;;i++,i2++){
861 if(IsCommandDelimitation(basbuf[i])){
862 temporary[i2]=0;
863 break;
864 }
865 temporary[i2]=basbuf[i];
866 }
867 if(temporary[0]=='\0'){
868 if(basbuf[i]=='\0'){
869
870 if(dwClassType==ESC_CLASS)
871 compiler.errorMessenger.Output(22,"Class",top_pos);
872 else
873 compiler.errorMessenger.Output(22,"Type",top_pos);
874
875 i--;
876 break;
877 }
878 continue;
879 }
880
881 //End Class記述の場合
882 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
883 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
884
885 //アクセスを変更
886 if(lstrcmpi(temporary,"Private")==0){
887 accessibility = Prototype::Private;
888 continue;
889 }
890 if(lstrcmpi(temporary,"Public")==0){
891 accessibility = Prototype::Public;
892 continue;
893 }
894 if(lstrcmpi(temporary,"Protected")==0){
895 accessibility = Prototype::Protected;
896 continue;
897 }
898
899 extern int cp;
900 if(i3==0){
901 if(bStatic){
902 //静的メンバを追加
903 cp=i; //エラー用
904 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
905 }
906 else{
907 //メンバを追加
908 cp=i; //エラー用
909 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
910
911
912 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
913 if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
914 //参照先が読み取られていないとき
915 GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
916 }
917 }
918
919
920 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
921 //循環参照のチェック
922 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
923 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
924 //エラー回避
925 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
926 type.SetBasicType( DEF_PTR_VOID );
927 }
928 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
929 }
930 }
931 }
932 else{
933 //関数ハッシュへ登録
934 char interfaceName[VN_SIZE] = "";
935 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,isVirtual,pobj_c, (bStatic!=0), interfaceName );
936 if( pUserProc )
937 {
938 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, i );
939
940 //メソッドを追加
941 cp=i; //エラー用
942 LexicalAnalyzer::AddMethod(pobj_c,
943 pUserProc,
944 accessibility,
945 bStatic,
946 isConst,
947 isAbstract,
948 isVirtual,
949 isOverride,
950 interfaceName,
951 false,
952 sub_address);
953 }
954
955 if( isAbstract ) continue;
956
957 for(;;i++){
958 if(basbuf[i]=='\0'){
959 i--;
960 break;
961 }
962 if(basbuf[i-1]!='*'&&
963 basbuf[i]==1&&(
964 basbuf[i+1]==ESC_SUB||
965 basbuf[i+1]==ESC_FUNCTION||
966 basbuf[i+1]==ESC_MACRO||
967 basbuf[i+1]==ESC_TYPE||
968 basbuf[i+1]==ESC_CLASS||
969 basbuf[i+1]==ESC_INTERFACE||
970 basbuf[i+1]==ESC_ENUM)){
971 GetDefaultNameFromES(i3,temporary);
972 compiler.errorMessenger.Output(22,temporary,i);
973 }
974 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
975 i+=2;
976 break;
977 }
978 }
979 }
980 }
981 }
982 }
983
984 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
985 compiler.SetCompilingClass( pBackCompilingClass );
986
987 // 名前空間を元に戻す
988 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
989
990 // インポートされた名前空間を元に戻す
991 compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces;
992}
993
994void LexicalAnalyzer::LookaheadClass( const char *className, Classes &classes )
995{
996 pobj_LoopRefCheck->add( className );
997 GetClass_recur( className, classes );
998 pobj_LoopRefCheck->del( className );
999}
1000
1001bool LexicalAnalyzer::LoopRefCheck( const CClass &objClass )
1002{
1003 if( pobj_LoopRefCheck->check( objClass ) )
1004 {
1005 return false;
1006 }
1007
1008 return true;
1009}
1010
1011void LexicalAnalyzer::CollectClasses( const char *source, Classes &classes ){
1012 //ループ継承チェック用のクラス
1013 pobj_LoopRefCheck=new CLoopRefCheck();
1014
1015 //クラスを取得
1016 GetClass_recur( 0, classes );
1017
1018 delete pobj_LoopRefCheck;
1019 pobj_LoopRefCheck=0;
1020
1021 // イテレータの準備
1022 classes.Iterator_Init();
1023}
Note: See TracBrowser for help on using the repository browser.