Changes in src/CodeGen/CodeGenerator.cc [0dd18fd:d104b02]
- File:
-
- 1 edited
-
src/CodeGen/CodeGenerator.cc (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r0dd18fd rd104b02 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 18 15:34:00 201713 // Update Count : 48 812 // Last Modified On : Tus Jul 25 15:29:00 2017 13 // Update Count : 486 14 14 // 15 15 #include "CodeGenerator.h" … … 79 79 } 80 80 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; 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; 110 100 } 111 101 } … … 192 182 genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() ); 193 183 output << ")" << endl; 184 output << indent; 194 185 } 195 186 … … 204 195 ++indent; 205 196 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) { 206 updateLocation( *i );197 output << lineDirective( *i ) << indent; 207 198 (*i)->accept( *this ); 208 199 output << ";" << endl; … … 227 218 void CodeGenerator::visit( EnumDecl * enumDecl ) { 228 219 extension( enumDecl ); 229 updateLocation( enumDecl );220 output << lineDirective ( enumDecl ); 230 221 output << "enum "; 231 222 genAttributes( enumDecl->get_attributes() ); … … 243 234 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); 244 235 assert( obj ); 245 updateLocation( obj ); 246 output << mangleName( obj ); 236 output << lineDirective( obj ) << indent << mangleName( obj ); 247 237 if ( obj->get_init() ) { 248 238 output << " = "; … … 262 252 void CodeGenerator::visit( TypedefDecl * typeDecl ) { 263 253 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." ); 264 updateLocation( typeDecl );254 output << lineDirective( typeDecl ); 265 255 output << "typedef "; 266 256 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl; … … 332 322 void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){ 333 323 assertf( ! genC, "ConstructorInit nodes should not reach code generation." ); 334 // xxx - generate something reasonable for constructor/destructor pairs 335 output << "<ctorinit>"; 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 << "}"; 336 330 } 337 331 … … 347 341 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) { 348 342 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 argument359 *arg = addrExpr->get_arg();360 } else {361 // no address-of operator, so must be a pointer - add dereference362 // 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 application364 // 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 } // if372 break;373 }374 375 default:376 // do nothing377 ;378 } // switch379 380 343 switch ( opInfo.type ) { 381 344 case OT_INDEX: … … 584 547 if ( castExpr->get_result()->isVoid() ) { 585 548 output << "(void)" ; 586 } else if ( ! castExpr->get_result()->get_lvalue() ) { 587 // at least one result type of cast, but not an lvalue 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. 588 553 output << "("; 589 554 output << genType( castExpr->get_result(), "", pretty, genC ); 590 555 output << ")"; 591 } else {592 // otherwise, the cast is to an lvalue type, so the cast should be dropped, since the result of a cast is593 // never an lvalue in C594 556 } // if 595 557 castExpr->get_arg()->accept( *this ); … … 706 668 extension( commaExpr ); 707 669 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 } 708 674 commaExpr->get_arg1()->accept( *this ); 709 675 output << " , "; 710 676 commaExpr->get_arg2()->accept( *this ); 711 677 output << ")"; 678 } 679 680 void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) { 681 assertf( ! genC, "TupleAssignExpr should not reach code generation." ); 682 tupleExpr->stmtExpr->accept( *this ); 712 683 } 713 684 … … 761 732 } 762 733 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 763 741 void CodeGenerator::visit( StmtExpr * stmtExpr ) { 764 742 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids(); 765 updateLocation( stmtExpr ); 766 output << "({" << std::endl; 743 output << lineDirective( stmtExpr) << "({" << std::endl; 767 744 ++indent; 768 745 unsigned int numStmts = stmts.size(); 769 746 unsigned int i = 0; 770 747 for ( Statement * stmt : stmts ) { 771 updateLocation( stmt );772 output << printLabels( stmt->get_labels() );748 output << lineDirective( stmt ) << indent; 749 output << printLabels( stmt->get_labels() ); 773 750 if ( i+1 == numStmts ) { 774 751 // last statement in a statement expression needs to be handled specially - … … 815 792 void CodeGenerator::visit( ExprStmt * exprStmt ) { 816 793 assert( exprStmt ); 817 Expression * expr = exprStmt->get_expr();818 794 if ( genC ) { 819 795 // cast the top-level expression to void to reduce gcc warnings. 820 expr = new CastExpr( expr);796 exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) ); 821 797 } 822 expr ->accept( *this );798 exprStmt->get_expr()->accept( *this ); 823 799 output << ";"; 824 800 } … … 856 832 857 833 void CodeGenerator::visit( IfStmt * ifStmt ) { 858 updateLocation( ifStmt );834 output << lineDirective( ifStmt ); 859 835 output << "if ( "; 860 836 ifStmt->get_condition()->accept( *this ); … … 870 846 871 847 void CodeGenerator::visit( SwitchStmt * switchStmt ) { 872 updateLocation( switchStmt );848 output << lineDirective( switchStmt ); 873 849 output << "switch ( " ; 874 850 switchStmt->get_condition()->accept( *this ); … … 883 859 884 860 void CodeGenerator::visit( CaseStmt * caseStmt ) { 885 updateLocation( caseStmt ); 861 output << lineDirective( caseStmt ); 862 output << indent; 886 863 if ( caseStmt->isDefault()) { 887 864 output << "default";
Note:
See TracChangeset
for help on using the changeset viewer.