Changeset 4864a73


Ignore:
Timestamp:
Jun 5, 2019, 4:28:28 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
0ce063b
Parents:
2a8f0c1
Message:

Added chain mutation and example use in resolver

Location:
src
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Node.cpp

    r2a8f0c1 r4864a73  
    3434template< typename node_t, enum ast::Node::ref_type ref_t >
    3535void 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); }
    3639
    3740template< typename node_t, enum ast::Node::ref_type ref_t >
  • src/AST/Node.hpp

    r2a8f0c1 r4864a73  
    4646        };
    4747
     48        bool unique() const { return strong_count == 1; }
     49
    4850private:
    4951        /// Make a copy of this node; should be overridden in subclass with more precise return type
     
    5658        mutable size_t strong_count = 0;
    5759        mutable size_t weak_count = 0;
     60        mutable bool was_ever_strong = false;
    5861
    5962        void increment(ref_type ref) const {
    6063                switch (ref) {
    61                         case ref_type::strong: strong_count++; break;
     64                        case ref_type::strong: strong_count++; was_ever_strong = true; break;
    6265                        case ref_type::weak  : weak_count  ++; break;
    6366                }
     
    176179        }
    177180
    178         const node_t * get() const { return  node; }
    179         const node_t * operator->() const { return  node; }
    180         const node_t & operator* () const { return *node; }
    181         explicit operator bool() const { return node; }
    182         operator const node_t * () const { return node; }
     181        const node_t * get() const { _check(); return  node; }
     182        const node_t * operator->() const { _check(); return  node; }
     183        const node_t & operator* () const { _check(); return *node; }
     184        explicit operator bool() const { _check(); return node; }
     185        operator const node_t * () const { _check(); return node; }
    183186
    184187        /// wrapper for convenient access to dynamic_cast
    185188        template<typename o_node_t>
    186         const o_node_t * as() const { return dynamic_cast<const o_node_t *>(node); }
     189        const o_node_t * as() const { _check(); return dynamic_cast<const o_node_t *>(node); }
    187190
    188191        /// wrapper for convenient access to strict_dynamic_cast
     
    208211        void _inc( const node_t * other );
    209212        void _dec( const node_t * other );
     213        void _check() const;
    210214
    211215protected:
  • src/ResolvExpr/Resolver.cc

    r2a8f0c1 r4864a73  
    2727#include "typeops.h"                     // for extractResultType
    2828#include "Unify.h"                       // for unify
     29#include "AST/Chain.hpp"
    2930#include "AST/Decl.hpp"
    3031#include "AST/Init.hpp"
     
    407408
    408409        void Resolver_old::previsit( ObjectDecl * objectDecl ) {
    409                 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 
    410                 // class-variable initContext is changed multiple time because the LHS is analysed twice. 
    411                 // The second analysis changes initContext because of a function type can contain object 
    412                 // declarations in the return and parameter types. So each value of initContext is 
     410                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that
     411                // class-variable initContext is changed multiple time because the LHS is analysed twice.
     412                // The second analysis changes initContext because of a function type can contain object
     413                // declarations in the return and parameter types. So each value of initContext is
    413414                // retained, so the type on the first analysis is preserved and used for selecting the RHS.
    414415                GuardValue( currentObject );
     
    447448
    448449        void Resolver_old::postvisit( FunctionDecl * functionDecl ) {
    449                 // default value expressions have an environment which shouldn't be there and trips up 
     450                // default value expressions have an environment which shouldn't be there and trips up
    450451                // later passes.
    451452                // xxx - it might be necessary to somehow keep the information from this environment, but I
     
    939940        ///////////////////////////////////////////////////////////////////////////
    940941
    941         class Resolver_new final 
    942         : public ast::WithSymbolTable, public ast::WithGuards, 
    943           public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting, 
     942        class Resolver_new final
     943        : public ast::WithSymbolTable, public ast::WithGuards,
     944          public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting,
    944945          public ast::WithStmtsToAdd<> {
    945        
     946
    946947                ast::ptr< ast::Type > functionReturn = nullptr;
    947948                // ast::CurrentObject currentObject = nullptr;
    948949                // bool inEnumDecl = false;
    949950
    950         public: 
     951        public:
    951952                Resolver_new() = default;
    952953                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
     
    991992
    992993        const ast::FunctionDecl * Resolver_new::postvisit( const ast::FunctionDecl * functionDecl ) {
    993                 // default value expressions have an environment which shouldn't be there and trips up 
     994                // default value expressions have an environment which shouldn't be there and trips up
    994995                // later passes.
    995996                ast::ptr< ast::FunctionDecl > ret = functionDecl;
    996997                for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {
    997998                        const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i];
    998                        
     999
    9991000                        if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {
    10001001                                if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) {
    10011002                                        if ( init->value->env == nullptr ) continue;
    10021003                                        // clone initializer minus the initializer environment
    1003                                         strict_dynamic_cast< ast::SingleInit * >(
    1004                                                 strict_dynamic_cast< ast::ObjectDecl * >(
    1005                                                         ret.get_and_mutate()->type.get_and_mutate()->params[i].get_and_mutate()
    1006                                                 )->init.get_and_mutate()
    1007                                         )->value.get_and_mutate()->env = nullptr;
     1004                                        ast::chain_mutate( ret )
     1005                                                ( &ast::FunctionDecl::type )
     1006                                                        ( &ast::FunctionType::params )
     1007                                                                [i]
     1008                                                                ( &ast::ObjectDecl::init )
     1009                                                                        ( &ast::SingleInit::value )->env = nullptr;
     1010
     1011                                        assert( functionDecl != ret.get() || functionDecl->unique() );
     1012                                        assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env );
    10081013                                }
    10091014                        }
Note: See TracChangeset for help on using the changeset viewer.