Changeset bf32bb8


Ignore:
Timestamp:
Oct 18, 2016, 4:23:04 PM (5 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
f0121d7
Parents:
848ce71
Message:

implement transformation for MemberTupleExprs?

Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.cc

    r848ce71 rbf32bb8  
    10231023static const yytype_uint16 yyrline[] =
    10241024{
    1025        0,   302,   302,   306,   313,   314,   315,   319,   320,   321,
    1026      325,   326,   330,   331,   335,   336,   340,   344,   345,   356,
    1027      358,   360,   362,   367,   368,   374,   378,   380,   382,   384,
    1028      386,   388,   390,   392,   394,   403,   404,   410,   411,   415,
    1029      416,   420,   424,   426,   428,   430,   435,   436,   440,   443,
     1025       0,   301,   301,   305,   312,   313,   314,   318,   319,   320,
     1026     324,   325,   329,   330,   334,   335,   339,   343,   344,   355,
     1027     357,   359,   361,   366,   367,   373,   377,   379,   381,   383,
     1028     385,   387,   389,   391,   393,   402,   403,   409,   410,   414,
     1029     415,   419,   422,   424,   426,   428,   433,   435,   440,   443,
    10301030     445,   447,   452,   465,   467,   469,   471,   473,   475,   477,
    10311031     479,   481,   483,   485,   492,   493,   499,   500,   501,   502,
     
    49774977
    49784978/* Line 1806 of yacc.c  */
    4979 #line 302 "parser.yy"
     4979#line 301 "parser.yy"
    49804980    { typedefTable.enterScope(); }
    49814981    break;
     
    49844984
    49854985/* Line 1806 of yacc.c  */
    4986 #line 306 "parser.yy"
     4986#line 305 "parser.yy"
    49874987    { typedefTable.leaveScope(); }
    49884988    break;
     
    49914991
    49924992/* Line 1806 of yacc.c  */
     4993#line 312 "parser.yy"
     4994    { (yyval.en) = new ExpressionNode( build_constantInteger( *(yyvsp[(1) - (1)].tok) ) ); }
     4995    break;
     4996
     4997  case 5:
     4998
     4999/* Line 1806 of yacc.c  */
    49935000#line 313 "parser.yy"
    4994     { (yyval.en) = new ExpressionNode( build_constantInteger( *(yyvsp[(1) - (1)].tok) ) ); }
    4995     break;
    4996 
    4997   case 5:
     5001    { (yyval.en) = new ExpressionNode( build_constantFloat( *(yyvsp[(1) - (1)].tok) ) ); }
     5002    break;
     5003
     5004  case 6:
    49985005
    49995006/* Line 1806 of yacc.c  */
    50005007#line 314 "parser.yy"
    5001     { (yyval.en) = new ExpressionNode( build_constantFloat( *(yyvsp[(1) - (1)].tok) ) ); }
    5002     break;
    5003 
    5004   case 6:
    5005 
    5006 /* Line 1806 of yacc.c  */
    5007 #line 315 "parser.yy"
    50085008    { (yyval.en) = new ExpressionNode( build_constantChar( *(yyvsp[(1) - (1)].tok) ) ); }
    50095009    break;
     
    50125012
    50135013/* Line 1806 of yacc.c  */
    5014 #line 340 "parser.yy"
     5014#line 339 "parser.yy"
    50155015    { (yyval.constant) = build_constantStr( *(yyvsp[(1) - (1)].str) ); }
    50165016    break;
     
    50195019
    50205020/* Line 1806 of yacc.c  */
    5021 #line 344 "parser.yy"
     5021#line 343 "parser.yy"
    50225022    { (yyval.str) = (yyvsp[(1) - (1)].tok); }
    50235023    break;
     
    50265026
    50275027/* Line 1806 of yacc.c  */
    5028 #line 346 "parser.yy"
     5028#line 345 "parser.yy"
    50295029    {
    50305030                        appendStr( (yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].tok) );                                            // append 2nd juxtaposed string to 1st
     
    50375037
    50385038/* Line 1806 of yacc.c  */
    5039 #line 357 "parser.yy"
     5039#line 356 "parser.yy"
    50405040    { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); }
    50415041    break;
     
    50445044
    50455045/* Line 1806 of yacc.c  */
    5046 #line 359 "parser.yy"
     5046#line 358 "parser.yy"
    50475047    { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); }
    50485048    break;
     
    50515051
    50525052/* Line 1806 of yacc.c  */
    5053 #line 361 "parser.yy"
     5053#line 360 "parser.yy"
    50545054    { (yyval.en) = (yyvsp[(2) - (3)].en); }
    50555055    break;
     
    50585058
    50595059/* Line 1806 of yacc.c  */
    5060 #line 363 "parser.yy"
     5060#line 362 "parser.yy"
    50615061    { (yyval.en) = new ExpressionNode( build_valexpr( (yyvsp[(2) - (3)].sn) ) ); }
    50625062    break;
     
    50655065
    50665066/* Line 1806 of yacc.c  */
    5067 #line 373 "parser.yy"
     5067#line 372 "parser.yy"
    50685068    { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Index, (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en) ) ); }
    50695069    break;
     
    50725072
    50735073/* Line 1806 of yacc.c  */
    5074 #line 375 "parser.yy"
     5074#line 374 "parser.yy"
    50755075    { (yyval.en) = new ExpressionNode( build_func( (yyvsp[(1) - (4)].en), (yyvsp[(3) - (4)].en) ) ); }
    50765076    break;
     
    50795079
    50805080/* Line 1806 of yacc.c  */
    5081 #line 379 "parser.yy"
     5081#line 378 "parser.yy"
    50825082    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); }
    50835083    break;
     
    50865086
    50875087/* Line 1806 of yacc.c  */
    5088 #line 381 "parser.yy"
     5088#line 380 "parser.yy"
    50895089    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
    50905090    break;
     
    50935093
    50945094/* Line 1806 of yacc.c  */
    5095 #line 383 "parser.yy"
     5095#line 382 "parser.yy"
    50965096    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (3)].en), build_constantInteger( *(yyvsp[(3) - (3)].tok) ) ) ); }
    50975097    break;
     
    51005100
    51015101/* Line 1806 of yacc.c  */
    5102 #line 385 "parser.yy"
     5102#line 384 "parser.yy"
    51035103    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); }
    51045104    break;
     
    51075107
    51085108/* Line 1806 of yacc.c  */
    5109 #line 387 "parser.yy"
     5109#line 386 "parser.yy"
    51105110    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
    51115111    break;
     
    51145114
    51155115/* Line 1806 of yacc.c  */
    5116 #line 389 "parser.yy"
     5116#line 388 "parser.yy"
    51175117    { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, (yyvsp[(1) - (2)].en) ) ); }
    51185118    break;
     
    51215121
    51225122/* Line 1806 of yacc.c  */
    5123 #line 391 "parser.yy"
     5123#line 390 "parser.yy"
    51245124    { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, (yyvsp[(1) - (2)].en) ) ); }
    51255125    break;
     
    51285128
    51295129/* Line 1806 of yacc.c  */
    5130 #line 393 "parser.yy"
     5130#line 392 "parser.yy"
    51315131    { (yyval.en) = new ExpressionNode( build_compoundLiteral( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ) ); }
    51325132    break;
     
    51355135
    51365136/* Line 1806 of yacc.c  */
    5137 #line 395 "parser.yy"
     5137#line 394 "parser.yy"
    51385138    {
    51395139                        Token fn;
     
    51465146
    51475147/* Line 1806 of yacc.c  */
    5148 #line 405 "parser.yy"
     5148#line 404 "parser.yy"
    51495149    { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); }
    51505150    break;
     
    51535153
    51545154/* Line 1806 of yacc.c  */
    5155 #line 410 "parser.yy"
     5155#line 409 "parser.yy"
    51565156    { (yyval.en) = 0; }
    51575157    break;
     
    51605160
    51615161/* Line 1806 of yacc.c  */
    5162 #line 416 "parser.yy"
     5162#line 415 "parser.yy"
    51635163    { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
    51645164    break;
    51655165
    5166   case 41:
     5166  case 42:
    51675167
    51685168/* Line 1806 of yacc.c  */
    51695169#line 423 "parser.yy"
     5170    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (3)].en), maybeMoveBuild<Expression>( (yyvsp[(3) - (3)].en) ) ) ); }
     5171    break;
     5172
     5173  case 43:
     5174
     5175/* Line 1806 of yacc.c  */
     5176#line 425 "parser.yy"
     5177    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
     5178    break;
     5179
     5180  case 44:
     5181
     5182/* Line 1806 of yacc.c  */
     5183#line 427 "parser.yy"
     5184    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), maybeMoveBuild<Expression>( (yyvsp[(3) - (3)].en) ) ) ); }
     5185    break;
     5186
     5187  case 45:
     5188
     5189/* Line 1806 of yacc.c  */
     5190#line 429 "parser.yy"
     5191    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
     5192    break;
     5193
     5194  case 46:
     5195
     5196/* Line 1806 of yacc.c  */
     5197#line 434 "parser.yy"
    51705198    { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); }
    51715199    break;
    51725200
    5173   case 42:
    5174 
    5175 /* Line 1806 of yacc.c  */
    5176 #line 425 "parser.yy"
    5177     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }
    5178     break;
    5179 
    5180   case 43:
    5181 
    5182 /* Line 1806 of yacc.c  */
    5183 #line 427 "parser.yy"
    5184     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }
    5185     break;
    5186 
    5187   case 44:
    5188 
    5189 /* Line 1806 of yacc.c  */
    5190 #line 429 "parser.yy"
    5191     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }
    5192     break;
    5193 
    5194   case 45:
    5195 
    5196 /* Line 1806 of yacc.c  */
    5197 #line 431 "parser.yy"
    5198     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }
     5201  case 47:
     5202
     5203/* Line 1806 of yacc.c  */
     5204#line 436 "parser.yy"
     5205    { (yyval.en) = new ExpressionNode( build_constantInteger( *(yyvsp[(1) - (1)].tok) ) ); }
    51995206    break;
    52005207
     
    92089215
    92099216/* Line 1806 of yacc.c  */
    9210 #line 9211 "Parser/parser.cc"
     9217#line 9218 "Parser/parser.cc"
    92119218      default: break;
    92129219    }
  • src/Parser/parser.yy

    r848ce71 rbf32bb8  
    195195
    196196%type<decl> field_declaration field_declaration_list field_declarator field_declaring_list
    197 %type<en> field field_list
    198 %type<tok> field_name
     197%type<en> field field_list field_name
    199198
    200199%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    421420                // ambiguity with .0 so space required after field-selection, e.g.
    422421                //   struct S { int 0, 1; } s; s. 0 = 0; s. 1 = 1;
    423                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
    424422        | field_name '.' field
    425                 { $$ = new ExpressionNode( build_fieldSel( $3, build_varref( $1 ) ) ); }
     423                { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    426424        | field_name '.' '[' push field_list pop ']'
    427                 { $$ = new ExpressionNode( build_fieldSel( $5, build_varref( $1 ) ) ); }
     425                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
    428426        | field_name ARROW field
    429                 { $$ = new ExpressionNode( build_pfieldSel( $3, build_varref( $1 ) ) ); }
     427                { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    430428        | field_name ARROW '[' push field_list pop ']'
    431                 { $$ = new ExpressionNode( build_pfieldSel( $5, build_varref( $1 ) ) ); }
     429                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
    432430        ;
    433431
    434432field_name:
    435433        no_attr_identifier
     434                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    436435        | INTEGERconstant
     436                { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }
    437437        ;
    438438
  • src/ResolvExpr/AlternativeFinder.cc

    r848ce71 rbf32bb8  
    209209        template< typename StructOrUnionType >
    210210        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    211                 // member must be either a tuple expression or a name expr
    212                 if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    213                         const std::string & name = nameExpr->get_name();
    214                         std::list< Declaration* > members;
    215                         aggInst->lookup( name, members );
    216                         for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    217                                 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    218                                         alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    219                                         renameTypes( alternatives.back().expr );
    220                                 } else {
    221                                         assert( false );
    222                                 }
    223                         }
    224                 } else if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( member ) ) {
    225                         assert( false );
    226                 } else {
    227                         // xxx - temporary
    228                         std::cerr << member << std::endl;
    229                         assertf( false, "reached unexpected case of addAggMembers" );
     211
     212                // by this point, member must be a name expr
     213                NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
     214                const std::string & name = nameExpr->get_name();
     215                std::list< Declaration* > members;
     216                aggInst->lookup( name, members );
     217                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
     218                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
     219                                alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
     220                                renameTypes( alternatives.back().expr );
     221                        } else {
     222                                assert( false );
     223                        }
    230224                }
    231225        }
     
    10591053                alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
    10601054        }
     1055
     1056        void AlternativeFinder::visit( UniqueExpr *unqExpr ) {
     1057                AlternativeFinder finder( indexer, env );
     1058                finder.findWithAdjustment( unqExpr->get_expr() );
     1059                for ( Alternative & alt : finder.alternatives ) {
     1060                        // xxx - it's possible that this won't always do the right thing, i.e. two UniqueExprs
     1061                        // with the same ID may resolve to different expressions. If this ever happens, it might be necessary
     1062                        // to try to select an alternative here (i.e. error is there is not a unique min-cost expression).
     1063                        // One other thought is to to resolve each ID once and map the IDs to resolved expressions,
     1064                        // but this isn't as simple as it sounds since the alternative is not selected here, meaning it might
     1065                        // require complicated tracking throughout the system.
     1066
     1067                        // brand the new UniqueExprs with the same id so that they are recognized as the same expression by the expansion pass
     1068                        alternatives.push_back( Alternative( new UniqueExpr( alt.expr->clone(), unqExpr->get_id() ), env, Cost::zero ) );
     1069                }
     1070        }
     1071
    10611072} // namespace ResolvExpr
    10621073
  • src/ResolvExpr/AlternativeFinder.h

    r848ce71 rbf32bb8  
    6969                virtual void visit( TupleIndexExpr *tupleExpr );
    7070                virtual void visit( TupleAssignExpr *tupleExpr );
     71                virtual void visit( UniqueExpr *unqExpr );
    7172                /// Runs a new alternative finder on each element in [begin, end)
    7273                /// and writes each alternative finder to out.
  • src/SynTree/Expression.cc

    r848ce71 rbf32bb8  
    580580
    581581
    582 UniqueExpr::UniqueExpr( Expression *expr ) : expr( new Expression* ) {
     582long long UniqueExpr::count = 0;
     583UniqueExpr::UniqueExpr( Expression *expr, long long idVal ) : expr( new Expression* ), id( idVal ) {
     584        assert( count != -1 );
     585        if ( id == -1 ) id = count++;
    583586        set_expr( expr );
    584587        assert( expr );
    585         assert( expr->has_result() );
    586         set_result( expr->get_result()->clone() );
    587 }
    588 UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( other.expr ) {
     588        if ( expr->get_result() ) {
     589                set_result( expr->get_result()->clone() );
     590        }
     591}
     592UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( other.expr ), id( other.id ) {
    589593}
    590594UniqueExpr::~UniqueExpr() {
     
    594598}
    595599void UniqueExpr::print( std::ostream &os, int indent ) const {
    596         os << "Unique Expression: " << std::endl << std::string( indent+2, ' ' );
     600        os << "Unique Expression with id:" << id << std::endl << std::string( indent+2, ' ' );
    597601        get_expr()->print( os, indent+2 );
    598602}
  • src/SynTree/Expression.h

    r848ce71 rbf32bb8  
    735735class UniqueExpr : public Expression {
    736736public:
    737         UniqueExpr( Expression * expr );
     737        UniqueExpr( Expression * expr, long long idVal = -1 );
    738738        UniqueExpr( const UniqueExpr & other );
    739739        ~UniqueExpr();
     
    742742        UniqueExpr * set_expr( Expression * newValue ) { *expr = newValue; return this; }
    743743
     744        int get_id() const { return id; }
     745
    744746        virtual UniqueExpr *clone() const { return new UniqueExpr( *this ); }
    745747        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    748750private:
    749751        std::shared_ptr< Expression * > expr;
     752        int id;
     753        static long long count;
    750754};
    751755
  • src/Tuples/TupleExpansion.cc

    r848ce71 rbf32bb8  
    3131namespace Tuples {
    3232        namespace {
     33                class MemberTupleExpander : public Mutator {
     34                public:
     35                        typedef Mutator Parent;
     36                        virtual Expression * mutate( UntypedMemberExpr * memberExpr );
     37                };
     38
    3339                class UniqueExprExpander : public GenPoly::DeclMutator {
    3440                public:
    3541                        typedef GenPoly::DeclMutator Parent;
    3642                        virtual Expression * mutate( UniqueExpr * unqExpr );
    37                         std::map< Expression *, ObjectDecl * > decls;
     43                        std::map< int, ObjectDecl * > decls; // not vector, because order added may not be increasing order
    3844                };
    3945
     
    7379        }
    7480
     81        void expandMemberTuples( std::list< Declaration * > & translationUnit ) {
     82                MemberTupleExpander expander;
     83                mutateAll( translationUnit, expander );
     84        }
     85
    7586        void expandUniqueExpr( std::list< Declaration * > & translationUnit ) {
    7687                UniqueExprExpander unqExpander;
     
    92103        }
    93104
     105        namespace {
     106                /// given a expression representing the member and an expression representing the aggregate,
     107                /// reconstructs a flattened UntypedMemberExpr with the right precedence
     108                Expression * reconstructMemberExpr( Expression * member, UniqueExpr * aggr ) {
     109                        if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( member ) ) {
     110                                // construct a new UntypedMemberExpr with the correct structure , and recursively
     111                                // expand that member expression.
     112                                MemberTupleExpander expander;
     113                                UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member(), new UntypedMemberExpr( memberExpr->get_aggregate(), aggr->clone() ) );
     114
     115                                memberExpr->set_member(nullptr);
     116                                memberExpr->set_aggregate(nullptr);
     117                                delete memberExpr;
     118                                return newMemberExpr->acceptMutator( expander );
     119                        } else {
     120                                // not a member expression, so there is nothing to do but attach and return
     121                                return new UntypedMemberExpr( member, aggr->clone() );
     122                        }
     123                }
     124        }
     125
     126        Expression * MemberTupleExpander::mutate( UntypedMemberExpr * memberExpr ) {
     127                if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * > ( memberExpr->get_member() ) ) {
     128                        UniqueExpr * unqExpr = new UniqueExpr( memberExpr->get_aggregate()->clone() );
     129                        for ( Expression *& expr : tupleExpr->get_exprs() ) {
     130                                expr = reconstructMemberExpr( expr, unqExpr );
     131                        }
     132                        delete unqExpr;
     133                        return tupleExpr;
     134                } else {
     135                        return memberExpr;
     136                }
     137        }
     138
    94139        Expression * UniqueExprExpander::mutate( UniqueExpr * unqExpr ) {
    95140                static UniqueName tempNamer( "_unq_expr_" );
    96141                unqExpr = safe_dynamic_cast< UniqueExpr * > ( Parent::mutate( unqExpr ) );
    97                 if ( ! decls.count( unqExpr->get_expr() ) ) {
     142                if ( ! decls.count( unqExpr->get_id() ) ) {
    98143                        // xxx - it's possible (likely?) that expressions can appear in the wrong order because of this. Need to ensure they're placed in the correct location.
     144                        // xxx - is it possible to make the decl's type const?
    99145                        ObjectDecl * decl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), new SingleInit( unqExpr->get_expr()->clone() ) );
    100                         decls[unqExpr->get_expr()] = decl;
     146                        decls[unqExpr->get_id()] = decl;
    101147                        addDeclaration( decl );
    102148                }
    103                 return new VariableExpr( decls[unqExpr->get_expr()] );
     149                return new VariableExpr( decls[unqExpr->get_id()] );
    104150        }
    105151
     
    176222
    177223        Expression * TupleExprExpander::mutate( TupleExpr * tupleExpr ) {
     224                // recursively expand sub-tuple-expressions
     225                tupleExpr = safe_dynamic_cast<TupleExpr *>(Parent::mutate(tupleExpr));
    178226                Type * result = tupleExpr->get_result();
    179227                std::list< Expression * > exprs = tupleExpr->get_exprs();
    180228                assert( result );
    181229
     230                // remove data from shell and delete it
    182231                tupleExpr->set_result( nullptr );
    183232                tupleExpr->get_exprs().clear();
  • src/Tuples/Tuples.h

    r848ce71 rbf32bb8  
    3030
    3131        // TupleExpansion.cc
     32        /// expands z.[a, b.[x, y], c] into [z.a, z.b.x, z.b.y, z.c], inserting UniqueExprs as appropriate
     33        void expandMemberTuples( std::list< Declaration * > & translationUnit );
     34
     35        /// replaces tuple-related elements, such as TupleType, TupleExpr, TupleAssignExpr, etc.
    3236        void expandTuples( std::list< Declaration * > & translationUnit );
    3337
    34   void expandUniqueExpr( std::list< Declaration * > & translationUnit );
     38        /// replaces UniqueExprs with a temporary variable and one call
     39        void expandUniqueExpr( std::list< Declaration * > & translationUnit );
    3540
    36   /// returns VoidType if any of the expressions have Voidtype, otherwise TupleType of the Expression result types
    37   Type * makeTupleType( const std::list< Expression * > & exprs );
     41        /// returns VoidType if any of the expressions have Voidtype, otherwise TupleType of the Expression result types
     42        Type * makeTupleType( const std::list< Expression * > & exprs );
    3843
    39   bool maybeImpure( Expression * expr );
     44        /// returns true if the expression may contain side-effects.
     45        bool maybeImpure( Expression * expr );
    4046
    4147
  • src/main.cc

    r848ce71 rbf32bb8  
    232232                OPTPRINT( "tweakInit" )
    233233                InitTweak::genInit( translationUnit );
    234 
     234                OPTPRINT( "expandMemberTuples" );
     235                Tuples::expandMemberTuples( translationUnit );
    235236                if ( libcfap ) {
    236237                        // generate the bodies of cfa library functions
Note: See TracChangeset for help on using the changeset viewer.