Changeset 65197c2
- Timestamp:
- Dec 5, 2017, 2:17:17 PM (5 years ago)
- Branches:
- aaron-thesis, arm-eh, 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:
- 971d9f2, a85e44c, c13e8dc8
- Parents:
- 12d2dc8 (diff), 866f560 (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:
-
- 2 added
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r12d2dc8 r65197c2 1012 1012 } 1013 1013 1014 void CodeGenerator::postvisit( WithStmt * with ) { 1015 if ( ! genC ) { 1016 output << "with ( "; 1017 genCommaList( with->exprs.begin(), with->exprs.end() ); 1018 output << " ) "; 1019 } 1020 with->stmt->accept( *visitor ); 1021 } 1014 1022 1015 1023 void CodeGenerator::postvisit( WhileStmt * whileStmt ) { -
src/CodeGen/CodeGenerator.h
r12d2dc8 r65197c2 102 102 void postvisit( CatchStmt * ); 103 103 void postvisit( WaitForStmt * ); 104 void postvisit( WithStmt * ); 104 105 void postvisit( WhileStmt * ); 105 106 void postvisit( ForStmt * ); -
src/Common/PassVisitor.h
r12d2dc8 r65197c2 81 81 virtual void visit( FinallyStmt * finallyStmt ) override final; 82 82 virtual void visit( WaitForStmt * waitforStmt ) override final; 83 virtual void visit( WithStmt * withStmt ) override final; 83 84 virtual void visit( NullStmt * nullStmt ) override final; 84 85 virtual void visit( DeclStmt * declStmt ) override final; … … 172 173 virtual Statement * mutate( FinallyStmt * finallyStmt ) override final; 173 174 virtual Statement * mutate( WaitForStmt * waitforStmt ) override final; 175 virtual Statement * mutate( WithStmt * withStmt ) override final; 174 176 virtual NullStmt * mutate( NullStmt * nullStmt ) override final; 175 177 virtual Statement * mutate( DeclStmt * declStmt ) override final; … … 296 298 void indexerAddUnionFwd ( UnionDecl * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); } 297 299 void indexerAddTrait ( TraitDecl * node ) { indexer_impl_addTrait ( pass, 0, node ); } 300 void indexerAddWith ( WithStmt * node ) { indexer_impl_addWith ( pass, 0, node ); } 301 298 302 299 303 template< typename TreeType, typename VisitorType > -
src/Common/PassVisitor.impl.h
r12d2dc8 r65197c2 985 985 } 986 986 987 988 989 //-------------------------------------------------------------------------- 990 // NullStmt 991 template< typename pass_type > 992 void PassVisitor< pass_type >::visit( WithStmt * node ) { 993 VISIT_START( node ); 994 maybeAccept_impl( node->exprs, *this ); 995 { 996 // catch statements introduce a level of scope (for the caught exception) 997 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 998 indexerAddWith( node ); 999 maybeAccept_impl( node->stmt, *this ); 1000 } 1001 VISIT_END( node ); 1002 } 1003 1004 template< typename pass_type > 1005 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) { 1006 MUTATE_START( node ); 1007 maybeMutate_impl( node->exprs, *this ); 1008 { 1009 // catch statements introduce a level of scope (for the caught exception) 1010 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1011 indexerAddWith( node ); 1012 maybeMutate_impl( node->stmt, *this ); 1013 } 1014 MUTATE_END( Statement, node ); 1015 } 1016 987 1017 //-------------------------------------------------------------------------- 988 1018 // NullStmt -
src/Common/PassVisitor.proto.h
r12d2dc8 r65197c2 208 208 INDEXER_FUNC( addUnion , UnionDecl * ); 209 209 INDEXER_FUNC( addTrait , TraitDecl * ); 210 INDEXER_FUNC( addWith , WithStmt * ); 210 211 211 212 -
src/GenPoly/InstantiateGeneric.cc
r12d2dc8 r65197c2 453 453 return false; 454 454 } 455 456 AggregateDecl * getAggr( Type * t ) {457 if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {458 return inst->baseStruct;459 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {460 return inst->baseUnion;461 }462 assertf( false, "Non-aggregate type: %s", toString( t ).c_str() );463 }464 455 } 465 456 … … 469 460 if ( isGenericType( memberExpr->aggregate->result ) ) { 470 461 // find the location of the member 471 AggregateDecl * aggr = getAggr( memberExpr->aggregate->result);462 AggregateDecl * aggr = memberExpr->aggregate->result->getAggr(); 472 463 std::list< Declaration * > & members = aggr->members; 473 464 memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) ); … … 479 470 if ( memberIndex != -1 ) { 480 471 // using the location from the generic type, find the member in the instantiation and rebuild the member expression 481 AggregateDecl * aggr = getAggr( memberExpr->aggregate->result);472 AggregateDecl * aggr = memberExpr->aggregate->result->getAggr(); 482 473 assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." ); 483 474 Declaration * member = *std::next( aggr->members.begin(), memberIndex ); -
src/Parser/DeclarationNode.cc
r12d2dc8 r65197c2 717 717 } 718 718 719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body ) {719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, StatementNode * with ) { 720 720 assert( type ); 721 721 assert( type->kind == TypeData::Function ); 722 722 assert( ! type->function.body ); 723 if ( with ) { 724 // convert 725 // void f(S s) with (s) { x = 0; } 726 // to 727 // void f(S s) { with(s) { x = 0; } } 728 WithStmt * withStmt = strict_dynamic_cast< WithStmt * >( with->build() ); 729 withStmt->stmt = body->build(); 730 delete body; 731 delete with; 732 body = new StatementNode( new CompoundStmt( { withStmt } ) ); 733 } 723 734 type->function.body = body; 724 735 return this; -
src/Parser/ParseNode.h
r12d2dc8 r65197c2 69 69 70 70 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {} 71 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {} 71 virtual void printList( std::ostream &os, int indent = 0 ) const { 72 print( os, indent ); 73 if ( next ) next->print( os, indent ); 74 } 72 75 73 76 static int indent_by; … … 120 123 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; } 121 124 122 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {} 125 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override { 126 os << expr.get() << std::endl; 127 } 123 128 void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {} 124 129 … … 257 262 DeclarationNode * addBitfield( ExpressionNode * size ); 258 263 DeclarationNode * addVarArgs(); 259 DeclarationNode * addFunctionBody( StatementNode * body );264 DeclarationNode * addFunctionBody( StatementNode * body, StatementNode * with = nullptr ); 260 265 DeclarationNode * addOldDeclList( DeclarationNode * list ); 261 266 DeclarationNode * setBase( TypeData * newType ); … … 359 364 virtual StatementNode * append_last_case( StatementNode * ); 360 365 361 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {} 362 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {} 366 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override { 367 os << stmt.get() << std::endl; 368 } 363 369 private: 364 370 std::unique_ptr<Statement> stmt; … … 408 414 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ); 409 415 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ); 416 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ); 410 417 411 418 //############################################################################## -
src/Parser/StatementNode.cc
r12d2dc8 r65197c2 282 282 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 283 283 284 node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );284 node->orelse.statement = maybeMoveBuild<Statement >( else_stmt ); 285 285 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( else_when ) ); 286 286 287 287 return node; 288 } 289 290 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) { 291 std::list< Expression * > e; 292 buildMoveList( exprs, e ); 293 Statement * s = maybeMoveBuild<Statement>( stmt ); 294 return new WithStmt( e, s ); 288 295 } 289 296 -
src/Parser/parser.yy
r12d2dc8 r65197c2 1058 1058 with_statement: 1059 1059 WITH '(' tuple_expression_list ')' statement 1060 { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME 1060 { 1061 $$ = new StatementNode( build_with( $3, $5 ) ); 1062 } 1061 1063 ; 1062 1064 … … 2410 2412 { $$ = nullptr; } 2411 2413 | WITH '(' tuple_expression_list ')' 2412 { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME2414 { $$ = new StatementNode( build_with( $3, nullptr ) ); } 2413 2415 ; 2414 2416 … … 2420 2422 // Add the function body to the last identifier in the function definition list, i.e., foo3: 2421 2423 // [const double] foo1(), foo2( int ), foo3( double ) { return 3.0; } 2422 $1->get_last()->addFunctionBody( $3 );2424 $1->get_last()->addFunctionBody( $3, $2 ); 2423 2425 $$ = $1; 2424 2426 } … … 2428 2430 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2429 2431 typedefTable.leaveScope(); 2430 $$ = $2->addFunctionBody( $4 )->addType( $1 );2432 $$ = $2->addFunctionBody( $4, $3 )->addType( $1 ); 2431 2433 } 2432 2434 // handles default int return type, OBSOLESCENT (see 1) … … 2435 2437 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2436 2438 typedefTable.leaveScope(); 2437 $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );2439 $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); 2438 2440 } 2439 2441 // handles default int return type, OBSOLESCENT (see 1) … … 2442 2444 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2443 2445 typedefTable.leaveScope(); 2444 $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );2446 $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); 2445 2447 } 2446 2448 // handles default int return type, OBSOLESCENT (see 1) … … 2449 2451 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2450 2452 typedefTable.leaveScope(); 2451 $$ = $3->addFunctionBody( $5 )->addQualifiers( $2 )->addQualifiers( $1 );2453 $$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 ); 2452 2454 } 2453 2455 … … 2458 2460 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2459 2461 typedefTable.leaveScope(); 2460 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addType( $1 );2462 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addType( $1 ); 2461 2463 } 2462 2464 // handles default int return type, OBSOLESCENT (see 1) … … 2465 2467 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2466 2468 typedefTable.leaveScope(); 2467 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addQualifiers( $1 );2469 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); 2468 2470 } 2469 2471 // handles default int return type, OBSOLESCENT (see 1) … … 2472 2474 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2473 2475 typedefTable.leaveScope(); 2474 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addQualifiers( $1 );2476 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); 2475 2477 } 2476 2478 // handles default int return type, OBSOLESCENT (see 1) … … 2479 2481 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2480 2482 typedefTable.leaveScope(); 2481 $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );2483 $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 ); 2482 2484 } 2483 2485 ; -
src/ResolvExpr/AlternativeFinder.cc
r12d2dc8 r65197c2 83 83 } 84 84 85 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) { 86 Indenter indent = { Indenter::tabsize, indentAmt }; 87 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 88 i->print( os, indent ); 89 os << std::endl; 90 } 91 } 92 85 93 namespace { 86 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) {87 Indenter indent = { Indenter::tabsize, indentAmt };88 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {89 i->print( os, indent );90 os << std::endl;91 }92 }93 94 94 void makeExprList( const AltList &in, std::list< Expression* > &out ) { 95 95 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) { … … 469 469 std::cerr << std::endl; 470 470 ) 471 std::list< DeclarationWithType*> candidates;471 std::list< SymTab::Indexer::IdData > candidates; 472 472 decls.lookupId( curDecl->get_name(), candidates ); 473 473 /// if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; } 474 for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) { 474 for ( const auto & data : candidates ) { 475 DeclarationWithType * candidate = data.id; 475 476 PRINT( 476 477 std::cerr << "inferRecursive: candidate is "; 477 (*candidate)->print( std::cerr );478 candidate->print( std::cerr ); 478 479 std::cerr << std::endl; 479 480 ) … … 482 483 TypeEnvironment newEnv( newAlt.env ); 483 484 OpenVarSet newOpenVars( openVars ); 484 Type *adjType = (*candidate)->get_type()->clone();485 Type *adjType = candidate->get_type()->clone(); 485 486 adjustExprType( adjType, newEnv, indexer ); 486 487 adjType->accept( global_renamer ); … … 500 501 Alternative newerAlt( newAlt ); 501 502 newerAlt.env = newEnv; 502 assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() ); 503 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 503 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 504 504 505 505 // everything with an empty idChain was pulled in by the current assertion. … … 516 516 // DOESN'T WORK: grandchild nodes conflict with their cousins 517 517 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 518 Expression *varExpr = new VariableExpr( candDecl);518 Expression *varExpr = data.combine(); 519 519 delete varExpr->get_result(); 520 520 varExpr->set_result( adjType->clone() ); … … 522 522 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; 523 523 curDecl->print( std::cerr ); 524 std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " ";525 (*candidate)->print( std::cerr );524 std::cerr << " with declaration " << candidate->get_uniqueId() << " "; 525 candidate->print( std::cerr ); 526 526 std::cerr << std::endl; 527 527 ) … … 532 532 } 533 533 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 534 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );534 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 535 535 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out ); 536 536 } else { … … 1317 1317 1318 1318 void AlternativeFinder::visit( NameExpr *nameExpr ) { 1319 std::list< DeclarationWithType*> declList;1319 std::list< SymTab::Indexer::IdData > declList; 1320 1320 indexer.lookupId( nameExpr->get_name(), declList ); 1321 1321 PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; ) 1322 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 1323 VariableExpr newExpr( *i ); 1324 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1322 for ( auto & data : declList ) { 1323 Expression * newExpr = data.combine(); 1324 // xxx - add in extra cost for with-statement exprs? 1325 alternatives.push_back( Alternative( newExpr, env, Cost::zero ) ); 1325 1326 PRINT( 1326 1327 std::cerr << "decl is "; 1327 (*i)->print( std::cerr );1328 data.id->print( std::cerr ); 1328 1329 std::cerr << std::endl; 1329 1330 std::cerr << "newExpr is "; 1330 newExpr .print( std::cerr );1331 newExpr->print( std::cerr ); 1331 1332 std::cerr << std::endl; 1332 1333 ) … … 1420 1421 } 1421 1422 1422 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 1423 // assume no polymorphism 1424 // assume no implicit conversions 1425 assert( function->get_parameters().size() == 1 ); 1426 PRINT( 1427 std::cerr << "resolvAttr: funcDecl is "; 1428 funcDecl->print( std::cerr ); 1429 std::cerr << " argType is "; 1430 argType->print( std::cerr ); 1431 std::cerr << std::endl; 1432 ) 1433 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1434 alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) ); 1435 for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 1436 alternatives.back().expr->set_result( (*i)->get_type()->clone() ); 1437 } // for 1438 } // if 1423 namespace { 1424 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1425 // assume no polymorphism 1426 // assume no implicit conversions 1427 assert( function->get_parameters().size() == 1 ); 1428 PRINT( 1429 std::cerr << "resolvAttr: funcDecl is "; 1430 data.id->print( std::cerr ); 1431 std::cerr << " argType is "; 1432 argType->print( std::cerr ); 1433 std::cerr << std::endl; 1434 ) 1435 const SymTab::Indexer & indexer = finder.get_indexer(); 1436 AltList & alternatives = finder.get_alternatives(); 1437 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1438 alternatives.push_back( Alternative( new AttrExpr( data.combine(), argType->clone() ), env, Cost::zero ) ); 1439 for ( DeclarationWithType * retVal : function->returnVals ) { 1440 alternatives.back().expr->result = retVal->get_type()->clone(); 1441 } // for 1442 } // if 1443 } 1439 1444 } 1440 1445 … … 1443 1448 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1444 1449 assert( nameExpr ); 1445 std::list< DeclarationWithType*> attrList;1450 std::list< SymTab::Indexer::IdData > attrList; 1446 1451 indexer.lookupId( nameExpr->get_name(), attrList ); 1447 1452 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1448 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1453 for ( auto & data : attrList ) { 1454 DeclarationWithType * id = data.id; 1449 1455 // check if the type is function 1450 if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {1456 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) { 1451 1457 // assume exactly one parameter 1452 1458 if ( function->get_parameters().size() == 1 ) { 1453 1459 if ( attrExpr->get_isType() ) { 1454 resolveAttr( *i, function, attrExpr->get_type(), env);1460 resolveAttr( data, function, attrExpr->get_type(), env, *this ); 1455 1461 } else { 1456 1462 AlternativeFinder finder( indexer, env ); … … 1458 1464 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 1459 1465 if ( choice->expr->get_result()->size() == 1 ) { 1460 resolveAttr( *i, function, choice->expr->get_result(), choice->env);1466 resolveAttr(data, function, choice->expr->get_result(), choice->env, *this ); 1461 1467 } // fi 1462 1468 } // for … … 1466 1472 } // for 1467 1473 } else { 1468 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1469 VariableExpr newExpr( *i ); 1470 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1474 for ( auto & data : attrList ) { 1475 alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) ); 1471 1476 renameTypes( alternatives.back().expr ); 1472 1477 } // for -
src/ResolvExpr/AlternativeFinder.h
r12d2dc8 r65197c2 142 142 template< typename OutputIterator > 143 143 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); 144 void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );145 144 146 145 const SymTab::Indexer &indexer; … … 151 150 152 151 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ); 153 void referenceToRvalueConversion( Expression *& expr );154 152 155 153 template< typename InputIterator, typename OutputIterator > … … 174 172 175 173 Cost sumCost( const AltList &in ); 174 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ); 176 175 177 176 template< typename InputIterator > … … 181 180 } 182 181 } 182 183 183 } // namespace ResolvExpr 184 184 -
src/ResolvExpr/Resolver.cc
r12d2dc8 r65197c2 26 26 #include "Common/utility.h" // for ValueGuard, group_iterate 27 27 #include "CurrentObject.h" // for CurrentObject 28 #include "InitTweak/GenInit.h" 28 29 #include "InitTweak/InitTweak.h" // for isIntrinsicSingleArgCallStmt 29 30 #include "RenameVars.h" // for RenameVars, global_renamer … … 40 41 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 41 42 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 43 #include "Tuples/Tuples.h" 42 44 #include "typeops.h" // for extractResultType 43 45 #include "Unify.h" // for unify … … 46 48 47 49 namespace ResolvExpr { 48 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting {50 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting, public WithStmtsToAdd { 49 51 Resolver() {} 50 52 Resolver( const SymTab::Indexer & other ) { … … 74 76 void previsit( CatchStmt *catchStmt ); 75 77 void previsit( WaitForStmt * stmt ); 78 void previsit( WithStmt * withStmt ); 76 79 77 80 void previsit( SingleInit *singleInit ); … … 571 574 } 572 575 576 bool isStructOrUnion( Type * t ) { 577 t = t->stripReferences(); 578 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ); 579 } 580 581 void Resolver::previsit( WithStmt * withStmt ) { 582 for ( Expression *& expr : withStmt->exprs ) { 583 TypeEnvironment env; 584 AlternativeFinder finder( indexer, env ); 585 finder.findWithAdjustment( expr ); 586 587 // only struct- and union-typed expressions are viable candidates 588 AltList candidates; 589 for ( Alternative & alt : finder.get_alternatives() ) { 590 if ( isStructOrUnion( alt.expr->result ) ) { 591 candidates.push_back( std::move( alt ) ); 592 } 593 } 594 595 // choose the lowest cost expression among the candidates 596 AltList winners; 597 findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) ); 598 if ( winners.size() == 0 ) { 599 throw SemanticError( "No reasonable alternatives for with statement expression: ", expr ); 600 } else if ( winners.size() != 1 ) { 601 std::ostringstream stream; 602 stream << "Cannot choose between " << winners.size() << " alternatives for with statement expression\n"; 603 expr->print( stream ); 604 stream << "Alternatives are:\n"; 605 printAlts( winners, stream, 1 ); 606 throw SemanticError( stream.str() ); 607 } 608 609 // there is one unambiguous interpretation - move the expression into the with statement 610 Alternative & alt = winners.front(); 611 finishExpr( alt.expr, alt.env, expr->env ); 612 delete expr; 613 expr = alt.expr; 614 alt.expr = nullptr; 615 616 // if with expression might be impure, create a temporary so that it is evaluated once 617 if ( Tuples::maybeImpure( expr ) ) { 618 static UniqueName tmpNamer( "_with_tmp_" ); 619 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) ); 620 expr = new VariableExpr( tmp ); 621 stmtsToAddBefore.push_back( new DeclStmt( tmp ) ); 622 if ( InitTweak::isConstructable( tmp->type ) ) { 623 // generate ctor/dtor and resolve them 624 tmp->init = InitTweak::genCtorInit( tmp ); 625 tmp->accept( *visitor ); 626 } 627 } 628 } 629 } 630 573 631 template< typename T > 574 632 bool isCharType( T t ) { -
src/ResolvExpr/typeops.h
r12d2dc8 r65197c2 102 102 bool occurs( Type *type, std::string varName, const TypeEnvironment &env ); 103 103 104 // in AlternativeFinder.cc 105 void referenceToRvalueConversion( Expression *& expr ); 106 104 107 // flatten tuple type into list of types 105 108 template< typename OutputIterator > -
src/SymTab/Indexer.cc
r12d2dc8 r65197c2 40 40 41 41 namespace SymTab { 42 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 42 std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) { 43 return out << "(" << data.id << "," << data.baseExpr << ")"; 44 } 45 46 typedef std::unordered_map< std::string, Indexer::IdData > MangleTable; 43 47 typedef std::unordered_map< std::string, MangleTable > IdTable; 44 48 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; … … 97 101 } 98 102 99 void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType *> & out ) const {103 void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const { 100 104 // only need to perform this step for constructors, destructors, and assignment functions 101 105 if ( ! CodeGen::isCtorDtorAssign( id ) ) return; … … 104 108 struct ValueType { 105 109 struct DeclBall { 106 FunctionDecl *decl;110 IdData decl; 107 111 bool isUserDefinedFunc; // properties for this particular decl 108 112 bool isDefaultCtor; … … 120 124 // another FunctionDecl for the current type was found - determine 121 125 // if it has special properties and update data structure accordingly 122 ValueType & operator+=( FunctionDecl * function ) { 126 ValueType & operator+=( IdData data ) { 127 DeclarationWithType * function = data.id; 123 128 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() ); 124 129 bool isDefaultCtor = InitTweak::isDefaultConstructor( function ); 125 130 bool isDtor = InitTweak::isDestructor( function ); 126 131 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() ); 127 decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );132 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } ); 128 133 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc; 129 134 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) ); … … 135 140 }; // ValueType 136 141 137 std::list< DeclarationWithType *> copy;142 std::list< IdData > copy; 138 143 copy.splice( copy.end(), out ); 139 144 140 145 // organize discovered declarations by type 141 146 std::unordered_map< std::string, ValueType > funcMap; 142 for ( DeclarationWithType *decl : copy ) {143 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) {147 for ( auto decl : copy ) { 148 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) { 144 149 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters(); 145 150 assert( ! params.empty() ); … … 147 152 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 148 153 assert( base ); 149 funcMap[ Mangler::mangle( base ) ] += function;154 funcMap[ Mangler::mangle( base ) ] += decl; 150 155 } else { 151 156 out.push_back( decl ); … … 164 169 bool noUserDefinedFunc = ! val.existsUserDefinedFunc; 165 170 bool isUserDefinedFunc = ball.isUserDefinedFunc; 166 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl ->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides171 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides 167 172 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator 168 173 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor; … … 219 224 } 220 225 221 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType*> &out ) const {226 void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const { 222 227 std::unordered_set< std::string > foundMangleNames; 223 228 … … 289 294 const MangleTable &mangleTable = decls->second; 290 295 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 291 if ( decl != mangleTable.end() ) return decl->second ;296 if ( decl != mangleTable.end() ) return decl->second.id; 292 297 } 293 298 … … 304 309 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 305 310 // check for C decls with the same name, skipping those with a compatible type (by mangleName) 306 if ( ! LinkageSpec::isMangled( decl->second ->get_linkage() ) && decl->first != mangleName ) return true;311 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true; 307 312 } 308 313 } … … 321 326 // check for C decls with the same name, skipping 322 327 // those with an incompatible type (by mangleName) 323 if ( ! LinkageSpec::isMangled( decl->second ->get_linkage() ) && decl->first == mangleName ) return true;328 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true; 324 329 } 325 330 } … … 403 408 } 404 409 405 void Indexer::addId( DeclarationWithType *decl ) {410 void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) { 406 411 debugPrint( "Adding Id " << decl->name << std::endl ); 407 412 makeWritable(); … … 439 444 440 445 // add to indexer 441 tables->idTable[ name ][ mangleName ] = decl;446 tables->idTable[ name ][ mangleName ] = { decl, baseExpr }; 442 447 ++tables->size; 443 448 } … … 563 568 if ( ! addedDeclConflicts( existing->second, decl ) ) { 564 569 existing->second = decl; 570 } 571 } 572 } 573 574 void Indexer::addWith( WithStmt * stmt ) { 575 for ( Expression * expr : stmt->exprs ) { 576 if ( expr->result ) { 577 AggregateDecl * aggr = expr->result->stripReferences()->getAggr(); 578 assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() ); 579 580 for ( Declaration * decl : aggr->members ) { 581 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 582 addId( dwt, expr ); 583 } 584 } 565 585 } 566 586 } … … 645 665 646 666 } 667 668 Expression * Indexer::IdData::combine() const { 669 if ( baseExpr ) { 670 Expression * base = baseExpr->clone(); 671 ResolvExpr::referenceToRvalueConversion( base ); 672 Expression * ret = new MemberExpr( id, base ); 673 // xxx - this introduces hidden environments, for now remove them. 674 // std::swap( base->env, ret->env ); 675 delete base->env; 676 base->env = nullptr; 677 return ret; 678 } else { 679 return new VariableExpr( id ); 680 } 681 } 647 682 } // namespace SymTab 648 683 -
src/SymTab/Indexer.h
r12d2dc8 r65197c2 39 39 void leaveScope(); 40 40 41 struct IdData { 42 DeclarationWithType * id; 43 Expression * baseExpr; // WithExpr 44 45 Expression * combine() const; 46 }; 47 41 48 /// Gets all declarations with the given ID 42 void lookupId( const std::string &id, std::list< DeclarationWithType*> &out ) const;49 void lookupId( const std::string &id, std::list< IdData > &out ) const; 43 50 /// Gets the top-most type declaration with the given ID 44 51 NamedTypeDecl *lookupType( const std::string &id ) const; … … 67 74 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 68 75 69 void addId( DeclarationWithType *decl );76 void addId( DeclarationWithType *decl, Expression * baseExpr = nullptr ); 70 77 void addType( NamedTypeDecl *decl ); 71 78 void addStruct( const std::string &id ); … … 75 82 void addUnion( UnionDecl *decl ); 76 83 void addTrait( TraitDecl *decl ); 84 85 /// adds all of the IDs from WithStmt exprs 86 void addWith( WithStmt * ); 77 87 78 88 /// convenience function for adding a list of Ids to the indexer … … 100 110 // so that they will not be selected 101 111 // void removeSpecialOverrides( FunctionDecl *decl ); 102 void removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType *> & out ) const;112 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const; 103 113 104 114 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope) -
src/SynTree/Mutator.cc
r12d2dc8 r65197c2 203 203 } 204 204 205 Statement * Mutator::mutate( WithStmt * withStmt ) { 206 mutateAll( withStmt->exprs, *this ); 207 withStmt->stmt = maybeMutate( withStmt->stmt, *this ); 208 return withStmt; 209 } 210 205 211 NullStmt * Mutator::mutate( NullStmt *nullStmt ) { 206 212 return nullStmt; -
src/SynTree/Mutator.h
r12d2dc8 r65197c2 50 50 virtual Statement * mutate( FinallyStmt * catchStmt ); 51 51 virtual Statement * mutate( WaitForStmt * waitforStmt ); 52 virtual Statement * mutate( WithStmt * withStmt ); 52 53 virtual NullStmt * mutate( NullStmt * nullStmt ); 53 54 virtual Statement * mutate( DeclStmt * declStmt ); -
src/SynTree/ReferenceToType.cc
r12d2dc8 r65197c2 70 70 bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; } 71 71 72 AggregateDecl * StructInstType::getAggr() { return baseStruct; } 73 72 74 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const { 73 75 assert( baseStruct ); … … 101 103 102 104 bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; } 105 106 AggregateDecl * UnionInstType::getAggr() { return baseUnion; } 103 107 104 108 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const { -
src/SynTree/Statement.cc
r12d2dc8 r65197c2 456 456 } 457 457 458 459 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {} 460 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) { 461 cloneAll( other.exprs, exprs ); 462 } 463 WithStmt::~WithStmt() { 464 deleteAll( exprs ); 465 delete stmt; 466 } 467 468 void WithStmt::print( std::ostream & os, Indenter indent ) const { 469 os << "With statement" << endl; 470 os << indent << "... with statement:" << endl << indent+1; 471 stmt->print( os, indent+1 ); 472 } 473 474 458 475 NullStmt::NullStmt( const std::list<Label> & labels ) : Statement( labels ) { 459 476 } -
src/SynTree/Statement.h
r12d2dc8 r65197c2 431 431 }; 432 432 433 class WithStmt : public Statement { 434 public: 435 std::list< Expression * > exprs; 436 Statement * stmt; 437 438 WithStmt( const std::list< Expression * > & exprs, Statement * stmt ); 439 WithStmt( const WithStmt & other ); 440 virtual ~WithStmt(); 441 442 virtual WithStmt * clone() const override { return new WithStmt( *this ); } 443 virtual void accept( Visitor & v ) override { v.visit( this ); } 444 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 445 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 446 }; 447 433 448 434 449 // represents a declaration that occurs as part of a compound statement -
src/SynTree/SynTree.h
r12d2dc8 r65197c2 55 55 class FinallyStmt; 56 56 class WaitForStmt; 57 class WithStmt; 57 58 class NullStmt; 58 59 class DeclStmt; -
src/SynTree/Type.h
r12d2dc8 r65197c2 178 178 virtual bool isComplete() const { return true; } 179 179 180 virtual AggregateDecl * getAggr() { assertf( false, "Non-aggregate type: %s", toString( this ).c_str() ); } 181 180 182 virtual Type *clone() const = 0; 181 183 virtual void accept( Visitor & v ) = 0; … … 405 407 virtual bool isComplete() const override; 406 408 409 virtual AggregateDecl * getAggr() override; 410 407 411 /// Looks up the members of this struct named "name" and places them into "foundDecls". 408 412 /// Clones declarations into "foundDecls", caller responsible for freeing … … 436 440 437 441 virtual bool isComplete() const override; 442 443 virtual AggregateDecl * getAggr() override; 438 444 439 445 /// looks up the members of this union named "name" and places them into "foundDecls" -
src/SynTree/Visitor.cc
r12d2dc8 r65197c2 174 174 } 175 175 176 void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) { 176 void Visitor::visit( WithStmt * withStmt ) { 177 acceptAll( withStmt->exprs, *this ); 178 maybeAccept( withStmt->stmt, *this ); 179 } 180 181 void Visitor::visit( NullStmt * ) { 177 182 } 178 183 -
src/SynTree/Visitor.h
r12d2dc8 r65197c2 52 52 virtual void visit( FinallyStmt * finallyStmt ); 53 53 virtual void visit( WaitForStmt * waitforStmt ); 54 virtual void visit( WithStmt * withStmt ); 54 55 virtual void visit( NullStmt * nullStmt ); 55 56 virtual void visit( DeclStmt * declStmt ); -
src/tests/.expect/declarationErrors.txt
r12d2dc8 r65197c2 7 7 declarationErrors.c:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0 8 8 with members 9 i: int 9 10 with body 10 11 … … 12 13 declarationErrors.c:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1 13 14 with members 15 i: int 14 16 with body 15 17
Note: See TracChangeset
for help on using the changeset viewer.