Changeset e0e9a0b


Ignore:
Timestamp:
Jun 27, 2019, 5:16:54 PM (2 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast, new-ast-unique-expr
Children:
7d0881c
Parents:
6be3b7d6
Message:

Somewhat deeper clone for types with forall qualifiers.

Location:
src
Files:
3 added
14 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Decl.cpp

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

    r6be3b7d6 re0e9a0b  
    8787        virtual const Type * get_type() const = 0;
    8888        /// Set type of this declaration. May be verified by subclass
    89         virtual void set_type(Type *) = 0;
     89        virtual void set_type( const Type * ) = 0;
    9090
    9191        const DeclWithType * accept( Visitor & v ) const override = 0;
     
    110110
    111111        const Type* get_type() const override { return type; }
    112         void set_type( Type * ty ) override { type = ty; }
     112        void set_type( const Type * ty ) override { type = ty; }
    113113
    114114        const DeclWithType * accept( Visitor& v ) const override { return v.visit( this ); }
     
    132132
    133133        const Type * get_type() const override;
    134         void set_type(Type * t) override;
     134        void set_type( const Type * t ) override;
    135135
    136136        bool has_body() const { return stmts; }
     
    149149        std::vector<ptr<DeclWithType>> assertions;
    150150
    151         NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
    152                 Type* b, Linkage::Spec spec = Linkage::Cforall )
     151        NamedTypeDecl(
     152                const CodeLocation & loc, const std::string & name, Storage::Classes storage,
     153                const Type * b, Linkage::Spec spec = Linkage::Cforall )
    153154        : Decl( loc, name, storage, spec ), base( b ), params(), assertions() {}
    154155
     
    185186        };
    186187
    187         TypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, Type* b,
    188                 TypeVar::Kind k, bool s, Type* i = nullptr )
     188        TypeDecl(
     189                const CodeLocation & loc, const std::string & name, Storage::Classes storage,
     190                const Type * b, TypeVar::Kind k, bool s, const Type * i = nullptr )
    189191        : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == TypeVar::Ttype || s ),
    190192          init( i ) {}
     
    201203        TypeDecl * clone() const override { return new TypeDecl{ *this }; }
    202204        MUTATE_FRIEND
    203         friend class ParameterizedType;  // to allow deep clones
    204205};
    205206
  • src/AST/Node.cpp

    r6be3b7d6 re0e9a0b  
    5656
    5757template< typename node_t, enum ast::Node::ref_type ref_t >
    58 void ast::ptr_base<node_t, ref_t>::_check() const { if(node) assert(node->was_ever_strong == false || node->strong_count > 0); }
     58void ast::ptr_base<node_t, ref_t>::_check() const {
     59        // if(node) assert(node->was_ever_strong == false || node->strong_count > 0);
     60}
    5961
    6062template< typename node_t, enum ast::Node::ref_type ref_t >
  • src/AST/Node.hpp

    r6be3b7d6 re0e9a0b  
    125125}
    126126
     127/// Mutate an entire indexed collection by cloning to accepted value
     128template<typename node_t, typename parent_t, typename coll_t>
     129const node_t * mutate_each( const node_t * node, coll_t parent_t::* field, Visitor & v ) {
     130        for ( unsigned i = 0; i < (node->*field).size(); ++i ) {
     131                node = mutate_field_index( node, field, i, (node->*field)[i]->accept( v ) );
     132        }
     133        return node;
     134}
     135
    127136std::ostream& operator<< ( std::ostream& out, const Node * node );
    128137
  • src/AST/Pass.hpp

    r6be3b7d6 re0e9a0b  
    3535#include "AST/SymbolTable.hpp"
    3636
     37#include "AST/ForallSubstitutionTable.hpp"
     38
    3739// Private prelude header, needed for some of the magic tricks this class pulls off
    3840#include "AST/Pass.proto.hpp"
     
    4648//
    4749// Several additional features are available through inheritance
    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
     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
    6467//-------------------------------------------------------------------------------------------------
    6568template< typename pass_t >
     
    201204        container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container );
    202205
     206        /// Mutate forall-list, accounting for presence of type substitution map
     207        template<typename node_t>
     208        void mutate_forall( const node_t *& );
     209
    203210public:
    204211        /// Logic to call the accept and mutate the parent if needed, delegates call to accept
     
    221228        };
    222229
     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;
     237        };
     238
    223239private:
    224240        bool inFunction = false;
     
    313329        SymbolTable symtab;
    314330};
     331
     332/// Use when the templated visitor needs to keep TypeInstType instances properly linked to TypeDecl
     333struct WithForallSubstitutor {
     334        ForallSubstitutionTable subs;
     335};
     336
    315337}
    316338
  • src/AST/Pass.impl.hpp

    r6be3b7d6 re0e9a0b  
    127127                        , decltype( node->accept(*this) )
    128128                >::type
    129 
    130129        {
    131130                __pedantic_pass_assert( __visit_children() );
    132                 __pedantic_pass_assert( expr );
     131                __pedantic_pass_assert( node );
    133132
    134133                static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR");
     
    323322        }
    324323
     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        }
    325340}
    326341
     
    16671682        VISIT_START( node );
    16681683
    1669         VISIT(
    1670                 maybe_accept( node, &FunctionType::forall  );
     1684        VISIT({
     1685                guard_forall_subs forall_guard { *this, node };
     1686                mutate_forall( node );
    16711687                maybe_accept( node, &FunctionType::returns );
    16721688                maybe_accept( node, &FunctionType::params  );
    1673         )
     1689        })
    16741690
    16751691        VISIT_END( Type, node );
     
    16861702        VISIT({
    16871703                guard_symtab guard { *this };
    1688                 maybe_accept( node, &StructInstType::forall );
     1704                guard_forall_subs forall_guard { *this, node };
     1705                mutate_forall( node );
    16891706                maybe_accept( node, &StructInstType::params );
    16901707        })
     
    16991716        VISIT_START( node );
    17001717
    1701         __pass::symtab::addStruct( pass, 0, node->name );
    1702 
    1703         {
     1718        __pass::symtab::addUnion( pass, 0, node->name );
     1719
     1720        VISIT({
    17041721                guard_symtab guard { *this };
    1705                 maybe_accept( node, &UnionInstType::forall );
     1722                guard_forall_subs forall_guard { *this, node };
     1723                mutate_forall( node );
    17061724                maybe_accept( node, &UnionInstType::params );
    1707         }
     1725        })
    17081726
    17091727        VISIT_END( Type, node );
     
    17161734        VISIT_START( node );
    17171735
    1718         VISIT(
    1719                 maybe_accept( node, &EnumInstType::forall );
     1736        VISIT({
     1737                guard_forall_subs forall_guard { *this, node };
     1738                mutate_forall( node );
    17201739                maybe_accept( node, &EnumInstType::params );
    1721         )
     1740        })
    17221741
    17231742        VISIT_END( Type, node );
     
    17301749        VISIT_START( node );
    17311750
    1732         VISIT(
    1733                 maybe_accept( node, &TraitInstType::forall );
     1751        VISIT({
     1752                guard_forall_subs forall_guard { *this, node };
     1753                mutate_forall( node );
    17341754                maybe_accept( node, &TraitInstType::params );
    1735         )
     1755        })
    17361756
    17371757        VISIT_END( Type, node );
     
    17451765
    17461766        VISIT(
    1747                 maybe_accept( node, &TypeInstType::forall );
    1748                 maybe_accept( node, &TypeInstType::params );
     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 );
    17491774        )
    17501775
  • src/AST/Pass.proto.hpp

    r6be3b7d6 re0e9a0b  
    263263                template<typename pass_t>
    264264                static inline void leave( pass_t &, long ) {}
    265         };
    266 
    267         // Finally certain pass desire an up to date symbol table automatically
     265        } // namespace scope
     266
     267        // Certain passes 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 {
     
    356356                #undef SYMTAB_FUNC1
    357357                #undef SYMTAB_FUNC2
    358         };
    359 };
    360 };
     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
  • src/AST/Type.cpp

    r6be3b7d6 re0e9a0b  
    2121
    2222#include "Decl.hpp"
     23#include "ForallSubstitutor.hpp" // for substituteForall
    2324#include "Init.hpp"
     25#include "Common/utility.h"      // for copy, move
    2426#include "InitTweak/InitTweak.h" // for getPointerBase
    2527#include "Tuples/Tuples.h"       // for isTtype
     
    9193);
    9294
     95// --- ParameterizedType
     96
     97void ParameterizedType::initWithSub(
     98        const ParameterizedType & o, Pass< ForallSubstitutor > & sub
     99) {
     100        forall = sub.pass( o.forall );
     101}
     102
    93103// --- FunctionType
     104
     105FunctionType::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}
    94113
    95114namespace {
     
    107126
    108127// --- ReferenceToType
     128
     129void 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
     134ReferenceToType::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
    109141std::vector<readonly<Decl>> ReferenceToType::lookup( const std::string& name ) const {
    110142        assertf( aggr(), "Must have aggregate to perform lookup" );
     
    119151// --- StructInstType
    120152
    121 StructInstType::StructInstType( const StructDecl * b, CV::Qualifiers q,
    122         std::vector<ptr<Attribute>>&& as )
    123 : ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
     153StructInstType::StructInstType(
     154        const StructDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
     155: ReferenceToType( b->name, q, move(as) ), base( b ) {}
    124156
    125157bool StructInstType::isComplete() const { return base ? base->body : false; }
     
    127159// --- UnionInstType
    128160
    129 UnionInstType::UnionInstType( const UnionDecl * b, CV::Qualifiers q,
    130         std::vector<ptr<Attribute>>&& as )
    131 : ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
     161UnionInstType::UnionInstType(
     162        const UnionDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
     163: ReferenceToType( b->name, q, move(as) ), base( b ) {}
    132164
    133165bool UnionInstType::isComplete() const { return base ? base->body : false; }
     
    135167// --- EnumInstType
    136168
    137 EnumInstType::EnumInstType( const EnumDecl * b, CV::Qualifiers q,
    138         std::vector<ptr<Attribute>>&& as )
    139 : ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
     169EnumInstType::EnumInstType(
     170        const EnumDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
     171: ReferenceToType( b->name, q, move(as) ), base( b ) {}
    140172
    141173bool EnumInstType::isComplete() const { return base ? base->body : false; }
     
    143175// --- TraitInstType
    144176
    145 TraitInstType::TraitInstType( const TraitDecl * b, CV::Qualifiers q,
    146         std::vector<ptr<Attribute>>&& as )
    147 : ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
     177TraitInstType::TraitInstType(
     178        const TraitDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
     179: ReferenceToType( b->name, q, move(as) ), base( b ) {}
    148180
    149181// --- TypeInstType
     182
     183TypeInstType::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}
    150189
    151190void TypeInstType::set_base( const TypeDecl * b ) {
     
    159198
    160199TupleType::TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q )
    161 : Type( q ), types( std::move(ts) ), members() {
     200: Type( q ), types( move(ts) ), members() {
    162201        // This constructor is awkward. `TupleType` needs to contain objects so that members can be
    163202        // named, but members without initializer nodes end up getting constructors, which breaks
  • src/AST/Type.hpp

    r6be3b7d6 re0e9a0b  
    3333
    3434namespace ast {
     35
     36template< typename T > class Pass;
     37class ForallSubstitutor;
    3538
    3639class Type : public Node {
     
    266269/// Base type for potentially forall-qualified types
    267270class ParameterizedType : public Type {
     271protected:
     272        /// initializes forall with substitutor
     273        void initWithSub( const ParameterizedType & o, Pass< ForallSubstitutor > & sub );
    268274public:
    269275        using ForallList = std::vector<ptr<TypeDecl>>;
     
    278284        : Type(q, std::move(as)), forall() {}
    279285
    280         ParameterizedType( const ParameterizedType & o ) : Type( o ), forall() {
    281                 // one-level deep clone to avoid weak-reference errors
    282                 forall.reserve( o.forall.size() );
    283                 for ( const TypeDecl * d : o.forall ) { forall.emplace_back( d->clone() ); }
    284         }
     286        // enforce use of ForallSubstitutor to copy parameterized type
     287        ParameterizedType( const ParameterizedType & ) = delete;
    285288
    286289        ParameterizedType( ParameterizedType && ) = default;
     
    312315        : ParameterizedType(q), returns(), params(), isVarArgs(va) {}
    313316
     317        FunctionType( const FunctionType & o );
     318
    314319        /// true if either the parameters or return values contain a tttype
    315320        bool isTtype() const;
     
    325330/// base class for types that refer to types declared elsewhere (aggregates and typedefs)
    326331class ReferenceToType : public ParameterizedType {
     332protected:
     333        /// Initializes forall and parameters based on substitutor
     334        void initWithSub( const ReferenceToType & o, Pass< ForallSubstitutor > & sub );
    327335public:
    328336        std::vector<ptr<Expr>> params;
     
    330338        bool hoistType = false;
    331339
    332         ReferenceToType( const std::string& n, CV::Qualifiers q = {},
    333                 std::vector<ptr<Attribute>> && as = {} )
     340        ReferenceToType(
     341                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    334342        : ParameterizedType(q, std::move(as)), params(), name(n) {}
     343
     344        ReferenceToType( const ReferenceToType & o );
    335345
    336346        /// Gets aggregate declaration this type refers to
     
    349359        readonly<StructDecl> base;
    350360
    351         StructInstType( const std::string& n, CV::Qualifiers q = {},
    352                 std::vector<ptr<Attribute>> && as = {} )
     361        StructInstType(
     362                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    353363        : ReferenceToType( n, q, std::move(as) ), base() {}
    354         StructInstType( const StructDecl * b, CV::Qualifiers q = {},
    355                 std::vector<ptr<Attribute>> && as = {} );
     364
     365        StructInstType(
     366                const StructDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
    356367
    357368        bool isComplete() const override;
     
    370381        readonly<UnionDecl> base;
    371382
    372         UnionInstType( const std::string& n, CV::Qualifiers q = {},
    373                 std::vector<ptr<Attribute>> && as = {} )
     383        UnionInstType(
     384                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    374385        : ReferenceToType( n, q, std::move(as) ), base() {}
    375         UnionInstType( const UnionDecl * b, CV::Qualifiers q = {},
    376                 std::vector<ptr<Attribute>> && as = {} );
     386
     387        UnionInstType(
     388                const UnionDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
    377389
    378390        bool isComplete() const override;
     
    391403        readonly<EnumDecl> base;
    392404
    393         EnumInstType( const std::string& n, CV::Qualifiers q = {},
    394                 std::vector<ptr<Attribute>> && as = {} )
     405        EnumInstType(
     406                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    395407        : ReferenceToType( n, q, std::move(as) ), base() {}
    396         EnumInstType( const EnumDecl * b, CV::Qualifiers q = {},
    397                 std::vector<ptr<Attribute>> && as = {} );
     408
     409        EnumInstType(
     410                const EnumDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
    398411
    399412        bool isComplete() const override;
     
    412425        readonly<TraitDecl> base;
    413426
    414         TraitInstType( const std::string& n, CV::Qualifiers q = {},
    415                 std::vector<ptr<Attribute>> && as = {} )
     427        TraitInstType(
     428                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    416429        : ReferenceToType( n, q, std::move(as) ), base() {}
    417         TraitInstType( const TraitDecl * b, CV::Qualifiers q = {},
    418                 std::vector<ptr<Attribute>> && as = {} );
     430       
     431        TraitInstType(
     432                const TraitDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
    419433
    420434        // not meaningful for TraitInstType
     
    435449        TypeVar::Kind kind;
    436450
    437         TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
     451        TypeInstType(
     452                const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
    438453                std::vector<ptr<Attribute>> && as = {} )
    439454        : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
    440         TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
     455       
     456        TypeInstType(
     457                const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
    441458                std::vector<ptr<Attribute>> && as = {} )
    442459        : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {}
     460
     461        TypeInstType( const TypeInstType & o );
    443462
    444463        /// sets `base`, updating `kind` correctly
  • src/AST/module.mk

    r6be3b7d6 re0e9a0b  
    2222        AST/DeclReplacer.cpp \
    2323        AST/Expr.cpp \
     24        AST/ForallSubstitutionTable.cpp \
    2425        AST/GenericSubstitution.cpp \
    2526        AST/Init.cpp \
  • src/Common/ScopedMap.h

    r6be3b7d6 re0e9a0b  
    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; }
    251253        Note& getNote( size_type i ) { return scopes[i].note; }
    252254        const Note& getNote( size_type i ) const { return scopes[i].note; }
  • src/Makefile.in

    r6be3b7d6 re0e9a0b  
    168168        AST/Convert.$(OBJEXT) AST/Decl.$(OBJEXT) \
    169169        AST/DeclReplacer.$(OBJEXT) AST/Expr.$(OBJEXT) \
     170        AST/ForallSubstitutionTable.$(OBJEXT) \
    170171        AST/GenericSubstitution.$(OBJEXT) AST/Init.$(OBJEXT) \
    171172        AST/LinkageSpec.$(OBJEXT) AST/Node.$(OBJEXT) \
     
    585586        AST/DeclReplacer.cpp \
    586587        AST/Expr.cpp \
     588        AST/ForallSubstitutionTable.cpp \
    587589        AST/GenericSubstitution.cpp \
    588590        AST/Init.cpp \
     
    759761        AST/$(DEPDIR)/$(am__dirstamp)
    760762AST/Expr.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     763AST/ForallSubstitutionTable.$(OBJEXT): AST/$(am__dirstamp) \
     764        AST/$(DEPDIR)/$(am__dirstamp)
    761765AST/GenericSubstitution.$(OBJEXT): AST/$(am__dirstamp) \
    762766        AST/$(DEPDIR)/$(am__dirstamp)
     
    12121216@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/DeclReplacer.Po@am__quote@
    12131217@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@
    12141219@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/GenericSubstitution.Po@am__quote@
    12151220@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Init.Po@am__quote@
  • src/ResolvExpr/CandidateFinder.cpp

    r6be3b7d6 re0e9a0b  
    548548                genStart = genEnd;
    549549
    550                 return genEnd != results.size();
     550                return genEnd != results.size();  // were any new results added?
    551551        }
    552552
     
    677677                        ast::TypeEnvironment funcEnv{ func->env };
    678678                        makeUnifiableVars( funcType, funcOpen, funcNeed );
    679                         // add all type variables as open variables now so that those not used in the parameter
    680                         // list are still considered open
     679                        // add all type variables as open variables now so that those not used in the
     680                        // parameter list are still considered open
    681681                        funcEnv.add( funcType->forall );
    682682
  • src/ResolvExpr/RenameVars.cc

    r6be3b7d6 re0e9a0b  
    1919#include <utility>                 // for pair
    2020
     21#include "AST/ForallSubstitutionTable.hpp"
    2122#include "AST/Pass.hpp"
    2223#include "AST/Type.hpp"
     
    3738                int resetCount = 0;
    3839                ScopedMap< std::string, std::string > nameMap;
     40        public:
     41                ast::ForallSubstitutionTable subs;
    3942
    40         public:
    4143                void reset() {
    4244                        level = 0;
     
    4446                }
    4547
    46                 using mapConstIterator = ScopedMap< std::string, std::string >::const_iterator;
    47 
    4848                void rename( TypeInstType * type ) {
    49                         mapConstIterator it = nameMap.find( type->name );
     49                        auto it = nameMap.find( type->name );
    5050                        if ( it != nameMap.end() ) {
    5151                                type->name = it->second;
     
    6565                                        // ditto for assertion names, the next level in
    6666                                        level++;
    67                                         // acceptAll( td->assertions, *this );
    68                                 } // for
    69                         } // if
     67                                }
     68                        }
    7069                }
    7170
     
    7776
    7877                const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
    79                         mapConstIterator it = nameMap.find( type->name );
     78                        // re-linking of base type handled by WithForallSubstitutor
     79
     80                        // rename
     81                        auto it = nameMap.find( type->name );
    8082                        if ( it != nameMap.end() ) {
    81                                 ast::TypeInstType * mutType = ast::mutate( type );
    82                                 mutType->name = it->second;
    83                     type = mutType;
     83                                // unconditionally mutate because map will *always* have different name,
     84                                // if this mutates, will *always* have been mutated by ForallSubstitutor above
     85                                ast::TypeInstType * mut = ast::mutate( type );
     86                                mut->name = it->second;
     87                    type = mut;
    8488                        }
     89
    8590                        return type;
    8691                }
     
    8893                template<typename NodeT>
    8994                const NodeT * openLevel( const NodeT * type ) {
    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;
     95                        if ( type->forall.empty() ) return type;
     96                       
     97                        nameMap.beginScope();
    10098
    101                                         ast::TypeDecl * decl = ast::mutate( td.get() );
    102                                         decl->name = newname;
    103                                         td = decl;
    104                                 }
     99                        // Load new names from this forall clause and perform renaming.
     100                        NodeT * mutType = ast::mutate( type );
     101                        assert( type == mutType && "mutated type must be unique from ForallSubstitutor" );
     102                        for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
     103                                std::ostringstream output;
     104                                output << "_" << resetCount << "_" << level << "_" << td->name;
     105                                std::string newname =  output.str();
     106                                nameMap[ td->name ] = newname;
     107                                ++level;
     108
     109                                ast::TypeDecl * mutDecl = ast::mutate( td.get() );
     110                                assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" );
     111                                mutDecl->name = newname;
     112                                // assertion above means `td = mutDecl;` is unnecessary
    105113                        }
     114                        // assertion above means `type = mutType;` is unnecessary
     115
    106116                        return type;
    107117                }
    108118
    109                 template<typename NodeT>
    110                 const NodeT * closeLevel( const NodeT * type ) {
    111                         if ( !type->forall.empty() ) {
    112                                 nameMap.endScope();
    113                         }
    114                         return type;
     119                void closeLevel( const ast::ParameterizedType * type ) {
     120                        if ( type->forall.empty() ) return;
     121                       
     122                        nameMap.endScope();
    115123                }
    116124        };
     
    119127        RenamingData renaming;
    120128
    121         struct RenameVars {
     129        struct RenameVars_old {
    122130                void previsit( TypeInstType * instType ) {
    123131                        renaming.openLevel( (Type*)instType );
     
    130138                        renaming.closeLevel( type );
    131139                }
     140        };
     141       
     142        struct RenameVars_new /*: public ast::WithForallSubstitutor*/ {
     143                #warning when old RenameVars goes away, replace hack below with global pass inheriting from WithForallSubstitutor
     144                ast::ForallSubstitutionTable & subs = renaming.subs;
    132145
    133146                const ast::FunctionType * previsit( const ast::FunctionType * type ) {
     
    146159                        return renaming.rename( renaming.openLevel( type ) );
    147160                }
    148                 const ast::ParameterizedType * postvisit( const ast::ParameterizedType * type ) {
    149                         return renaming.closeLevel( type );
     161                void postvisit( const ast::ParameterizedType * type ) {
     162                        renaming.closeLevel( type );
    150163                }
    151164        };
     
    154167
    155168void renameTyVars( Type * t ) {
    156         PassVisitor<RenameVars> renamer;
     169        PassVisitor<RenameVars_old> renamer;
    157170        t->accept( renamer );
    158171}
    159172
    160173const ast::Type * renameTyVars( const ast::Type * t ) {
    161         ast::Pass<RenameVars> renamer;
     174        ast::Pass<RenameVars_new> renamer;
    162175        return t->accept( renamer );
    163176}
Note: See TracChangeset for help on using the changeset viewer.