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