Changes in / [65197c2:12d2dc8]
- Location:
- src
- Files:
-
- 2 deleted
- 26 edited
-
CodeGen/CodeGenerator.cc (modified) (1 diff)
-
CodeGen/CodeGenerator.h (modified) (1 diff)
-
Common/PassVisitor.h (modified) (3 diffs)
-
Common/PassVisitor.impl.h (modified) (1 diff)
-
Common/PassVisitor.proto.h (modified) (1 diff)
-
GenPoly/InstantiateGeneric.cc (modified) (3 diffs)
-
Parser/DeclarationNode.cc (modified) (1 diff)
-
Parser/ParseNode.h (modified) (5 diffs)
-
Parser/StatementNode.cc (modified) (1 diff)
-
Parser/parser.yy (modified) (11 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (12 diffs)
-
ResolvExpr/AlternativeFinder.h (modified) (4 diffs)
-
ResolvExpr/Resolver.cc (modified) (5 diffs)
-
ResolvExpr/typeops.h (modified) (1 diff)
-
SymTab/Indexer.cc (modified) (15 diffs)
-
SymTab/Indexer.h (modified) (4 diffs)
-
SynTree/Mutator.cc (modified) (1 diff)
-
SynTree/Mutator.h (modified) (1 diff)
-
SynTree/ReferenceToType.cc (modified) (2 diffs)
-
SynTree/Statement.cc (modified) (1 diff)
-
SynTree/Statement.h (modified) (1 diff)
-
SynTree/SynTree.h (modified) (1 diff)
-
SynTree/Type.h (modified) (3 diffs)
-
SynTree/Visitor.cc (modified) (1 diff)
-
SynTree/Visitor.h (modified) (1 diff)
-
tests/.expect/declarationErrors.txt (modified) (2 diffs)
-
tests/.expect/with-statement.txt (deleted)
-
tests/with-statement.c (deleted)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r65197c2 r12d2dc8 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 }1022 1014 1023 1015 void CodeGenerator::postvisit( WhileStmt * whileStmt ) { -
src/CodeGen/CodeGenerator.h
r65197c2 r12d2dc8 102 102 void postvisit( CatchStmt * ); 103 103 void postvisit( WaitForStmt * ); 104 void postvisit( WithStmt * );105 104 void postvisit( WhileStmt * ); 106 105 void postvisit( ForStmt * ); -
src/Common/PassVisitor.h
r65197c2 r12d2dc8 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;84 83 virtual void visit( NullStmt * nullStmt ) override final; 85 84 virtual void visit( DeclStmt * declStmt ) override final; … … 173 172 virtual Statement * mutate( FinallyStmt * finallyStmt ) override final; 174 173 virtual Statement * mutate( WaitForStmt * waitforStmt ) override final; 175 virtual Statement * mutate( WithStmt * withStmt ) override final;176 174 virtual NullStmt * mutate( NullStmt * nullStmt ) override final; 177 175 virtual Statement * mutate( DeclStmt * declStmt ) override final; … … 298 296 void indexerAddUnionFwd ( UnionDecl * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); } 299 297 void indexerAddTrait ( TraitDecl * node ) { indexer_impl_addTrait ( pass, 0, node ); } 300 void indexerAddWith ( WithStmt * node ) { indexer_impl_addWith ( pass, 0, node ); }301 302 298 303 299 template< typename TreeType, typename VisitorType > -
src/Common/PassVisitor.impl.h
r65197c2 r12d2dc8 985 985 } 986 986 987 988 989 //--------------------------------------------------------------------------990 // NullStmt991 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 1017 987 //-------------------------------------------------------------------------- 1018 988 // NullStmt -
src/Common/PassVisitor.proto.h
r65197c2 r12d2dc8 208 208 INDEXER_FUNC( addUnion , UnionDecl * ); 209 209 INDEXER_FUNC( addTrait , TraitDecl * ); 210 INDEXER_FUNC( addWith , WithStmt * );211 210 212 211 -
src/GenPoly/InstantiateGeneric.cc
r65197c2 r12d2dc8 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 } 455 464 } 456 465 … … 460 469 if ( isGenericType( memberExpr->aggregate->result ) ) { 461 470 // find the location of the member 462 AggregateDecl * aggr = memberExpr->aggregate->result->getAggr();471 AggregateDecl * aggr = getAggr( memberExpr->aggregate->result ); 463 472 std::list< Declaration * > & members = aggr->members; 464 473 memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) ); … … 470 479 if ( memberIndex != -1 ) { 471 480 // using the location from the generic type, find the member in the instantiation and rebuild the member expression 472 AggregateDecl * aggr = memberExpr->aggregate->result->getAggr();481 AggregateDecl * aggr = getAggr( memberExpr->aggregate->result ); 473 482 assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." ); 474 483 Declaration * member = *std::next( aggr->members.begin(), memberIndex ); -
src/Parser/DeclarationNode.cc
r65197c2 r12d2dc8 717 717 } 718 718 719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body , StatementNode * with) {719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body ) { 720 720 assert( type ); 721 721 assert( type->kind == TypeData::Function ); 722 722 assert( ! type->function.body ); 723 if ( with ) {724 // convert725 // void f(S s) with (s) { x = 0; }726 // to727 // 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 }734 723 type->function.body = body; 735 724 return this; -
src/Parser/ParseNode.h
r65197c2 r12d2dc8 69 69 70 70 virtual void print( __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 } 71 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {} 75 72 76 73 static int indent_by; … … 123 120 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; } 124 121 125 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override { 126 os << expr.get() << std::endl; 127 } 122 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {} 128 123 void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {} 129 124 … … 262 257 DeclarationNode * addBitfield( ExpressionNode * size ); 263 258 DeclarationNode * addVarArgs(); 264 DeclarationNode * addFunctionBody( StatementNode * body , StatementNode * with = nullptr);259 DeclarationNode * addFunctionBody( StatementNode * body ); 265 260 DeclarationNode * addOldDeclList( DeclarationNode * list ); 266 261 DeclarationNode * setBase( TypeData * newType ); … … 364 359 virtual StatementNode * append_last_case( StatementNode * ); 365 360 366 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override { 367 os << stmt.get() << std::endl; 368 } 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 {} 369 363 private: 370 364 std::unique_ptr<Statement> stmt; … … 414 408 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ); 415 409 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ); 416 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );417 410 418 411 //############################################################################## -
src/Parser/StatementNode.cc
r65197c2 r12d2dc8 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 );295 288 } 296 289 -
src/Parser/parser.yy
r65197c2 r12d2dc8 1058 1058 with_statement: 1059 1059 WITH '(' tuple_expression_list ')' statement 1060 { 1061 $$ = new StatementNode( build_with( $3, $5 ) ); 1062 } 1060 { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME 1063 1061 ; 1064 1062 … … 2412 2410 { $$ = nullptr; } 2413 2411 | WITH '(' tuple_expression_list ')' 2414 { $$ = new StatementNode( build_with( $3, nullptr ) ); }2412 { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME 2415 2413 ; 2416 2414 … … 2422 2420 // Add the function body to the last identifier in the function definition list, i.e., foo3: 2423 2421 // [const double] foo1(), foo2( int ), foo3( double ) { return 3.0; } 2424 $1->get_last()->addFunctionBody( $3 , $2);2422 $1->get_last()->addFunctionBody( $3 ); 2425 2423 $$ = $1; 2426 2424 } … … 2430 2428 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2431 2429 typedefTable.leaveScope(); 2432 $$ = $2->addFunctionBody( $4 , $3)->addType( $1 );2430 $$ = $2->addFunctionBody( $4 )->addType( $1 ); 2433 2431 } 2434 2432 // handles default int return type, OBSOLESCENT (see 1) … … 2437 2435 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2438 2436 typedefTable.leaveScope(); 2439 $$ = $2->addFunctionBody( $4 , $3)->addQualifiers( $1 );2437 $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 ); 2440 2438 } 2441 2439 // handles default int return type, OBSOLESCENT (see 1) … … 2444 2442 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2445 2443 typedefTable.leaveScope(); 2446 $$ = $2->addFunctionBody( $4 , $3)->addQualifiers( $1 );2444 $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 ); 2447 2445 } 2448 2446 // handles default int return type, OBSOLESCENT (see 1) … … 2451 2449 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2452 2450 typedefTable.leaveScope(); 2453 $$ = $3->addFunctionBody( $5 , $4)->addQualifiers( $2 )->addQualifiers( $1 );2451 $$ = $3->addFunctionBody( $5 )->addQualifiers( $2 )->addQualifiers( $1 ); 2454 2452 } 2455 2453 … … 2460 2458 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2461 2459 typedefTable.leaveScope(); 2462 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 , $4)->addType( $1 );2460 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addType( $1 ); 2463 2461 } 2464 2462 // handles default int return type, OBSOLESCENT (see 1) … … 2467 2465 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2468 2466 typedefTable.leaveScope(); 2469 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 , $4)->addQualifiers( $1 );2467 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addQualifiers( $1 ); 2470 2468 } 2471 2469 // handles default int return type, OBSOLESCENT (see 1) … … 2474 2472 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2475 2473 typedefTable.leaveScope(); 2476 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 , $4)->addQualifiers( $1 );2474 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addQualifiers( $1 ); 2477 2475 } 2478 2476 // handles default int return type, OBSOLESCENT (see 1) … … 2481 2479 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2482 2480 typedefTable.leaveScope(); 2483 $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6 , $5)->addQualifiers( $2 )->addQualifiers( $1 );2481 $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 ); 2484 2482 } 2485 2483 ; -
src/ResolvExpr/AlternativeFinder.cc
r65197c2 r12d2dc8 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 93 85 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< SymTab::Indexer::IdData> candidates;471 std::list< DeclarationWithType* > candidates; 472 472 decls.lookupId( curDecl->get_name(), candidates ); 473 473 /// if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; } 474 for ( const auto & data : candidates ) { 475 DeclarationWithType * candidate = data.id; 474 for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) { 476 475 PRINT( 477 476 std::cerr << "inferRecursive: candidate is "; 478 candidate->print( std::cerr );477 (*candidate)->print( std::cerr ); 479 478 std::cerr << std::endl; 480 479 ) … … 483 482 TypeEnvironment newEnv( newAlt.env ); 484 483 OpenVarSet newOpenVars( openVars ); 485 Type *adjType = candidate->get_type()->clone();484 Type *adjType = (*candidate)->get_type()->clone(); 486 485 adjustExprType( adjType, newEnv, indexer ); 487 486 adjType->accept( global_renamer ); … … 501 500 Alternative newerAlt( newAlt ); 502 501 newerAlt.env = newEnv; 503 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 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() ) ); 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 = data.combine();518 Expression *varExpr = new VariableExpr( candDecl ); 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< SymTab::Indexer::IdData> declList;1319 std::list< DeclarationWithType* > declList; 1320 1320 indexer.lookupId( nameExpr->get_name(), declList ); 1321 1321 PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; ) 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 ) ); 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 ) ); 1326 1325 PRINT( 1327 1326 std::cerr << "decl is "; 1328 data.id->print( std::cerr );1327 (*i)->print( std::cerr ); 1329 1328 std::cerr << std::endl; 1330 1329 std::cerr << "newExpr is "; 1331 newExpr ->print( std::cerr );1330 newExpr.print( std::cerr ); 1332 1331 std::cerr << std::endl; 1333 1332 ) … … 1421 1420 } 1422 1421 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 } 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 1444 1439 } 1445 1440 … … 1448 1443 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1449 1444 assert( nameExpr ); 1450 std::list< SymTab::Indexer::IdData> attrList;1445 std::list< DeclarationWithType* > attrList; 1451 1446 indexer.lookupId( nameExpr->get_name(), attrList ); 1452 1447 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1453 for ( auto & data : attrList ) { 1454 DeclarationWithType * id = data.id; 1448 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1455 1449 // check if the type is function 1456 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {1450 if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) { 1457 1451 // assume exactly one parameter 1458 1452 if ( function->get_parameters().size() == 1 ) { 1459 1453 if ( attrExpr->get_isType() ) { 1460 resolveAttr( data, function, attrExpr->get_type(), env, *this);1454 resolveAttr( *i, function, attrExpr->get_type(), env ); 1461 1455 } else { 1462 1456 AlternativeFinder finder( indexer, env ); … … 1464 1458 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 1465 1459 if ( choice->expr->get_result()->size() == 1 ) { 1466 resolveAttr( data, function, choice->expr->get_result(), choice->env, *this);1460 resolveAttr(*i, function, choice->expr->get_result(), choice->env ); 1467 1461 } // fi 1468 1462 } // for … … 1472 1466 } // for 1473 1467 } else { 1474 for ( auto & data : attrList ) { 1475 alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) ); 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 ) ); 1476 1471 renameTypes( alternatives.back().expr ); 1477 1472 } // for -
src/ResolvExpr/AlternativeFinder.h
r65197c2 r12d2dc8 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 ); 144 145 145 146 const SymTab::Indexer &indexer; … … 150 151 151 152 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ); 153 void referenceToRvalueConversion( Expression *& expr ); 152 154 153 155 template< typename InputIterator, typename OutputIterator > … … 172 174 173 175 Cost sumCost( const AltList &in ); 174 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 );175 176 176 177 template< typename InputIterator > … … 180 181 } 181 182 } 182 183 183 } // namespace ResolvExpr 184 184 -
src/ResolvExpr/Resolver.cc
r65197c2 r12d2dc8 26 26 #include "Common/utility.h" // for ValueGuard, group_iterate 27 27 #include "CurrentObject.h" // for CurrentObject 28 #include "InitTweak/GenInit.h"29 28 #include "InitTweak/InitTweak.h" // for isIntrinsicSingleArgCallStmt 30 29 #include "RenameVars.h" // for RenameVars, global_renamer … … 41 40 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 42 41 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 43 #include "Tuples/Tuples.h"44 42 #include "typeops.h" // for extractResultType 45 43 #include "Unify.h" // for unify … … 48 46 49 47 namespace ResolvExpr { 50 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting , public WithStmtsToAdd{48 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting { 51 49 Resolver() {} 52 50 Resolver( const SymTab::Indexer & other ) { … … 76 74 void previsit( CatchStmt *catchStmt ); 77 75 void previsit( WaitForStmt * stmt ); 78 void previsit( WithStmt * withStmt );79 76 80 77 void previsit( SingleInit *singleInit ); … … 574 571 } 575 572 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 candidates588 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 candidates596 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 statement610 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 once617 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 them624 tmp->init = InitTweak::genCtorInit( tmp );625 tmp->accept( *visitor );626 }627 }628 }629 }630 631 573 template< typename T > 632 574 bool isCharType( T t ) { -
src/ResolvExpr/typeops.h
r65197c2 r12d2dc8 102 102 bool occurs( Type *type, std::string varName, const TypeEnvironment &env ); 103 103 104 // in AlternativeFinder.cc105 void referenceToRvalueConversion( Expression *& expr );106 107 104 // flatten tuple type into list of types 108 105 template< typename OutputIterator > -
src/SymTab/Indexer.cc
r65197c2 r12d2dc8 40 40 41 41 namespace SymTab { 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; 42 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 47 43 typedef std::unordered_map< std::string, MangleTable > IdTable; 48 44 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; … … 101 97 } 102 98 103 void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData> & out ) const {99 void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const { 104 100 // only need to perform this step for constructors, destructors, and assignment functions 105 101 if ( ! CodeGen::isCtorDtorAssign( id ) ) return; … … 108 104 struct ValueType { 109 105 struct DeclBall { 110 IdDatadecl;106 FunctionDecl * decl; 111 107 bool isUserDefinedFunc; // properties for this particular decl 112 108 bool isDefaultCtor; … … 124 120 // another FunctionDecl for the current type was found - determine 125 121 // if it has special properties and update data structure accordingly 126 ValueType & operator+=( IdData data ) { 127 DeclarationWithType * function = data.id; 122 ValueType & operator+=( FunctionDecl * function ) { 128 123 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() ); 129 124 bool isDefaultCtor = InitTweak::isDefaultConstructor( function ); 130 125 bool isDtor = InitTweak::isDestructor( function ); 131 126 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() ); 132 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );127 decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } ); 133 128 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc; 134 129 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) ); … … 140 135 }; // ValueType 141 136 142 std::list< IdData> copy;137 std::list< DeclarationWithType * > copy; 143 138 copy.splice( copy.end(), out ); 144 139 145 140 // organize discovered declarations by type 146 141 std::unordered_map< std::string, ValueType > funcMap; 147 for ( autodecl : copy ) {148 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl .id) ) {142 for ( DeclarationWithType * decl : copy ) { 143 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) { 149 144 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters(); 150 145 assert( ! params.empty() ); … … 152 147 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 153 148 assert( base ); 154 funcMap[ Mangler::mangle( base ) ] += decl;149 funcMap[ Mangler::mangle( base ) ] += function; 155 150 } else { 156 151 out.push_back( decl ); … … 169 164 bool noUserDefinedFunc = ! val.existsUserDefinedFunc; 170 165 bool isUserDefinedFunc = ball.isUserDefinedFunc; 171 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 overrides166 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 overrides 172 167 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator 173 168 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor; … … 224 219 } 225 220 226 void Indexer::lookupId( const std::string &id, std::list< IdData> &out ) const {221 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const { 227 222 std::unordered_set< std::string > foundMangleNames; 228 223 … … 294 289 const MangleTable &mangleTable = decls->second; 295 290 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 296 if ( decl != mangleTable.end() ) return decl->second .id;291 if ( decl != mangleTable.end() ) return decl->second; 297 292 } 298 293 … … 309 304 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 310 305 // check for C decls with the same name, skipping those with a compatible type (by mangleName) 311 if ( ! LinkageSpec::isMangled( decl->second .id->get_linkage() ) && decl->first != mangleName ) return true;306 if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first != mangleName ) return true; 312 307 } 313 308 } … … 326 321 // check for C decls with the same name, skipping 327 322 // those with an incompatible type (by mangleName) 328 if ( ! LinkageSpec::isMangled( decl->second .id->get_linkage() ) && decl->first == mangleName ) return true;323 if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first == mangleName ) return true; 329 324 } 330 325 } … … 408 403 } 409 404 410 void Indexer::addId( DeclarationWithType *decl , Expression * baseExpr) {405 void Indexer::addId( DeclarationWithType *decl ) { 411 406 debugPrint( "Adding Id " << decl->name << std::endl ); 412 407 makeWritable(); … … 444 439 445 440 // add to indexer 446 tables->idTable[ name ][ mangleName ] = { decl, baseExpr };441 tables->idTable[ name ][ mangleName ] = decl; 447 442 ++tables->size; 448 443 } … … 568 563 if ( ! addedDeclConflicts( existing->second, decl ) ) { 569 564 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 }585 565 } 586 566 } … … 665 645 666 646 } 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 }682 647 } // namespace SymTab 683 648 -
src/SymTab/Indexer.h
r65197c2 r12d2dc8 39 39 void leaveScope(); 40 40 41 struct IdData {42 DeclarationWithType * id;43 Expression * baseExpr; // WithExpr44 45 Expression * combine() const;46 };47 48 41 /// Gets all declarations with the given ID 49 void lookupId( const std::string &id, std::list< IdData> &out ) const;42 void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const; 50 43 /// Gets the top-most type declaration with the given ID 51 44 NamedTypeDecl *lookupType( const std::string &id ) const; … … 74 67 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 75 68 76 void addId( DeclarationWithType *decl , Expression * baseExpr = nullptr);69 void addId( DeclarationWithType *decl ); 77 70 void addType( NamedTypeDecl *decl ); 78 71 void addStruct( const std::string &id ); … … 82 75 void addUnion( UnionDecl *decl ); 83 76 void addTrait( TraitDecl *decl ); 84 85 /// adds all of the IDs from WithStmt exprs86 void addWith( WithStmt * );87 77 88 78 /// convenience function for adding a list of Ids to the indexer … … 110 100 // so that they will not be selected 111 101 // void removeSpecialOverrides( FunctionDecl *decl ); 112 void removeSpecialOverrides( const std::string &id, std::list< IdData> & out ) const;102 void removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const; 113 103 114 104 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope) -
src/SynTree/Mutator.cc
r65197c2 r12d2dc8 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 211 205 NullStmt * Mutator::mutate( NullStmt *nullStmt ) { 212 206 return nullStmt; -
src/SynTree/Mutator.h
r65197c2 r12d2dc8 50 50 virtual Statement * mutate( FinallyStmt * catchStmt ); 51 51 virtual Statement * mutate( WaitForStmt * waitforStmt ); 52 virtual Statement * mutate( WithStmt * withStmt );53 52 virtual NullStmt * mutate( NullStmt * nullStmt ); 54 53 virtual Statement * mutate( DeclStmt * declStmt ); -
src/SynTree/ReferenceToType.cc
r65197c2 r12d2dc8 70 70 bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; } 71 71 72 AggregateDecl * StructInstType::getAggr() { return baseStruct; }73 74 72 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const { 75 73 assert( baseStruct ); … … 103 101 104 102 bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; } 105 106 AggregateDecl * UnionInstType::getAggr() { return baseUnion; }107 103 108 104 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const { -
src/SynTree/Statement.cc
r65197c2 r12d2dc8 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 475 458 NullStmt::NullStmt( const std::list<Label> & labels ) : Statement( labels ) { 476 459 } -
src/SynTree/Statement.h
r65197c2 r12d2dc8 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 448 433 449 434 // represents a declaration that occurs as part of a compound statement -
src/SynTree/SynTree.h
r65197c2 r12d2dc8 55 55 class FinallyStmt; 56 56 class WaitForStmt; 57 class WithStmt;58 57 class NullStmt; 59 58 class DeclStmt; -
src/SynTree/Type.h
r65197c2 r12d2dc8 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 182 180 virtual Type *clone() const = 0; 183 181 virtual void accept( Visitor & v ) = 0; … … 407 405 virtual bool isComplete() const override; 408 406 409 virtual AggregateDecl * getAggr() override;410 411 407 /// Looks up the members of this struct named "name" and places them into "foundDecls". 412 408 /// Clones declarations into "foundDecls", caller responsible for freeing … … 440 436 441 437 virtual bool isComplete() const override; 442 443 virtual AggregateDecl * getAggr() override;444 438 445 439 /// looks up the members of this union named "name" and places them into "foundDecls" -
src/SynTree/Visitor.cc
r65197c2 r12d2dc8 174 174 } 175 175 176 void Visitor::visit( WithStmt * withStmt ) { 177 acceptAll( withStmt->exprs, *this ); 178 maybeAccept( withStmt->stmt, *this ); 179 } 180 181 void Visitor::visit( NullStmt * ) { 176 void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) { 182 177 } 183 178 -
src/SynTree/Visitor.h
r65197c2 r12d2dc8 52 52 virtual void visit( FinallyStmt * finallyStmt ); 53 53 virtual void visit( WaitForStmt * waitforStmt ); 54 virtual void visit( WithStmt * withStmt );55 54 virtual void visit( NullStmt * nullStmt ); 56 55 virtual void visit( DeclStmt * declStmt ); -
src/tests/.expect/declarationErrors.txt
r65197c2 r12d2dc8 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: int10 9 with body 11 10 … … 13 12 declarationErrors.c:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1 14 13 with members 15 i: int16 14 with body 17 15
Note:
See TracChangeset
for help on using the changeset viewer.