Ignore:
Timestamp:
Jul 12, 2007, 2:58:26 AM (17 years ago)
Author:
dai_9181
Message:

コード全体のリファクタリングを実施

File:
1 moved

Legend:

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

    r204 r206  
     1#include "stdafx.h"
     2
    13#include <jenga/include/smoothie/Smoothie.h>
    2 #include <jenga/include/smoothie/Class.h>
    34#include <jenga/include/smoothie/Source.h>
    45#include <jenga/include/smoothie/SmoothieException.h>
    56#include <jenga/include/smoothie/LexicalAnalysis.h>
    67
    7 #include <ClassImpl.h>
     8#include <Class.h>
    89#include <Compiler.h>
    910#include <NamespaceSupporter.h>
     
    1516#include "../../BasicCompiler32/opcode.h"
    1617#endif
    17 
    18 
    1918
    2019
     
    7776
    7877
    79 bool ClassImpl::IsEqualSymbol( const NamespaceScopes &namespaceScopes, const string &name ) const
    80 {
    81     if( GetName() != name ){
     78bool CClass::IsClass() const
     79{
     80    return classType == CClass::Class;
     81}
     82bool CClass::IsInterface() const
     83{
     84    return classType == CClass::Interface;
     85}
     86bool CClass::IsEnum() const
     87{
     88    return classType == CClass::Enum;
     89}
     90bool CClass::IsDelegate() const
     91{
     92    return classType == CClass::Delegate;
     93}
     94bool CClass::IsStructure() const
     95{
     96    return classType == CClass::Structure;
     97}
     98
     99
     100// コンストラクタのコンパイルを開始
     101void CClass::NotifyStartConstructorCompile() const
     102{
     103    isCompilingConstructor = true;
     104}
     105
     106//コンストラクタのコンパイルを終了
     107void CClass::NotifyFinishConstructorCompile() const
     108{
     109    isCompilingConstructor = false;
     110}
     111
     112//コンストラクタをコンパイル中かどうかを判別
     113bool CClass::IsCompilingConstructor() const
     114{
     115    return isCompilingConstructor;
     116}
     117
     118//デストラクタのコンパイルを開始
     119void CClass::NotifyStartDestructorCompile() const{
     120    isCompilingDestructor = true;
     121}
     122
     123//デストラクタのコンパイルを終了
     124void CClass::NotifyFinishDestructorCompile() const{
     125    isCompilingDestructor = false;
     126}
     127
     128//デストラクタをコンパイル中かどうかを判別
     129bool CClass::IsCompilingDestructor() const
     130{
     131    return isCompilingDestructor;
     132}
     133
     134//自身の派生クラスかどうかを確認
     135bool CClass::IsSubClass( const CClass *pClass ) const
     136{
     137    if( !pClass->HasSuperClass() )
     138    {
    82139        return false;
    83140    }
    84141
    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//自身と等しいまたは派生クラスかどうかを確認
     151bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
     152{
     153    if( IsEquals( pClass ) ) return true;
     154    return IsSubClass( pClass );
     155}
     156
     157// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
     158bool 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
     166bool 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
     176bool CClass::Inherits( const char *inheritNames, int nowLine ){
    89177    int i = 0;
    90178    bool isInheritsClass = false;
     
    183271    return true;
    184272}
    185 bool ClassImpl::InheritsClass( const CClass &inheritsClass, int nowLine ){
     273bool CClass::InheritsClass( const CClass &inheritsClass, int nowLine ){
    186274
    187275    //ループ継承でないかをチェック
     
    245333    return true;
    246334}
    247 bool ClassImpl::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
     335bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
    248336
    249337    //ループ継承でないかをチェック
     
    291379    return true;
    292380}
    293 CMember *ClassImpl::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
     381CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
    294382{
    295383    extern int cp;
     
    299387    char initBuffer[VN_SIZE];
    300388    char lpszConstructParameter[VN_SIZE];
    301     int SubScripts[MAX_ARRAYDIM];
     389    Subscripts subscripts;
    302390    Type type;
    303     GetDimentionFormat(buffer,VarName,SubScripts,type,initBuffer,lpszConstructParameter);
     391    GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
    304392
    305393    //重複チェック
     
    308396    }
    309397
    310     CMember *pMember = new CMember( accessibility, VarName, type, isConst, initBuffer, lpszConstructParameter );
     398    CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
    311399    pMember->source_code_address = nowLine;
    312     memcpy( pMember->SubScripts, SubScripts, MAX_ARRAYDIM * sizeof(int) );
    313400    return pMember;
    314401}
    315 void ClassImpl::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
     402void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
    316403    dynamicMembers.push_back(
    317404        CreateMember( accessibility, isConst, isRef, buffer, nowLine )
    318405    );
    319406}
    320 void ClassImpl::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
     407void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
    321408    staticMembers.push_back(
    322409        CreateMember( accessibility, isConst, isRef, buffer, nowLine )
     
    324411}
    325412
    326 void ClassImpl::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
     413void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
    327414                         bool isVirtual, bool isOverride, char *buffer, int nowLine){
    328415    int i,i2;
     
    340427
    341428    //関数ハッシュへ登録
    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) );
    344430    if(!pUserProc) return;
    345431
     
    394480        if( pMethod->GetInheritsClassPtr() ) continue;
    395481
    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() ) ){
    398484                //関数名、パラメータ属性が合致したとき
    399485                SetError(15,pUserProc->GetName().c_str(),nowLine);
     
    408494    //メソッドのオーバーライド
    409495    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() ) ){
    412498
    413499                if(pMethod->IsVirtual()){
    414500                    //メンバ関数を上書き
    415                     pMethod->pUserProc=pUserProc;
     501                    pMethod->SetUserProcPtr( pUserProc );
    416502                    pMethod->Override();
    417503
     
    446532}
    447533
    448 LONG_PTR ClassImpl::GetVtblGlobalOffset(void) const
     534bool 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}
     549bool 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//サイズを取得
     570int CClass::GetSize() const
     571{
     572    return GetMemberOffset( NULL, NULL );
     573}
     574
     575//メンバのオフセットを取得
     576int 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}
     647int 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}
     673int 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}
     682LONG_PTR CClass::GetVtblGlobalOffset(void) const
    449683{
    450684
     
    458692    //////////////////////////////////////
    459693
    460     UserProc **ppsi;
    461     ppsi=(UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
     694    const UserProc **ppsi;
     695    ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
    462696
    463697    //関数テーブルに値をセット
     
    465699    BOOST_FOREACH( const CMethod *pMethod, methods ){
    466700        if(pMethod->IsVirtual()){
    467             pMethod->pUserProc->Using();
     701            pMethod->GetUserProc().Using();
    468702
    469703            if(pMethod->IsAbstract()){
     
    474708            }
    475709            else{
    476                 ppsi[i2]=pMethod->pUserProc;
     710                ppsi[i2]=&pMethod->GetUserProc();
    477711            }
    478712            i2++;
     
    490724    return vtbl_offset;
    491725}
    492 void ClassImpl::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
     726void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
    493727    if(vtbl_offset==-1) return;
    494728
     
    501735        pUserProc=(UserProc *)pVtbl[i];
    502736        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}
     740bool 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
     756int 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
     767CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
     768    return new CClass(namespaceScopes, importedNamespaces, name);
     769}
     770bool 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}
     809CClass *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
     825void Classes::CollectClassesForNameOnly( const BasicSource &source )
    512826{
    513827    int i, i2;
     
    641955}
    642956
    643 void ClassesImpl::InitStaticMember(){
     957void 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
     974void Classes::InitStaticMember(){
    644975    //静的メンバをグローバル領域に作成
    645976
     
    662993            dim(
    663994                temporary,
    664                 member->SubScripts,
     995                member->GetSubscripts(),
    665996                member->GetType(),
    666997                member->GetInitializeExpression().c_str(),
     
    6791010    cp=back_cp;
    6801011}
    681 bool ClassesImpl::MemberVar_LoopRefCheck(const CClass &objClass){
     1012bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){
    6821013    bool result = true;
    6831014    BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
     
    7041035    return result;
    7051036}
    706 void ClassesImpl::GetClass_recur(const char *lpszInheritsClass){
     1037void Classes::GetClass_recur(const char *lpszInheritsClass){
    7071038    extern char *basbuf;
    7081039    int i,i2,i3,sub_address,top_pos;
     
    11561487    compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
    11571488}
    1158 void ClassesImpl::GetAllClassInfo(void){
     1489void Classes::GetAllClassInfo(void){
    11591490    //ループ継承チェック用のクラス
    11601491    pobj_LoopRefCheck=new CLoopRefCheck();
     
    11691500    this->Iterator_Init();
    11701501}
    1171 void ClassesImpl::Compile_System_InitializeUserTypes(){
     1502void Classes::Compile_System_InitializeUserTypes(){
    11721503    char temporary[VN_SIZE];
    11731504
     
    12961627}
    12971628
    1298 const CClass *ClassesImpl::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
     1629const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
    12991630{
    13001631    int key;
     
    13331664    return NULL;
    13341665}
     1666const 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}
     1674void 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
     1692CClass *Classes::GetStringClassPtr() const
     1693{
     1694    if( !pStringClass ){
     1695        SmoothieException::Throw();
     1696        return NULL;
     1697    }
     1698    return pStringClass;
     1699}
     1700CClass *Classes::GetObjectClassPtr() const
     1701{
     1702    if( !pObjectClass ){
     1703        SmoothieException::Throw();
     1704        return NULL;
     1705    }
     1706    return pObjectClass;
     1707}
     1708
     1709
     1710//////////////////////
     1711// イテレータ
     1712//////////////////////
     1713
     1714void 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}
     1738void Classes::Iterator_Reset() const
     1739{
     1740    iIteNextNum = 0;
     1741}
     1742BOOL Classes::Iterator_HasNext() const
     1743{
     1744    if(iIteNextNum<iIteMaxNum) return 1;
     1745    return 0;
     1746}
     1747CClass *Classes::Iterator_GetNext() const
     1748{
     1749    CClass *pobj_c = ppobj_IteClass[iIteNextNum];
     1750    iIteNextNum++;
     1751    return pobj_c;
     1752}
     1753int Classes::Iterator_GetMaxCount() const
     1754{
     1755    return iIteMaxNum;
     1756}
Note: See TracChangeset for help on using the changeset viewer.