Changeset 409 in dev for trunk/abdev/BasicCompiler_Common/src/Class.cpp
- Timestamp:
- Mar 3, 2008, 6:33:29 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/abdev/BasicCompiler_Common/src/Class.cpp
r407 r409 246 246 //継承先が読み取られていないとき 247 247 compiler.GetObjectModule().meta.GetClasses().LookaheadClass(inheritsClass.GetName().c_str()); 248 }249 250 //メンバをコピー251 BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.GetDynamicMembers() ){252 CMember *pMember = new CMember( *inheritsClassDynamicMember );253 254 // アクセシビリティ255 if( inheritsClassDynamicMember->IsPrivate() ){256 pMember->SetAccessibility( Prototype::None );257 }258 else{259 pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() );260 }261 262 // メンバのみ、型パラメータを解決する(メソッドのほうは呼び出し時に解決する)263 if( pMember->GetType().IsTypeParameter() )264 {265 pMember->ResetType( actualTypeParameters[pMember->GetType().GetFormalTypeIndex()] );266 }267 268 dynamicMembers.push_back( pMember );269 248 } 270 249 … … 592 571 } 593 572 594 bool CClass::DupliCheckAll(const char *name){ 573 bool CClass::DupliCheckAll(const char *name) const 574 { 595 575 //重複チェック 596 576 … … 607 587 return 0; 608 588 } 609 bool CClass::DupliCheckMember(const char *name){ 589 bool CClass::DupliCheckMember(const char *name) const 590 { 610 591 //重複チェック 611 592 593 if( this->HasSuperClass() ) 594 { 595 if( this->GetSuperClass().DupliCheckMember( name ) ) 596 { 597 // 基底クラスで重複が発見された 598 return true; 599 } 600 } 601 612 602 // 動的メンバ 613 BOOST_FOREACH( CMember *pMember, dynamicMembers ){ 614 if( GetName() == pMember->GetName() ){ 615 return 1; 603 BOOST_FOREACH( CMember *pMember, dynamicMembers ) 604 { 605 if( GetName() == pMember->GetName() ) 606 { 607 return true; 616 608 } 617 609 } … … 620 612 BOOST_FOREACH( CMember *pMember, staticMembers ){ 621 613 if( GetName() == pMember->GetName() ){ 622 return 1; 623 } 624 } 625 626 return 0; 614 return true; 615 } 616 } 617 618 return false; 619 } 620 621 const CMember *CClass::FindDynamicMember( const char *memberName ) const 622 { 623 if( this->HasSuperClass() ) 624 { 625 // 基底クラスで検索 626 const CMember *result = this->GetSuperClass().FindDynamicMember( memberName ); 627 if( result ) 628 { 629 return result; 630 } 631 } 632 633 BOOST_FOREACH( CMember *pMember, GetDynamicMembers() ) 634 { 635 if( pMember->GetName() == memberName ) 636 { 637 return pMember; 638 } 639 } 640 return NULL; 627 641 } 628 642 … … 679 693 int CClass::GetSize() const 680 694 { 681 return GetMemberOffset( NULL, NULL ); 695 int resultSize = 0; 696 697 int alignment = 1; 698 if( this->IsStructure() ) 699 { 700 // 構造体のとき 701 702 if( this->GetFixedAlignment() ) 703 { 704 // アラインメントの固定値が指定されていた場合はそれを取得 705 alignment = this->GetFixedAlignment(); 706 } 707 } 708 else 709 { 710 // それ以外 711 712 if( this->HasSuperClass() ) 713 { 714 // 基底クラスのサイズを追加 715 resultSize += this->GetSuperClass().GetSize(); 716 717 // 基底クラスのアラインメントを取得 718 alignment = this->GetSuperClass().GetAlignment(); 719 } 720 else 721 { 722 // 基底クラスが存在しないとき 723 724 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加 725 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0; 726 } 727 } 728 729 BOOST_FOREACH( CMember *pMember, dynamicMembers ) 730 { 731 // メンバサイズ 732 int tempMemberSize = pMember->GetType().GetSize(); 733 734 // 一時アラインメントを算出 735 int tempAlignment = tempMemberSize; 736 if( pMember->GetType().IsStruct() ) 737 { 738 // メンバが構造体の場合は、メンバのアラインメントを取得 739 tempAlignment = pMember->GetType().GetClass().GetAlignment(); 740 } 741 742 // アラインメントを考慮してパディングを追加 743 if( GetFixedAlignment() && alignment < tempAlignment ) 744 { 745 if( resultSize % alignment ) 746 { 747 resultSize += alignment - ( resultSize % alignment ); 748 } 749 } 750 else 751 { 752 if( alignment < tempAlignment ) 753 { 754 // 最大アラインメントを更新 755 alignment = tempAlignment; 756 } 757 758 if( tempMemberSize == 0 ) 759 { 760 if( !pMember->GetType().IsStruct() ) 761 { 762 SetError(); 763 } 764 765 //メンバを持たない構造体 766 //※何もしない(オフセットの計算をしない) 767 } 768 else{ 769 if( resultSize % tempAlignment ) 770 { 771 resultSize += tempAlignment - ( resultSize % tempAlignment ); 772 } 773 } 774 } 775 776 // メンバサイズを加算(配列を考慮) 777 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() ); 778 } 779 780 if( alignment ) 781 { 782 // 末尾アラインメントを考慮してパディングを追加 783 if( resultSize % alignment ) 784 { 785 resultSize += alignment - ( resultSize % alignment ); 786 } 787 } 788 789 return resultSize; 682 790 } 683 791 684 792 //メンバのオフセットを取得 685 int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const 686 { 687 int i2; 688 689 //仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加 690 int offset = IsExistVirtualFunctions() ? PTR_SIZE*2 : 0; 793 int CClass::GetMemberOffset( const char *memberName ) const 794 { 795 int resultSize = 0; 691 796 692 797 int alignment = 1; 693 if( GetFixedAlignment() ) 694 { 695 alignment = GetFixedAlignment(); 696 } 697 698 int iMaxAlign=0; 699 int i = -1; 700 BOOST_FOREACH( CMember *pMember, dynamicMembers ){ 701 i++; 702 703 i2 = pMember->GetType().GetSize(); 704 705 //アラインメントを算出 706 int member_size; 707 if( pMember->GetType().IsStruct() ){ 708 //メンバクラスのアラインメントを取得 709 member_size=pMember->GetType().GetClass().GetAlignment(); 710 } 711 else{ 712 //メンバサイズを取得 713 member_size=i2; 714 } 715 if(iMaxAlign<member_size) iMaxAlign=member_size; 716 717 //アラインメントを考慮 718 if(GetFixedAlignment()&&GetFixedAlignment()<member_size){ 719 if(offset%alignment) offset+=alignment-(offset%alignment); 720 } 721 else{ 722 if(alignment<member_size) alignment=member_size; 723 724 if(member_size==0){ 725 //メンバを持たないクラス 798 if( this->IsStructure() ) 799 { 800 // 構造体のとき 801 802 if( this->GetFixedAlignment() ) 803 { 804 // アラインメントの固定値が指定されていた場合はそれを取得 805 alignment = this->GetFixedAlignment(); 806 } 807 } 808 else 809 { 810 // それ以外 811 812 if( this->HasSuperClass() ) 813 { 814 if( this->GetSuperClass().HasDynamicMember( memberName ) ) 815 { 816 // 基底クラスのメンバを取得 817 return this->GetSuperClass().GetMemberOffset( memberName ); 818 } 819 820 // 基底クラスのサイズを追加 821 resultSize += this->GetSuperClass().GetSize(); 822 823 // 基底クラスのアラインメントを取得 824 alignment = this->GetSuperClass().GetAlignment(); 825 } 826 else 827 { 828 // 基底クラスが存在しないとき 829 830 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加 831 resultSize += IsExistVirtualFunctions() ? PTR_SIZE*2 : 0; 832 } 833 } 834 835 BOOST_FOREACH( CMember *pMember, dynamicMembers ) 836 { 837 // メンバサイズ 838 int tempMemberSize = pMember->GetType().GetSize(); 839 840 // 一時アラインメントを算出 841 int tempAlignment = tempMemberSize; 842 if( pMember->GetType().IsStruct() ) 843 { 844 // メンバが構造体の場合は、メンバのアラインメントを取得 845 tempAlignment = pMember->GetType().GetClass().GetAlignment(); 846 } 847 848 // アラインメントを考慮してパディングを追加 849 if( GetFixedAlignment() && alignment < tempAlignment ) 850 { 851 if( resultSize % alignment ) 852 { 853 resultSize += alignment - ( resultSize % alignment ); 854 } 855 } 856 else 857 { 858 if( alignment < tempAlignment ) 859 { 860 // 最大アラインメントを更新 861 alignment = tempAlignment; 862 } 863 864 if( tempMemberSize == 0 ) 865 { 866 if( !pMember->GetType().IsStruct() ) 867 { 868 SetError(); 869 } 870 871 //メンバを持たない構造体 726 872 //※何もしない(オフセットの計算をしない) 727 873 } 728 874 else{ 729 if(offset%member_size) offset+=member_size-(offset%member_size); 875 if( resultSize % tempAlignment ) 876 { 877 resultSize += tempAlignment - ( resultSize % tempAlignment ); 878 } 730 879 } 731 880 } … … 733 882 if(memberName){ 734 883 //メンバ指定がある場合は、オフセットを返す 735 if( pMember->GetName() == memberName ){ 736 if(pMemberNum) *pMemberNum=i; 737 return offset; 738 } 739 } 740 741 //配列を考慮したメンバサイズを取得 742 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() ); 743 744 //メンバサイズを加算 745 offset+= member_size; 746 } 747 748 if(iMaxAlign<alignment) alignment=iMaxAlign; 749 750 //アラインメントを考慮 751 if(alignment){ 752 if(offset%alignment) offset+=alignment-(offset%alignment); 753 } 754 755 if(pMemberNum) *pMemberNum=i; 756 return offset; 884 if( pMember->GetName() == memberName ) 885 { 886 return resultSize; 887 } 888 } 889 890 // メンバサイズを加算(配列を考慮) 891 resultSize += tempMemberSize * Variable::GetSubScriptCounts( pMember->GetSubscripts() ); 892 } 893 894 if( alignment ) 895 { 896 // 末尾アラインメントを考慮してパディングを追加 897 if( resultSize % alignment ) 898 { 899 resultSize += alignment - ( resultSize % alignment ); 900 } 901 } 902 903 return resultSize; 757 904 } 758 905 int CClass::GetAlignment() const 759 906 { 760 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加 761 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0; 762 763 BOOST_FOREACH( CMember *pMember, dynamicMembers ){ 764 int member_size; 765 if(pMember->GetType().IsStruct()){ 766 //メンバクラスのアラインメントを取得 767 member_size=pMember->GetType().GetClass().GetAlignment(); 768 } 769 else{ 770 //メンバサイズを取得 771 member_size = pMember->GetType().GetSize(); 772 } 773 774 //アラインメントをセット 775 if(alignment<member_size) alignment=member_size; 776 } 777 778 if(alignment==0) return 0; 779 780 if(GetFixedAlignment()) alignment=GetFixedAlignment(); 907 int alignment = 1; 908 if( this->IsStructure() ) 909 { 910 // 構造体のとき 911 912 if( this->GetFixedAlignment() ) 913 { 914 // アラインメントの固定値が指定されていた場合はそれを取得 915 return this->GetFixedAlignment(); 916 } 917 } 918 else 919 { 920 // それ以外 921 922 if( this->HasSuperClass() ) 923 { 924 // 基底クラスのアラインメントを取得 925 alignment = this->GetSuperClass().GetAlignment(); 926 } 927 else 928 { 929 // 基底クラスが存在しないとき 930 931 // 仮想関数が存在する場合はvtbl及びvtblMasterListへのポインタのサイズを追加 932 alignment = PTR_SIZE; 933 } 934 } 935 936 BOOST_FOREACH( CMember *pMember, dynamicMembers ) 937 { 938 int tempAlignment = pMember->GetType().GetSize(); 939 if( pMember->GetType().IsStruct() ) 940 { 941 // メンバが構造体の場合は、メンバのアラインメントを取得 942 tempAlignment = pMember->GetType().GetClass().GetAlignment(); 943 } 944 945 if( alignment < tempAlignment ) 946 { 947 // 最大アラインメントを更新 948 alignment = tempAlignment; 949 } 950 } 781 951 782 952 return alignment; … … 1187 1357 } 1188 1358 1189 if( objClass.HasSuperClass() ){1359 if( objClass.HasSuperClass() || objClass.GetDynamicMembers().size() ){ 1190 1360 sprintf( temporary 1191 1361 , "tempType=Search(\"%s\")" … … 1196 1366 ChangeOpcode( temporary ); 1197 1367 1198 sprintf( temporary 1199 , "tempType.SetBaseType(Search(\"%s\"))" 1200 , objClass.GetSuperClass().GetFullName().c_str() 1201 ); 1202 1203 // コンパイル 1204 ChangeOpcode( temporary ); 1205 1206 1207 // メンバの型を示すTypeInfoオブジェクトへのDataOffset配列の静的データ定義文字列を取得 1208 sprintf( 1209 temporary, 1210 "tempType.SetMembers([%s],[%s],%d)", 1211 objClass.GetStaticDefiningStringAsMemberNames().c_str(), 1212 objClass.GetStaticDefiningStringAsMemberTypeInfoNames().c_str(), 1213 objClass.GetDynamicMembers().size() 1214 ); 1215 ChangeOpcode( temporary ); 1368 if( objClass.HasSuperClass() ) 1369 { 1370 sprintf( temporary 1371 , "tempType.SetBaseType(Search(\"%s\"))" 1372 , objClass.GetSuperClass().GetFullName().c_str() 1373 ); 1374 1375 // コンパイル 1376 ChangeOpcode( temporary ); 1377 } 1378 1379 if( objClass.GetDynamicMembers().size() ) 1380 { 1381 // メンバの型を示すTypeInfoオブジェクトへのDataOffset配列の静的データ定義文字列を取得 1382 sprintf( 1383 temporary, 1384 "tempType.SetMembers([%s],[%s],%d)", 1385 objClass.GetStaticDefiningStringAsMemberNames().c_str(), 1386 objClass.GetStaticDefiningStringAsMemberTypeInfoNames().c_str(), 1387 objClass.GetDynamicMembers().size() 1388 ); 1389 ChangeOpcode( temporary ); 1390 } 1216 1391 } 1217 1392 }
Note:
See TracChangeset
for help on using the changeset viewer.