Changes in src/CodeGen/CodeGenerator.cc [d104b02:0dd18fd]
- File:
-
- 1 edited
-
src/CodeGen/CodeGenerator.cc (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rd104b02 r0dd18fd 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 25 15:29:00 201713 // Update Count : 48 612 // Last Modified On : Fri Aug 18 15:34:00 2017 13 // Update Count : 488 14 14 // 15 15 #include "CodeGenerator.h" … … 79 79 } 80 80 81 CodeGenerator::LineMarker::LineMarker( 82 CodeLocation const & loc, bool toPrint) : 83 loc(loc), toPrint(toPrint) 84 {} 85 86 CodeGenerator::LineMarker CodeGenerator::lineDirective( 87 BaseSyntaxNode const * node) { 88 return LineMarker(node->location, lineMarks); 89 } 90 91 std::ostream & operator<<(std::ostream & out, 92 CodeGenerator::LineMarker const & marker) { 93 if (marker.toPrint && marker.loc.isSet()) { 94 return out << "\n# " << marker.loc.linenumber << " \"" 95 << marker.loc.filename << "\"\n"; 96 } else if (marker.toPrint) { 97 return out << "\n/* Missing CodeLocation */\n"; 98 } else { 99 return out; 81 /* Using updateLocation at the beginning of a node and nextLine 82 * within a node should become the method of formating. 83 */ 84 void CodeGenerator::updateLocation( CodeLocation const & to ) { 85 if ( !lineMarks ) { 86 return; 87 } else if ( currentLocation.followedBy( to, 0 ) ) { 88 return; 89 } else if ( currentLocation.followedBy( to, 1 ) ) { 90 output << "\n" << indent; 91 currentLocation.linenumber += 1; 92 } else if ( currentLocation.followedBy( to, 2 ) ) { 93 output << "\n\n" << indent; 94 currentLocation.linenumber += 2; 95 } else { 96 output << "\n# " << to.linenumber << " \"" << to.filename 97 << "\"\n" << indent; 98 currentLocation = to; 99 } 100 output << std::flush; 101 } 102 103 void CodeGenerator::updateLocation( BaseSyntaxNode const * to ) { 104 updateLocation( to->location ); 105 } 106 107 void CodeGenerator::nextLine() { 108 if ( !lineMarks ) { 109 output << "\n" << indent << std::flush; 100 110 } 101 111 } … … 182 192 genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() ); 183 193 output << ")" << endl; 184 output << indent;185 194 } 186 195 … … 195 204 ++indent; 196 205 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) { 197 output << lineDirective( *i ) << indent;206 updateLocation( *i ); 198 207 (*i)->accept( *this ); 199 208 output << ";" << endl; … … 218 227 void CodeGenerator::visit( EnumDecl * enumDecl ) { 219 228 extension( enumDecl ); 220 output << lineDirective( enumDecl );229 updateLocation( enumDecl ); 221 230 output << "enum "; 222 231 genAttributes( enumDecl->get_attributes() ); … … 234 243 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); 235 244 assert( obj ); 236 output << lineDirective( obj ) << indent << mangleName( obj ); 245 updateLocation( obj ); 246 output << mangleName( obj ); 237 247 if ( obj->get_init() ) { 238 248 output << " = "; … … 252 262 void CodeGenerator::visit( TypedefDecl * typeDecl ) { 253 263 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." ); 254 output << lineDirective( typeDecl );264 updateLocation( typeDecl ); 255 265 output << "typedef "; 256 266 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl; … … 322 332 void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){ 323 333 assertf( ! genC, "ConstructorInit nodes should not reach code generation." ); 324 // pseudo-output for constructor/destructor pairs 325 output << "<ctorinit>{" << std::endl << ++indent << "ctor: "; 326 maybeAccept( init->get_ctor(), *this ); 327 output << ", " << std::endl << indent << "dtor: "; 328 maybeAccept( init->get_dtor(), *this ); 329 output << std::endl << --indent << "}"; 334 // xxx - generate something reasonable for constructor/destructor pairs 335 output << "<ctorinit>"; 330 336 } 331 337 … … 341 347 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) { 342 348 std::list< Expression* >::iterator arg = applicationExpr->get_args().begin(); 349 switch ( opInfo.type ) { 350 case OT_PREFIXASSIGN: 351 case OT_POSTFIXASSIGN: 352 case OT_INFIXASSIGN: 353 case OT_CTOR: 354 case OT_DTOR: 355 { 356 assert( arg != applicationExpr->get_args().end() ); 357 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) { 358 // remove & from first assignment/ctor argument 359 *arg = addrExpr->get_arg(); 360 } else { 361 // no address-of operator, so must be a pointer - add dereference 362 // NOTE: if the assertion starts to trigger, check that the application expr isn't being shared. 363 // Since its arguments are modified here, this assertion most commonly triggers when the application 364 // is visited multiple times. 365 UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 366 newExpr->get_args().push_back( *arg ); 367 Type * type = InitTweak::getPointerBase( (*arg)->get_result() ); 368 assertf( type, "First argument to a derefence must be a pointer. Ensure that expressions are not being shared." ); 369 newExpr->set_result( type->clone() ); 370 *arg = newExpr; 371 } // if 372 break; 373 } 374 375 default: 376 // do nothing 377 ; 378 } // switch 379 343 380 switch ( opInfo.type ) { 344 381 case OT_INDEX: … … 547 584 if ( castExpr->get_result()->isVoid() ) { 548 585 output << "(void)" ; 549 } else { 550 // at least one result type of cast. 551 // Note: previously, lvalue casts were skipped. Since it's now impossible for the user to write 552 // an lvalue cast, this has been taken out. 586 } else if ( ! castExpr->get_result()->get_lvalue() ) { 587 // at least one result type of cast, but not an lvalue 553 588 output << "("; 554 589 output << genType( castExpr->get_result(), "", pretty, genC ); 555 590 output << ")"; 591 } else { 592 // otherwise, the cast is to an lvalue type, so the cast should be dropped, since the result of a cast is 593 // never an lvalue in C 556 594 } // if 557 595 castExpr->get_arg()->accept( *this ); … … 668 706 extension( commaExpr ); 669 707 output << "("; 670 if ( genC ) {671 // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.672 commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );673 }674 708 commaExpr->get_arg1()->accept( *this ); 675 709 output << " , "; 676 710 commaExpr->get_arg2()->accept( *this ); 677 711 output << ")"; 678 }679 680 void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) {681 assertf( ! genC, "TupleAssignExpr should not reach code generation." );682 tupleExpr->stmtExpr->accept( *this );683 712 } 684 713 … … 732 761 } 733 762 734 void CodeGenerator::visit( UniqueExpr * unqExpr ) {735 assertf( ! genC, "Unique expressions should not reach code generation." );736 output << "unq<" << unqExpr->get_id() << ">{ ";737 unqExpr->get_expr()->accept( *this );738 output << " }";739 }740 741 763 void CodeGenerator::visit( StmtExpr * stmtExpr ) { 742 764 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids(); 743 output << lineDirective( stmtExpr) << "({" << std::endl; 765 updateLocation( stmtExpr ); 766 output << "({" << std::endl; 744 767 ++indent; 745 768 unsigned int numStmts = stmts.size(); 746 769 unsigned int i = 0; 747 770 for ( Statement * stmt : stmts ) { 748 output << lineDirective( stmt ) << indent;749 output << printLabels( stmt->get_labels() );771 updateLocation( stmt ); 772 output << printLabels( stmt->get_labels() ); 750 773 if ( i+1 == numStmts ) { 751 774 // last statement in a statement expression needs to be handled specially - … … 792 815 void CodeGenerator::visit( ExprStmt * exprStmt ) { 793 816 assert( exprStmt ); 817 Expression * expr = exprStmt->get_expr(); 794 818 if ( genC ) { 795 819 // cast the top-level expression to void to reduce gcc warnings. 796 expr Stmt->set_expr( new CastExpr( exprStmt->get_expr() ));820 expr = new CastExpr( expr ); 797 821 } 798 expr Stmt->get_expr()->accept( *this );822 expr->accept( *this ); 799 823 output << ";"; 800 824 } … … 832 856 833 857 void CodeGenerator::visit( IfStmt * ifStmt ) { 834 output << lineDirective( ifStmt );858 updateLocation( ifStmt ); 835 859 output << "if ( "; 836 860 ifStmt->get_condition()->accept( *this ); … … 846 870 847 871 void CodeGenerator::visit( SwitchStmt * switchStmt ) { 848 output << lineDirective( switchStmt );872 updateLocation( switchStmt ); 849 873 output << "switch ( " ; 850 874 switchStmt->get_condition()->accept( *this ); … … 859 883 860 884 void CodeGenerator::visit( CaseStmt * caseStmt ) { 861 output << lineDirective( caseStmt ); 862 output << indent; 885 updateLocation( caseStmt ); 863 886 if ( caseStmt->isDefault()) { 864 887 output << "default";
Note:
See TracChangeset
for help on using the changeset viewer.