Ignore:
Timestamp:
May 21, 2019, 4:08:38 PM (6 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
a83044fb
Parents:
292642a
Message:

Start on Type conversions, add caching

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r292642a rd148778  
    1616#include "Convert.hpp"
    1717
     18#include <unordered_map>
     19
    1820#include "AST/Attribute.hpp"
    1921#include "AST/Decl.hpp"
     
    4244class ConverterNewToOld : public ast::Visitor {
    4345        BaseSyntaxNode * node = nullptr;
     46        std::unordered_map< ast::Node *, BaseSyntaxNode * > cache;
    4447
    4548        template<typename T>
     
    4952                template<typename U>
    5053                T * accept1( const ast::ptr<U> & ptr ) {
     54                        if ( ! ptr ) return nullptr;
    5155                        ptr->accept( visitor );
    5256                        T * ret = strict_dynamic_cast< T * >( visitor.node );
     
    8589                }
    8690                return ret;
     91        }
     92
     93        /// get new qualifiers from old type
     94        Type::Qualifiers cv( const ast::Type * ty ) { return { ty->qualifiers.val }; }
     95
     96        template<typename NewT, typename OldT>
     97        NewT * cached( OldT * old ) {
     98                auto it = cache.find( old );
     99                // doesn't update cache, that should be handled by the accept function
     100                ast::Node * nw = it == cache.end() ? getAccept1< NewT >( old ) : it->second;
     101                return strict_dynamic_cast< NewT * >( nw );
    87102        }
    88103
     
    598613
    599614        const ast::Type * visit( const ast::VoidType * node ) override final {
    600                 (void)node;
     615                this->node = new VoidType{ cv( node ) };
    601616                return nullptr;
    602617        }
    603618
    604619        const ast::Type * visit( const ast::BasicType * node ) override final {
    605                 (void)node;
     620                this->node = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind };
    606621                return nullptr;
    607622        }
    608623
    609624        const ast::Type * visit( const ast::PointerType * node ) override final {
    610                 (void)node;
     625                this->node = new PointerType{
     626                        cv( node ),
     627                        get<Type>().accept1( node->base ),
     628                        get<Expression>().accept1( node->dimension ),
     629                        node->isVarLen,
     630                        node->isStatic
     631                };
    611632                return nullptr;
    612633        }
    613634
    614635        const ast::Type * visit( const ast::ArrayType * node ) override final {
    615                 (void)node;
     636                this->node = new ArrayType{
     637                        cv( node ),
     638                        get<Type>().accept1( node->base ),
     639                        get<Expression>().accept1( node->dimension ),
     640                        node->isVarLen,
     641                        node->isStatic
     642                };
    616643                return nullptr;
    617644        }
    618645
    619646        const ast::Type * visit( const ast::ReferenceType * node ) override final {
    620                 (void)node;
     647                this->node = new ReferenceType{
     648                        cv( node ),
     649                        get<Type>().accept1( node->base )
     650                };
    621651                return nullptr;
    622652        }
    623653
    624654        const ast::Type * visit( const ast::QualifiedType * node ) override final {
    625                 (void)node;
     655                this->node = new QualifiedType{
     656                        cv( node ),
     657                        get<Type>().accept1( node->parent ),
     658                        get<Type>().accept1( node->child )
     659                };
    626660                return nullptr;
    627661        }
    628662
    629663        const ast::Type * visit( const ast::FunctionType * node ) override final {
    630                 (void)node;
     664                auto ty = new FunctionType { cv( node ), node->isVarArgs };
     665                ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
     666                ty->parameters = get<DeclarationWithType>().acceptL( node->params );
     667                ty->forall = get<TypeDecl>().acceptL( node->forall );
     668                node = ty;
    631669                return nullptr;
    632670        }
     
    736774        }
    737775private:
     776        /// conversion output
    738777        ast::Node * node;
     778        /// cache of nodes that might be referenced by readonly<> for de-duplication
     779        std::unordered_map< BaseSyntaxNode *, ast::Node * > cache;
    739780
    740781        // Local Utilities:
     
    742783        template<typename NewT, typename OldT>
    743784        NewT * getAccept1( OldT old ) {
     785                if ( ! old ) return nullptr;
    744786                old->accept(*this);
    745787                return strict_dynamic_cast< NewT * >( node );
     
    782824#       define GET_LABELS_V(labels) \
    783825                to<std::vector>::from( make_labels( std::move( labels ) ) )
     826       
     827        static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
     828
     829        template<typename NewT, typename OldT>
     830        NewT * cached( OldT * old ) {
     831                auto it = cache.find( old );
     832                // doesn't update cache, that should be handled by the accept function
     833                ast::Node * nw = it == cache.end() ? getAccept1< NewT >( old ) : it->second;
     834                return strict_dynamic_cast< NewT * >( nw );
     835        }
    784836
    785837        // Now all the visit functions:
     
    13591411        }
    13601412
    1361         virtual void visit( VoidType * ) override final {
    1362 
    1363         }
    1364 
    1365         virtual void visit( BasicType * ) override final {
    1366 
    1367         }
    1368 
    1369         virtual void visit( PointerType * ) override final {
    1370 
    1371         }
    1372 
    1373         virtual void visit( ArrayType * ) override final {
    1374 
    1375         }
    1376 
    1377         virtual void visit( ReferenceType * ) override final {
    1378 
    1379         }
    1380 
    1381         virtual void visit( QualifiedType * ) override final {
    1382 
    1383         }
    1384 
    1385         virtual void visit( FunctionType * ) override final {
    1386 
    1387         }
    1388 
    1389         virtual void visit( StructInstType * ) override final {
    1390 
    1391         }
    1392 
    1393         virtual void visit( UnionInstType * ) override final {
    1394 
    1395         }
    1396 
    1397         virtual void visit( EnumInstType * ) override final {
    1398 
    1399         }
    1400 
    1401         virtual void visit( TraitInstType * ) override final {
    1402 
    1403         }
    1404 
    1405         virtual void visit( TypeInstType * ) override final {
    1406 
     1413        virtual void visit( VoidType * old ) override final {
     1414                this->node = new ast::VoidType{ cv( old ) };
     1415        }
     1416
     1417        virtual void visit( BasicType * old ) override final {
     1418                this->node = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
     1419        }
     1420
     1421        virtual void visit( PointerType * old ) override final {
     1422                this->node = new ast::PointerType{
     1423                        GET_ACCEPT_1( base, Type ),
     1424                        GET_ACCEPT_1( dimension, Expr ),
     1425                        (ast::LengthFlag)old->isVarLen,
     1426                        (ast::DimensionFlag)old->isStatic,
     1427                        cv( old )
     1428                };
     1429        }
     1430
     1431        virtual void visit( ArrayType * old ) override final {
     1432                this->node = new ast::ArrayType{
     1433                        GET_ACCEPT_1( base, Type ),
     1434                        GET_ACCEPT_1( dimension, Expr ),
     1435                        (ast::LengthFlag)old->isVarLen,
     1436                        (ast::DimensionFlag)old->isStatic,
     1437                        cv( old )
     1438                };
     1439        }
     1440
     1441        virtual void visit( ReferenceType * old ) override final {
     1442                this->node = new ast::ReferenceType{
     1443                        GET_ACCEPT_1( base, Type ),
     1444                        cv( old )
     1445                };
     1446        }
     1447
     1448        virtual void visit( QualifiedType * old ) override final {
     1449                this->node = new ast::QualifiedType{
     1450                        GET_ACCEPT_1( parent, Type ),
     1451                        GET_ACCEPT_1( child, Type ),
     1452                        cv( old )
     1453                };
     1454        }
     1455
     1456        virtual void visit( FunctionType * old ) override final {
     1457                auto ty = new ast::FunctionType {
     1458                        (ast::ArgumentFlag)old->isVarArgs,
     1459                        cv( old )
     1460                };
     1461                ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
     1462                ty->params = GET_ACCEPT_V( parameters, DeclWithType );
     1463                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
     1464                this->node = ty;
     1465        }
     1466
     1467        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
     1468                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
     1469                ty->params = GET_ACCEPT_V( parameters, Expr );
     1470                ty->hoistType = old->hoistType;
     1471        }
     1472
     1473        virtual void visit( StructInstType * old ) override final {
     1474                auto ty = new ast::StructInstType{
     1475                        cached< ast::StructDecl >( old->baseStruct ),
     1476                        cv( old ),
     1477                        GET_ACCEPT_V( attributes, Attribute )
     1478                };
     1479                postvisit( old, ty );
     1480                this->node = ty;
     1481        }
     1482
     1483        virtual void visit( UnionInstType * old ) override final {
     1484                auto ty = new ast::UnionInstType{
     1485                        cached< ast::UnionDecl >( old->baseUnion ),
     1486                        cv( old ),
     1487                        GET_ACCEPT_V( attributes, Attribute )
     1488                };
     1489                postvisit( old, ty );
     1490                this->node = ty;
     1491        }
     1492
     1493        virtual void visit( EnumInstType * old ) override final {
     1494                auto ty = new ast::EnumInstType{
     1495                        cached< ast::EnumDecl >( old->baseEnum ),
     1496                        cv( old ),
     1497                        GET_ACCEPT_V( attributes, Attribute )
     1498                };
     1499                postvisit( old, ty );
     1500                this->node = ty;
     1501        }
     1502
     1503        virtual void visit( TraitInstType * old ) override final {
     1504                auto ty = new ast::TraitInstType{
     1505                        cached< ast::TraitDecl >( old->baseTrait ),
     1506                        cv( old ),
     1507                        GET_ACCEPT_V( attributes, Attribute )
     1508                };
     1509                postvisit( old, ty );
     1510                this->node = ty;
     1511        }
     1512
     1513        virtual void visit( TypeInstType * old ) override final {
     1514                auto ty = new ast::TypeInstType{
     1515                        cached< ast::TypeDecl >( old->baseStruct ),
     1516                        cv( old ),
     1517                        GET_ACCEPT_V( attributes, Attribute )
     1518                };
     1519                postvisit( old, ty );
     1520                this->node = ty;
    14071521        }
    14081522
Note: See TracChangeset for help on using the changeset viewer.