- Timestamp:
- Feb 1, 2018, 5:40:01 PM (8 years ago)
- 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:
- 0188a0bc
- Parents:
- d0a045c7 (diff), 33c0ce8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/PassVisitor.h
rd0a045c7 r85521c7 291 291 bool_ref * get_visit_children_ptr() { return visit_children_impl(pass, 0); } 292 292 293 void indexerScopeEnter () { indexer_impl_enterScope ( pass, 0 ); }294 void indexerScopeLeave () { indexer_impl_leaveScope ( pass, 0 ); }295 void indexerAddId ( DeclarationWithType * node) { indexer_impl_addId ( pass, 0, node ); }296 void indexerAddType ( NamedTypeDecl * node) { indexer_impl_addType ( pass, 0, node ); }297 void indexerAddStruct ( const std::string & id) { indexer_impl_addStruct ( pass, 0, id ); }298 void indexerAddStruct ( StructDecl * node) { indexer_impl_addStruct ( pass, 0, node ); }299 void indexerAddStructFwd( StructDecl * node) { indexer_impl_addStructFwd( pass, 0, node ); }300 void indexerAddEnum ( EnumDecl * node) { indexer_impl_addEnum ( pass, 0, node ); }301 void indexerAddUnion ( const std::string & id) { indexer_impl_addUnion ( pass, 0, id ); }302 void indexerAddUnion ( UnionDecl * node) { indexer_impl_addUnion ( pass, 0, node ); }303 void indexerAddUnionFwd ( UnionDecl * node) { indexer_impl_addUnionFwd ( pass, 0, node ); }304 void indexerAddTrait ( TraitDecl * node) { indexer_impl_addTrait ( pass, 0, node ); }305 void indexerAddWith ( WithStmt * node ) { indexer_impl_addWith ( pass, 0, node); }293 void indexerScopeEnter () { indexer_impl_enterScope ( pass, 0 ); } 294 void indexerScopeLeave () { indexer_impl_leaveScope ( pass, 0 ); } 295 void indexerAddId ( DeclarationWithType * node ) { indexer_impl_addId ( pass, 0, node ); } 296 void indexerAddType ( NamedTypeDecl * node ) { indexer_impl_addType ( pass, 0, node ); } 297 void indexerAddStruct ( const std::string & id ) { indexer_impl_addStruct ( pass, 0, id ); } 298 void indexerAddStruct ( StructDecl * node ) { indexer_impl_addStruct ( pass, 0, node ); } 299 void indexerAddStructFwd( StructDecl * node ) { indexer_impl_addStructFwd( pass, 0, node ); } 300 void indexerAddEnum ( EnumDecl * node ) { indexer_impl_addEnum ( pass, 0, node ); } 301 void indexerAddUnion ( const std::string & id ) { indexer_impl_addUnion ( pass, 0, id ); } 302 void indexerAddUnion ( UnionDecl * node ) { indexer_impl_addUnion ( pass, 0, node ); } 303 void indexerAddUnionFwd ( UnionDecl * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); } 304 void indexerAddTrait ( TraitDecl * node ) { indexer_impl_addTrait ( pass, 0, node ); } 305 void indexerAddWith ( std::list< Expression * > & exprs ) { indexer_impl_addWith ( pass, 0, exprs ); } 306 306 307 307 -
src/Common/PassVisitor.impl.h
rd0a045c7 r85521c7 365 365 maybeAccept_impl ( node->attributes , *this ); 366 366 367 if ( node->name != "" ) { 368 indexerAddId( node ); 369 } 367 indexerAddId( node ); 370 368 371 369 VISIT_END( node ); … … 381 379 maybeMutate_impl ( node->attributes , *this ); 382 380 383 if ( node->name != "" ) { 384 indexerAddId( node ); 385 } 381 indexerAddId( node ); 386 382 387 383 MUTATE_END( DeclarationWithType, node ); … … 394 390 VISIT_START( node ); 395 391 396 if ( node->name != "" ) { 397 indexerAddId( node ); 398 } 399 400 { 401 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 402 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 403 static ObjectDecl func( 404 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 405 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 406 nullptr 407 ); 408 indexerAddId( &func ); 409 maybeAccept_impl( node->type, *this ); 410 maybeAccept_impl( node->statements, *this ); 411 maybeAccept_impl( node->attributes, *this ); 392 indexerAddId( node ); 393 394 maybeAccept_impl( node->withExprs, *this ); 395 { 396 // with clause introduces a level of scope (for the with expression members). 397 // with clause exprs are added to the indexer before parameters so that parameters 398 // shadow with exprs and not the other way around. 399 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 400 indexerAddWith( node->withExprs ); 401 { 402 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 403 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 404 static ObjectDecl func( 405 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 406 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 407 nullptr 408 ); 409 indexerAddId( &func ); 410 maybeAccept_impl( node->type, *this ); 411 maybeAccept_impl( node->statements, *this ); 412 maybeAccept_impl( node->attributes, *this ); 413 } 412 414 } 413 415 … … 419 421 MUTATE_START( node ); 420 422 421 if ( node->name != "" ) { 422 indexerAddId( node ); 423 } 424 425 { 426 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 427 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 428 static ObjectDecl func( 429 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 430 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 431 nullptr 432 ); 433 indexerAddId( &func ); 434 maybeMutate_impl( node->type, *this ); 435 maybeMutate_impl( node->statements, *this ); 436 maybeMutate_impl( node->attributes, *this ); 423 indexerAddId( node ); 424 425 { 426 // with clause introduces a level of scope (for the with expression members). 427 // with clause exprs are added to the indexer before parameters so that parameters 428 // shadow with exprs and not the other way around. 429 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 430 indexerAddWith( node->withExprs ); 431 { 432 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 433 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 434 static ObjectDecl func( 435 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 436 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 437 nullptr 438 ); 439 indexerAddId( &func ); 440 maybeMutate_impl( node->type, *this ); 441 maybeMutate_impl( node->statements, *this ); 442 maybeMutate_impl( node->attributes, *this ); 443 } 437 444 } 438 445 … … 730 737 template< typename pass_type > 731 738 void PassVisitor< pass_type >::visit( AsmStmt * node ) { 732 VISIT_BODY( node ); 739 VISIT_START( node ) 740 741 maybeAccept_impl( node->instruction, *this ); 742 maybeAccept_impl( node->output, *this ); 743 maybeAccept_impl( node->input, *this ); 744 maybeAccept_impl( node->clobber, *this ); 745 746 VISIT_END( node ); 733 747 } 734 748 735 749 template< typename pass_type > 736 750 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) { 737 MUTATE_BODY( Statement, node ); 751 MUTATE_START( node ); 752 753 maybeMutate_impl( node->instruction, *this ); 754 maybeMutate_impl( node->output, *this ); 755 maybeMutate_impl( node->input, *this ); 756 maybeMutate_impl( node->clobber, *this ); 757 758 MUTATE_END( Statement, node ); 738 759 } 739 760 … … 868 889 template< typename pass_type > 869 890 void PassVisitor< pass_type >::visit( BranchStmt * node ) { 870 VISIT_BODY( node ); 891 VISIT_START( node ); 892 VISIT_END( node ); 871 893 } 872 894 873 895 template< typename pass_type > 874 896 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) { 875 MUTATE_BODY( Statement, node ); 897 MUTATE_START( node ); 898 MUTATE_END( Statement, node ); 876 899 } 877 900 … … 901 924 template< typename pass_type > 902 925 void PassVisitor< pass_type >::visit( ThrowStmt * node ) { 903 VISIT_BODY( node ); 926 VISIT_START( node ); 927 928 maybeAccept_impl( node->expr, *this ); 929 maybeAccept_impl( node->target, *this ); 930 931 VISIT_END( node ); 904 932 } 905 933 906 934 template< typename pass_type > 907 935 Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) { 908 MUTATE_BODY( Statement, node ); 936 MUTATE_START( node ); 937 938 maybeMutate_impl( node->expr, *this ); 939 maybeMutate_impl( node->target, *this ); 940 941 MUTATE_END( Statement, node ); 909 942 } 910 943 … … 996 1029 // catch statements introduce a level of scope (for the caught exception) 997 1030 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 998 indexerAddWith( node );1031 indexerAddWith( node->exprs ); 999 1032 maybeAccept_impl( node->stmt, *this ); 1000 1033 } … … 1009 1042 // catch statements introduce a level of scope (for the caught exception) 1010 1043 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1011 indexerAddWith( node );1044 indexerAddWith( node->exprs ); 1012 1045 maybeMutate_impl( node->stmt, *this ); 1013 1046 } -
src/Common/PassVisitor.proto.h
rd0a045c7 r85521c7 202 202 static inline void indexer_impl_##func ( pass_type &, long, type ) { } \ 203 203 204 INDEXER_FUNC( addId , DeclarationWithType * );205 INDEXER_FUNC( addType , NamedTypeDecl * );206 INDEXER_FUNC( addStruct , StructDecl * );207 INDEXER_FUNC( addEnum , EnumDecl * );208 INDEXER_FUNC( addUnion , UnionDecl * );209 INDEXER_FUNC( addTrait , TraitDecl * );210 INDEXER_FUNC( addWith , WithStmt *);204 INDEXER_FUNC( addId , DeclarationWithType * ); 205 INDEXER_FUNC( addType , NamedTypeDecl * ); 206 INDEXER_FUNC( addStruct , StructDecl * ); 207 INDEXER_FUNC( addEnum , EnumDecl * ); 208 INDEXER_FUNC( addUnion , UnionDecl * ); 209 INDEXER_FUNC( addTrait , TraitDecl * ); 210 INDEXER_FUNC( addWith , std::list< Expression * > & ); 211 211 212 212 -
src/Parser/DeclarationNode.cc
rd0a045c7 r85521c7 723 723 } 724 724 725 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, StatementNode * with) {725 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, ExpressionNode * withExprs ) { 726 726 assert( type ); 727 727 assert( type->kind == TypeData::Function ); 728 728 assert( ! type->function.body ); 729 if ( with ) {730 // convert731 // void f(S s) with (s) { x = 0; }732 // to733 // void f(S s) { with(s) { x = 0; } }734 WithStmt * withStmt = strict_dynamic_cast< WithStmt * >( with->build() );735 withStmt->stmt = body->build();736 delete body;737 delete with;738 body = new StatementNode( new CompoundStmt( { withStmt } ) );739 }740 729 type->function.body = body; 730 type->function.withExprs = withExprs; 741 731 return this; 742 732 } -
src/Parser/ParseNode.h
rd0a045c7 r85521c7 262 262 DeclarationNode * addBitfield( ExpressionNode * size ); 263 263 DeclarationNode * addVarArgs(); 264 DeclarationNode * addFunctionBody( StatementNode * body, StatementNode * with = nullptr );264 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr ); 265 265 DeclarationNode * addOldDeclList( DeclarationNode * list ); 266 266 DeclarationNode * setBase( TypeData * newType ); -
src/Parser/TypeData.cc
rd0a045c7 r85521c7 55 55 function.body = nullptr; 56 56 function.newStyle = false; 57 function.withExprs = nullptr; 57 58 break; 58 59 // Enum is an Aggregate, so both structures are initialized together. … … 122 123 delete function.oldDeclList; 123 124 delete function.body; 125 delete function.withExprs; 124 126 // delete function; 125 127 break; … … 194 196 newtype->function.body = maybeClone( function.body ); 195 197 newtype->function.newStyle = function.newStyle; 198 newtype->function.withExprs = maybeClone( function.withExprs ); 196 199 break; 197 200 case Aggregate: … … 861 864 CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt ); 862 865 decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec ); 866 buildList( td->function.withExprs, decl->withExprs ); 863 867 return decl->set_asmName( asmName ); 864 868 } else if ( td->kind == TypeData::Aggregate ) { -
src/Parser/TypeData.h
rd0a045c7 r85521c7 65 65 StatementNode * body; 66 66 bool newStyle; 67 ExpressionNode * withExprs; // expressions from function's with_clause 67 68 }; 68 69 -
src/Parser/parser.yy
rd0a045c7 r85521c7 259 259 %type<sn> iteration_statement jump_statement 260 260 %type<sn> expression_statement asm_statement 261 %type<sn> with_statement with_clause_opt 261 %type<sn> with_statement 262 %type<en> with_clause_opt 262 263 %type<sn> exception_statement handler_clause finally_clause 263 264 %type<catch_kind> handler_key … … 2417 2418 { $$ = nullptr; } 2418 2419 | WITH '(' tuple_expression_list ')' 2419 { $$ = new StatementNode( build_with( $3, nullptr ) ); }2420 { $$ = $3; } 2420 2421 ; 2421 2422 -
src/ResolvExpr/AlternativeFinder.cc
rd0a045c7 r85521c7 1563 1563 // find alternatives for condition 1564 1564 AlternativeFinder firstFinder( indexer, env ); 1565 firstFinder.findWithAdjustment( conditionalExpr-> get_arg1());1565 firstFinder.findWithAdjustment( conditionalExpr->arg1 ); 1566 1566 if ( firstFinder.alternatives.empty() ) return; 1567 1567 // find alternatives for true expression 1568 1568 AlternativeFinder secondFinder( indexer, env ); 1569 secondFinder.findWithAdjustment( conditionalExpr-> get_arg2());1569 secondFinder.findWithAdjustment( conditionalExpr->arg2 ); 1570 1570 if ( secondFinder.alternatives.empty() ) return; 1571 1571 // find alterantives for false expression 1572 1572 AlternativeFinder thirdFinder( indexer, env ); 1573 thirdFinder.findWithAdjustment( conditionalExpr-> get_arg3());1573 thirdFinder.findWithAdjustment( conditionalExpr->arg3 ); 1574 1574 if ( thirdFinder.alternatives.empty() ) return; 1575 for ( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first) {1576 for ( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second) {1577 for ( AltList::const_iterator third = thirdFinder.alternatives.begin(); third != thirdFinder.alternatives.end(); ++third) {1575 for ( const Alternative & first : firstFinder.alternatives ) { 1576 for ( const Alternative & second : secondFinder.alternatives ) { 1577 for ( const Alternative & third : thirdFinder.alternatives ) { 1578 1578 TypeEnvironment compositeEnv; 1579 compositeEnv.simpleCombine( first ->env );1580 compositeEnv.simpleCombine( second ->env );1581 compositeEnv.simpleCombine( third ->env );1579 compositeEnv.simpleCombine( first.env ); 1580 compositeEnv.simpleCombine( second.env ); 1581 compositeEnv.simpleCombine( third.env ); 1582 1582 1583 1583 // unify true and false types, then infer parameters to produce new alternatives 1584 1584 OpenVarSet openVars; 1585 1585 AssertionSet needAssertions, haveAssertions; 1586 Alternative newAlt( 0, compositeEnv, first ->cost + second->cost + third->cost );1586 Alternative newAlt( 0, compositeEnv, first.cost + second.cost + third.cost ); 1587 1587 Type* commonType = nullptr; 1588 if ( unify( second ->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {1589 ConditionalExpr *newExpr = new ConditionalExpr( first ->expr->clone(), second->expr->clone(), third->expr->clone() );1590 newExpr-> set_result( commonType ? commonType : second->expr->get_result()->clone());1588 if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1589 ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() ); 1590 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1591 1591 // convert both options to the conditional result type 1592 1592 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env ); -
src/ResolvExpr/Resolver.cc
rd0a045c7 r85521c7 82 82 void previsit( ConstructorInit *ctorInit ); 83 83 private: 84 84 typedef std::list< Initializer * >::iterator InitIterator; 85 85 86 86 template< typename PtrType > 87 87 void handlePtrType( PtrType * type ); 88 88 89 void resolveAggrInit( ReferenceToType *, InitIterator &, InitIterator & ); 90 void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator &, TypeSubstitution sub ); 91 void fallbackInit( ConstructorInit * ctorInit ); 89 void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ); 90 void fallbackInit( ConstructorInit * ctorInit ); 92 91 93 92 Type * functionReturn = nullptr; … … 269 268 std::cerr << std::endl; 270 269 #endif 271 Type *new_type = resolveTypeof( functionDecl-> get_type(), indexer );270 Type *new_type = resolveTypeof( functionDecl->type, indexer ); 272 271 functionDecl->set_type( new_type ); 273 272 GuardValue( functionReturn ); 274 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 273 functionReturn = ResolvExpr::extractResultType( functionDecl->type ); 274 275 { 276 // resolve with-exprs with parameters in scope and add any newly generated declarations to the 277 // front of the function body. 278 auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this](){ indexer.leaveScope(); } ); 279 indexer.addFunctionType( functionDecl->type ); 280 std::list< Statement * > newStmts; 281 resolveWithExprs( functionDecl->withExprs, newStmts ); 282 functionDecl->statements->kids.splice( functionDecl->statements->kids.begin(), newStmts ); 283 } 275 284 } 276 285 … … 279 288 // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently 280 289 // see how it's useful. 281 for ( Declaration * d : functionDecl-> get_functionType()->get_parameters()) {290 for ( Declaration * d : functionDecl->type->parameters ) { 282 291 if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( d ) ) { 283 if ( SingleInit * init = dynamic_cast< SingleInit * >( obj-> get_init()) ) {284 delete init-> get_value()->get_env();285 init-> get_value()->set_env( nullptr );292 if ( SingleInit * init = dynamic_cast< SingleInit * >( obj->init ) ) { 293 delete init->value->env; 294 init->value->env = nullptr; 286 295 } 287 296 } … … 584 593 } 585 594 586 587 void Resolver::previsit( WithStmt * withStmt ) { 588 for ( Expression *& expr : withStmt->exprs ) { 595 void Resolver::resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ) { 596 for ( Expression *& expr : withExprs ) { 589 597 // only struct- and union-typed expressions are viable candidates 590 598 findKindExpression( expr, indexer, "with statement", isStructOrUnion ); … … 595 603 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) ); 596 604 expr = new VariableExpr( tmp ); 597 stmtsToAddBefore.push_back( new DeclStmt( tmp ) );605 newStmts.push_back( new DeclStmt( tmp ) ); 598 606 if ( InitTweak::isConstructable( tmp->type ) ) { 599 607 // generate ctor/dtor and resolve them … … 603 611 } 604 612 } 613 } 614 615 void Resolver::previsit( WithStmt * withStmt ) { 616 resolveWithExprs( withStmt->exprs, stmtsToAddBefore ); 605 617 } 606 618 … … 716 728 PassVisitor<Resolver> resolver( indexer ); 717 729 stmtExpr->accept( resolver ); 730 stmtExpr->computeResult(); 718 731 } 719 732 -
src/SymTab/Indexer.cc
rd0a045c7 r85521c7 409 409 410 410 void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) { 411 if ( decl->name == "" ) return; 411 412 debugPrint( "Adding Id " << decl->name << std::endl ); 412 413 makeWritable(); … … 588 589 } 589 590 590 void Indexer::addWith( WithStmt * stmt) {591 for ( Expression * expr : stmt->exprs ) {591 void Indexer::addWith( std::list< Expression * > & withExprs ) { 592 for ( Expression * expr : withExprs ) { 592 593 if ( expr->result ) { 593 594 AggregateDecl * aggr = expr->result->stripReferences()->getAggr(); -
src/SymTab/Indexer.h
rd0a045c7 r85521c7 84 84 85 85 /// adds all of the IDs from WithStmt exprs 86 void addWith( WithStmt *);86 void addWith( std::list< Expression * > & withExprs ); 87 87 88 88 /// adds all of the members of the Aggregate (addWith helper) -
src/SynTree/Declaration.h
rd0a045c7 r85521c7 151 151 FunctionType *type; 152 152 CompoundStmt *statements; 153 std::list< Expression * > withExprs; 153 154 154 155 FunctionDecl( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, FunctionType *type, CompoundStmt *statements, -
src/SynTree/Expression.cc
rd0a045c7 r85521c7 597 597 598 598 StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) { 599 assert( statements ); 600 std::list< Statement * > & body = statements->get_kids(); 601 if ( ! body.empty() ) { 602 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) { 603 result = maybeClone( exprStmt->expr->result ); 604 } 605 } 606 // ensure that StmtExpr has a result type 607 if ( ! result ) { 608 result = new VoidType( Type::Qualifiers() ); 609 } 599 computeResult(); 610 600 } 611 601 StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) { … … 617 607 deleteAll( dtors ); 618 608 deleteAll( returnDecls ); 609 } 610 void StmtExpr::computeResult() { 611 assert( statements ); 612 std::list< Statement * > & body = statements->kids; 613 delete result; 614 result = nullptr; 615 if ( ! returnDecls.empty() ) { 616 // prioritize return decl for result type, since if a return decl exists, then 617 // the StmtExpr is currently in an intermediate state where the body will always 618 // give a void result type. 619 result = returnDecls.front()->get_type()->clone(); 620 } else if ( ! body.empty() ) { 621 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) { 622 result = maybeClone( exprStmt->expr->result ); 623 } 624 } 625 // ensure that StmtExpr has a result type 626 if ( ! result ) { 627 result = new VoidType( Type::Qualifiers() ); 628 } 619 629 } 620 630 void StmtExpr::print( std::ostream &os, Indenter indent ) const { -
src/SynTree/Expression.h
rd0a045c7 r85521c7 728 728 StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; } 729 729 730 // call to set the result type of this StmtExpr based on its body 731 void computeResult(); 732 730 733 std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; } 731 734 std::list< Expression * > & get_dtors() { return dtors; } -
src/SynTree/FunctionDecl.cc
rd0a045c7 r85521c7 51 51 VarExprReplacer::replace( this, declMap ); 52 52 } 53 cloneAll( other.withExprs, withExprs ); 53 54 } 54 55 … … 56 57 delete type; 57 58 delete statements; 59 deleteAll( withExprs ); 58 60 } 59 61
Note:
See TracChangeset
for help on using the changeset viewer.