Ignore:
Timestamp:
Mar 3, 2008, 6:33:29 PM (16 years ago)
Author:
dai_9181
Message:

クラス継承を行う際、dynamicMembersの中身をコピーする方式をやめ、基底クラスのものを参照するように修正した。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler_Common/src/Class.cpp

    r407 r409  
    246246        //継承先が読み取られていないとき
    247247        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 );
    269248    }
    270249
     
    592571}
    593572
    594 bool CClass::DupliCheckAll(const char *name){
     573bool CClass::DupliCheckAll(const char *name) const
     574{
    595575    //重複チェック
    596576
     
    607587    return 0;
    608588}
    609 bool CClass::DupliCheckMember(const char *name){
     589bool CClass::DupliCheckMember(const char *name) const
     590{
    610591    //重複チェック
    611592
     593    if( this->HasSuperClass() )
     594    {
     595        if( this->GetSuperClass().DupliCheckMember( name ) )
     596        {
     597            // 基底クラスで重複が発見された
     598            return true;
     599        }
     600    }
     601
    612602    // 動的メンバ
    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;
    616608        }
    617609    }
     
    620612    BOOST_FOREACH( CMember *pMember, staticMembers ){
    621613        if( GetName() == pMember->GetName() ){
    622             return 1;
    623         }
    624     }
    625 
    626     return 0;
     614            return true;
     615        }
     616    }
     617
     618    return false;
     619}
     620
     621const 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;
    627641}
    628642
     
    679693int CClass::GetSize() const
    680694{
    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;
    682790}
    683791
    684792//メンバのオフセットを取得
    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;
     793int CClass::GetMemberOffset( const char *memberName ) const
     794{
     795    int resultSize = 0;
    691796
    692797    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                //メンバを持たない構造体
    726872                //※何もしない(オフセットの計算をしない)
    727873            }
    728874            else{
    729                 if(offset%member_size) offset+=member_size-(offset%member_size);
     875                if( resultSize % tempAlignment )
     876                {
     877                    resultSize += tempAlignment - ( resultSize % tempAlignment );
     878                }
    730879            }
    731880        }
     
    733882        if(memberName){
    734883            //メンバ指定がある場合は、オフセットを返す
    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;
    757904}
    758905int CClass::GetAlignment() const
    759906{
    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    }
    781951
    782952    return alignment;
     
    11871357        }
    11881358
    1189         if( objClass.HasSuperClass() ){
     1359        if( objClass.HasSuperClass() || objClass.GetDynamicMembers().size() ){
    11901360            sprintf( temporary
    11911361                , "tempType=Search(\"%s\")"
     
    11961366            ChangeOpcode( temporary );
    11971367
    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            }
    12161391        }
    12171392    }
Note: See TracChangeset for help on using the changeset viewer.