Changeset 4b0f997


Ignore:
Timestamp:
Apr 11, 2017, 2:34:28 PM (7 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:
32bcef7
Parents:
5a48d79
Message:

fix implicit conversion to anonymous members

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r5a48d79 r4b0f997  
    211211        }
    212212
    213         // std::unordered_map< Expression *, UniqueExpr * > ;
     213        void AlternativeFinder::addAnonConversions( const Alternative & alt ) {
     214                // adds anonymous member interpretations whenever an aggregate value type is seen.
     215                Expression * expr = alt.expr->clone();
     216                std::unique_ptr< Expression > manager( expr ); // RAII for expr
     217                alt.env.apply( expr->get_result() );
     218                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( expr->get_result() ) ) {
     219                        NameExpr nameExpr( "" );
     220                        addAggMembers( structInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
     221                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( expr->get_result() ) ) {
     222                        NameExpr nameExpr( "" );
     223                        addAggMembers( unionInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
     224                } // if
     225        }
    214226
    215227        template< typename StructOrUnionType >
     
    220232                std::list< Declaration* > members;
    221233                aggInst->lookup( name, members );
     234
    222235                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    223236                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    224237                                alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    225238                                renameTypes( alternatives.back().expr );
     239                                addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
    226240                        } else {
    227241                                assert( false );
     
    730744                if ( candidates.empty() && ! errors.isEmpty() ) { throw errors; }
    731745
     746                // compute conversionsion costs
    732747                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    733748                        Cost cvtCost = computeConversionCost( *withFunc, indexer );
     
    751766                        } // if
    752767                } // for
     768                // function may return struct or union value, in which case we need to add alternatives for implicit conversions to each of the anonymous members
     769                for ( const Alternative & alt : alternatives ) {
     770                        addAnonConversions( alt );
     771                }
     772
    753773                candidates.clear();
    754774                candidates.splice( candidates.end(), alternatives );
     
    885905                        )
    886906                        renameTypes( alternatives.back().expr );
    887                         if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    888                                 NameExpr nameExpr( "" );
    889                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    890                         } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    891                                 NameExpr nameExpr( "" );
    892                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    893                         } // if
     907                        addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
    894908                } // for
    895909        }
  • src/ResolvExpr/AlternativeFinder.h

    r5a48d79 r4b0f997  
    7878                void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    7979
     80                /// Adds alternatives for anonymous members
     81                void addAnonConversions( const Alternative & alt );
    8082                /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
    8183                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
  • src/SymTab/Autogen.cc

    r5a48d79 r4b0f997  
    498498                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) );
    499499                if ( returnVal ) {
    500                         if ( isDynamicLayout ) makeUnionFieldsAssignment( srcParam, returnVal, back_inserter( funcDecl->get_statements()->get_kids() ) );
    501                         else funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     500                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    502501                }
    503502        }
  • src/SynTree/Expression.cc

    r5a48d79 r4b0f997  
    339339                        return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() );
    340340                } else {
    341                         assertf( false, "makeSub expects struct or union type for aggregate" );
     341                        assertf( false, "makeSub expects struct or union type for aggregate, but got: %s", toString( t ).c_str() );
    342342                }
    343343        }
Note: See TracChangeset for help on using the changeset viewer.