Ignore:
Timestamp:
Nov 9, 2016, 2:21:05 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
b726084
Parents:
23bb1b9
Message:

rework UniqueExpr?, handle UniqueExpr? in FixInit?, fix translation for UniqueExprs?, refactor explode functions and fix AddressExpr? distribution over exploded tuple exprs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r23bb1b9 r141b786  
    6565                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit );
    6666
     67                        typedef SymTab::Indexer Parent;
     68                        using Parent::visit;
     69
    6770                        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
     71                        virtual void visit( UniqueExpr * unqExpr );
    6872
    6973                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
     
    178182
    179183                        virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr );
     184                        virtual Expression * mutate( UniqueExpr * unqExpr );
    180185                };
    181186
     
    421426                void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    422427                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    423                         Visitor::visit( impCpCtorExpr );
     428                        Parent::visit( impCpCtorExpr );
    424429                        env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer...
    425430
     
    455460                }
    456461
     462                void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) {
     463                        static std::unordered_set< int > vars;
     464                        if ( vars.count( unqExpr->get_id() ) ) {
     465                                // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
     466                                return;
     467                        }
     468
     469                        Parent::visit( unqExpr );
     470                        // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought
     471                        assert( unqExpr->get_result() );
     472                        if ( ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast<ImplicitCopyCtorExpr*>( unqExpr->get_expr() ) ) {
     473                                // note the variable used as the result from the call
     474                                assert( impCpCtorExpr->get_result() && impCpCtorExpr->get_returnDecls().size() == 1 );
     475                                unqExpr->set_var( new VariableExpr( impCpCtorExpr->get_returnDecls().front() ) );
     476                        } else {
     477                                // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
     478                                unqExpr->set_object( new ObjectDecl( toString("_unq_expr_", unqExpr->get_id()), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) );
     479                                unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
     480                        }
     481                        vars.insert( unqExpr->get_id() );
     482                }
     483
    457484
    458485                Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     
    526553                                return callExpr;
    527554                        } // if
     555                }
     556
     557                Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
     558                        static std::unordered_map< int, UniqueExpr * > unqMap;
     559                        static std::unordered_set< int > addDeref;
     560                        // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
     561                        unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) );
     562                        if ( unqMap.count( unqExpr->get_id() ) ) {
     563                                // take data from other UniqueExpr to ensure consistency
     564                                delete unqExpr->get_expr();
     565                                unqExpr->set_expr( unqMap[unqExpr->get_id()]->get_expr()->clone() );
     566                                delete unqExpr->get_result();
     567                                unqExpr->set_result( maybeClone( unqExpr->get_expr()->get_result() ) );
     568                                if ( addDeref.count( unqExpr->get_id() ) ) {
     569                                        // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too
     570                                        return UntypedExpr::createDeref( unqExpr );
     571                                }
     572                                return unqExpr;
     573                        }
     574                        unqMap[unqExpr->get_id()] = unqExpr;
     575                        if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
     576                                // unique expression is now a dereference, because the inner expression is an lvalue returning function call.
     577                                // Normalize the expression by dereferencing the unique expression, rather than the inner expression
     578                                // (i.e. move the dereference out a level)
     579                                assert( getFunctionName( deref ) == "*?" );
     580                                unqExpr->set_expr( getCallArg( deref, 0 ) );
     581                                getCallArg( deref, 0 ) = unqExpr;
     582                                addDeref.insert( unqExpr->get_id() );
     583                                return deref;
     584                        }
     585                        return unqExpr;
    528586                }
    529587
Note: See TracChangeset for help on using the changeset viewer.