Changes in / [96ac72c0:83b52f1]


Ignore:
Files:
1 added
6 deleted
35 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Attribute.hpp

    r96ac72c0 r83b52f1  
    5151        template<typename node_t>
    5252        friend node_t * mutate(const node_t * node);
    53         template<typename node_t>
    54     friend node_t * shallowCopy(const node_t * node);
    5553};
    5654
  • src/AST/Convert.cpp

    r96ac72c0 r83b52f1  
    608608
    609609                tgt->result = get<Type>().accept1(src->result);
    610                 // Unconditionally use a clone of the result type.
    611                 // We know this will leak some objects: much of the immediate conversion result.
    612                 // In some cases, using the conversion result directly gives unintended object sharing.
    613                 // A parameter (ObjectDecl, a child of a FunctionType) is shared by the weak-ref cache.
    614                 // But tgt->result must be fully owned privately by tgt.
    615                 // Applying these conservative copies here means
    616                 // - weak references point at the declaration's copy, not these expr.result copies (good)
    617                 // - we copy more objects than really needed (bad, tolerated)
    618                 if (tgt->result) {
    619                         tgt->result = tgt->result->clone();
    620                 }
    621610                return visitBaseExpr_skipResultType(src, tgt);
    622611        }
  • src/AST/Decl.cpp

    r96ac72c0 r83b52f1  
    5252
    5353const Type * FunctionDecl::get_type() const { return type.get(); }
    54 void FunctionDecl::set_type( const Type * t ) {
    55         type = strict_dynamic_cast< const FunctionType * >( t );
    56 }
     54void FunctionDecl::set_type(Type * t) { type = strict_dynamic_cast< FunctionType* >( t ); }
    5755
    5856// --- TypeDecl
  • src/AST/Decl.hpp

    r96ac72c0 r83b52f1  
    3232
    3333// Must be included in *all* AST classes; should be #undef'd at the end of the file
    34 #define MUTATE_FRIEND \
    35     template<typename node_t> friend node_t * mutate(const node_t * node); \
    36         template<typename node_t> friend node_t * shallowCopy(const node_t * node);
     34#define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
    3735
    3836namespace ast {
     
    8987        virtual const Type * get_type() const = 0;
    9088        /// Set type of this declaration. May be verified by subclass
    91         virtual void set_type( const Type * ) = 0;
     89        virtual void set_type(Type *) = 0;
    9290
    9391        const DeclWithType * accept( Visitor & v ) const override = 0;
     
    112110
    113111        const Type* get_type() const override { return type; }
    114         void set_type( const Type * ty ) override { type = ty; }
     112        void set_type( Type * ty ) override { type = ty; }
    115113
    116114        const DeclWithType * accept( Visitor& v ) const override { return v.visit( this ); }
     
    134132
    135133        const Type * get_type() const override;
    136         void set_type( const Type * t ) override;
     134        void set_type(Type * t) override;
    137135
    138136        bool has_body() const { return stmts; }
     
    151149        std::vector<ptr<DeclWithType>> assertions;
    152150
    153         NamedTypeDecl(
    154                 const CodeLocation & loc, const std::string & name, Storage::Classes storage,
    155                 const Type * b, Linkage::Spec spec = Linkage::Cforall )
     151        NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
     152                Type* b, Linkage::Spec spec = Linkage::Cforall )
    156153        : Decl( loc, name, storage, spec ), base( b ), params(), assertions() {}
    157154
     
    188185        };
    189186
    190         TypeDecl(
    191                 const CodeLocation & loc, const std::string & name, Storage::Classes storage,
    192                 const Type * b, TypeVar::Kind k, bool s, const Type * i = nullptr )
     187        TypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, Type* b,
     188                TypeVar::Kind k, bool s, Type* i = nullptr )
    193189        : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == TypeVar::Ttype || s ),
    194190          init( i ) {}
  • src/AST/Expr.cpp

    r96ac72c0 r83b52f1  
    2020#include <vector>
    2121
    22 #include "Eval.hpp"                // for call
    2322#include "GenericSubstitution.hpp"
    2423#include "Stmt.hpp"
     
    5251        assert( arg );
    5352
    54         UntypedExpr * ret = call( loc, "*?", arg );
     53        UntypedExpr * ret = new UntypedExpr{
     54                loc, new NameExpr{loc, "*?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ arg } }
     55        };
    5556        if ( const Type * ty = arg->result ) {
    5657                const Type * base = InitTweak::getPointerBase( ty );
     
    7374        assert( lhs && rhs );
    7475
    75         UntypedExpr * ret = call( loc, "?=?", lhs, rhs );
     76        UntypedExpr * ret = new UntypedExpr{
     77                loc, new NameExpr{loc, "?=?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ lhs }, ptr<Expr>{ rhs } }
     78        };
    7679        if ( lhs->result && rhs->result ) {
    7780                // if both expressions are typed, assumes that this assignment is a C bitwise assignment,
  • src/AST/Expr.hpp

    r96ac72c0 r83b52f1  
    3030
    3131// Must be included in *all* AST classes; should be #undef'd at the end of the file
    32 #define MUTATE_FRIEND \
    33     template<typename node_t> friend node_t * mutate(const node_t * node); \
    34         template<typename node_t> friend node_t * shallowCopy(const node_t * node);
    35 
     32#define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
    3633
    3734class ConverterOldToNew;
  • src/AST/Init.hpp

    r96ac72c0 r83b52f1  
    2525
    2626// Must be included in *all* AST classes; should be #undef'd at the end of the file
    27 #define MUTATE_FRIEND \
    28     template<typename node_t> friend node_t * mutate(const node_t * node); \
    29         template<typename node_t> friend node_t * shallowCopy(const node_t * node);
     27#define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
    3028
    3129namespace ast {
  • src/AST/Node.cpp

    r96ac72c0 r83b52f1  
    1717#include "Fwd.hpp"
    1818
    19 #include <csignal>  // MEMORY DEBUG -- for raise
    2019#include <iostream>
    2120
     
    3029#include "Print.hpp"
    3130
    32 /// MEMORY DEBUG -- allows breaking on ref-count changes of dynamically chosen object.
    33 /// Process to use in GDB:
    34 ///   break ast::Node::_trap()
    35 ///   run
    36 ///   set variable MEM_TRAP_OBJ = <target>
    37 ///   disable <first breakpoint>
    38 ///   continue
    39 void * MEM_TRAP_OBJ = nullptr;
    40 
    41 void _trap( const void * node ) {
    42         if ( node == MEM_TRAP_OBJ ) std::raise(SIGTRAP);
    43 }
    44 
    45 template< typename node_t, enum ast::Node::ref_type ref_t >
    46 void ast::ptr_base<node_t, ref_t>::_inc( const node_t * node ) {
    47         node->increment(ref_t);
    48         _trap( node );
    49 }
    50 
    51 template< typename node_t, enum ast::Node::ref_type ref_t >
    52 void ast::ptr_base<node_t, ref_t>::_dec( const node_t * node, bool do_delete ) {
    53         _trap( node );
    54         node->decrement(ref_t, do_delete );
    55 }
    56 
    57 template< typename node_t, enum ast::Node::ref_type ref_t >
    58 void ast::ptr_base<node_t, ref_t>::_check() const {
    59         // if(node) assert(node->was_ever_strong == false || node->strong_count > 0);
    60 }
     31template< typename node_t, enum ast::Node::ref_type ref_t >
     32void ast::ptr_base<node_t, ref_t>::_inc( const node_t * node ) { node->increment(ref_t); }
     33
     34template< typename node_t, enum ast::Node::ref_type ref_t >
     35void ast::ptr_base<node_t, ref_t>::_dec( const node_t * node ) { node->decrement(ref_t); }
     36
     37template< typename node_t, enum ast::Node::ref_type ref_t >
     38void ast::ptr_base<node_t, ref_t>::_check() const { if(node) assert(node->was_ever_strong == false || node->strong_count > 0); }
    6139
    6240template< typename node_t, enum ast::Node::ref_type ref_t >
  • src/AST/Node.hpp

    r96ac72c0 r83b52f1  
    3838        Node& operator= (const Node&) = delete;
    3939        Node& operator= (Node&&) = delete;
    40         virtual ~Node() {}
     40        virtual ~Node() = default;
    4141
    4242        virtual const Node * accept( Visitor & v ) const = 0;
     
    5757        template<typename node_t>
    5858        friend node_t * mutate(const node_t * node);
    59         template<typename node_t>
    60         friend node_t * shallowCopy(const node_t * node);
    6159
    6260        mutable size_t strong_count = 0;
     
    7169        }
    7270
    73         void decrement(ast::Node::ref_type ref, bool do_delete = true) const {
     71        void decrement(ast::Node::ref_type ref) const {
    7472                switch (ref) {
    7573                        case ref_type::strong: strong_count--; break;
     
    7775                }
    7876
    79                 if( do_delete && !strong_count && !weak_count) {
     77                if(!strong_count && !weak_count) {
    8078                        delete this;
    8179                }
     
    125123        (ret->*field)[i] = std::forward< field_t >( val );
    126124        return ret;
    127 }
    128 
    129 /// Mutate an entire indexed collection by cloning to accepted value
    130 template<typename node_t, typename parent_t, typename coll_t>
    131 const node_t * mutate_each( const node_t * node, coll_t parent_t::* field, Visitor & v ) {
    132         for ( unsigned i = 0; i < (node->*field).size(); ++i ) {
    133                 node = mutate_field_index( node, field, i, (node->*field)[i]->accept( v ) );
    134         }
    135         return node;
    136125}
    137126
     
    230219        operator const node_t * () const { _check(); return node; }
    231220
    232         const node_t * release() {
    233                 const node_t * ret = node;
    234                 if ( node ) {
    235                         _dec(node, false);
    236                         node = nullptr;
    237                 }
    238                 return ret;
    239         }
    240 
    241221        /// wrapper for convenient access to dynamic_cast
    242222        template<typename o_node_t>
     
    264244
    265245        void _inc( const node_t * other );
    266         void _dec( const node_t * other, bool do_delete = true );
     246        void _dec( const node_t * other );
    267247        void _check() const;
    268248
  • src/AST/Pass.hpp

    r96ac72c0 r83b52f1  
    3535#include "AST/SymbolTable.hpp"
    3636
    37 #include "AST/ForallSubstitutionTable.hpp"
    38 
    3937// Private prelude header, needed for some of the magic tricks this class pulls off
    4038#include "AST/Pass.proto.hpp"
     
    4846//
    4947// Several additional features are available through inheritance
    50 // | WithTypeSubstitution  - provides polymorphic const TypeSubstitution * env for the
    51 //                           current expression
    52 // | WithStmtsToAdd        - provides the ability to insert statements before or after the current
    53 //                           statement by adding new statements into stmtsToAddBefore or
    54 //                           stmtsToAddAfter respectively.
    55 // | WithDeclsToAdd        - provides the ability to insert declarations before or after the
    56 //                           current declarations by adding new DeclStmt into declsToAddBefore or
    57 //                           declsToAddAfter respectively.
    58 // | WithShortCircuiting   - provides the ability to skip visiting child nodes; set visit_children
    59 //                           to false in pre{visit,visit} to skip visiting children
    60 // | WithGuards            - provides the ability to save/restore data like a LIFO stack; to save,
    61 //                           call GuardValue with the variable to save, the variable will
    62 //                           automatically be restored to its previous value after the
    63 //                           corresponding postvisit/postmutate teminates.
    64 // | WithVisitorRef        - provides an pointer to the templated visitor wrapper
    65 // | WithSymbolTable       - provides symbol table functionality
    66 // | WithForallSubstitutor - maintains links between TypeInstType and TypeDecl under mutation
     48// | WithTypeSubstitution - provides polymorphic const TypeSubstitution * env for the
     49//                          current expression
     50// | WithStmtsToAdd       - provides the ability to insert statements before or after the current
     51//                          statement by adding new statements into stmtsToAddBefore or
     52//                          stmtsToAddAfter respectively.
     53// | WithDeclsToAdd       - provides the ability to insert declarations before or after the current
     54//                          declarations by adding new DeclStmt into declsToAddBefore or
     55//                          declsToAddAfter respectively.
     56// | WithShortCircuiting  - provides the ability to skip visiting child nodes; set visit_children
     57//                          to false in pre{visit,visit} to skip visiting children
     58// | WithGuards           - provides the ability to save/restore data like a LIFO stack; to save,
     59//                          call GuardValue with the variable to save, the variable will
     60//                          automatically be restored to its previous value after the corresponding
     61//                          postvisit/postmutate teminates.
     62// | WithVisitorRef       - provides an pointer to the templated visitor wrapper
     63// | WithSymbolTable      - provides symbol table functionality
    6764//-------------------------------------------------------------------------------------------------
    6865template< typename pass_t >
     
    204201        container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container );
    205202
    206         /// Mutate forall-list, accounting for presence of type substitution map
    207         template<typename node_t>
    208         void mutate_forall( const node_t *& );
    209 
    210203public:
    211204        /// Logic to call the accept and mutate the parent if needed, delegates call to accept
     
    216209        /// Internal RAII guard for symbol table features
    217210        struct guard_symtab {
    218                 guard_symtab( Pass<pass_t> & pass ): pass( pass ) { __pass::symtab::enter(pass.pass, 0); }
    219                 ~guard_symtab()                                   { __pass::symtab::leave(pass.pass, 0); }
     211                guard_symtab( Pass<pass_t> & pass ): pass( pass ) { __pass::symtab::enter(pass, 0); }
     212                ~guard_symtab()                                   { __pass::symtab::leave(pass, 0); }
    220213                Pass<pass_t> & pass;
    221214        };
     
    223216        /// Internal RAII guard for scope features
    224217        struct guard_scope {
    225                 guard_scope( Pass<pass_t> & pass ): pass( pass ) { __pass::scope::enter(pass.pass, 0); }
    226                 ~guard_scope()                                   { __pass::scope::leave(pass.pass, 0); }
     218                guard_scope( Pass<pass_t> & pass ): pass( pass ) { __pass::scope::enter(pass, 0); }
     219                ~guard_scope()                                   { __pass::scope::leave(pass, 0); }
    227220                Pass<pass_t> & pass;
    228         };
    229 
    230         /// Internal RAII guard for forall substitutions
    231         struct guard_forall_subs {
    232                 guard_forall_subs( Pass<pass_t> & pass, const ParameterizedType * type )
    233                 : pass( pass ), type( type ) { __pass::forall::enter(pass.pass, 0, type ); }
    234                 ~guard_forall_subs()         { __pass::forall::leave(pass.pass, 0, type ); }
    235                 Pass<pass_t> & pass;
    236                 const ParameterizedType * type;
    237221        };
    238222
     
    329313        SymbolTable symtab;
    330314};
    331 
    332 /// Use when the templated visitor needs to keep TypeInstType instances properly linked to TypeDecl
    333 struct WithForallSubstitutor {
    334         ForallSubstitutionTable subs;
    335 };
    336 
    337315}
    338316
  • src/AST/Pass.impl.hpp

    r96ac72c0 r83b52f1  
    127127                        , decltype( node->accept(*this) )
    128128                >::type
     129
    129130        {
    130131                __pedantic_pass_assert( __visit_children() );
    131                 __pedantic_pass_assert( node );
     132                __pedantic_pass_assert( expr );
    132133
    133134                static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR");
     
    322323        }
    323324
    324 
    325         template< typename pass_t >
    326         template< typename node_t >
    327         void ast::Pass< pass_t >::mutate_forall( const node_t *& node ) {
    328                 if ( auto subs = __pass::forall::subs( pass, 0 ) ) {
    329                         // tracking TypeDecl substitution, full clone
    330                         if ( node->forall.empty() ) return;
    331 
    332                         node_t * mut = mutate( node );
    333                         mut->forall = subs->clone( node->forall, *this );
    334                         node = mut;
    335                 } else {
    336                         // not tracking TypeDecl substitution, just mutate
    337                         maybe_accept( node, &node_t::forall );
    338                 }
    339         }
    340325}
    341326
     
    444429                        guard_symtab guard { *this };
    445430                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
    446                         static ast::ptr< ast::ObjectDecl > func{ new ast::ObjectDecl{
    447                                 CodeLocation{}, "__func__",
    448                                 new ast::ArrayType{
    449                                         new ast::BasicType{ ast::BasicType::Char, ast::CV::Const },
     431                        static ast::ObjectDecl func(
     432                                node->location, "__func__",
     433                                new ast::ArrayType(
     434                                        new ast::BasicType( ast::BasicType::Char, ast::CV::Qualifiers( ast::CV::Const ) ),
    450435                                        nullptr, VariableLen, DynamicDim
    451                                 }
    452                         } };
    453                         __pass::symtab::addId( pass, 0, func );
     436                                )
     437                        );
     438                        __pass::symtab::addId( pass, 0, &func );
    454439                        VISIT(
    455440                                maybe_accept( node, &FunctionDecl::type );
     
    625610        VISIT({
    626611                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
    627                 auto guard1 = makeFuncGuard( [this, inFunctionCpy = this->inFunction]() {
    628                         if ( ! inFunctionCpy ) __pass::symtab::enter(pass, 0);
    629                 }, [this, inFunctionCpy = this->inFunction]() {
    630                         if ( ! inFunctionCpy ) __pass::symtab::leave(pass, 0);
     612                auto guard1 = makeFuncGuard( [this, inFunction = this->inFunction]() {
     613                        if ( ! inFunction ) __pass::symtab::enter(pass, 0);
     614                }, [this, inFunction = this->inFunction]() {
     615                        if ( ! inFunction ) __pass::symtab::leave(pass, 0);
    631616                });
    632617                ValueGuard< bool > guard2( inFunction );
     
    16821667        VISIT_START( node );
    16831668
    1684         VISIT({
    1685                 guard_forall_subs forall_guard { *this, node };
    1686                 mutate_forall( node );
     1669        VISIT(
     1670                maybe_accept( node, &FunctionType::forall  );
    16871671                maybe_accept( node, &FunctionType::returns );
    16881672                maybe_accept( node, &FunctionType::params  );
    1689         })
     1673        )
    16901674
    16911675        VISIT_END( Type, node );
     
    17021686        VISIT({
    17031687                guard_symtab guard { *this };
    1704                 guard_forall_subs forall_guard { *this, node };
    1705                 mutate_forall( node );
     1688                maybe_accept( node, &StructInstType::forall );
    17061689                maybe_accept( node, &StructInstType::params );
    17071690        })
     
    17161699        VISIT_START( node );
    17171700
    1718         __pass::symtab::addUnion( pass, 0, node->name );
    1719 
    1720         VISIT({
     1701        __pass::symtab::addStruct( pass, 0, node->name );
     1702
     1703        {
    17211704                guard_symtab guard { *this };
    1722                 guard_forall_subs forall_guard { *this, node };
    1723                 mutate_forall( node );
     1705                maybe_accept( node, &UnionInstType::forall );
    17241706                maybe_accept( node, &UnionInstType::params );
    1725         })
     1707        }
    17261708
    17271709        VISIT_END( Type, node );
     
    17341716        VISIT_START( node );
    17351717
    1736         VISIT({
    1737                 guard_forall_subs forall_guard { *this, node };
    1738                 mutate_forall( node );
     1718        VISIT(
     1719                maybe_accept( node, &EnumInstType::forall );
    17391720                maybe_accept( node, &EnumInstType::params );
    1740         })
     1721        )
    17411722
    17421723        VISIT_END( Type, node );
     
    17491730        VISIT_START( node );
    17501731
    1751         VISIT({
    1752                 guard_forall_subs forall_guard { *this, node };
    1753                 mutate_forall( node );
     1732        VISIT(
     1733                maybe_accept( node, &TraitInstType::forall );
    17541734                maybe_accept( node, &TraitInstType::params );
    1755         })
     1735        )
    17561736
    17571737        VISIT_END( Type, node );
     
    17651745
    17661746        VISIT(
    1767                 {
    1768                         guard_forall_subs forall_guard { *this, node };
    1769                         mutate_forall( node );
    1770                         maybe_accept( node, &TypeInstType::params );
    1771                 }
    1772                 // ensure that base re-bound if doing substitution
    1773                 __pass::forall::replace( pass, 0, node );
     1747                maybe_accept( node, &TypeInstType::forall );
     1748                maybe_accept( node, &TypeInstType::params );
    17741749        )
    17751750
     
    19201895                                guard_symtab guard { *this };
    19211896                                auto new_node = p.second->accept( *this );
    1922                                 if (new_node != p.second) mutated = true;
     1897                                if (new_node != p.second) mutated = false;
    19231898                                new_map.insert({ p.first, new_node });
    19241899                        }
     
    19361911                                guard_symtab guard { *this };
    19371912                                auto new_node = p.second->accept( *this );
    1938                                 if (new_node != p.second) mutated = true;
     1913                                if (new_node != p.second) mutated = false;
    19391914                                new_map.insert({ p.first, new_node });
    19401915                        }
  • src/AST/Pass.proto.hpp

    r96ac72c0 r83b52f1  
    263263                template<typename pass_t>
    264264                static inline void leave( pass_t &, long ) {}
    265         } // namespace scope
    266 
    267         // Certain passes desire an up to date symbol table automatically
     265        };
     266
     267        // Finally certain pass desire an up to date symbol table automatically
    268268        // detect the presence of a member name `symtab` and call all the members appropriately
    269269        namespace symtab {
    270270                // Some simple scoping rules
    271271                template<typename pass_t>
    272                 static inline auto enter( pass_t & pass, int ) -> decltype( pass.symtab, void() ) {
     272                static inline auto enter( pass_t & pass, int ) -> decltype( pass.symtab.enterScope(), void() ) {
    273273                        pass.symtab.enterScope();
    274274                }
     
    278278
    279279                template<typename pass_t>
    280                 static inline auto leave( pass_t & pass, int ) -> decltype( pass.symtab, void() ) {
     280                static inline auto leave( pass_t & pass, int ) -> decltype( pass.symtab.leaveScope(), void() ) {
    281281                        pass.symtab.leaveScope();
    282282                }
     
    356356                #undef SYMTAB_FUNC1
    357357                #undef SYMTAB_FUNC2
    358         } // namespace symtab
    359 
    360         // Some passes need to mutate TypeDecl and properly update their pointing TypeInstType.
    361         // Detect the presence of a member name `subs` and call all members appropriately
    362         namespace forall {
    363                 // Some simple scoping rules
    364                 template<typename pass_t>
    365                 static inline auto enter( pass_t & pass, int, const ast::ParameterizedType * type )
    366                 -> decltype( pass.subs, void() ) {
    367                         if ( ! type->forall.empty() ) pass.subs.beginScope();
    368                 }
    369 
    370                 template<typename pass_t>
    371                 static inline auto enter( pass_t &, long, const ast::ParameterizedType * ) {}
    372 
    373                 template<typename pass_t>
    374                 static inline auto leave( pass_t & pass, int, const ast::ParameterizedType * type )
    375                 -> decltype( pass.subs, void() ) {
    376                         if ( ! type->forall.empty() ) { pass.subs.endScope(); }
    377                 }
    378 
    379                 template<typename pass_t>
    380                 static inline auto leave( pass_t &, long, const ast::ParameterizedType * ) {}
    381 
    382                 // Get the substitution table, if present
    383                 template<typename pass_t>
    384                 static inline auto subs( pass_t & pass, int ) -> decltype( &pass.subs ) {
    385                         return &pass.subs;
    386                 }
    387                
    388                 template<typename pass_t>
    389                 static inline ast::ForallSubstitutionTable * subs( pass_t &, long ) { return nullptr; }
    390 
    391                 // Replaces a TypeInstType's base TypeDecl according to the table
    392                 template<typename pass_t>
    393                 static inline auto replace( pass_t & pass, int, const ast::TypeInstType *& inst )
    394                 -> decltype( pass.subs, void() ) {
    395                         inst = ast::mutate_field(
    396                                 inst, &ast::TypeInstType::base, pass.subs.replace( inst->base ) );
    397                 }
    398 
    399                 template<typename pass_t>
    400                 static inline auto replace( pass_t &, long, const ast::TypeInstType *& ) {}
    401 
    402         } // namespace forall
    403 } // namespace __pass
    404 } // namespace ast
     358        };
     359};
     360};
  • src/AST/Stmt.hpp

    r96ac72c0 r83b52f1  
    2727
    2828// Must be included in *all* AST classes; should be #undef'd at the end of the file
    29 #define MUTATE_FRIEND \
    30     template<typename node_t> friend node_t * mutate(const node_t * node); \
    31         template<typename node_t> friend node_t * shallowCopy(const node_t * node);
     29#define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
    3230
    3331namespace ast {
  • src/AST/Type.cpp

    r96ac72c0 r83b52f1  
    2121
    2222#include "Decl.hpp"
    23 #include "ForallSubstitutor.hpp" // for substituteForall
    2423#include "Init.hpp"
    25 #include "Common/utility.h"      // for copy, move
    2624#include "InitTweak/InitTweak.h" // for getPointerBase
    2725#include "Tuples/Tuples.h"       // for isTtype
     
    9391);
    9492
    95 // --- ParameterizedType
    96 
    97 void ParameterizedType::initWithSub(
    98         const ParameterizedType & o, Pass< ForallSubstitutor > & sub
    99 ) {
    100         forall = sub.pass( o.forall );
    101 }
    102 
    10393// --- FunctionType
    104 
    105 FunctionType::FunctionType( const FunctionType & o )
    106 : ParameterizedType( o.qualifiers, copy( o.attributes ) ), returns(), params(),
    107   isVarArgs( o.isVarArgs ) {
    108         Pass< ForallSubstitutor > sub;
    109         initWithSub( o, sub );           // initialize substitution map
    110         returns = sub.pass( o.returns ); // apply to return and parameter types
    111         params = sub.pass( o.params );
    112 }
    11394
    11495namespace {
     
    126107
    127108// --- ReferenceToType
    128 
    129 void ReferenceToType::initWithSub( const ReferenceToType & o, Pass< ForallSubstitutor > & sub ) {
    130         ParameterizedType::initWithSub( o, sub ); // initialize substitution
    131         params = sub.pass( o.params );            // apply to parameters
    132 }
    133 
    134 ReferenceToType::ReferenceToType( const ReferenceToType & o )
    135 : ParameterizedType( o.qualifiers, copy( o.attributes ) ), params(), name( o.name ),
    136   hoistType( o.hoistType ) {
    137         Pass< ForallSubstitutor > sub;
    138         initWithSub( o, sub );
    139 }
    140 
    141109std::vector<readonly<Decl>> ReferenceToType::lookup( const std::string& name ) const {
    142110        assertf( aggr(), "Must have aggregate to perform lookup" );
     
    151119// --- StructInstType
    152120
    153 StructInstType::StructInstType(
    154         const StructDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
    155 : ReferenceToType( b->name, q, move(as) ), base( b ) {}
     121StructInstType::StructInstType( const StructDecl * b, CV::Qualifiers q,
     122        std::vector<ptr<Attribute>>&& as )
     123: ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
    156124
    157125bool StructInstType::isComplete() const { return base ? base->body : false; }
     
    159127// --- UnionInstType
    160128
    161 UnionInstType::UnionInstType(
    162         const UnionDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
    163 : ReferenceToType( b->name, q, move(as) ), base( b ) {}
     129UnionInstType::UnionInstType( const UnionDecl * b, CV::Qualifiers q,
     130        std::vector<ptr<Attribute>>&& as )
     131: ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
    164132
    165133bool UnionInstType::isComplete() const { return base ? base->body : false; }
     
    167135// --- EnumInstType
    168136
    169 EnumInstType::EnumInstType(
    170         const EnumDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
    171 : ReferenceToType( b->name, q, move(as) ), base( b ) {}
     137EnumInstType::EnumInstType( const EnumDecl * b, CV::Qualifiers q,
     138        std::vector<ptr<Attribute>>&& as )
     139: ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
    172140
    173141bool EnumInstType::isComplete() const { return base ? base->body : false; }
     
    175143// --- TraitInstType
    176144
    177 TraitInstType::TraitInstType(
    178         const TraitDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
    179 : ReferenceToType( b->name, q, move(as) ), base( b ) {}
     145TraitInstType::TraitInstType( const TraitDecl * b, CV::Qualifiers q,
     146        std::vector<ptr<Attribute>>&& as )
     147: ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
    180148
    181149// --- TypeInstType
    182 
    183 TypeInstType::TypeInstType( const TypeInstType & o )
    184 : ReferenceToType( o.name, o.qualifiers, copy( o.attributes ) ), base(), kind( o.kind ) {
    185         Pass< ForallSubstitutor > sub;
    186         initWithSub( o, sub );      // initialize substitution
    187         base = sub.pass( o.base );  // apply to base type
    188 }
    189150
    190151void TypeInstType::set_base( const TypeDecl * b ) {
     
    198159
    199160TupleType::TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q )
    200 : Type( q ), types( move(ts) ), members() {
     161: Type( q ), types( std::move(ts) ), members() {
    201162        // This constructor is awkward. `TupleType` needs to contain objects so that members can be
    202163        // named, but members without initializer nodes end up getting constructors, which breaks
  • src/AST/Type.hpp

    r96ac72c0 r83b52f1  
    3030
    3131// Must be included in *all* AST classes; should be #undef'd at the end of the file
    32 #define MUTATE_FRIEND \
    33     template<typename node_t> friend node_t * mutate(const node_t * node); \
    34         template<typename node_t> friend node_t * shallowCopy(const node_t * node);
     32#define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
    3533
    3634namespace ast {
    37 
    38 template< typename T > class Pass;
    39 
    40 struct ForallSubstitutor;
    4135
    4236class Type : public Node {
     
    170164        static const char *typeNames[];
    171165
    172         BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
     166        BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 
    173167        : Type(q, std::move(as)), kind(k) {}
    174168
     
    272266/// Base type for potentially forall-qualified types
    273267class ParameterizedType : public Type {
    274 protected:
    275         /// initializes forall with substitutor
    276         void initWithSub( const ParameterizedType & o, Pass< ForallSubstitutor > & sub );
    277268public:
    278269        using ForallList = std::vector<ptr<TypeDecl>>;
     
    286277        ParameterizedType( CV::Qualifiers q, std::vector<ptr<Attribute>> && as = {} )
    287278        : Type(q, std::move(as)), forall() {}
    288 
    289         // enforce use of ForallSubstitutor to copy parameterized type
    290         ParameterizedType( const ParameterizedType & ) = delete;
    291 
    292         ParameterizedType( ParameterizedType && ) = default;
    293 
    294         // no need to change destructor, and operator= deleted in Node
    295279
    296280private:
     
    318302        : ParameterizedType(q), returns(), params(), isVarArgs(va) {}
    319303
    320         FunctionType( const FunctionType & o );
    321 
    322304        /// true if either the parameters or return values contain a tttype
    323305        bool isTtype() const;
     
    333315/// base class for types that refer to types declared elsewhere (aggregates and typedefs)
    334316class ReferenceToType : public ParameterizedType {
    335 protected:
    336         /// Initializes forall and parameters based on substitutor
    337         void initWithSub( const ReferenceToType & o, Pass< ForallSubstitutor > & sub );
    338317public:
    339318        std::vector<ptr<Expr>> params;
     
    341320        bool hoistType = false;
    342321
    343         ReferenceToType(
    344                 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
     322        ReferenceToType( const std::string& n, CV::Qualifiers q = {},
     323                std::vector<ptr<Attribute>> && as = {} )
    345324        : ParameterizedType(q, std::move(as)), params(), name(n) {}
    346 
    347         ReferenceToType( const ReferenceToType & o );
    348325
    349326        /// Gets aggregate declaration this type refers to
     
    362339        readonly<StructDecl> base;
    363340
    364         StructInstType(
    365                 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
     341        StructInstType( const std::string& n, CV::Qualifiers q = {},
     342                std::vector<ptr<Attribute>> && as = {} )
    366343        : ReferenceToType( n, q, std::move(as) ), base() {}
    367 
    368         StructInstType(
    369                 const StructDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
     344        StructInstType( const StructDecl * b, CV::Qualifiers q = {},
     345                std::vector<ptr<Attribute>> && as = {} );
    370346
    371347        bool isComplete() const override;
     
    384360        readonly<UnionDecl> base;
    385361
    386         UnionInstType(
    387                 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
     362        UnionInstType( const std::string& n, CV::Qualifiers q = {},
     363                std::vector<ptr<Attribute>> && as = {} )
    388364        : ReferenceToType( n, q, std::move(as) ), base() {}
    389 
    390         UnionInstType(
    391                 const UnionDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
     365        UnionInstType( const UnionDecl * b, CV::Qualifiers q = {},
     366                std::vector<ptr<Attribute>> && as = {} );
    392367
    393368        bool isComplete() const override;
     
    406381        readonly<EnumDecl> base;
    407382
    408         EnumInstType(
    409                 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
     383        EnumInstType( const std::string& n, CV::Qualifiers q = {},
     384                std::vector<ptr<Attribute>> && as = {} )
    410385        : ReferenceToType( n, q, std::move(as) ), base() {}
    411 
    412         EnumInstType(
    413                 const EnumDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
     386        EnumInstType( const EnumDecl * b, CV::Qualifiers q = {},
     387                std::vector<ptr<Attribute>> && as = {} );
    414388
    415389        bool isComplete() const override;
     
    428402        readonly<TraitDecl> base;
    429403
    430         TraitInstType(
    431                 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
     404        TraitInstType( const std::string& n, CV::Qualifiers q = {},
     405                std::vector<ptr<Attribute>> && as = {} )
    432406        : ReferenceToType( n, q, std::move(as) ), base() {}
    433 
    434         TraitInstType(
    435                 const TraitDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
     407        TraitInstType( const TraitDecl * b, CV::Qualifiers q = {},
     408                std::vector<ptr<Attribute>> && as = {} );
    436409
    437410        // not meaningful for TraitInstType
     
    452425        TypeVar::Kind kind;
    453426
    454         TypeInstType(
    455                 const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
     427        TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
    456428                std::vector<ptr<Attribute>> && as = {} )
    457429        : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
    458 
    459         TypeInstType(
    460                 const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
     430        TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
    461431                std::vector<ptr<Attribute>> && as = {} )
    462432        : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {}
    463 
    464         TypeInstType( const TypeInstType & o );
    465433
    466434        /// sets `base`, updating `kind` correctly
  • src/AST/TypeSubstitution.cpp

    r96ac72c0 r83b52f1  
    9292namespace {
    9393        struct EnvTrimmer {
    94                 const TypeSubstitution * env;
     94                ptr<TypeSubstitution> env;
    9595                TypeSubstitution * newEnv;
    9696                EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
     
    108108        if ( env ) {
    109109                TypeSubstitution * newEnv = new TypeSubstitution();
     110#if TIME_TO_CONVERT_PASSES
    110111                Pass<EnvTrimmer> trimmer( env, newEnv );
    111112                expr->accept( trimmer );
     113#else
     114                (void)expr;
     115                (void)env;
     116#endif
    112117                return newEnv;
    113118        }
     
    116121
    117122void TypeSubstitution::normalize() {
    118         Pass<Substituter> sub( *this, true );
     123#if TIME_TO_CONVERT_PASSES
     124        PassVisitor<Substituter> sub( *this, true );
    119125        do {
    120126                sub.pass.subCount = 0;
    121127                sub.pass.freeOnly = true;
    122128                for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) {
    123                         i->second = i->second->accept( sub );
     129                        i->second = i->second->acceptMutator( sub );
    124130                }
    125131        } while ( sub.pass.subCount );
    126 }
    127 
    128 const Type * TypeSubstitution::Substituter::postvisit( const TypeInstType *inst ) {
     132#endif
     133}
     134
     135#if TIME_TO_CONVERT_PASSES
     136
     137Type * TypeSubstitution::Substituter::postmutate( TypeInstType *inst ) {
    129138        BoundVarsType::const_iterator bound = boundVars.find( inst->name );
    130139        if ( bound != boundVars.end() ) return inst;
     
    137146                // Note: this does not prevent cycles in the general case, so it may be necessary to do something more sophisticated here.
    138147                // TODO: investigate preventing type variables from being bound to themselves in the first place.
    139                 if ( const TypeInstType * replacement = i->second.as<TypeInstType>() ) {
     148                if ( TypeInstType * replacement = i->second.as<TypeInstType>() ) {
    140149                        if ( inst->name == replacement->name ) {
    141150                                return inst;
     
    144153                // std::cerr << "found " << inst->name << ", replacing with " << i->second << std::endl;
    145154                subCount++;
    146                 ptr<Type> newType = i->second; // force clone if needed
    147                 add_qualifiers( newType, inst->qualifiers );
    148                 // Note: need to recursively apply substitution to the new type because normalize does not
    149                 // substitute bound vars, but bound vars must be substituted when not in freeOnly mode.
    150                 newType = newType->accept( *visitor );
    151                 return newType.release();
    152         } // if
    153 }
    154 
    155 const Expr * TypeSubstitution::Substituter::postvisit( const NameExpr * nameExpr ) {
     155                Type * newtype = i->second->clone();
     156                newtype->get_qualifiers() |= inst->get_qualifiers();
     157                delete inst;
     158                // Note: need to recursively apply substitution to the new type because normalize does not substitute bound vars, but bound vars must be substituted when not in freeOnly mode.
     159                return newtype->acceptMutator( *visitor );
     160        } // if
     161}
     162
     163Expression * TypeSubstitution::Substituter::postmutate( NameExpr * nameExpr ) {
    156164        VarEnvType::const_iterator i = sub.varEnv.find( nameExpr->name );
    157165        if ( i == sub.varEnv.end() ) {
     
    160168                subCount++;
    161169                delete nameExpr;
    162                 return i->second;
    163         } // if
    164 }
    165 
    166 void TypeSubstitution::Substituter::previsit( const ParameterizedType * ptype ) {
     170                return i->second->clone();
     171        } // if
     172}
     173
     174void TypeSubstitution::Substituter::premutate( Type * type ) {
    167175        GuardValue( boundVars );
    168176        // bind type variables from forall-qualifiers
    169177        if ( freeOnly ) {
    170                 for ( const TypeDecl * tyvar : ptype->forall ) {
    171                                 boundVars.insert( tyvar->name );
     178                for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar ) {
     179                        boundVars.insert( (*tyvar)->name );
    172180                } // for
    173181        } // if
    174182}
    175183
    176 void TypeSubstitution::Substituter::handleAggregateType( const ReferenceToType * type ) {
     184template< typename TypeClass >
     185void TypeSubstitution::Substituter::handleAggregateType( TypeClass * type ) {
    177186        GuardValue( boundVars );
    178187        // bind type variables from forall-qualifiers
    179188        if ( freeOnly ) {
    180                 for ( const TypeDecl * tyvar : type->forall ) {
    181                         boundVars.insert( tyvar->name );
     189                for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar ) {
     190                        boundVars.insert( (*tyvar)->name );
    182191                } // for
    183192                // bind type variables from generic type instantiations
    184                 if ( auto decl = type->aggr() ) {
    185                         if ( ! type->params.empty() ) {
    186                                 for ( const TypeDecl * tyvar : decl->params ) {
    187                                         boundVars.insert( tyvar->name );
    188                                 } // for
    189                         } // if
    190                 }
    191         } // if
    192 }
    193 
    194 void TypeSubstitution::Substituter::previsit( const StructInstType * aggregateUseType ) {
     193                std::list< TypeDecl* > *baseParameters = type->get_baseParameters();
     194                if ( baseParameters && ! type->parameters.empty() ) {
     195                        for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) {
     196                                boundVars.insert( (*tyvar)->name );
     197                        } // for
     198                } // if
     199        } // if
     200}
     201
     202void TypeSubstitution::Substituter::premutate( StructInstType * aggregateUseType ) {
    195203        handleAggregateType( aggregateUseType );
    196204}
    197205
    198 void TypeSubstitution::Substituter::previsit( const UnionInstType *aggregateUseType ) {
     206void TypeSubstitution::Substituter::premutate( UnionInstType *aggregateUseType ) {
    199207        handleAggregateType( aggregateUseType );
    200208}
     209
     210#endif
    201211
    202212} // namespace ast
  • src/AST/TypeSubstitution.hpp

    r96ac72c0 r83b52f1  
    155155                Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
    156156
    157                 const Type * postvisit( const TypeInstType * aggregateUseType );
    158                 const Expr * postvisit( const NameExpr * nameExpr );
     157#if TIME_TO_CONVERT_PASSES
     158
     159                Type * postmutate( TypeInstType * aggregateUseType );
     160                Expression * postmutate( NameExpr * nameExpr );
    159161
    160162                /// Records type variable bindings from forall-statements
    161                 void previsit( const ParameterizedType * type );
     163                void premutate( Type * type );
    162164                /// Records type variable bindings from forall-statements and instantiations of generic types
    163                 void handleAggregateType( const ReferenceToType * type );
    164 
    165                 void previsit( const StructInstType * aggregateUseType );
    166                 void previsit( const UnionInstType * aggregateUseType );
     165                template< typename TypeClass > void handleAggregateType( TypeClass * type );
     166
     167                void premutate( StructInstType * aggregateUseType );
     168                void premutate( UnionInstType * aggregateUseType );
     169
     170#endif
    167171
    168172                const TypeSubstitution & sub;
  • src/AST/module.mk

    r96ac72c0 r83b52f1  
    2222        AST/DeclReplacer.cpp \
    2323        AST/Expr.cpp \
    24         AST/ForallSubstitutionTable.cpp \
    2524        AST/GenericSubstitution.cpp \
    2625        AST/Init.cpp \
  • src/Common/ScopedMap.h

    r96ac72c0 r83b52f1  
    249249
    250250        /// Gets the note at the given scope
    251         Note& getNote() { return scopes.back().note; }
    252         const Note& getNote() const { return scopes.back().note; }
    253251        Note& getNote( size_type i ) { return scopes[i].note; }
    254252        const Note& getNote( size_type i ) const { return scopes[i].note; }
  • src/Makefile.in

    r96ac72c0 r83b52f1  
    168168        AST/Convert.$(OBJEXT) AST/Decl.$(OBJEXT) \
    169169        AST/DeclReplacer.$(OBJEXT) AST/Expr.$(OBJEXT) \
    170         AST/ForallSubstitutionTable.$(OBJEXT) \
    171170        AST/GenericSubstitution.$(OBJEXT) AST/Init.$(OBJEXT) \
    172171        AST/LinkageSpec.$(OBJEXT) AST/Node.$(OBJEXT) \
     
    586585        AST/DeclReplacer.cpp \
    587586        AST/Expr.cpp \
    588         AST/ForallSubstitutionTable.cpp \
    589587        AST/GenericSubstitution.cpp \
    590588        AST/Init.cpp \
     
    761759        AST/$(DEPDIR)/$(am__dirstamp)
    762760AST/Expr.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
    763 AST/ForallSubstitutionTable.$(OBJEXT): AST/$(am__dirstamp) \
    764         AST/$(DEPDIR)/$(am__dirstamp)
    765761AST/GenericSubstitution.$(OBJEXT): AST/$(am__dirstamp) \
    766762        AST/$(DEPDIR)/$(am__dirstamp)
     
    12161212@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/DeclReplacer.Po@am__quote@
    12171213@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Expr.Po@am__quote@
    1218 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/ForallSubstitutionTable.Po@am__quote@
    12191214@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/GenericSubstitution.Po@am__quote@
    12201215@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Init.Po@am__quote@
  • src/ResolvExpr/AdjustExprType.cc

    r96ac72c0 r83b52f1  
    100100
    101101namespace {
    102         class AdjustExprType_new final : public ast::WithShortCircuiting {
     102        struct AdjustExprType_new final : public ast::WithShortCircuiting {
     103                const ast::TypeEnvironment & tenv;
    103104                const ast::SymbolTable & symtab;
    104         public:
    105                 const ast::TypeEnvironment & tenv;
    106105
    107106                AdjustExprType_new( const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
    108                 : symtab( syms ), tenv( e ) {}
     107                : tenv( e ), symtab( syms ) {}
    109108
    110                 void previsit( const ast::VoidType * ) { visit_children = false; }
    111                 void previsit( const ast::BasicType * ) { visit_children = false; }
    112                 void previsit( const ast::PointerType * ) { visit_children = false; }
    113                 void previsit( const ast::ArrayType * ) { visit_children = false; }
    114                 void previsit( const ast::FunctionType * ) { visit_children = false; }
    115                 void previsit( const ast::StructInstType * ) { visit_children = false; }
    116                 void previsit( const ast::UnionInstType * ) { visit_children = false; }
    117                 void previsit( const ast::EnumInstType * ) { visit_children = false; }
    118                 void previsit( const ast::TraitInstType * ) { visit_children = false; }
    119                 void previsit( const ast::TypeInstType * ) { visit_children = false; }
    120                 void previsit( const ast::TupleType * ) { visit_children = false; }
    121                 void previsit( const ast::VarArgsType * ) { visit_children = false; }
    122                 void previsit( const ast::ZeroType * ) { visit_children = false; }
    123                 void previsit( const ast::OneType * ) { visit_children = false; }
     109                void premutate( const ast::VoidType * ) { visit_children = false; }
     110                void premutate( const ast::BasicType * ) { visit_children = false; }
     111                void premutate( const ast::PointerType * ) { visit_children = false; }
     112                void premutate( const ast::ArrayType * ) { visit_children = false; }
     113                void premutate( const ast::FunctionType * ) { visit_children = false; }
     114                void premutate( const ast::StructInstType * ) { visit_children = false; }
     115                void premutate( const ast::UnionInstType * ) { visit_children = false; }
     116                void premutate( const ast::EnumInstType * ) { visit_children = false; }
     117                void premutate( const ast::TraitInstType * ) { visit_children = false; }
     118                void premutate( const ast::TypeInstType * ) { visit_children = false; }
     119                void premutate( const ast::TupleType * ) { visit_children = false; }
     120                void premutate( const ast::VarArgsType * ) { visit_children = false; }
     121                void premutate( const ast::ZeroType * ) { visit_children = false; }
     122                void premutate( const ast::OneType * ) { visit_children = false; }
    124123
    125                 const ast::Type * postvisit( const ast::ArrayType * at ) {
     124                const ast::Type * postmutate( const ast::ArrayType * at ) {
    126125                        return new ast::PointerType{ at->base, at->qualifiers };
    127126                }
    128127
    129                 const ast::Type * postvisit( const ast::FunctionType * ft ) {
     128                const ast::Type * postmutate( const ast::FunctionType * ft ) {
    130129                        return new ast::PointerType{ ft };
    131130                }
    132131
    133                 const ast::Type * postvisit( const ast::TypeInstType * inst ) {
     132                const ast::Type * postmutate( const ast::TypeInstType * inst ) {
    134133                        // replace known function-type-variables with pointer-to-function
    135134                        if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name ) ) {
  • src/ResolvExpr/CandidateFinder.cpp

    r96ac72c0 r83b52f1  
    370370                                                        // push empty tuple expression
    371371                                                        newResult.parent = i;
    372                                                         newResult.expr = new ast::TupleExpr{ CodeLocation{}, {} };
     372                                                        std::vector< ast::ptr< ast::Expr > > emptyList;
     373                                                        newResult.expr =
     374                                                                new ast::TupleExpr{ CodeLocation{}, move( emptyList ) };
    373375                                                        argType = newResult.expr->result;
    374376                                                } else {
     
    546548                genStart = genEnd;
    547549
    548                 return genEnd != results.size();  // were any new results added?
     550                return genEnd != results.size();
    549551        }
    550552
     
    592594
    593595        /// Actually visits expressions to find their candidate interpretations
    594         class Finder final : public ast::WithShortCircuiting {
     596        struct Finder final : public ast::WithShortCircuiting {
     597                CandidateFinder & selfFinder;
    595598                const ast::SymbolTable & symtab;
    596         public:
    597                 CandidateFinder & selfFinder;
    598599                CandidateList & candidates;
    599600                const ast::TypeEnvironment & tenv;
     
    601602
    602603                Finder( CandidateFinder & f )
    603                 : symtab( f.localSyms ), selfFinder( f ), candidates( f.candidates ), tenv( f.env ),
     604                : selfFinder( f ), symtab( f.symtab ), candidates( f.candidates ), tenv( f.env ),
    604605                  targetType( f.targetType ) {}
    605606               
     
    675676                        ast::TypeEnvironment funcEnv{ func->env };
    676677                        makeUnifiableVars( funcType, funcOpen, funcNeed );
    677                         // add all type variables as open variables now so that those not used in the
    678                         // parameter list are still considered open
     678                        // add all type variables as open variables now so that those not used in the parameter
     679                        // list are still considered open
    679680                        funcEnv.add( funcType->forall );
    680681
     
    15571558                std::vector< std::string > errors;
    15581559                for ( CandidateRef & candidate : candidates ) {
    1559                         satisfyAssertions( candidate, localSyms, satisfied, errors );
     1560                        satisfyAssertions( candidate, symtab, satisfied, errors );
    15601561                }
    15611562
     
    16121613                        r->expr = ast::mutate_field(
    16131614                                r->expr.get(), &ast::Expr::result,
    1614                                 adjustExprType( r->expr->result, r->env, localSyms ) );
     1615                                adjustExprType( r->expr->result, r->env, symtab ) );
    16151616                }
    16161617        }
     
    16301631
    16311632        for ( const auto & x : xs ) {
    1632                 out.emplace_back( localSyms, env );
     1633                out.emplace_back( symtab, env );
    16331634                out.back().find( x, ResolvMode::withAdjustment() );
    16341635               
  • src/ResolvExpr/CandidateFinder.hpp

    r96ac72c0 r83b52f1  
    2828struct CandidateFinder {
    2929        CandidateList candidates;          ///< List of candidate resolutions
    30         const ast::SymbolTable & localSyms;   ///< Symbol table to lookup candidates
     30        const ast::SymbolTable & symtab;   ///< Symbol table to lookup candidates
    3131        const ast::TypeEnvironment & env;  ///< Substitutions performed in this resolution
    3232        ast::ptr< ast::Type > targetType;  ///< Target type for resolution
    3333
    3434        CandidateFinder(
    35                 const ast::SymbolTable & syms, const ast::TypeEnvironment & env,
     35                const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
    3636                const ast::Type * tt = nullptr )
    37         : candidates(), localSyms( syms ), env( env ), targetType( tt ) {}
     37        : candidates(), symtab( symtab ), env( env ), targetType( tt ) {}
    3838
    3939        /// Fill candidates with feasible resolutions for `expr`
  • src/ResolvExpr/CommonType.cc

    r96ac72c0 r83b52f1  
    939939                        ast::ptr< ast::Type > result;
    940940                        const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
    941                         const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >();
     941                        const ast::ReferenceType * ref2 = type1.as< ast::ReferenceType >();
    942942
    943943                        if ( depth1 > depth2 ) {
  • src/ResolvExpr/ConversionCost.cc

    r96ac72c0 r83b52f1  
    1010// Created On       : Sun May 17 07:06:19 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Jul  4 10:56:00 2019
    13 // Update Count     : 27
     12// Last Modified On : Mon Jun 24 13:33:00 2019
     13// Update Count     : 26
    1414//
    1515
     
    764764                        cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
    765765                }
    766         } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
    767                 cost = Cost::zero;
    768                 // +1 for zero_t ->, +1 for disambiguation
    769                 cost.incSafe( maxIntCost + 2 );
    770766        }
    771767}
     
    785781                        cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
    786782                }
     783        } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
     784                cost = Cost::zero;
     785                cost.incSafe( maxIntCost + 2 );
    787786        }
    788787}
  • src/ResolvExpr/PolyCost.cc

    r96ac72c0 r83b52f1  
    5858
    5959// TODO: When the old PolyCost is torn out get rid of the _new suffix.
    60 class PolyCost_new {
     60struct PolyCost_new {
     61        int result;
    6162        const ast::SymbolTable &symtab;
    62 public:
    63         int result;
    6463        const ast::TypeEnvironment &env_;
    6564
    66         PolyCost_new( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env )
    67         : symtab( symtab ), result( 0 ), env_( env ) {}
     65        PolyCost_new( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ) :
     66                result( 0 ), symtab( symtab ), env_( env ) {}
    6867
    6968        void previsit( const ast::TypeInstType * type ) {
  • src/ResolvExpr/RenameVars.cc

    r96ac72c0 r83b52f1  
    1919#include <utility>                 // for pair
    2020
    21 #include "AST/ForallSubstitutionTable.hpp"
    2221#include "AST/Pass.hpp"
    2322#include "AST/Type.hpp"
     
    3130#include "SynTree/Visitor.h"       // for acceptAll, maybeAccept
    3231
    33 #include "AST/Copy.hpp"
    34 
    3532namespace ResolvExpr {
    3633
     
    4037                int resetCount = 0;
    4138                ScopedMap< std::string, std::string > nameMap;
     39
    4240        public:
    43                 ast::ForallSubstitutionTable subs;
    44 
    4541                void reset() {
    4642                        level = 0;
     
    4844                }
    4945
     46                using mapConstIterator = ScopedMap< std::string, std::string >::const_iterator;
     47
    5048                void rename( TypeInstType * type ) {
    51                         auto it = nameMap.find( type->name );
     49                        mapConstIterator it = nameMap.find( type->name );
    5250                        if ( it != nameMap.end() ) {
    5351                                type->name = it->second;
     
    6765                                        // ditto for assertion names, the next level in
    6866                                        level++;
    69                                 }
    70                         }
     67                                        // acceptAll( td->assertions, *this );
     68                                } // for
     69                        } // if
    7170                }
    7271
     
    7877
    7978                const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
    80                         // re-linking of base type handled by WithForallSubstitutor
    81 
    82                         // rename
    83                         auto it = nameMap.find( type->name );
     79                        mapConstIterator it = nameMap.find( type->name );
    8480                        if ( it != nameMap.end() ) {
    85                                 // unconditionally mutate because map will *always* have different name,
    86                                 // if this mutates, will *always* have been mutated by ForallSubstitutor above
    87                                 ast::TypeInstType * mut = ast::mutate( type );
    88                                 mut->name = it->second;
    89                     type = mut;
     81                                ast::TypeInstType * mutType = ast::mutate( type );
     82                                mutType->name = it->second;
     83                    type = mutType;
    9084                        }
    91 
    9285                        return type;
    9386                }
     
    9588                template<typename NodeT>
    9689                const NodeT * openLevel( const NodeT * type ) {
    97                         if ( type->forall.empty() ) return type;
    98                        
    99                         nameMap.beginScope();
     90                        if ( !type->forall.empty() ) {
     91                                nameMap.beginScope();
     92                                // Load new names from this forall clause and perform renaming.
     93                                NodeT * mutType = ast::mutate( type );
     94                                for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
     95                                        std::ostringstream output;
     96                                        output << "_" << resetCount << "_" << level << "_" << td->name;
     97                                        std::string newname( output.str() );
     98                                        nameMap[ td->name ] = newname;
     99                                        ++level;
    100100
    101                         // Load new names from this forall clause and perform renaming.
    102                         NodeT * mutType = ast::mutate( type );
    103                         assert( type == mutType && "mutated type must be unique from ForallSubstitutor" );
    104                         for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
    105                                 std::ostringstream output;
    106                                 output << "_" << resetCount << "_" << level << "_" << td->name;
    107                                 std::string newname =  output.str();
    108                                 nameMap[ td->name ] = newname;
    109                                 ++level;
    110 
    111                                 ast::TypeDecl * mutDecl = ast::mutate( td.get() );
    112                                 assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" );
    113                                 mutDecl->name = newname;
    114                                 // assertion above means `td = mutDecl;` is unnecessary
     101                                        ast::TypeDecl * decl = ast::mutate( td.get() );
     102                                        decl->name = newname;
     103                                        td = decl;
     104                                }
    115105                        }
    116                         // assertion above means `type = mutType;` is unnecessary
    117 
    118106                        return type;
    119107                }
    120108
    121                 void closeLevel( const ast::ParameterizedType * type ) {
    122                         if ( type->forall.empty() ) return;
    123                        
    124                         nameMap.endScope();
     109                template<typename NodeT>
     110                const NodeT * closeLevel( const NodeT * type ) {
     111                        if ( !type->forall.empty() ) {
     112                                nameMap.endScope();
     113                        }
     114                        return type;
    125115                }
    126116        };
     
    129119        RenamingData renaming;
    130120
    131         struct RenameVars_old {
     121        struct RenameVars {
    132122                void previsit( TypeInstType * instType ) {
    133123                        renaming.openLevel( (Type*)instType );
     
    140130                        renaming.closeLevel( type );
    141131                }
    142         };
    143        
    144         struct RenameVars_new /*: public ast::WithForallSubstitutor*/ {
    145                 #warning when old RenameVars goes away, replace hack below with global pass inheriting from WithForallSubstitutor
    146                 ast::ForallSubstitutionTable & subs = renaming.subs;
    147132
    148133                const ast::FunctionType * previsit( const ast::FunctionType * type ) {
     
    161146                        return renaming.rename( renaming.openLevel( type ) );
    162147                }
    163                 void postvisit( const ast::ParameterizedType * type ) {
    164                         renaming.closeLevel( type );
     148                const ast::ParameterizedType * postvisit( const ast::ParameterizedType * type ) {
     149                        return renaming.closeLevel( type );
    165150                }
    166151        };
     
    169154
    170155void renameTyVars( Type * t ) {
    171         PassVisitor<RenameVars_old> renamer;
     156        PassVisitor<RenameVars> renamer;
    172157        t->accept( renamer );
    173158}
    174159
    175160const ast::Type * renameTyVars( const ast::Type * t ) {
    176         ast::Type *tc = ast::deepCopy(t);
    177         ast::Pass<RenameVars_new> renamer;
    178 //      return t->accept( renamer );
    179         return tc->accept( renamer );
     161        ast::Pass<RenameVars> renamer;
     162        return t->accept( renamer );
    180163}
    181164
  • src/ResolvExpr/ResolveTypeof.cc

    r96ac72c0 r83b52f1  
    153153                        }
    154154
    155                         return newType.release();
     155                        return newType;
    156156                }
    157157        };
  • src/ResolvExpr/Resolver.cc

    r96ac72c0 r83b52f1  
    11081108
    11091109                // set up and resolve expression cast to void
    1110                 ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr };
     1110                ast::CastExpr * untyped = new ast::CastExpr{ expr };
    11111111                CandidateRef choice = findUnfinishedKindExpression(
    11121112                        untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
     
    12471247        };
    12481248
    1249         void resolve( std::list< ast::ptr< ast::Decl > >& translationUnit ) {
     1249        void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ) {
    12501250                ast::Pass< Resolver_new > resolver;
    12511251                accept_all( translationUnit, resolver );
     
    12811281                ast::ptr< ast::FunctionDecl > ret = functionDecl;
    12821282                for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {
    1283                         const ast::ptr< ast::DeclWithType > & d = functionDecl->type->params[i];
     1283                        const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i];
    12841284
    12851285                        if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {
     
    12981298                        }
    12991299                }
    1300                 return ret.release();
     1300                return ret.get();
    13011301        }
    13021302
  • src/ResolvExpr/SpecCost.cc

    r96ac72c0 r83b52f1  
    1010// Created On       : Tue Oct 02 15:50:00 2018
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul  3 11:07:00 2019
    13 // Update Count     : 3
    14 //
    15 
    16 #include <cassert>
     12// Last Modified On : Wed Jun 19 10:43:00 2019
     13// Update Count     : 2
     14//
     15
    1716#include <limits>
    1817#include <list>
     
    130129                        typename std::add_pointer<ast::Type const *(typename T::value_type const &)>::type;
    131130
    132                 #warning Should use a standard maybe_accept
    133                 void maybe_accept( ast::Type const * type ) {
    134                         if ( type ) {
    135                                 auto node = type->accept( *visitor );
    136                                 assert( node == nullptr || node == type );
    137                         }
    138                 }
    139 
    140131                // Update the minimum to the new lowest non-none value.
    141132                template<typename T>
     
    143134                        for ( const auto & node : list ) {
    144135                                count = -1;
    145                                 maybe_accept( mapper( node ) );
     136                                mapper( node )->accept( *visitor );
    146137                                if ( count != -1 && count < minimum ) minimum = count;
    147138                        }
  • src/SymTab/Autogen.h

    r96ac72c0 r83b52f1  
    2121
    2222#include "AST/Decl.hpp"
    23 #include "AST/Eval.hpp"
    2423#include "AST/Expr.hpp"
    2524#include "AST/Init.hpp"
     
    265264                }
    266265
    267                 ast::ptr< ast::Expr > begin, end;
    268                 std::string cmp, update;
     266                ast::ptr< ast::Expr > begin, end, cmp, update;
    269267
    270268                if ( forward ) {
     
    272270                        begin = ast::ConstantExpr::from_int( loc, 0 );
    273271                        end = array->dimension;
    274                         cmp = "?<?";
    275                         update = "++?";
     272                        cmp = new ast::NameExpr{ loc, "?<?" };
     273                        update = new ast::NameExpr{ loc, "++?" };
    276274                } else {
    277275                        // generate: for ( int i = N-1; i >= 0; --i )
    278                         begin = ast::call(
    279                                 loc, "?-?", array->dimension, ast::ConstantExpr::from_int( loc, 1 ) );
     276                        begin = new ast::UntypedExpr{
     277                                loc, new ast::NameExpr{ loc, "?-?" },
     278                                { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } };
    280279                        end = ast::ConstantExpr::from_int( loc, 0 );
    281                         cmp = "?>=?";
    282                         update = "--?";
     280                        cmp = new ast::NameExpr{ loc, "?>=?" };
     281                        update = new ast::NameExpr{ loc, "--?" };
    283282                }
    284283
     
    286285                        loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt },
    287286                        new ast::SingleInit{ loc, begin } };
    288                 ast::ptr< ast::Expr > indexVar = new ast::VariableExpr{ loc, index };
    289                
    290                 ast::ptr< ast::Expr > cond = ast::call( loc, cmp, indexVar, end );
    291                
    292                 ast::ptr< ast::Expr > inc = ast::call( loc, update, indexVar );
    293                
    294                 ast::ptr< ast::Expr > dstIndex = ast::call( loc, "?[?]", dstParam, indexVar );
     287               
     288                ast::ptr< ast::Expr > cond = new ast::UntypedExpr{
     289                        loc, cmp, { new ast::VariableExpr{ loc, index }, end } };
     290               
     291                ast::ptr< ast::Expr > inc = new ast::UntypedExpr{
     292                        loc, update, { new ast::VariableExpr{ loc, index } } };
     293               
     294                ast::ptr< ast::Expr > dstIndex = new ast::UntypedExpr{
     295                        loc, new ast::NameExpr{ loc, "?[?]" },
     296                        { dstParam, new ast::VariableExpr{ loc, index } } };
    295297               
    296298                // srcParam must keep track of the array indices to build the source parameter and/or
    297299                // array list initializer
    298                 srcParam.addArrayIndex( indexVar, array->dimension );
     300                srcParam.addArrayIndex( new ast::VariableExpr{ loc, index }, array->dimension );
    299301
    300302                // for stmt's body, eventually containing call
     
    382384                if ( isUnnamedBitfield( obj ) ) return {};
    383385
    384                 ast::ptr< ast::Type > addCast;
     386                ast::ptr< ast::Type > addCast = nullptr;
    385387                if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) {
    386388                        assert( dstParam->result );
  • src/Tuples/Explode.cc

    r96ac72c0 r83b52f1  
    129129                        for ( const ast::Expr * expr : tupleExpr->exprs ) {
    130130                                exprs.emplace_back( applyCast( expr, false ) );
     131                                //exprs.emplace_back( ast::ptr< ast::Expr >( applyCast( expr, false ) ) );
    131132                        }
    132133                        if ( first ) {
  • src/Tuples/Explode.h

    r96ac72c0 r83b52f1  
    210210                        }
    211211                        // Cast a reference away to a value-type to allow further explosion.
    212                         if ( local->result.as< ast::ReferenceType >() ) {
     212                        if ( dynamic_cast< const ast::ReferenceType *>( local->result.get() ) ) {
    213213                                local = new ast::CastExpr{ local, tupleType };
    214214                        }
     
    220220                                // delete idx;
    221221                        }
     222                        // delete local;
    222223                }
    223224        } else {
  • src/Tuples/TupleAssignment.cc

    r96ac72c0 r83b52f1  
    465465                                        // resolve ctor/dtor for the new object
    466466                                        ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit(
    467                                                         InitTweak::genCtorInit( location, ret ), spotter.crntFinder.localSyms );
     467                                                        InitTweak::genCtorInit( location, ret ), spotter.crntFinder.symtab );
    468468                                        // remove environments from subexpressions of stmtExpr
    469469                                        ast::Pass< EnvRemover > rm{ env };
     
    560560                                        // resolve the cast expression so that rhsCand return type is bound by the cast
    561561                                        // type as needed, and transfer the resulting environment
    562                                         ResolvExpr::CandidateFinder finder{ spotter.crntFinder.localSyms, env };
     562                                        ResolvExpr::CandidateFinder finder{ spotter.crntFinder.symtab, env };
    563563                                        finder.find( rhsCand->expr, ResolvExpr::ResolvMode::withAdjustment() );
    564564                                        assert( finder.candidates.size() == 1 );
     
    609609                                        // explode the LHS so that each field of a tuple-valued expr is assigned
    610610                                        ResolvExpr::CandidateList lhs;
    611                                         explode( *lhsCand, crntFinder.localSyms, back_inserter(lhs), true );
     611                                        explode( *lhsCand, crntFinder.symtab, back_inserter(lhs), true );
    612612                                        for ( ResolvExpr::CandidateRef & cand : lhs ) {
    613613                                                // each LHS value must be a reference - some come in with a cast, if not
     
    629629                                                        if ( isTuple( rhsCand->expr ) ) {
    630630                                                                // multiple assignment
    631                                                                 explode( *rhsCand, crntFinder.localSyms, back_inserter(rhs), true );
     631                                                                explode( *rhsCand, crntFinder.symtab, back_inserter(rhs), true );
    632632                                                                matcher.reset(
    633633                                                                        new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
     
    648648                                                        // multiple assignment
    649649                                                        ResolvExpr::CandidateList rhs;
    650                                                         explode( rhsCand, crntFinder.localSyms, back_inserter(rhs), true );
     650                                                        explode( rhsCand, crntFinder.symtab, back_inserter(rhs), true );
    651651                                                        matcher.reset(
    652652                                                                new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
     
    678678                                )
    679679
    680                                 ResolvExpr::CandidateFinder finder{ crntFinder.localSyms, matcher->env };
     680                                ResolvExpr::CandidateFinder finder{ crntFinder.symtab, matcher->env };
    681681
    682682                                try {
  • src/main.cc

    r96ac72c0 r83b52f1  
    2929#include <string>                           // for char_traits, operator<<
    3030
    31 #include "AST/Convert.hpp"
    3231#include "CompilationState.h"
    3332#include "../config.h"                      // for CFA_LIBDIR
     
    303302                } // if
    304303
    305                 // PASS( "Resolve", ResolvExpr::resolve( translationUnit ) );
    306                 {
    307                         auto transUnit = convert( move( translationUnit ) );
    308                         PASS( "Resolve", ResolvExpr::resolve( transUnit ) );
    309                         translationUnit = convert( move( transUnit ) );
    310                 }
     304                PASS( "Resolve", ResolvExpr::resolve( translationUnit ) );
    311305                if ( exprp ) {
    312306                        dump( translationUnit );
Note: See TracChangeset for help on using the changeset viewer.