Changeset 206 in dev for trunk/abdev/BasicCompiler_Common/src/Class.cpp
- Timestamp:
- Jul 12, 2007, 2:58:26 AM (17 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/abdev/BasicCompiler_Common/src/Class.cpp
r204 r206 1 #include "stdafx.h" 2 1 3 #include <jenga/include/smoothie/Smoothie.h> 2 #include <jenga/include/smoothie/Class.h>3 4 #include <jenga/include/smoothie/Source.h> 4 5 #include <jenga/include/smoothie/SmoothieException.h> 5 6 #include <jenga/include/smoothie/LexicalAnalysis.h> 6 7 7 #include <Class Impl.h>8 #include <Class.h> 8 9 #include <Compiler.h> 9 10 #include <NamespaceSupporter.h> … … 15 16 #include "../../BasicCompiler32/opcode.h" 16 17 #endif 17 18 19 18 20 19 … … 77 76 78 77 79 bool ClassImpl::IsEqualSymbol( const NamespaceScopes &namespaceScopes, const string &name ) const 80 { 81 if( GetName() != name ){ 78 bool CClass::IsClass() const 79 { 80 return classType == CClass::Class; 81 } 82 bool CClass::IsInterface() const 83 { 84 return classType == CClass::Interface; 85 } 86 bool CClass::IsEnum() const 87 { 88 return classType == CClass::Enum; 89 } 90 bool CClass::IsDelegate() const 91 { 92 return classType == CClass::Delegate; 93 } 94 bool CClass::IsStructure() const 95 { 96 return classType == CClass::Structure; 97 } 98 99 100 // コンストラクタのコンパイルを開始 101 void CClass::NotifyStartConstructorCompile() const 102 { 103 isCompilingConstructor = true; 104 } 105 106 //コンストラクタのコンパイルを終了 107 void CClass::NotifyFinishConstructorCompile() const 108 { 109 isCompilingConstructor = false; 110 } 111 112 //コンストラクタをコンパイル中かどうかを判別 113 bool CClass::IsCompilingConstructor() const 114 { 115 return isCompilingConstructor; 116 } 117 118 //デストラクタのコンパイルを開始 119 void CClass::NotifyStartDestructorCompile() const{ 120 isCompilingDestructor = true; 121 } 122 123 //デストラクタのコンパイルを終了 124 void CClass::NotifyFinishDestructorCompile() const{ 125 isCompilingDestructor = false; 126 } 127 128 //デストラクタをコンパイル中かどうかを判別 129 bool CClass::IsCompilingDestructor() const 130 { 131 return isCompilingDestructor; 132 } 133 134 //自身の派生クラスかどうかを確認 135 bool CClass::IsSubClass( const CClass *pClass ) const 136 { 137 if( !pClass->HasSuperClass() ) 138 { 82 139 return false; 83 140 } 84 141 85 return compiler.GetNamespaceSupporter().IsSameAreaNamespace( GetNamespaceScopes(), namespaceScopes ); 86 } 87 88 bool ClassImpl::Inherits( const char *inheritNames, int nowLine ){ 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 //自身と等しいまたは派生クラスかどうかを確認 151 bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const 152 { 153 if( IsEquals( pClass ) ) return true; 154 return IsSubClass( pClass ); 155 } 156 157 // 自身と等しいまたは派生クラス、基底クラスかどうかを確認 158 bool 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 166 bool 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 176 bool CClass::Inherits( const char *inheritNames, int nowLine ){ 89 177 int i = 0; 90 178 bool isInheritsClass = false; … … 183 271 return true; 184 272 } 185 bool C lassImpl::InheritsClass( const CClass &inheritsClass, int nowLine ){273 bool CClass::InheritsClass( const CClass &inheritsClass, int nowLine ){ 186 274 187 275 //ループ継承でないかをチェック … … 245 333 return true; 246 334 } 247 bool C lassImpl::InheritsInterface( const CClass &inheritsInterface, int nowLine ){335 bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){ 248 336 249 337 //ループ継承でないかをチェック … … 291 379 return true; 292 380 } 293 CMember *C lassImpl::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )381 CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ) 294 382 { 295 383 extern int cp; … … 299 387 char initBuffer[VN_SIZE]; 300 388 char lpszConstructParameter[VN_SIZE]; 301 int SubScripts[MAX_ARRAYDIM];389 Subscripts subscripts; 302 390 Type type; 303 GetDimentionFormat(buffer,VarName, SubScripts,type,initBuffer,lpszConstructParameter);391 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter); 304 392 305 393 //重複チェック … … 308 396 } 309 397 310 CMember *pMember = new CMember( accessibility, VarName, type, isConst, initBuffer, lpszConstructParameter );398 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter ); 311 399 pMember->source_code_address = nowLine; 312 memcpy( pMember->SubScripts, SubScripts, MAX_ARRAYDIM * sizeof(int) );313 400 return pMember; 314 401 } 315 void C lassImpl::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){402 void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){ 316 403 dynamicMembers.push_back( 317 404 CreateMember( accessibility, isConst, isRef, buffer, nowLine ) 318 405 ); 319 406 } 320 void C lassImpl::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){407 void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){ 321 408 staticMembers.push_back( 322 409 CreateMember( accessibility, isConst, isRef, buffer, nowLine ) … … 324 411 } 325 412 326 void C lassImpl::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,413 void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract, 327 414 bool isVirtual, bool isOverride, char *buffer, int nowLine){ 328 415 int i,i2; … … 340 427 341 428 //関数ハッシュへ登録 342 GlobalProc *pUserProc; 343 pUserProc=AddSubData( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0) ); 429 UserProc *pUserProc = compiler.GetMeta().GetUserProcs().Add( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0) ); 344 430 if(!pUserProc) return; 345 431 … … 394 480 if( pMethod->GetInheritsClassPtr() ) continue; 395 481 396 if( pMethod-> pUserProc->GetName() == temporary ){397 if( pMethod-> pUserProc->Params().Equals( pUserProc->Params() ) ){482 if( pMethod->GetUserProc().GetName() == temporary ){ 483 if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){ 398 484 //関数名、パラメータ属性が合致したとき 399 485 SetError(15,pUserProc->GetName().c_str(),nowLine); … … 408 494 //メソッドのオーバーライド 409 495 BOOST_FOREACH( CMethod *pMethod, pobj_c->GetMethods() ){ 410 if( pMethod-> pUserProc->GetName() == temporary ){411 if( pMethod-> pUserProc->Params().Equals( pUserProc->Params() ) ){496 if( pMethod->GetUserProc().GetName() == temporary ){ 497 if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){ 412 498 413 499 if(pMethod->IsVirtual()){ 414 500 //メンバ関数を上書き 415 pMethod-> pUserProc=pUserProc;501 pMethod->SetUserProcPtr( pUserProc ); 416 502 pMethod->Override(); 417 503 … … 446 532 } 447 533 448 LONG_PTR ClassImpl::GetVtblGlobalOffset(void) const 534 bool CClass::DupliCheckAll(const char *name){ 535 //重複チェック 536 537 //メンバ 538 if(DupliCheckMember(name)) return 1; 539 540 //メソッド 541 BOOST_FOREACH( const CMethod *pMethod, methods ){ 542 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){ 543 return 1; 544 } 545 } 546 547 return 0; 548 } 549 bool CClass::DupliCheckMember(const char *name){ 550 //重複チェック 551 552 // 動的メンバ 553 BOOST_FOREACH( CMember *pMember, dynamicMembers ){ 554 if( GetName() == pMember->GetName() ){ 555 return 1; 556 } 557 } 558 559 // 静的メンバ 560 BOOST_FOREACH( CMember *pMember, staticMembers ){ 561 if( GetName() == pMember->GetName() ){ 562 return 1; 563 } 564 } 565 566 return 0; 567 } 568 569 //サイズを取得 570 int CClass::GetSize() const 571 { 572 return GetMemberOffset( NULL, NULL ); 573 } 574 575 //メンバのオフセットを取得 576 int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const 577 { 578 int i2; 579 580 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加 581 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0; 582 583 int alignment; 584 if(iAlign) alignment=iAlign; 585 else alignment=1; 586 587 int iMaxAlign=0; 588 int i = -1; 589 BOOST_FOREACH( CMember *pMember, dynamicMembers ){ 590 i++; 591 592 i2 = pMember->GetType().GetSize(); 593 594 //アラインメントを算出 595 int member_size; 596 if( pMember->GetType().IsStruct() ){ 597 //メンバクラスのアラインメントを取得 598 member_size=pMember->GetType().GetClass().GetAlignment(); 599 } 600 else{ 601 //メンバサイズを取得 602 member_size=i2; 603 } 604 if(iMaxAlign<member_size) iMaxAlign=member_size; 605 606 //アラインメントを考慮 607 if(iAlign&&iAlign<member_size){ 608 if(offset%alignment) offset+=alignment-(offset%alignment); 609 } 610 else{ 611 if(alignment<member_size) alignment=member_size; 612 613 if(member_size==0){ 614 //メンバを持たないクラス 615 //※何もしない(オフセットの計算をしない) 616 } 617 else{ 618 if(offset%member_size) offset+=member_size-(offset%member_size); 619 } 620 } 621 622 if(memberName){ 623 //メンバ指定がある場合は、オフセットを返す 624 if( pMember->GetName() == memberName ){ 625 if(pMemberNum) *pMemberNum=i; 626 return offset; 627 } 628 } 629 630 //配列を考慮したメンバサイズを取得 631 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() ); 632 633 //メンバサイズを加算 634 offset+= member_size; 635 } 636 637 if(iMaxAlign<alignment) alignment=iMaxAlign; 638 639 //アラインメントを考慮 640 if(alignment){ 641 if(offset%alignment) offset+=alignment-(offset%alignment); 642 } 643 644 if(pMemberNum) *pMemberNum=i; 645 return offset; 646 } 647 int CClass::GetAlignment() const 648 { 649 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加 650 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0; 651 652 BOOST_FOREACH( CMember *pMember, dynamicMembers ){ 653 int member_size; 654 if(pMember->GetType().IsStruct()){ 655 //メンバクラスのアラインメントを取得 656 member_size=pMember->GetType().GetClass().GetAlignment(); 657 } 658 else{ 659 //メンバサイズを取得 660 member_size = pMember->GetType().GetSize(); 661 } 662 663 //アラインメントをセット 664 if(alignment<member_size) alignment=member_size; 665 } 666 667 if(alignment==0) return 0; 668 669 if(iAlign) alignment=iAlign; 670 671 return alignment; 672 } 673 int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const 674 { 675 int n = 0; 676 BOOST_FOREACH( const CMethod *pMethod, methods ){ 677 if( &pMethod->GetUserProc() == pUserProc ) break; 678 if( pMethod->IsVirtual() ) n++; 679 } 680 return n; 681 } 682 LONG_PTR CClass::GetVtblGlobalOffset(void) const 449 683 { 450 684 … … 458 692 ////////////////////////////////////// 459 693 460 UserProc **ppsi;461 ppsi=( UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));694 const UserProc **ppsi; 695 ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *)); 462 696 463 697 //関数テーブルに値をセット … … 465 699 BOOST_FOREACH( const CMethod *pMethod, methods ){ 466 700 if(pMethod->IsVirtual()){ 467 pMethod-> pUserProc->Using();701 pMethod->GetUserProc().Using(); 468 702 469 703 if(pMethod->IsAbstract()){ … … 474 708 } 475 709 else{ 476 ppsi[i2]= pMethod->pUserProc;710 ppsi[i2]=&pMethod->GetUserProc(); 477 711 } 478 712 i2++; … … 490 724 return vtbl_offset; 491 725 } 492 void C lassImpl::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){726 void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){ 493 727 if(vtbl_offset==-1) return; 494 728 … … 501 735 pUserProc=(UserProc *)pVtbl[i]; 502 736 if(!pUserProc) continue; 503 pVtbl[i]=pUserProc->beginOpAddress+ImageBase+MemPos_CodeSection; 504 } 505 } 506 507 CClass *ClassesImpl::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){ 508 return new ClassImpl(namespaceScopes, importedNamespaces, name); 509 } 510 511 void ClassesImpl::CollectClassesForNameOnly( const BasicSource &source ) 737 pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection; 738 } 739 } 740 bool CClass::IsAbstract() const 741 { 742 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す 743 744 BOOST_FOREACH( const CMethod *pMethod, methods ){ 745 if(pMethod->IsVirtual()){ 746 if(pMethod->IsAbstract()){ 747 return true; 748 } 749 } 750 } 751 752 return false; 753 } 754 755 756 int Classes::GetHashCode(const char *name) const 757 { 758 int key; 759 760 for(key=0;*name!='\0';name++){ 761 key=((key<<8)+ *name )%MAX_CLASS_HASH; 762 } 763 764 return key; 765 } 766 767 CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){ 768 return new CClass(namespaceScopes, importedNamespaces, name); 769 } 770 bool Classes::Insert( CClass *pClass ) 771 { 772 // キャッシュしておくクラス 773 if( pClass->GetName() == "String" ) 774 { 775 pStringClass=pClass; 776 } 777 else if( pClass->GetName() == "Object" ) 778 { 779 pObjectClass = pClass; 780 } 781 782 ///////////////////////////////// 783 // ハッシュデータに追加 784 ///////////////////////////////// 785 786 int key; 787 key=GetHashCode( pClass->GetName().c_str() ); 788 789 if(pobj_ClassHash[key]){ 790 CClass *pobj_c2; 791 pobj_c2=pobj_ClassHash[key]; 792 while(1){ 793 if( ((const Prototype *)pobj_c2)->IsEqualSymbol( *(const Prototype *)pClass ) ){ 794 //名前空間及びクラス名が重複した場合 795 SmoothieException::Throw(15,pClass->GetName()); 796 return false; 797 } 798 799 if(pobj_c2->pobj_NextClass==0) break; 800 pobj_c2=pobj_c2->pobj_NextClass; 801 } 802 pobj_c2->pobj_NextClass=pClass; 803 } 804 else{ 805 pobj_ClassHash[key]=pClass; 806 } 807 return true; 808 } 809 CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){ 810 ////////////////////////////////////////////////////////////////////////// 811 // クラスを追加 812 // ※名前のみを登録。その他の情報はSetClassメソッドで! 813 ////////////////////////////////////////////////////////////////////////// 814 815 CClass *pClass = Create(namespaceScopes, importedNamespaces, name); 816 817 if( !Insert( pClass ) ) 818 { 819 return NULL; 820 } 821 822 return pClass; 823 } 824 825 void Classes::CollectClassesForNameOnly( const BasicSource &source ) 512 826 { 513 827 int i, i2; … … 641 955 } 642 956 643 void ClassesImpl::InitStaticMember(){ 957 void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){ 958 int i; 959 for(i=0;i<MAX_CLASS_HASH;i++){ 960 if(pobj_ClassHash[i]){ 961 CClass *pobj_c; 962 pobj_c=pobj_ClassHash[i]; 963 while(1){ 964 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection); 965 966 if(pobj_c->pobj_NextClass==0) break; 967 pobj_c=pobj_c->pobj_NextClass; 968 } 969 } 970 } 971 } 972 973 974 void Classes::InitStaticMember(){ 644 975 //静的メンバをグローバル領域に作成 645 976 … … 662 993 dim( 663 994 temporary, 664 member-> SubScripts,995 member->GetSubscripts(), 665 996 member->GetType(), 666 997 member->GetInitializeExpression().c_str(), … … 679 1010 cp=back_cp; 680 1011 } 681 bool Classes Impl::MemberVar_LoopRefCheck(const CClass &objClass){1012 bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){ 682 1013 bool result = true; 683 1014 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){ … … 704 1035 return result; 705 1036 } 706 void Classes Impl::GetClass_recur(const char *lpszInheritsClass){1037 void Classes::GetClass_recur(const char *lpszInheritsClass){ 707 1038 extern char *basbuf; 708 1039 int i,i2,i3,sub_address,top_pos; … … 1156 1487 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes; 1157 1488 } 1158 void Classes Impl::GetAllClassInfo(void){1489 void Classes::GetAllClassInfo(void){ 1159 1490 //ループ継承チェック用のクラス 1160 1491 pobj_LoopRefCheck=new CLoopRefCheck(); … … 1169 1500 this->Iterator_Init(); 1170 1501 } 1171 void Classes Impl::Compile_System_InitializeUserTypes(){1502 void Classes::Compile_System_InitializeUserTypes(){ 1172 1503 char temporary[VN_SIZE]; 1173 1504 … … 1296 1627 } 1297 1628 1298 const CClass *Classes Impl::Find( const NamespaceScopes &namespaceScopes, const string &name ) const1629 const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const 1299 1630 { 1300 1631 int key; … … 1333 1664 return NULL; 1334 1665 } 1666 const CClass *Classes::Find( const string &fullName ) const 1667 { 1668 char AreaName[VN_SIZE] = ""; //オブジェクト変数 1669 char NestName[VN_SIZE] = ""; //入れ子メンバ 1670 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName ); 1671 1672 return Find( NamespaceScopes( AreaName ), NestName ); 1673 } 1674 void Classes::StartCompile( const UserProc *pUserProc ){ 1675 const CClass *pParentClass = pUserProc->GetParentClassPtr(); 1676 if( pParentClass ){ 1677 pParentClass->Using(); 1678 1679 pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc ); 1680 if( !pCompilingMethod ){ 1681 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc ); 1682 if( !pCompilingMethod ){ 1683 SmoothieException::Throw(300); 1684 } 1685 } 1686 } 1687 else{ 1688 pCompilingMethod = NULL; 1689 } 1690 } 1691 1692 CClass *Classes::GetStringClassPtr() const 1693 { 1694 if( !pStringClass ){ 1695 SmoothieException::Throw(); 1696 return NULL; 1697 } 1698 return pStringClass; 1699 } 1700 CClass *Classes::GetObjectClassPtr() const 1701 { 1702 if( !pObjectClass ){ 1703 SmoothieException::Throw(); 1704 return NULL; 1705 } 1706 return pObjectClass; 1707 } 1708 1709 1710 ////////////////////// 1711 // イテレータ 1712 ////////////////////// 1713 1714 void Classes::Iterator_Init() const 1715 { 1716 if(ppobj_IteClass) free(ppobj_IteClass); 1717 1718 iIteMaxNum=0; 1719 iIteNextNum=0; 1720 ppobj_IteClass=(CClass **)malloc(1); 1721 1722 int i; 1723 for(i=0;i<MAX_CLASS_HASH;i++){ 1724 if(pobj_ClassHash[i]){ 1725 CClass *pobj_c; 1726 pobj_c=pobj_ClassHash[i]; 1727 while(1){ 1728 ppobj_IteClass=(CClass **)realloc(ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *)); 1729 ppobj_IteClass[iIteMaxNum]=pobj_c; 1730 iIteMaxNum++; 1731 1732 if(pobj_c->pobj_NextClass==0) break; 1733 pobj_c=pobj_c->pobj_NextClass; 1734 } 1735 } 1736 } 1737 } 1738 void Classes::Iterator_Reset() const 1739 { 1740 iIteNextNum = 0; 1741 } 1742 BOOL Classes::Iterator_HasNext() const 1743 { 1744 if(iIteNextNum<iIteMaxNum) return 1; 1745 return 0; 1746 } 1747 CClass *Classes::Iterator_GetNext() const 1748 { 1749 CClass *pobj_c = ppobj_IteClass[iIteNextNum]; 1750 iIteNextNum++; 1751 return pobj_c; 1752 } 1753 int Classes::Iterator_GetMaxCount() const 1754 { 1755 return iIteMaxNum; 1756 }
Note:
See TracChangeset
for help on using the changeset viewer.