Ignore:
Timestamp:
Jun 5, 2008, 10:04:39 PM (16 years ago)
Author:
dai_9181
Message:

ジェネリッククラスの型パラメータに値型が指定されたときに限り、テンプレート展開を行うようにした。

TODO: libファイルを跨ってテンプレート展開ができていないため、ソースコード管理部分に手を加える必要あり。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Class.cpp

    r603 r632  
    287287    Subscripts subscripts;
    288288    Type type;
    289     GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
     289    if( !GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter) )
     290    {
     291        return NULL;
     292    }
    290293
    291294    //重複チェック
     
    12171220                extern int cp;
    12181221                if(i3==0){
    1219                     if(bStatic){
    1220                         //静的メンバを追加
    1221                         cp=i;   //エラー用
    1222                         pobj_c->AddStaticMember(
    1223                             LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i )
    1224                         );
    1225                     }
    1226                     else{
    1227                         //メンバを追加
    1228                         cp=i;   //エラー用
    1229                         pobj_c->AddDynamicMember(
    1230                             LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i )
    1231                         );
    1232 
    1233 
    1234                         if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
    1235                             if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
    1236                                 //参照先が読み取られていないとき
    1237                                 GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
     1222                    cp=i;   //エラー用
     1223                    Member *pMember = LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i );
     1224                    if( pMember )
     1225                    {
     1226                        if(bStatic)
     1227                        {
     1228                            //静的メンバを追加
     1229                            pobj_c->AddStaticMember( pMember );
     1230                        }
     1231                        else
     1232                        {
     1233                            //メンバを追加
     1234                            pobj_c->AddDynamicMember( pMember );
     1235
     1236
     1237                            if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
     1238                                if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
     1239                                    //参照先が読み取られていないとき
     1240                                    GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
     1241                                }
    12381242                            }
    1239                         }
    1240 
    1241 
    1242                         if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
    1243                             //循環参照のチェック
    1244                             pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
    1245                             if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
    1246                                 //エラー回避
    1247                                 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
    1248                                 type.SetBasicType( DEF_PTR_VOID );
     1243
     1244
     1245                            if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
     1246                                //循環参照のチェック
     1247                                pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
     1248                                if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
     1249                                    //エラー回避
     1250                                    Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
     1251                                    type.SetBasicType( DEF_PTR_VOID );
     1252                                }
     1253                                pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
    12491254                            }
    1250                             pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
    12511255                        }
    12521256                    }
     
    13551359    classes.Iterator_Init();
    13561360}
     1361
     1362void LexicalAnalyzer::TemplateExpand_ResolveMethod( const CMethod *pBaseMethod, const Types &actualTypes, CClass *pNewClass )
     1363{
     1364    UserProc *pUserProc = new UserProc(
     1365        pBaseMethod->GetUserProc(),
     1366        pNewClass
     1367    );
     1368    pUserProc->Using();
     1369    pUserProc->GetParameters().clear();
     1370    pUserProc->RealParams().clear();
     1371
     1372    // パラメータのジェネリック型を解決
     1373    BOOST_FOREACH( const Parameter *pParam, pBaseMethod->GetUserProc().Params() )
     1374    {
     1375        Type type = pParam->IsTypeParameter()
     1376            ? actualTypes[pParam->GetFormalTypeIndex()]
     1377            : *pParam;
     1378        type.SetPtrLevel( pParam->PtrLevel() );
     1379
     1380        pUserProc->GetParameters().push_back( new Parameter( *pParam, type ) );
     1381    }
     1382    BOOST_FOREACH( const Parameter *pParam, pBaseMethod->GetUserProc().RealParams() )
     1383    {
     1384        Type type = pParam->IsTypeParameter()
     1385            ? actualTypes[pParam->GetFormalTypeIndex()]
     1386            : *pParam;
     1387        type.SetPtrLevel( pParam->PtrLevel() );
     1388
     1389        pUserProc->RealParams().push_back( new Parameter( *pParam, type ) );
     1390    }
     1391
     1392    // 戻り値のジェネリック型を解決
     1393    if( pUserProc->ReturnType().IsTypeParameter() )
     1394    {
     1395        Type type = actualTypes[pUserProc->ReturnType().GetFormalTypeIndex()];
     1396        type.SetPtrLevel( pUserProc->ReturnType().PtrLevel() );
     1397        pUserProc->SetReturnType( type );
     1398    }
     1399
     1400    compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
     1401    compiler.GetObjectModule().meta.GetUserProcs().Iterator_Init();
     1402
     1403    LexicalAnalyzer::AddMethod(
     1404        pNewClass,
     1405        pUserProc,
     1406        pBaseMethod->GetAccessibility(),
     1407        pBaseMethod->IsStatic(),
     1408        pBaseMethod->IsConst(),
     1409        pBaseMethod->IsAbstract(),
     1410        pBaseMethod->IsVirtual(),
     1411        false,
     1412        "",
     1413        false,
     1414        -1
     1415    );
     1416}
     1417
     1418const CClass *LexicalAnalyzer::TemplateExpand( CClass &_class, const Types &actualTypes )
     1419{
     1420    // 展開済みのクラスがあればそれを返す
     1421    BOOST_FOREACH( const ExpandedTemplateClass *pExpandedTemplateClass, _class.expandedTemplateClasses )
     1422    {
     1423        if( pExpandedTemplateClass->GetActualTypes().IsEquals( actualTypes ) )
     1424        {
     1425            return &pExpandedTemplateClass->GetClass();
     1426        }
     1427    }
     1428
     1429
     1430    /////////////////////////////////////////////////////////////////
     1431    // 未展開の場合は新たに展開する
     1432    /////////////////////////////////////////////////////////////////
     1433
     1434    // クラスをコピー
     1435    CClass *pNewClass = new CClass(
     1436        _class.GetNamespaceScopes(),
     1437        _class.GetImportedNamespaces(),
     1438        _class.GetName(),
     1439        _class.GetClassType(),
     1440        _class.GetFormalGenericTypes(),
     1441        actualTypes,
     1442        _class.GetConstructorMemberSubIndex(),
     1443        _class.GetDestructorMemberSubIndex(),
     1444        0,
     1445        _class.GetFixedAlignment()
     1446    );
     1447
     1448    // 基底クラス
     1449    pNewClass->SetSuperClass( &_class.GetSuperClass() );
     1450
     1451    // インターフェイスのジェネリック型を解決
     1452    BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() )
     1453    {
     1454        pNewClass->AddInterface( new ::Interface( &pInterface->GetClass(), actualTypes ) );
     1455    }
     1456
     1457    // メンバのジェネリック型を解決
     1458    BOOST_FOREACH( const Member *pMember, _class.GetDynamicMembers() )
     1459    {
     1460        Type type = pMember->GetType();
     1461        if( type.IsTypeParameter() )
     1462        {
     1463            // ジェネリック型だったときは値型に変換
     1464            type = actualTypes[type.GetFormalTypeIndex()];
     1465            type.SetPtrLevel( pMember->GetType().PtrLevel() );
     1466        }
     1467
     1468        pNewClass->GetDynamicMembers().push_back(
     1469            new Member( *pMember, type )
     1470        );
     1471    }
     1472
     1473    // クラス メソッドのジェネリック型を解決
     1474    BOOST_FOREACH( const CMethod *pMethod, _class.GetDynamicMethods() )
     1475    {
     1476        if( pMethod->GetUserProc().GetParentClassPtr() == &_class )
     1477        {
     1478            // ターゲットクラス内で実装されるメソッドの場合
     1479
     1480            TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
     1481        }
     1482        else
     1483        {
     1484            DynamicMethod *pNewDynamicMethod = new DynamicMethod( *pMethod );
     1485            pNewClass->GetDynamicMethods().push_back( pNewDynamicMethod );
     1486        }
     1487    }
     1488
     1489    // インターフェイス メソッドのジェネリック型を解決
     1490    BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() )
     1491    {
     1492        BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() )
     1493        {
     1494            TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
     1495        }
     1496    }
     1497
     1498    pNewClass->SetVtblNum( _class.GetVtblNum() );
     1499
     1500    // 展開済みクラスとして登録
     1501    _class.expandedTemplateClasses.push_back( new ExpandedTemplateClass( pNewClass, actualTypes ) );
     1502
     1503    pNewClass->Readed();
     1504
     1505    return pNewClass;
     1506}
Note: See TracChangeset for help on using the changeset viewer.