Changes in / [ca8704f:a83044fb]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    rca8704f ra83044fb  
    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
     
    729744
    730745        const ast::Type * visit( const ast::VoidType * node ) override final {
    731                 (void)node;
     746                this->node = new VoidType{ cv( node ) };
    732747                return nullptr;
    733748        }
    734749
    735750        const ast::Type * visit( const ast::BasicType * node ) override final {
    736                 (void)node;
     751                this->node = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind };
    737752                return nullptr;
    738753        }
    739754
    740755        const ast::Type * visit( const ast::PointerType * node ) override final {
    741                 (void)node;
     756                this->node = new PointerType{
     757                        cv( node ),
     758                        get<Type>().accept1( node->base ),
     759                        get<Expression>().accept1( node->dimension ),
     760                        node->isVarLen,
     761                        node->isStatic
     762                };
    742763                return nullptr;
    743764        }
    744765
    745766        const ast::Type * visit( const ast::ArrayType * node ) override final {
    746                 (void)node;
     767                this->node = new ArrayType{
     768                        cv( node ),
     769                        get<Type>().accept1( node->base ),
     770                        get<Expression>().accept1( node->dimension ),
     771                        node->isVarLen,
     772                        node->isStatic
     773                };
    747774                return nullptr;
    748775        }
    749776
    750777        const ast::Type * visit( const ast::ReferenceType * node ) override final {
    751                 (void)node;
     778                this->node = new ReferenceType{
     779                        cv( node ),
     780                        get<Type>().accept1( node->base )
     781                };
    752782                return nullptr;
    753783        }
    754784
    755785        const ast::Type * visit( const ast::QualifiedType * node ) override final {
    756                 (void)node;
     786                this->node = new QualifiedType{
     787                        cv( node ),
     788                        get<Type>().accept1( node->parent ),
     789                        get<Type>().accept1( node->child )
     790                };
    757791                return nullptr;
    758792        }
    759793
    760794        const ast::Type * visit( const ast::FunctionType * node ) override final {
    761                 (void)node;
     795                auto ty = new FunctionType { cv( node ), node->isVarArgs };
     796                ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
     797                ty->parameters = get<DeclarationWithType>().acceptL( node->params );
     798                ty->forall = get<TypeDecl>().acceptL( node->forall );
     799                node = ty;
    762800                return nullptr;
    763801        }
     
    867905        }
    868906private:
     907        /// conversion output
    869908        ast::Node * node;
     909        /// cache of nodes that might be referenced by readonly<> for de-duplication
     910        std::unordered_map< BaseSyntaxNode *, ast::Node * > cache;
    870911
    871912        // Local Utilities:
     
    873914        template<typename NewT, typename OldT>
    874915        NewT * getAccept1( OldT old ) {
     916                if ( ! old ) return nullptr;
    875917                old->accept(*this);
    876918                return strict_dynamic_cast< NewT * >( node );
     
    913955#       define GET_LABELS_V(labels) \
    914956                to<std::vector>::from( make_labels( std::move( labels ) ) )
     957       
     958        static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
     959
     960        template<typename NewT, typename OldT>
     961        NewT * cached( OldT * old ) {
     962                auto it = cache.find( old );
     963                // doesn't update cache, that should be handled by the accept function
     964                ast::Node * nw = it == cache.end() ? getAccept1< NewT >( old ) : it->second;
     965                return strict_dynamic_cast< NewT * >( nw );
     966        }
    915967
    916968        // Now all the visit functions:
     
    15261578        }
    15271579
    1528         virtual void visit( VoidType * ) override final {
    1529 
    1530         }
    1531 
    1532         virtual void visit( BasicType * ) override final {
    1533 
    1534         }
    1535 
    1536         virtual void visit( PointerType * ) override final {
    1537 
    1538         }
    1539 
    1540         virtual void visit( ArrayType * ) override final {
    1541 
    1542         }
    1543 
    1544         virtual void visit( ReferenceType * ) override final {
    1545 
    1546         }
    1547 
    1548         virtual void visit( QualifiedType * ) override final {
    1549 
    1550         }
    1551 
    1552         virtual void visit( FunctionType * ) override final {
    1553 
    1554         }
    1555 
    1556         virtual void visit( StructInstType * ) override final {
    1557 
    1558         }
    1559 
    1560         virtual void visit( UnionInstType * ) override final {
    1561 
    1562         }
    1563 
    1564         virtual void visit( EnumInstType * ) override final {
    1565 
    1566         }
    1567 
    1568         virtual void visit( TraitInstType * ) override final {
    1569 
    1570         }
    1571 
    1572         virtual void visit( TypeInstType * ) override final {
    1573 
     1580        virtual void visit( VoidType * old ) override final {
     1581                this->node = new ast::VoidType{ cv( old ) };
     1582        }
     1583
     1584        virtual void visit( BasicType * old ) override final {
     1585                this->node = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
     1586        }
     1587
     1588        virtual void visit( PointerType * old ) override final {
     1589                this->node = new ast::PointerType{
     1590                        GET_ACCEPT_1( base, Type ),
     1591                        GET_ACCEPT_1( dimension, Expr ),
     1592                        (ast::LengthFlag)old->isVarLen,
     1593                        (ast::DimensionFlag)old->isStatic,
     1594                        cv( old )
     1595                };
     1596        }
     1597
     1598        virtual void visit( ArrayType * old ) override final {
     1599                this->node = new ast::ArrayType{
     1600                        GET_ACCEPT_1( base, Type ),
     1601                        GET_ACCEPT_1( dimension, Expr ),
     1602                        (ast::LengthFlag)old->isVarLen,
     1603                        (ast::DimensionFlag)old->isStatic,
     1604                        cv( old )
     1605                };
     1606        }
     1607
     1608        virtual void visit( ReferenceType * old ) override final {
     1609                this->node = new ast::ReferenceType{
     1610                        GET_ACCEPT_1( base, Type ),
     1611                        cv( old )
     1612                };
     1613        }
     1614
     1615        virtual void visit( QualifiedType * old ) override final {
     1616                this->node = new ast::QualifiedType{
     1617                        GET_ACCEPT_1( parent, Type ),
     1618                        GET_ACCEPT_1( child, Type ),
     1619                        cv( old )
     1620                };
     1621        }
     1622
     1623        virtual void visit( FunctionType * old ) override final {
     1624                auto ty = new ast::FunctionType {
     1625                        (ast::ArgumentFlag)old->isVarArgs,
     1626                        cv( old )
     1627                };
     1628                ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
     1629                ty->params = GET_ACCEPT_V( parameters, DeclWithType );
     1630                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
     1631                this->node = ty;
     1632        }
     1633
     1634        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
     1635                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
     1636                ty->params = GET_ACCEPT_V( parameters, Expr );
     1637                ty->hoistType = old->hoistType;
     1638        }
     1639
     1640        virtual void visit( StructInstType * old ) override final {
     1641                auto ty = new ast::StructInstType{
     1642                        cached< ast::StructDecl >( old->baseStruct ),
     1643                        cv( old ),
     1644                        GET_ACCEPT_V( attributes, Attribute )
     1645                };
     1646                postvisit( old, ty );
     1647                this->node = ty;
     1648        }
     1649
     1650        virtual void visit( UnionInstType * old ) override final {
     1651                auto ty = new ast::UnionInstType{
     1652                        cached< ast::UnionDecl >( old->baseUnion ),
     1653                        cv( old ),
     1654                        GET_ACCEPT_V( attributes, Attribute )
     1655                };
     1656                postvisit( old, ty );
     1657                this->node = ty;
     1658        }
     1659
     1660        virtual void visit( EnumInstType * old ) override final {
     1661                auto ty = new ast::EnumInstType{
     1662                        cached< ast::EnumDecl >( old->baseEnum ),
     1663                        cv( old ),
     1664                        GET_ACCEPT_V( attributes, Attribute )
     1665                };
     1666                postvisit( old, ty );
     1667                this->node = ty;
     1668        }
     1669
     1670        virtual void visit( TraitInstType * old ) override final {
     1671                auto ty = new ast::TraitInstType{
     1672                        cached< ast::TraitDecl >( old->baseTrait ),
     1673                        cv( old ),
     1674                        GET_ACCEPT_V( attributes, Attribute )
     1675                };
     1676                postvisit( old, ty );
     1677                this->node = ty;
     1678        }
     1679
     1680        virtual void visit( TypeInstType * old ) override final {
     1681                auto ty = new ast::TypeInstType{
     1682                        cached< ast::TypeDecl >( old->baseStruct ),
     1683                        cv( old ),
     1684                        GET_ACCEPT_V( attributes, Attribute )
     1685                };
     1686                postvisit( old, ty );
     1687                this->node = ty;
    15741688        }
    15751689
Note: See TracChangeset for help on using the changeset viewer.