Changes in / [47b5b63:39fea2f]
- Location:
- src
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r47b5b63 r39fea2f 79 79 } 80 80 81 /* Using updateLocation at the beginning of a node and endl81 /* Using updateLocation at the beginning of a node and nextLine 82 82 * within a node should become the method of formating. 83 83 */ 84 84 void CodeGenerator::updateLocation( CodeLocation const & to ) { 85 // skip if linemarks shouldn't appear or if codelocation is unset 86 if ( !lineMarks || to.isUnset() ) return; 87 88 if ( currentLocation.followedBy( to, 0 ) ) { 85 if ( !lineMarks ) { 86 return; 87 } else if ( currentLocation.followedBy( to, 0 ) ) { 89 88 return; 90 89 } else if ( currentLocation.followedBy( to, 1 ) ) { 91 90 output << "\n" << indent; 92 currentLocation. first_line+= 1;91 currentLocation.linenumber += 1; 93 92 } else if ( currentLocation.followedBy( to, 2 ) ) { 94 93 output << "\n\n" << indent; 95 currentLocation. first_line+= 2;96 } else { 97 output << "\n# " << to. first_line<< " \"" << to.filename94 currentLocation.linenumber += 2; 95 } else { 96 output << "\n# " << to.linenumber << " \"" << to.filename 98 97 << "\"\n" << indent; 99 98 currentLocation = to; … … 106 105 } 107 106 108 // replace endl 109 ostream & CodeGenerator::LineEnder::operator()( ostream & os ) const { 110 // if ( !cg.lineMarks ) { 111 // os << "\n" << cg.indent << std::flush; 112 // } 113 os << "\n" << std::flush; 114 cg.currentLocation.first_line++; 115 // os << "/* did endl; current loc is: " << cg.currentLocation.first_line << "*/"; 116 return os; 117 } 118 119 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), endl( *this ) {} 107 void CodeGenerator::nextLine() { 108 if ( !lineMarks ) { 109 output << "\n" << indent << std::flush; 110 } 111 } 112 113 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {} 120 114 121 115 string CodeGenerator::mangleName( DeclarationWithType * decl ) { … … 145 139 } // CodeGenerator::genAttributes 146 140 147 // *** BaseSyntaxNode148 void CodeGenerator::previsit( BaseSyntaxNode * node ) {149 // turn off automatic recursion for all nodes, to allow each visitor to150 // precisely control the order in which its children are visited.151 visit_children = false;152 updateLocation( node );153 }154 155 // *** BaseSyntaxNode156 void CodeGenerator::postvisit( BaseSyntaxNode * node ) {157 std::stringstream ss;158 node->print( ss );159 assertf( false, "Unhandled node reached in CodeGenerator: %s", ss.str().c_str() );160 }161 141 162 142 // *** Declarations 163 void CodeGenerator:: postvisit( FunctionDecl * functionDecl ) {143 void CodeGenerator::visit( FunctionDecl * functionDecl ) { 164 144 extension( functionDecl ); 165 145 genAttributes( functionDecl->get_attributes() ); … … 172 152 asmName( functionDecl ); 173 153 154 // acceptAll( functionDecl->get_oldDecls(), *this ); 174 155 if ( functionDecl->get_statements() ) { 175 functionDecl->get_statements()->accept( * visitor);176 } // if 177 } 178 179 void CodeGenerator:: postvisit( ObjectDecl * objectDecl ) {156 functionDecl->get_statements()->accept( *this ); 157 } // if 158 } 159 160 void CodeGenerator::visit( ObjectDecl * objectDecl ) { 180 161 if (objectDecl->get_name().empty() && genC ) { 181 162 // only generate an anonymous name when generating C code, otherwise it clutters the output too much … … 194 175 if ( objectDecl->get_init() ) { 195 176 output << " = "; 196 objectDecl->get_init()->accept( * visitor);177 objectDecl->get_init()->accept( *this ); 197 178 } // if 198 179 199 180 if ( objectDecl->get_bitfieldWidth() ) { 200 181 output << ":"; 201 objectDecl->get_bitfieldWidth()->accept( * visitor);182 objectDecl->get_bitfieldWidth()->accept( *this ); 202 183 } // if 203 184 } … … 222 203 ++indent; 223 204 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) { 205 updateLocation( *i ); 224 206 output << indent; 225 (*i)->accept( * visitor);207 (*i)->accept( *this ); 226 208 output << ";" << endl; 227 209 } // for … … 233 215 } 234 216 235 void CodeGenerator:: postvisit( StructDecl * structDecl ) {217 void CodeGenerator::visit( StructDecl * structDecl ) { 236 218 extension( structDecl ); 237 219 handleAggregate( structDecl, "struct " ); 238 220 } 239 221 240 void CodeGenerator:: postvisit( UnionDecl * unionDecl ) {222 void CodeGenerator::visit( UnionDecl * unionDecl ) { 241 223 extension( unionDecl ); 242 224 handleAggregate( unionDecl, "union " ); 243 225 } 244 226 245 void CodeGenerator:: postvisit( EnumDecl * enumDecl ) {227 void CodeGenerator::visit( EnumDecl * enumDecl ) { 246 228 extension( enumDecl ); 229 updateLocation( enumDecl ); 247 230 output << "enum "; 248 231 genAttributes( enumDecl->get_attributes() ); … … 259 242 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); 260 243 assert( obj ); 244 updateLocation( obj ); 261 245 output << indent << mangleName( obj ); 262 246 if ( obj->get_init() ) { 263 247 output << " = "; 264 obj->get_init()->accept( * visitor);248 obj->get_init()->accept( *this ); 265 249 } // if 266 250 output << "," << endl; … … 273 257 } 274 258 275 void CodeGenerator:: postvisit( TraitDecl * traitDecl ) {259 void CodeGenerator::visit( TraitDecl * traitDecl ) { 276 260 assertf( ! genC, "TraitDecls should not reach code generation." ); 277 261 extension( traitDecl ); … … 279 263 } 280 264 281 void CodeGenerator:: postvisit( TypedefDecl * typeDecl ) {265 void CodeGenerator::visit( TypedefDecl * typeDecl ) { 282 266 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." ); 267 updateLocation( typeDecl ); 283 268 output << "typedef "; 284 269 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl; 285 270 } 286 271 287 void CodeGenerator:: postvisit( TypeDecl * typeDecl ) {272 void CodeGenerator::visit( TypeDecl * typeDecl ) { 288 273 assertf( ! genC, "TypeDecls should not reach code generation." ); 289 274 output << typeDecl->genTypeString() << " " << typeDecl->get_name(); … … 298 283 } 299 284 300 void CodeGenerator:: postvisit( Designation * designation ) {285 void CodeGenerator::visit( Designation * designation ) { 301 286 std::list< Expression * > designators = designation->get_designators(); 302 287 if ( designators.size() == 0 ) return; … … 305 290 // if expression is a NameExpr or VariableExpr, then initializing aggregate member 306 291 output << "."; 307 des->accept( * visitor);292 des->accept( *this ); 308 293 } else { 309 294 // otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt 310 295 output << "["; 311 des->accept( * visitor);296 des->accept( *this ); 312 297 output << "]"; 313 298 } // if … … 316 301 } 317 302 318 void CodeGenerator:: postvisit( SingleInit * init ) {319 init->get_value()->accept( * visitor);320 } 321 322 void CodeGenerator:: postvisit( ListInit * init ) {303 void CodeGenerator::visit( SingleInit * init ) { 304 init->get_value()->accept( *this ); 305 } 306 307 void CodeGenerator::visit( ListInit * init ) { 323 308 auto initBegin = init->begin(); 324 309 auto initEnd = init->end(); … … 328 313 output << "{ "; 329 314 for ( ; initBegin != initEnd && desigBegin != desigEnd; ) { 330 (*desigBegin)->accept( * visitor);331 (*initBegin)->accept( * visitor);315 (*desigBegin)->accept( *this ); 316 (*initBegin)->accept( *this ); 332 317 ++initBegin, ++desigBegin; 333 318 if ( initBegin != initEnd ) { … … 339 324 } 340 325 341 void CodeGenerator:: postvisit(ConstructorInit * init ){326 void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){ 342 327 assertf( ! genC, "ConstructorInit nodes should not reach code generation." ); 343 328 // pseudo-output for constructor/destructor pairs 344 output << "<ctorinit>{" << endl << ++indent << "ctor: ";345 maybeAccept( init->get_ctor(), * visitor);346 output << ", " << endl << indent << "dtor: ";347 maybeAccept( init->get_dtor(), * visitor);348 output << endl << --indent << "}";349 } 350 351 void CodeGenerator:: postvisit( Constant * constant ) {329 output << "<ctorinit>{" << std::endl << ++indent << "ctor: "; 330 maybeAccept( init->get_ctor(), *this ); 331 output << ", " << std::endl << indent << "dtor: "; 332 maybeAccept( init->get_dtor(), *this ); 333 output << std::endl << --indent << "}"; 334 } 335 336 void CodeGenerator::visit( Constant * constant ) { 352 337 output << constant->get_value() ; 353 338 } 354 339 355 340 // *** Expressions 356 void CodeGenerator:: postvisit( ApplicationExpr * applicationExpr ) {341 void CodeGenerator::visit( ApplicationExpr * applicationExpr ) { 357 342 extension( applicationExpr ); 358 343 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) { … … 363 348 case OT_INDEX: 364 349 assert( applicationExpr->get_args().size() == 2 ); 365 (*arg++)->accept( * visitor);350 (*arg++)->accept( *this ); 366 351 output << "["; 367 (*arg)->accept( * visitor);352 (*arg)->accept( *this ); 368 353 output << "]"; 369 354 break; … … 380 365 // effects, so must still output this expression 381 366 output << "("; 382 (*arg++)->accept( * visitor);367 (*arg++)->accept( *this ); 383 368 output << ") /* " << opInfo.inputName << " */"; 384 369 } else if ( applicationExpr->get_args().size() == 2 ) { 385 370 // intrinsic two parameter constructors are essentially bitwise assignment 386 371 output << "("; 387 (*arg++)->accept( * visitor);372 (*arg++)->accept( *this ); 388 373 output << opInfo.symbol; 389 (*arg)->accept( * visitor);374 (*arg)->accept( *this ); 390 375 output << ") /* " << opInfo.inputName << " */"; 391 376 } else { … … 400 385 output << "("; 401 386 output << opInfo.symbol; 402 (*arg)->accept( * visitor);387 (*arg)->accept( *this ); 403 388 output << ")"; 404 389 break; … … 407 392 case OT_POSTFIXASSIGN: 408 393 assert( applicationExpr->get_args().size() == 1 ); 409 (*arg)->accept( * visitor);394 (*arg)->accept( *this ); 410 395 output << opInfo.symbol; 411 396 break; … … 416 401 assert( applicationExpr->get_args().size() == 2 ); 417 402 output << "("; 418 (*arg++)->accept( * visitor);403 (*arg++)->accept( *this ); 419 404 output << opInfo.symbol; 420 (*arg)->accept( * visitor);405 (*arg)->accept( *this ); 421 406 output << ")"; 422 407 break; … … 428 413 } // switch 429 414 } else { 430 varExpr->accept( * visitor);415 varExpr->accept( *this ); 431 416 output << "("; 432 417 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() ); … … 434 419 } // if 435 420 } else { 436 applicationExpr->get_function()->accept( * visitor);421 applicationExpr->get_function()->accept( *this ); 437 422 output << "("; 438 423 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() ); … … 441 426 } 442 427 443 void CodeGenerator:: postvisit( UntypedExpr * untypedExpr ) {428 void CodeGenerator::visit( UntypedExpr * untypedExpr ) { 444 429 extension( untypedExpr ); 445 430 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { … … 450 435 case OT_INDEX: 451 436 assert( untypedExpr->get_args().size() == 2 ); 452 (*arg++)->accept( * visitor);437 (*arg++)->accept( *this ); 453 438 output << "["; 454 (*arg)->accept( * visitor);439 (*arg)->accept( *this ); 455 440 output << "]"; 456 441 break; … … 465 450 // effects, so must still output this expression 466 451 output << "("; 467 (*arg++)->accept( * visitor);452 (*arg++)->accept( *this ); 468 453 output << ") /* " << opInfo.inputName << " */"; 469 454 } else if ( untypedExpr->get_args().size() == 2 ) { 470 455 // intrinsic two parameter constructors are essentially bitwise assignment 471 456 output << "("; 472 (*arg++)->accept( * visitor);457 (*arg++)->accept( *this ); 473 458 output << opInfo.symbol; 474 (*arg)->accept( * visitor);459 (*arg)->accept( *this ); 475 460 output << ") /* " << opInfo.inputName << " */"; 476 461 } else { 477 462 // no constructors with 0 or more than 2 parameters 478 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." ); 479 output << "("; 480 (*arg++)->accept( *visitor ); 481 output << opInfo.symbol << "{ "; 482 genCommaList( arg, untypedExpr->get_args().end() ); 483 output << "}) /* " << opInfo.inputName << " */"; 463 assert( false ); 484 464 } // if 485 465 break; … … 491 471 output << "("; 492 472 output << opInfo.symbol; 493 (*arg)->accept( * visitor);473 (*arg)->accept( *this ); 494 474 output << ")"; 495 475 break; … … 498 478 case OT_POSTFIXASSIGN: 499 479 assert( untypedExpr->get_args().size() == 1 ); 500 (*arg)->accept( * visitor);480 (*arg)->accept( *this ); 501 481 output << opInfo.symbol; 502 482 break; … … 506 486 assert( untypedExpr->get_args().size() == 2 ); 507 487 output << "("; 508 (*arg++)->accept( * visitor);488 (*arg++)->accept( *this ); 509 489 output << opInfo.symbol; 510 (*arg)->accept( * visitor);490 (*arg)->accept( *this ); 511 491 output << ")"; 512 492 break; … … 519 499 if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2 520 500 assert( untypedExpr->get_args().size() == 2 ); 521 (*untypedExpr->get_args().begin())->accept( * visitor);501 (*untypedExpr->get_args().begin())->accept( *this ); 522 502 output << " ... "; 523 (*--untypedExpr->get_args().end())->accept( * visitor);503 (*--untypedExpr->get_args().end())->accept( *this ); 524 504 } else { // builtin routines 525 nameExpr->accept( * visitor);505 nameExpr->accept( *this ); 526 506 output << "("; 527 507 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); … … 530 510 } // if 531 511 } else { 532 untypedExpr->get_function()->accept( * visitor);512 untypedExpr->get_function()->accept( *this ); 533 513 output << "("; 534 514 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); … … 537 517 } 538 518 539 void CodeGenerator:: postvisit( RangeExpr * rangeExpr ) {540 rangeExpr->get_low()->accept( * visitor);519 void CodeGenerator::visit( RangeExpr * rangeExpr ) { 520 rangeExpr->get_low()->accept( *this ); 541 521 output << " ... "; 542 rangeExpr->get_high()->accept( * visitor);543 } 544 545 void CodeGenerator:: postvisit( NameExpr * nameExpr ) {522 rangeExpr->get_high()->accept( *this ); 523 } 524 525 void CodeGenerator::visit( NameExpr * nameExpr ) { 546 526 extension( nameExpr ); 547 527 OperatorInfo opInfo; … … 554 534 } 555 535 556 void CodeGenerator:: postvisit( AddressExpr * addressExpr ) {536 void CodeGenerator::visit( AddressExpr * addressExpr ) { 557 537 extension( addressExpr ); 558 538 output << "(&"; 559 addressExpr->arg->accept( * visitor);539 addressExpr->arg->accept( *this ); 560 540 output << ")"; 561 541 } 562 542 563 void CodeGenerator:: postvisit( LabelAddressExpr *addressExpr ) {543 void CodeGenerator::visit( LabelAddressExpr *addressExpr ) { 564 544 extension( addressExpr ); 565 545 output << "(&&" << addressExpr->arg << ")"; 566 546 } 567 547 568 void CodeGenerator:: postvisit( CastExpr * castExpr ) {548 void CodeGenerator::visit( CastExpr * castExpr ) { 569 549 extension( castExpr ); 570 550 output << "("; … … 579 559 output << ")"; 580 560 } // if 581 castExpr->get_arg()->accept( * visitor);561 castExpr->get_arg()->accept( *this ); 582 562 output << ")"; 583 563 } 584 564 585 void CodeGenerator:: postvisit( VirtualCastExpr * castExpr ) {565 void CodeGenerator::visit( VirtualCastExpr * castExpr ) { 586 566 assertf( ! genC, "VirtualCastExpr should not reach code generation." ); 587 567 extension( castExpr ); 588 568 output << "(virtual "; 589 castExpr->get_arg()->accept( * visitor);569 castExpr->get_arg()->accept( *this ); 590 570 output << ")"; 591 571 } 592 572 593 void CodeGenerator:: postvisit( UntypedMemberExpr * memberExpr ) {573 void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) { 594 574 assertf( ! genC, "UntypedMemberExpr should not reach code generation." ); 595 575 extension( memberExpr ); 596 memberExpr->get_aggregate()->accept( * visitor);576 memberExpr->get_aggregate()->accept( *this ); 597 577 output << "."; 598 memberExpr->get_member()->accept( * visitor);599 } 600 601 void CodeGenerator:: postvisit( MemberExpr * memberExpr ) {578 memberExpr->get_member()->accept( *this ); 579 } 580 581 void CodeGenerator::visit( MemberExpr * memberExpr ) { 602 582 extension( memberExpr ); 603 memberExpr->get_aggregate()->accept( * visitor);583 memberExpr->get_aggregate()->accept( *this ); 604 584 output << "." << mangleName( memberExpr->get_member() ); 605 585 } 606 586 607 void CodeGenerator:: postvisit( VariableExpr * variableExpr ) {587 void CodeGenerator::visit( VariableExpr * variableExpr ) { 608 588 extension( variableExpr ); 609 589 OperatorInfo opInfo; … … 615 595 } 616 596 617 void CodeGenerator:: postvisit( ConstantExpr * constantExpr ) {597 void CodeGenerator::visit( ConstantExpr * constantExpr ) { 618 598 assert( constantExpr->get_constant() ); 619 599 extension( constantExpr ); 620 constantExpr->get_constant()->accept( * visitor);621 } 622 623 void CodeGenerator:: postvisit( SizeofExpr * sizeofExpr ) {600 constantExpr->get_constant()->accept( *this ); 601 } 602 603 void CodeGenerator::visit( SizeofExpr * sizeofExpr ) { 624 604 extension( sizeofExpr ); 625 605 output << "sizeof("; … … 627 607 output << genType( sizeofExpr->get_type(), "", pretty, genC ); 628 608 } else { 629 sizeofExpr->get_expr()->accept( * visitor);609 sizeofExpr->get_expr()->accept( *this ); 630 610 } // if 631 611 output << ")"; 632 612 } 633 613 634 void CodeGenerator:: postvisit( AlignofExpr * alignofExpr ) {614 void CodeGenerator::visit( AlignofExpr * alignofExpr ) { 635 615 // use GCC extension to avoid bumping std to C11 636 616 extension( alignofExpr ); … … 639 619 output << genType( alignofExpr->get_type(), "", pretty, genC ); 640 620 } else { 641 alignofExpr->get_expr()->accept( * visitor);621 alignofExpr->get_expr()->accept( *this ); 642 622 } // if 643 623 output << ")"; 644 624 } 645 625 646 void CodeGenerator:: postvisit( UntypedOffsetofExpr * offsetofExpr ) {626 void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) { 647 627 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." ); 648 628 output << "offsetof("; … … 652 632 } 653 633 654 void CodeGenerator:: postvisit( OffsetofExpr * offsetofExpr ) {634 void CodeGenerator::visit( OffsetofExpr * offsetofExpr ) { 655 635 // use GCC builtin 656 636 output << "__builtin_offsetof("; … … 660 640 } 661 641 662 void CodeGenerator:: postvisit( OffsetPackExpr * offsetPackExpr ) {642 void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) { 663 643 assertf( ! genC, "OffsetPackExpr should not reach code generation." ); 664 644 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")"; 665 645 } 666 646 667 void CodeGenerator:: postvisit( LogicalExpr * logicalExpr ) {647 void CodeGenerator::visit( LogicalExpr * logicalExpr ) { 668 648 extension( logicalExpr ); 669 649 output << "("; 670 logicalExpr->get_arg1()->accept( * visitor);650 logicalExpr->get_arg1()->accept( *this ); 671 651 if ( logicalExpr->get_isAnd() ) { 672 652 output << " && "; … … 674 654 output << " || "; 675 655 } // if 676 logicalExpr->get_arg2()->accept( * visitor);656 logicalExpr->get_arg2()->accept( *this ); 677 657 output << ")"; 678 658 } 679 659 680 void CodeGenerator:: postvisit( ConditionalExpr * conditionalExpr ) {660 void CodeGenerator::visit( ConditionalExpr * conditionalExpr ) { 681 661 extension( conditionalExpr ); 682 662 output << "("; 683 conditionalExpr->get_arg1()->accept( * visitor);663 conditionalExpr->get_arg1()->accept( *this ); 684 664 output << " ? "; 685 conditionalExpr->get_arg2()->accept( * visitor);665 conditionalExpr->get_arg2()->accept( *this ); 686 666 output << " : "; 687 conditionalExpr->get_arg3()->accept( * visitor);667 conditionalExpr->get_arg3()->accept( *this ); 688 668 output << ")"; 689 669 } 690 670 691 void CodeGenerator:: postvisit( CommaExpr * commaExpr ) {671 void CodeGenerator::visit( CommaExpr * commaExpr ) { 692 672 extension( commaExpr ); 693 673 output << "("; … … 696 676 commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) ); 697 677 } 698 commaExpr->get_arg1()->accept( * visitor);678 commaExpr->get_arg1()->accept( *this ); 699 679 output << " , "; 700 commaExpr->get_arg2()->accept( * visitor);680 commaExpr->get_arg2()->accept( *this ); 701 681 output << ")"; 702 682 } 703 683 704 void CodeGenerator:: postvisit( TupleAssignExpr * tupleExpr ) {684 void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) { 705 685 assertf( ! genC, "TupleAssignExpr should not reach code generation." ); 706 tupleExpr->stmtExpr->accept( * visitor);707 } 708 709 void CodeGenerator:: postvisit( UntypedTupleExpr * tupleExpr ) {686 tupleExpr->stmtExpr->accept( *this ); 687 } 688 689 void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) { 710 690 assertf( ! genC, "UntypedTupleExpr should not reach code generation." ); 711 691 extension( tupleExpr ); … … 715 695 } 716 696 717 void CodeGenerator:: postvisit( TupleExpr * tupleExpr ) {697 void CodeGenerator::visit( TupleExpr * tupleExpr ) { 718 698 assertf( ! genC, "TupleExpr should not reach code generation." ); 719 699 extension( tupleExpr ); … … 723 703 } 724 704 725 void CodeGenerator:: postvisit( TupleIndexExpr * tupleExpr ) {705 void CodeGenerator::visit( TupleIndexExpr * tupleExpr ) { 726 706 assertf( ! genC, "TupleIndexExpr should not reach code generation." ); 727 707 extension( tupleExpr ); 728 tupleExpr->get_tuple()->accept( * visitor);708 tupleExpr->get_tuple()->accept( *this ); 729 709 output << "." << tupleExpr->get_index(); 730 710 } 731 711 732 void CodeGenerator:: postvisit( TypeExpr * typeExpr ) {712 void CodeGenerator::visit( TypeExpr * typeExpr ) { 733 713 // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl; 734 714 // assertf( ! genC, "TypeExpr should not reach code generation." ); … … 738 718 } 739 719 740 void CodeGenerator:: postvisit( AsmExpr * asmExpr ) {720 void CodeGenerator::visit( AsmExpr * asmExpr ) { 741 721 if ( asmExpr->get_inout() ) { 742 722 output << "[ "; 743 asmExpr->get_inout()->accept( * visitor);723 asmExpr->get_inout()->accept( *this ); 744 724 output << " ] "; 745 725 } // if 746 asmExpr->get_constraint()->accept( * visitor);726 asmExpr->get_constraint()->accept( *this ); 747 727 output << " ( "; 748 asmExpr->get_operand()->accept( * visitor);728 asmExpr->get_operand()->accept( *this ); 749 729 output << " )"; 750 730 } 751 731 752 void CodeGenerator:: postvisit( CompoundLiteralExpr *compLitExpr ) {732 void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) { 753 733 assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) ); 754 734 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")"; 755 compLitExpr->get_initializer()->accept( * visitor);756 } 757 758 void CodeGenerator:: postvisit( UniqueExpr * unqExpr ) {735 compLitExpr->get_initializer()->accept( *this ); 736 } 737 738 void CodeGenerator::visit( UniqueExpr * unqExpr ) { 759 739 assertf( ! genC, "Unique expressions should not reach code generation." ); 760 740 output << "unq<" << unqExpr->get_id() << ">{ "; 761 unqExpr->get_expr()->accept( * visitor);741 unqExpr->get_expr()->accept( *this ); 762 742 output << " }"; 763 743 } 764 744 765 void CodeGenerator:: postvisit( StmtExpr * stmtExpr ) {745 void CodeGenerator::visit( StmtExpr * stmtExpr ) { 766 746 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids(); 767 output << "({" << endl; 747 updateLocation( stmtExpr ); 748 output << "({" << std::endl; 768 749 ++indent; 769 750 unsigned int numStmts = stmts.size(); 770 751 unsigned int i = 0; 771 752 for ( Statement * stmt : stmts ) { 753 updateLocation( stmt ); 772 754 output << indent << printLabels( stmt->get_labels() ); 773 755 if ( i+1 == numStmts ) { … … 775 757 // cannot cast to void, otherwise the expression statement has no value 776 758 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) { 777 exprStmt->get_expr()->accept( * visitor);759 exprStmt->get_expr()->accept( *this ); 778 760 output << ";" << endl; 779 761 ++i; … … 781 763 } 782 764 } 783 stmt->accept( * visitor);765 stmt->accept( *this ); 784 766 output << endl; 785 767 if ( wantSpacing( stmt ) ) { … … 792 774 } 793 775 794 void CodeGenerator::postvisit( ConstructorExpr * expr ) {795 assertf( ! genC, "Unique expressions should not reach code generation." );796 expr->callExpr->accept( *visitor );797 }798 799 776 // *** Statements 800 void CodeGenerator:: postvisit( CompoundStmt * compoundStmt ) {777 void CodeGenerator::visit( CompoundStmt * compoundStmt ) { 801 778 std::list<Statement*> ks = compoundStmt->get_kids(); 802 779 output << "{" << endl; … … 806 783 for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end(); i++ ) { 807 784 output << indent << printLabels( (*i)->get_labels() ); 808 (*i)->accept( * visitor);785 (*i)->accept( *this ); 809 786 810 787 output << endl; … … 818 795 } 819 796 820 void CodeGenerator:: postvisit( ExprStmt * exprStmt ) {797 void CodeGenerator::visit( ExprStmt * exprStmt ) { 821 798 assert( exprStmt ); 822 799 if ( genC ) { … … 824 801 exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) ); 825 802 } 826 exprStmt->get_expr()->accept( * visitor);803 exprStmt->get_expr()->accept( *this ); 827 804 output << ";"; 828 805 } 829 806 830 void CodeGenerator:: postvisit( AsmStmt * asmStmt ) {807 void CodeGenerator::visit( AsmStmt * asmStmt ) { 831 808 output << "asm "; 832 809 if ( asmStmt->get_voltile() ) output << "volatile "; 833 810 if ( ! asmStmt->get_gotolabels().empty() ) output << "goto "; 834 811 output << "( "; 835 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( * visitor);812 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *this ); 836 813 output << " : "; 837 814 genCommaList( asmStmt->get_output().begin(), asmStmt->get_output().end() ); … … 851 828 } 852 829 853 void CodeGenerator:: postvisit( AsmDecl * asmDecl ) {830 void CodeGenerator::visit( AsmDecl * asmDecl ) { 854 831 output << "asm "; 855 832 AsmStmt * asmStmt = asmDecl->get_stmt(); 856 833 output << "( "; 857 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( * visitor);834 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *this ); 858 835 output << " )" ; 859 836 } 860 837 861 void CodeGenerator::postvisit( IfStmt * ifStmt ) { 838 void CodeGenerator::visit( IfStmt * ifStmt ) { 839 updateLocation( ifStmt ); 862 840 output << "if ( "; 863 ifStmt->get_condition()->accept( * visitor);841 ifStmt->get_condition()->accept( *this ); 864 842 output << " ) "; 865 843 866 ifStmt->get_thenPart()->accept( * visitor);844 ifStmt->get_thenPart()->accept( *this ); 867 845 868 846 if ( ifStmt->get_elsePart() != 0) { 869 847 output << " else "; 870 ifStmt->get_elsePart()->accept( *visitor ); 871 } // if 872 } 873 874 void CodeGenerator::postvisit( SwitchStmt * switchStmt ) { 848 ifStmt->get_elsePart()->accept( *this ); 849 } // if 850 } 851 852 void CodeGenerator::visit( SwitchStmt * switchStmt ) { 853 updateLocation( switchStmt ); 875 854 output << "switch ( " ; 876 switchStmt->get_condition()->accept( * visitor);855 switchStmt->get_condition()->accept( *this ); 877 856 output << " ) "; 878 857 879 output << "{" << endl;858 output << "{" << std::endl; 880 859 ++indent; 881 acceptAll( switchStmt->get_statements(), * visitor);860 acceptAll( switchStmt->get_statements(), *this ); 882 861 --indent; 883 862 output << indent << "}"; 884 863 } 885 864 886 void CodeGenerator::postvisit( CaseStmt * caseStmt ) { 865 void CodeGenerator::visit( CaseStmt * caseStmt ) { 866 updateLocation( caseStmt ); 887 867 if ( caseStmt->isDefault()) { 888 868 output << "default"; 889 869 } else { 890 870 output << "case "; 891 caseStmt->get_condition()->accept( * visitor);892 } // if 893 output << ": " << endl;871 caseStmt->get_condition()->accept( *this ); 872 } // if 873 output << ":\n"; 894 874 895 875 std::list<Statement *> sts = caseStmt->get_statements(); … … 898 878 for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end(); i++) { 899 879 output << indent << printLabels( (*i)->get_labels() ) ; 900 (*i)->accept( * visitor);880 (*i)->accept( *this ); 901 881 output << endl; 902 882 } // for … … 904 884 } 905 885 906 void CodeGenerator:: postvisit( BranchStmt * branchStmt ) {886 void CodeGenerator::visit( BranchStmt * branchStmt ) { 907 887 switch ( branchStmt->get_type()) { 908 888 case BranchStmt::Goto: … … 912 892 if ( branchStmt->get_computedTarget() != 0 ) { 913 893 output << "goto *"; 914 branchStmt->get_computedTarget()->accept( * visitor);894 branchStmt->get_computedTarget()->accept( *this ); 915 895 } // if 916 896 } // if … … 926 906 } 927 907 928 void CodeGenerator:: postvisit( ReturnStmt * returnStmt ) {908 void CodeGenerator::visit( ReturnStmt * returnStmt ) { 929 909 output << "return "; 930 maybeAccept( returnStmt->get_expr(), * visitor);910 maybeAccept( returnStmt->get_expr(), *this ); 931 911 output << ";"; 932 912 } 933 913 934 void CodeGenerator:: postvisit( ThrowStmt * throwStmt ) {914 void CodeGenerator::visit( ThrowStmt * throwStmt ) { 935 915 assertf( ! genC, "Throw statements should not reach code generation." ); 936 916 … … 939 919 if (throwStmt->get_expr()) { 940 920 output << " "; 941 throwStmt->get_expr()->accept( * visitor);921 throwStmt->get_expr()->accept( *this ); 942 922 } 943 923 if (throwStmt->get_target()) { 944 924 output << " _At "; 945 throwStmt->get_target()->accept( * visitor);925 throwStmt->get_target()->accept( *this ); 946 926 } 947 927 output << ";"; 948 928 } 949 929 950 void CodeGenerator:: postvisit( WhileStmt * whileStmt ) {930 void CodeGenerator::visit( WhileStmt * whileStmt ) { 951 931 if ( whileStmt->get_isDoWhile() ) { 952 932 output << "do" ; 953 933 } else { 954 934 output << "while (" ; 955 whileStmt->get_condition()->accept( * visitor);935 whileStmt->get_condition()->accept( *this ); 956 936 output << ")"; 957 937 } // if … … 959 939 960 940 output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() ); 961 whileStmt->get_body()->accept( * visitor);941 whileStmt->get_body()->accept( *this ); 962 942 963 943 output << indent; … … 965 945 if ( whileStmt->get_isDoWhile() ) { 966 946 output << " while (" ; 967 whileStmt->get_condition()->accept( * visitor);947 whileStmt->get_condition()->accept( *this ); 968 948 output << ");"; 969 949 } // if 970 950 } 971 951 972 void CodeGenerator:: postvisit( ForStmt * forStmt ) {952 void CodeGenerator::visit( ForStmt * forStmt ) { 973 953 // initialization is always hoisted, so don't bother doing anything with that 974 954 output << "for (;"; 975 955 976 956 if ( forStmt->get_condition() != 0 ) { 977 forStmt->get_condition()->accept( * visitor);957 forStmt->get_condition()->accept( *this ); 978 958 } // if 979 959 output << ";"; … … 982 962 // cast the top-level expression to void to reduce gcc warnings. 983 963 Expression * expr = new CastExpr( forStmt->get_increment() ); 984 expr->accept( * visitor);964 expr->accept( *this ); 985 965 } // if 986 966 output << ") "; … … 988 968 if ( forStmt->get_body() != 0 ) { 989 969 output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() ); 990 forStmt->get_body()->accept( * visitor);991 } // if 992 } 993 994 void CodeGenerator:: postvisit( __attribute__((unused)) NullStmt * nullStmt ) {970 forStmt->get_body()->accept( *this ); 971 } // if 972 } 973 974 void CodeGenerator::visit( __attribute__((unused)) NullStmt * nullStmt ) { 995 975 //output << indent << CodeGenerator::printLabels( nullStmt->get_labels() ); 996 976 output << "/* null statement */ ;"; 997 977 } 998 978 999 void CodeGenerator:: postvisit( DeclStmt * declStmt ) {1000 declStmt->get_decl()->accept( * visitor);979 void CodeGenerator::visit( DeclStmt * declStmt ) { 980 declStmt->get_decl()->accept( *this ); 1001 981 1002 982 if ( doSemicolon( declStmt->get_decl() ) ) { 1003 983 output << ";"; 1004 984 } // if 1005 }1006 1007 void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {1008 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );1009 stmt->callStmt->accept( *visitor );1010 985 } 1011 986 -
src/CodeGen/CodeGenerator.h
r47b5b63 r39fea2f 21 21 22 22 #include "Common/Indenter.h" // for Indenter 23 #include "Common/PassVisitor.h" // for PassVisitor24 23 #include "SynTree/Declaration.h" // for DeclarationWithType (ptr only), Fun... 25 24 #include "SynTree/Visitor.h" // for Visitor … … 27 26 28 27 namespace CodeGen { 29 struct CodeGenerator : public WithShortCircuiting, public WithVisitorRef<CodeGenerator> { 30 static int tabsize; 28 class CodeGenerator : public Visitor { 29 public: 30 static int tabsize; 31 31 32 32 CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false ); 33 34 //*** Turn off visit_children for all nodes 35 void previsit( BaseSyntaxNode * ); 36 37 //*** Error for unhandled node types 38 void postvisit( BaseSyntaxNode * ); 33 CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false ); 34 CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false ); 39 35 40 36 //*** Declaration 41 v oid postvisit( StructDecl * );42 v oid postvisit( FunctionDecl * );43 v oid postvisit( ObjectDecl * );44 v oid postvisit( UnionDecl *aggregateDecl );45 v oid postvisit( EnumDecl *aggregateDecl );46 v oid postvisit( TraitDecl *aggregateDecl );47 v oid postvisit( TypedefDecl *typeDecl );48 v oid postvisit( TypeDecl *typeDecl );37 virtual void visit( StructDecl * ); 38 virtual void visit( FunctionDecl * ); 39 virtual void visit( ObjectDecl * ); 40 virtual void visit( UnionDecl *aggregateDecl ); 41 virtual void visit( EnumDecl *aggregateDecl ); 42 virtual void visit( TraitDecl *aggregateDecl ); 43 virtual void visit( TypedefDecl *typeDecl ); 44 virtual void visit( TypeDecl *typeDecl ); 49 45 50 46 //*** Initializer 51 v oid postvisit( Designation * );52 v oid postvisit( SingleInit * );53 v oid postvisit( ListInit * );54 v oid postvisit( ConstructorInit * );47 virtual void visit( Designation * ); 48 virtual void visit( SingleInit * ); 49 virtual void visit( ListInit * ); 50 virtual void visit( ConstructorInit * ); 55 51 56 52 //*** Constant 57 v oid postvisit( Constant * );53 virtual void visit( Constant * ); 58 54 59 55 //*** Expression 60 void postvisit( ApplicationExpr *applicationExpr ); 61 void postvisit( UntypedExpr *untypedExpr ); 62 void postvisit( RangeExpr * rangeExpr ); 63 void postvisit( NameExpr *nameExpr ); 64 void postvisit( AddressExpr *addressExpr ); 65 void postvisit( LabelAddressExpr *addressExpr ); 66 void postvisit( CastExpr *castExpr ); 67 void postvisit( VirtualCastExpr *castExpr ); 68 void postvisit( UntypedMemberExpr *memberExpr ); 69 void postvisit( MemberExpr *memberExpr ); 70 void postvisit( VariableExpr *variableExpr ); 71 void postvisit( ConstantExpr *constantExpr ); 72 void postvisit( SizeofExpr *sizeofExpr ); 73 void postvisit( AlignofExpr *alignofExpr ); 74 void postvisit( UntypedOffsetofExpr *offsetofExpr ); 75 void postvisit( OffsetofExpr *offsetofExpr ); 76 void postvisit( OffsetPackExpr *offsetPackExpr ); 77 void postvisit( LogicalExpr *logicalExpr ); 78 void postvisit( ConditionalExpr *conditionalExpr ); 79 void postvisit( CommaExpr *commaExpr ); 80 void postvisit( CompoundLiteralExpr *compLitExpr ); 81 void postvisit( UniqueExpr * ); 82 void postvisit( TupleAssignExpr * tupleExpr ); 83 void postvisit( UntypedTupleExpr *tupleExpr ); 84 void postvisit( TupleExpr *tupleExpr ); 85 void postvisit( TupleIndexExpr * tupleExpr ); 86 void postvisit( TypeExpr *typeExpr ); 87 void postvisit( AsmExpr * ); 88 void postvisit( StmtExpr * ); 89 void postvisit( ConstructorExpr * ); 56 virtual void visit( ApplicationExpr *applicationExpr ); 57 virtual void visit( UntypedExpr *untypedExpr ); 58 virtual void visit( RangeExpr * rangeExpr ); 59 virtual void visit( NameExpr *nameExpr ); 60 virtual void visit( AddressExpr *addressExpr ); 61 virtual void visit( LabelAddressExpr *addressExpr ); 62 virtual void visit( CastExpr *castExpr ); 63 virtual void visit( VirtualCastExpr *castExpr ); 64 virtual void visit( UntypedMemberExpr *memberExpr ); 65 virtual void visit( MemberExpr *memberExpr ); 66 virtual void visit( VariableExpr *variableExpr ); 67 virtual void visit( ConstantExpr *constantExpr ); 68 virtual void visit( SizeofExpr *sizeofExpr ); 69 virtual void visit( AlignofExpr *alignofExpr ); 70 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 71 virtual void visit( OffsetofExpr *offsetofExpr ); 72 virtual void visit( OffsetPackExpr *offsetPackExpr ); 73 virtual void visit( LogicalExpr *logicalExpr ); 74 virtual void visit( ConditionalExpr *conditionalExpr ); 75 virtual void visit( CommaExpr *commaExpr ); 76 virtual void visit( CompoundLiteralExpr *compLitExpr ); 77 virtual void visit( UniqueExpr * ); 78 virtual void visit( TupleAssignExpr * tupleExpr ); 79 virtual void visit( UntypedTupleExpr *tupleExpr ); 80 virtual void visit( TupleExpr *tupleExpr ); 81 virtual void visit( TupleIndexExpr * tupleExpr ); 82 virtual void visit( TypeExpr *typeExpr ); 83 virtual void visit( AsmExpr * ); 84 virtual void visit( StmtExpr * ); 90 85 91 86 //*** Statements 92 void postvisit( CompoundStmt * ); 93 void postvisit( ExprStmt * ); 94 void postvisit( AsmStmt * ); 95 void postvisit( AsmDecl * ); // special: statement in declaration context 96 void postvisit( IfStmt * ); 97 void postvisit( SwitchStmt * ); 98 void postvisit( CaseStmt * ); 99 void postvisit( BranchStmt * ); 100 void postvisit( ReturnStmt * ); 101 void postvisit( ThrowStmt * ); 102 void postvisit( WhileStmt * ); 103 void postvisit( ForStmt * ); 104 void postvisit( NullStmt * ); 105 void postvisit( DeclStmt * ); 106 void postvisit( ImplicitCtorDtorStmt * ); 87 virtual void visit( CompoundStmt * ); 88 virtual void visit( ExprStmt * ); 89 virtual void visit( AsmStmt * ); 90 virtual void visit( AsmDecl * ); // special: statement in declaration context 91 virtual void visit( IfStmt * ); 92 virtual void visit( SwitchStmt * ); 93 virtual void visit( CaseStmt * ); 94 virtual void visit( BranchStmt * ); 95 virtual void visit( ReturnStmt * ); 96 virtual void visit( ThrowStmt * ); 97 virtual void visit( WhileStmt * ); 98 virtual void visit( ForStmt * ); 99 virtual void visit( NullStmt * ); 100 virtual void visit( DeclStmt * ); 107 101 108 102 void genAttributes( std::list< Attribute * > & attributes ); … … 123 117 124 118 void updateLocation( BaseSyntaxNode const * to ); 125 struct LineEnder {126 CodeGenerator & cg;127 LineEnder( CodeGenerator & cg ) : cg( cg ) {}128 std::ostream & operator()(std::ostream &) const;129 };130 119 private: 131 120 Indenter indent; 132 std::ostream & output; 121 bool insideFunction; 122 std::ostream &output; 133 123 LabelPrinter printLabels; 134 124 bool pretty = false; // pretty print 135 125 bool genC = false; // true if output has to be C code 136 126 bool lineMarks = false; 137 public:138 LineEnder endl;139 private:140 127 141 128 CodeLocation currentLocation; 142 129 void updateLocation( CodeLocation const & to ); 130 void nextLine(); 143 131 144 132 void handleStorageClass( DeclarationWithType *decl ); … … 152 140 if ( begin == end ) return; 153 141 for ( ;; ) { 154 (*begin++)->accept( * visitor);142 (*begin++)->accept( *this ); 155 143 if ( begin == end ) break; 156 144 output << ", "; // separator … … 167 155 /// returns C-compatible name of declaration 168 156 std::string genName( DeclarationWithType * decl ); 169 170 inline std::ostream & operator<<( std::ostream & os, const CodeGenerator::LineEnder & endl ) {171 return endl( os );172 }173 157 } // namespace CodeGen 174 158 -
src/CodeGen/GenType.cc
r47b5b63 r39fea2f 63 63 64 64 if ( ! type->get_attributes().empty() ) { 65 PassVisitor<CodeGenerator>cg( os, pretty, genC, lineMarks );66 cg. pass.genAttributes( type->get_attributes() );65 CodeGenerator cg( os, pretty, genC, lineMarks ); 66 cg.genAttributes( type->get_attributes() ); 67 67 } // if 68 68 … … 116 116 } // if 117 117 if ( dimension != 0 ) { 118 PassVisitor<CodeGenerator>cg( os, pretty, genC, lineMarks );118 CodeGenerator cg( os, pretty, genC, lineMarks ); 119 119 dimension->accept( cg ); 120 120 } else if ( isVarLen ) { … … 178 178 } // if 179 179 } else { 180 PassVisitor<CodeGenerator>cg( os, pretty, genC, lineMarks );180 CodeGenerator cg( os, pretty, genC, lineMarks ); 181 181 os << "(" ; 182 182 183 cg. pass.genCommaList( pars.begin(), pars.end() );183 cg.genCommaList( pars.begin(), pars.end() ); 184 184 185 185 if ( funcType->get_isVarArgs() ) { … … 201 201 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 202 202 std::ostringstream os; 203 PassVisitor<CodeGenerator>cg( os, pretty, genC, lineMarks );203 CodeGenerator cg( os, pretty, genC, lineMarks ); 204 204 os << "forall("; 205 cg. pass.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );205 cg.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() ); 206 206 os << ")" << std::endl; 207 207 typeString = os.str() + typeString; … … 212 212 if ( ! refType->get_parameters().empty() ) { 213 213 std::ostringstream os; 214 PassVisitor<CodeGenerator>cg( os, pretty, genC, lineMarks );214 CodeGenerator cg( os, pretty, genC, lineMarks ); 215 215 os << "("; 216 cg. pass.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );216 cg.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() ); 217 217 os << ") "; 218 218 return os.str(); -
src/CodeGen/Generate.cc
r47b5b63 r39fea2f 33 33 /// Removes misc. nodes that should not exist in CodeGen 34 34 struct TreeCleaner { 35 void premutate( CompoundStmt * stmt ); 36 Statement * postmutate( ImplicitCtorDtorStmt * stmt ); 35 void previsit( CompoundStmt * stmt ); 37 36 38 37 static bool shouldClean( Declaration * ); … … 42 41 PassVisitor<TreeCleaner> cleaner; 43 42 filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false ); 44 mutateAll( translationUnit, cleaner );43 acceptAll( translationUnit, cleaner ); 45 44 } // cleanTree 46 45 } // namespace … … 49 48 cleanTree( translationUnit ); 50 49 51 PassVisitor<CodeGenerator>cgv( os, pretty, generateC, lineMarks );50 CodeGen::CodeGenerator cgv( os, pretty, generateC, lineMarks ); 52 51 for ( auto & dcl : translationUnit ) { 53 52 if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) { 54 cgv. pass.updateLocation( dcl );53 cgv.updateLocation( dcl ); 55 54 dcl->accept(cgv); 56 55 if ( doSemicolon( dcl ) ) { 57 56 os << ";"; 58 57 } // if 59 os << cgv.pass.endl;58 os << std::endl; 60 59 } // if 61 60 } // for … … 66 65 os << CodeGen::genPrettyType( type, "" ); 67 66 } else { 68 PassVisitor<CodeGenerator>cgv( os, true, false, false );67 CodeGen::CodeGenerator cgv( os, true, false, false ); 69 68 node->accept( cgv ); 70 69 } … … 73 72 74 73 namespace { 75 void TreeCleaner::pre mutate( CompoundStmt * cstmt ) {74 void TreeCleaner::previsit( CompoundStmt * cstmt ) { 76 75 filter( cstmt->kids, [](Statement * stmt) { 77 76 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { … … 80 79 return false; 81 80 }, false ); 82 }83 84 Statement * TreeCleaner::postmutate( ImplicitCtorDtorStmt * stmt ) {85 Statement * callStmt = nullptr;86 std::swap( stmt->callStmt, callStmt );87 delete stmt;88 return callStmt;89 81 } 90 82 -
src/CodeTools/TrackLoc.cc
r47b5b63 r39fea2f 33 33 34 34 namespace CodeTools { 35 36 std::ostream & operator<<(std::ostream & out, CodeLocation const & loc) { 37 return out << loc.filename << '[' << loc.linenumber << ']'; 38 } 39 35 40 class LocationPrinter { 36 41 size_t printLevel; … … 64 69 } 65 70 else { 66 assertf( false, "Top level node has no CodeLocation %s", name.c_str() ); 71 std::cerr << "Top level node has no CodeLocation " << name << std::endl; 72 exit(EXIT_FAILURE); 67 73 } 68 74 } … … 89 95 acceptAll( translationUnit, printer ); 90 96 } 97 91 98 } // namespace CodeTools 92 99 -
src/Common/CodeLocation.h
r47b5b63 r39fea2f 16 16 #pragma once 17 17 18 #include <iostream>19 18 #include <string> 20 19 21 20 struct CodeLocation { 22 int first_line = -1, first_column = -1, last_line = -1, last_column = -1;23 std::string filename = "";21 int linenumber; 22 std::string filename; 24 23 25 24 /// Create a new unset CodeLocation. 26 CodeLocation() = default; 25 CodeLocation() 26 : linenumber( -1 ) 27 , filename("") 28 {} 27 29 28 30 /// Create a new CodeLocation with the given values. 29 31 CodeLocation( const char* filename, int lineno ) 30 : first_line( lineno )32 : linenumber( lineno ) 31 33 , filename(filename ? filename : "") 32 34 {} … … 35 37 36 38 bool isSet () const { 37 return -1 != first_line;39 return -1 != linenumber; 38 40 } 39 41 … … 42 44 } 43 45 46 void unset () { 47 linenumber = -1; 48 filename = ""; 49 } 50 51 // Use field access for set. 52 44 53 bool followedBy( CodeLocation const & other, int seperation ) { 45 return ( first_line + seperation == other.first_line&&54 return (linenumber + seperation == other.linenumber && 46 55 filename == other.filename); 47 56 } … … 56 65 }; 57 66 58 inline std:: ostream & operator<<( std::ostream & out, const CodeLocation& location ) {59 60 return location.isSet() ? out << location.filename << ":" << location.first_line << ":1 " : out;67 inline std::string to_string( const CodeLocation& location ) { 68 // Column number ":1" allows IDEs to parse the error message and position the cursor in the source text. 69 return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + ":1 " : ""; 61 70 } 71 -
src/Common/PassVisitor.h
r47b5b63 r39fea2f 133 133 virtual void visit( OneType *oneType ) override final; 134 134 135 virtual void visit( Designation *designation ) override final;136 135 virtual void visit( SingleInit *singleInit ) override final; 137 136 virtual void visit( ListInit *listInit ) override final; … … 222 221 virtual Type* mutate( OneType *oneType ) override final; 223 222 224 virtual Designation* mutate( Designation *designation ) override final;225 223 virtual Initializer* mutate( SingleInit *singleInit ) override final; 226 224 virtual Initializer* mutate( ListInit *listInit ) override final; -
src/Common/PassVisitor.impl.h
r47b5b63 r39fea2f 1926 1926 } 1927 1927 1928 template< typename pass_type >1929 void PassVisitor< pass_type >::visit( Designation * node ) {1930 VISIT_START( node );1931 1932 maybeAccept( node->get_designators(), *this );1933 1934 VISIT_END( node );1935 }1936 1937 template< typename pass_type >1938 Designation * PassVisitor< pass_type >::mutate( Designation * node ) {1939 MUTATE_START( node );1940 1941 maybeMutateRef( node->get_designators(), *this );1942 1943 MUTATE_END( Designation, node );1944 }1945 1946 1928 //-------------------------------------------------------------------------- 1947 1929 // SingleInit -
src/Common/SemanticError.cc
r47b5b63 r39fea2f 45 45 using std::to_string; 46 46 for( auto err : errors ) { 47 os << err.location<< err.description << std::endl;47 os << to_string( err.location ) << err.description << std::endl; 48 48 } 49 49 } -
src/Common/SemanticError.h
r47b5b63 r39fea2f 32 32 33 33 void maybeSet( const CodeLocation & location ) { 34 if( this->location. isUnset()) {34 if( this->location.linenumber < 0 ) { 35 35 this->location = location; 36 36 } -
src/ControlStruct/ExceptTranslate.cc
r47b5b63 r39fea2f 622 622 assertf(false, "Invalid throw in %s at %i\n", 623 623 throwStmt->location.filename.c_str(), 624 throwStmt->location. first_line);624 throwStmt->location.linenumber); 625 625 return nullptr; 626 626 } … … 633 633 assertf(false, "Invalid throwResume in %s at %i\n", 634 634 throwStmt->location.filename.c_str(), 635 throwStmt->location. first_line);635 throwStmt->location.linenumber); 636 636 return nullptr; 637 637 } -
src/InitTweak/FixInit.cc
r47b5b63 r39fea2f 105 105 106 106 /// collects constructed object decls - used as a base class 107 struct ObjDeclCollector : public WithGuards, public WithShortCircuiting { 107 class ObjDeclCollector : public AddStmtVisitor { 108 public: 109 typedef AddStmtVisitor Parent; 110 using Parent::visit; 108 111 // use ordered data structure to maintain ordering for set_difference and for consistent error messages 109 112 typedef std::list< ObjectDecl * > ObjectSet; 110 v oid previsit( CompoundStmt *compoundStmt );111 v oid previsit( DeclStmt *stmt );113 virtual void visit( CompoundStmt *compoundStmt ) override; 114 virtual void visit( DeclStmt *stmt ) override; 112 115 113 116 // don't go into other functions 114 v oid previsit( FunctionDecl * ) { visit_children = false;}117 virtual void visit( FunctionDecl * ) override {} 115 118 116 119 protected: … … 136 139 } 137 140 138 struct LabelFinder final : public ObjDeclCollector { 141 class LabelFinder final : public ObjDeclCollector { 142 public: 143 typedef ObjDeclCollector Parent; 139 144 typedef std::map< Label, ObjectSet > LabelMap; 140 145 // map of Label -> live variables at that label 141 146 LabelMap vars; 142 147 143 typedef ObjDeclCollector Parent; 144 using Parent::previsit; 145 void previsit( Statement * stmt ); 146 147 void previsit( CompoundStmt *compoundStmt ); 148 void previsit( DeclStmt *stmt ); 148 void handleStmt( Statement * stmt ); 149 150 // xxx - This needs to be done better. 151 // allow some generalization among different kinds of nodes with with similar parentage (e.g. all 152 // expressions, all statements, etc.) important to have this to provide a single entry point so that as new 153 // subclasses are added, there is only one place that the code has to be updated, rather than ensure that 154 // every specialized class knows about every new kind of statement that might be added. 155 using Parent::visit; 156 virtual void visit( CompoundStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 157 virtual void visit( ExprStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 158 virtual void visit( AsmStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 159 virtual void visit( IfStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 160 virtual void visit( WhileStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 161 virtual void visit( ForStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 162 virtual void visit( SwitchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 163 virtual void visit( CaseStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 164 virtual void visit( BranchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 165 virtual void visit( ReturnStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 166 virtual void visit( TryStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 167 virtual void visit( CatchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 168 virtual void visit( FinallyStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 169 virtual void visit( NullStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 170 virtual void visit( DeclStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 171 virtual void visit( ImplicitCtorDtorStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 149 172 }; 150 173 151 struct InsertDtors final : public ObjDeclCollector, public WithStmtsToAdd { 174 class InsertDtors final : public ObjDeclCollector { 175 public: 152 176 /// insert destructor calls at the appropriate places. must happen before CtorInit nodes are removed 153 177 /// (currently by FixInit) 154 178 static void insert( std::list< Declaration * > & translationUnit ); 155 179 180 typedef ObjDeclCollector Parent; 156 181 typedef std::list< ObjectDecl * > OrderedDecls; 157 182 typedef std::list< OrderedDecls > OrderedDeclsStack; 158 183 159 InsertDtors( PassVisitor<LabelFinder> & finder ) : finder( finder ), labelVars( finder.pass.vars ) {} 160 161 typedef ObjDeclCollector Parent; 162 using Parent::previsit; 163 164 void previsit( ObjectDecl * objDecl ); 165 void previsit( FunctionDecl * funcDecl ); 166 167 void previsit( CompoundStmt * compoundStmt ); 168 void postvisit( CompoundStmt * compoundStmt ); 169 void previsit( ReturnStmt * returnStmt ); 170 void previsit( BranchStmt * stmt ); 184 InsertDtors( LabelFinder & finder ) : finder( finder ), labelVars( finder.vars ) {} 185 186 using Parent::visit; 187 188 virtual void visit( ObjectDecl * objDecl ) override; 189 virtual void visit( FunctionDecl * funcDecl ) override; 190 191 virtual void visit( CompoundStmt * compoundStmt ) override; 192 virtual void visit( ReturnStmt * returnStmt ) override; 193 virtual void visit( BranchStmt * stmt ) override; 171 194 private: 172 195 void handleGoto( BranchStmt * stmt ); 173 196 174 PassVisitor<LabelFinder>& finder;197 LabelFinder & finder; 175 198 LabelFinder::LabelMap & labelVars; 176 199 OrderedDeclsStack reverseDeclOrder; … … 310 333 311 334 void InsertDtors::insert( std::list< Declaration * > & translationUnit ) { 312 PassVisitor<LabelFinder>finder;313 PassVisitor<InsertDtors>inserter( finder );335 LabelFinder finder; 336 InsertDtors inserter( finder ); 314 337 acceptAll( translationUnit, inserter ); 315 338 } … … 769 792 } 770 793 771 void ObjDeclCollector::previsit( CompoundStmt * ) { 772 GuardValue( curVars ); 773 } 774 775 void ObjDeclCollector::previsit( DeclStmt * stmt ) { 794 void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) { 795 ObjectSet prevVars = curVars; 796 Parent::visit( compoundStmt ); 797 curVars = prevVars; 798 } 799 800 void ObjDeclCollector::visit( DeclStmt * stmt ) { 776 801 // keep track of all variables currently in scope 777 802 if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) { 778 803 curVars.push_back( objDecl ); 779 804 } // if 780 } 781 782 void LabelFinder::previsit( Statement * stmt ) { 805 Parent::visit( stmt ); 806 } 807 808 void LabelFinder::handleStmt( Statement * stmt ) { 783 809 // for each label, remember the variables in scope at that label. 784 810 for ( Label l : stmt->get_labels() ) { … … 786 812 } // for 787 813 } 788 789 void LabelFinder::previsit( CompoundStmt * stmt ) {790 previsit( (Statement *)stmt );791 Parent::previsit( stmt );792 }793 794 void LabelFinder::previsit( DeclStmt * stmt ) {795 previsit( (Statement *)stmt );796 Parent::previsit( stmt );797 }798 799 814 800 815 template<typename Iterator, typename OutputIterator> … … 812 827 } 813 828 814 void InsertDtors:: previsit( ObjectDecl * objDecl ) {829 void InsertDtors::visit( ObjectDecl * objDecl ) { 815 830 // remember non-static destructed objects so that their destructors can be inserted later 816 831 if ( ! objDecl->get_storageClasses().is_static ) { … … 826 841 } // if 827 842 } // if 828 } 829 830 void InsertDtors::previsit( FunctionDecl * funcDecl ) { 843 Parent::visit( objDecl ); 844 } 845 846 template< typename Visitor > 847 void handleFuncDecl( FunctionDecl * funcDecl, Visitor & visitor ) { 848 maybeAccept( funcDecl->get_functionType(), visitor ); 849 maybeAccept( funcDecl->get_statements(), visitor ); 850 } 851 852 void InsertDtors::visit( FunctionDecl * funcDecl ) { 831 853 // each function needs to have its own set of labels 832 GuardValue( labelVars );854 ValueGuard< LabelFinder::LabelMap > oldLabels( labelVars ); 833 855 labelVars.clear(); 834 maybeAccept( funcDecl->type, finder ); 835 maybeAccept( funcDecl->statements, finder ); 836 837 // all labels for this function have been collected, insert destructors as appropriate via implicit recursion. 838 } 839 840 void InsertDtors::previsit( CompoundStmt * compoundStmt ) { 856 handleFuncDecl( funcDecl, finder ); 857 858 // all labels for this function have been collected, insert destructors as appropriate. 859 // can't be Parent::mutate, because ObjDeclCollector bottoms out on FunctionDecl 860 handleFuncDecl( funcDecl, *this ); 861 } 862 863 void InsertDtors::visit( CompoundStmt * compoundStmt ) { 841 864 // visit statements - this will also populate reverseDeclOrder list. don't want to dump all destructors 842 865 // when block is left, just the destructors associated with variables defined in this block, so push a new 843 866 // list to the top of the stack so that we can differentiate scopes 844 867 reverseDeclOrder.push_front( OrderedDecls() ); 845 Parent::previsit( compoundStmt ); 846 } 847 848 void InsertDtors::postvisit( CompoundStmt * compoundStmt ) { 868 Parent::visit( compoundStmt ); 869 849 870 // add destructors for the current scope that we're exiting, unless the last statement is a return, which 850 871 // causes unreachable code warnings … … 856 877 } 857 878 858 void InsertDtors:: previsit( ReturnStmt *) {879 void InsertDtors::visit( __attribute((unused)) ReturnStmt * returnStmt ) { 859 880 // return exits all scopes, so dump destructors for all scopes 860 881 for ( OrderedDecls & od : reverseDeclOrder ) { 861 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAdd Before) );882 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAdd ) ); 862 883 } // for 863 884 } … … 907 928 copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } ); 908 929 } // for 909 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd Before) );930 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) ); 910 931 } // if 911 932 } 912 933 913 void InsertDtors:: previsit( BranchStmt * stmt ) {934 void InsertDtors::visit( BranchStmt * stmt ) { 914 935 switch( stmt->get_type() ) { 915 936 case BranchStmt::Continue: -
src/Parser/ParseNode.h
r47b5b63 r39fea2f 44 44 //############################################################################## 45 45 46 typedef CodeLocation YYLTYPE;47 #define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */48 49 46 extern char * yyfilename; 50 47 extern int yylineno; 51 extern YYLTYPE yylloc;52 48 53 49 class ParseNode { … … 77 73 ParseNode * next = nullptr; 78 74 std::string * name = nullptr; 79 CodeLocation location = yylloc;75 CodeLocation location = { yyfilename, yylineno }; 80 76 }; // ParseNode 81 77 -
src/Parser/lex.ll
r47b5b63 r39fea2f 26 26 27 27 unsigned int column = 0; // position of the end of the last token parsed 28 #define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : ""; // trigger before each matching rule's action28 #define YY_USER_ACTION column += yyleng; // trigger before each matching rule's action 29 29 30 30 #include <string> -
src/Parser/parser.yy
r47b5b63 r39fea2f 116 116 117 117 bool forall = false; // aggregate have one or more forall qualifiers ? 118 119 # define YYLLOC_DEFAULT(Cur, Rhs, N) \120 do \121 if (N) { \122 (Cur).first_line = YYRHSLOC(Rhs, 1).first_line; \123 (Cur).first_column = YYRHSLOC(Rhs, 1).first_column; \124 (Cur).last_line = YYRHSLOC(Rhs, N).last_line; \125 (Cur).last_column = YYRHSLOC(Rhs, N).last_column; \126 (Cur).filename = YYRHSLOC(Rhs, 1).filename; \127 } else { \128 (Cur).first_line = (Cur).last_line = \129 YYRHSLOC(Rhs, 0).last_line; \130 (Cur).first_column = (Cur).last_column = \131 YYRHSLOC(Rhs, 0).last_column; \132 (Cur).filename = YYRHSLOC(Rhs, 0).filename; \133 } \134 while (0)135 118 %} 136 119 … … 363 346 %precedence ELSE // token precedence for start of else clause in IF/WAITFOR statement 364 347 365 %locations366 348 367 349 %start translation_unit // parse-tree root -
src/SymTab/Autogen.cc
r47b5b63 r39fea2f 223 223 FunctionType * ftype = data.genType( refType ); 224 224 225 if ( concurrent_type && CodeGen::isDestructor( data.fname )) {225 if(concurrent_type && CodeGen::isDestructor( data.fname )) { 226 226 ftype->parameters.front()->get_type()->set_mutex( true ); 227 227 } -
src/SynTree/BaseSyntaxNode.h
r47b5b63 r39fea2f 26 26 27 27 virtual void accept( Visitor & v ) = 0; 28 virtual void print( std::ostream & os, int indent = 0 ) const = 0;29 28 }; 30 29 -
src/tests/.expect/dtor-early-exit-ERR1.txt
r47b5b63 r39fea2f 1 dtor-early-exit.c:1 53:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)1 dtor-early-exit.c:142:1 error: jump to label 'L1' crosses initialization of y Branch (Goto) 2 2 with target: L1 3 3 with original target: L1 -
src/tests/.expect/dtor-early-exit-ERR2.txt
r47b5b63 r39fea2f 1 dtor-early-exit.c: 220:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)1 dtor-early-exit.c:142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto) 2 2 with target: L2 3 3 with original target: L2
Note: See TracChangeset
for help on using the changeset viewer.