Changes in / [e06be49:a9a4771]
- Location:
- src
- Files:
-
- 19 edited
-
CodeGen/CodeGenerator.cc (modified) (60 diffs)
-
CodeGen/CodeGenerator.h (modified) (4 diffs)
-
CodeGen/GenType.cc (modified) (5 diffs)
-
CodeGen/Generate.cc (modified) (6 diffs)
-
CodeTools/TrackLoc.cc (modified) (3 diffs)
-
Common/CodeLocation.h (modified) (4 diffs)
-
Common/PassVisitor.h (modified) (2 diffs)
-
Common/PassVisitor.impl.h (modified) (1 diff)
-
Common/SemanticError.cc (modified) (1 diff)
-
Common/SemanticError.h (modified) (1 diff)
-
ControlStruct/ExceptTranslate.cc (modified) (2 diffs)
-
InitTweak/FixInit.cc (modified) (9 diffs)
-
Parser/ParseNode.h (modified) (2 diffs)
-
Parser/lex.ll (modified) (1 diff)
-
Parser/parser.yy (modified) (2 diffs)
-
SymTab/Autogen.cc (modified) (1 diff)
-
SynTree/BaseSyntaxNode.h (modified) (1 diff)
-
tests/.expect/dtor-early-exit-ERR1.txt (modified) (1 diff)
-
tests/.expect/dtor-early-exit-ERR2.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
re06be49 ra9a4771 89 89 } else if ( currentLocation.followedBy( to, 1 ) ) { 90 90 output << "\n" << indent; 91 currentLocation. linenumber+= 1;91 currentLocation.first_line += 1; 92 92 } else if ( currentLocation.followedBy( to, 2 ) ) { 93 93 output << "\n\n" << indent; 94 currentLocation. linenumber+= 2;95 } else { 96 output << "\n# " << to. linenumber<< " \"" << to.filename94 currentLocation.first_line += 2; 95 } else { 96 output << "\n# " << to.first_line << " \"" << to.filename 97 97 << "\"\n" << indent; 98 98 currentLocation = to; … … 139 139 } // CodeGenerator::genAttributes 140 140 141 // *** BaseSyntaxNode 142 void CodeGenerator::previsit( BaseSyntaxNode * ) { 143 // turn off automatic recursion for all nodes, to allow each visitor to 144 // precisely control the order in which its children are visited. 145 visit_children = false; 146 } 147 148 // *** BaseSyntaxNode 149 void CodeGenerator::postvisit( BaseSyntaxNode * node ) { 150 std::stringstream ss; 151 node->print( ss ); 152 assertf( false, "Unhandled node reached in CodeGenerator: %s", ss.str().c_str() ); 153 } 141 154 142 155 // *** Declarations 143 void CodeGenerator:: visit( FunctionDecl * functionDecl ) {156 void CodeGenerator::postvisit( FunctionDecl * functionDecl ) { 144 157 extension( functionDecl ); 145 158 genAttributes( functionDecl->get_attributes() ); … … 152 165 asmName( functionDecl ); 153 166 154 // acceptAll( functionDecl->get_oldDecls(), * this);167 // acceptAll( functionDecl->get_oldDecls(), *visitor ); 155 168 if ( functionDecl->get_statements() ) { 156 functionDecl->get_statements()->accept( * this);157 } // if 158 } 159 160 void CodeGenerator:: visit( ObjectDecl * objectDecl ) {169 functionDecl->get_statements()->accept( *visitor ); 170 } // if 171 } 172 173 void CodeGenerator::postvisit( ObjectDecl * objectDecl ) { 161 174 if (objectDecl->get_name().empty() && genC ) { 162 175 // only generate an anonymous name when generating C code, otherwise it clutters the output too much … … 175 188 if ( objectDecl->get_init() ) { 176 189 output << " = "; 177 objectDecl->get_init()->accept( * this);190 objectDecl->get_init()->accept( *visitor ); 178 191 } // if 179 192 180 193 if ( objectDecl->get_bitfieldWidth() ) { 181 194 output << ":"; 182 objectDecl->get_bitfieldWidth()->accept( * this);195 objectDecl->get_bitfieldWidth()->accept( *visitor ); 183 196 } // if 184 197 } … … 205 218 updateLocation( *i ); 206 219 output << indent; 207 (*i)->accept( * this);220 (*i)->accept( *visitor ); 208 221 output << ";" << endl; 209 222 } // for … … 215 228 } 216 229 217 void CodeGenerator:: visit( StructDecl * structDecl ) {230 void CodeGenerator::postvisit( StructDecl * structDecl ) { 218 231 extension( structDecl ); 219 232 handleAggregate( structDecl, "struct " ); 220 233 } 221 234 222 void CodeGenerator:: visit( UnionDecl * unionDecl ) {235 void CodeGenerator::postvisit( UnionDecl * unionDecl ) { 223 236 extension( unionDecl ); 224 237 handleAggregate( unionDecl, "union " ); 225 238 } 226 239 227 void CodeGenerator:: visit( EnumDecl * enumDecl ) {240 void CodeGenerator::postvisit( EnumDecl * enumDecl ) { 228 241 extension( enumDecl ); 229 242 updateLocation( enumDecl ); … … 246 259 if ( obj->get_init() ) { 247 260 output << " = "; 248 obj->get_init()->accept( * this);261 obj->get_init()->accept( *visitor ); 249 262 } // if 250 263 output << "," << endl; … … 257 270 } 258 271 259 void CodeGenerator:: visit( TraitDecl * traitDecl ) {272 void CodeGenerator::postvisit( TraitDecl * traitDecl ) { 260 273 assertf( ! genC, "TraitDecls should not reach code generation." ); 261 274 extension( traitDecl ); … … 263 276 } 264 277 265 void CodeGenerator:: visit( TypedefDecl * typeDecl ) {278 void CodeGenerator::postvisit( TypedefDecl * typeDecl ) { 266 279 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." ); 267 280 updateLocation( typeDecl ); … … 270 283 } 271 284 272 void CodeGenerator:: visit( TypeDecl * typeDecl ) {285 void CodeGenerator::postvisit( TypeDecl * typeDecl ) { 273 286 assertf( ! genC, "TypeDecls should not reach code generation." ); 274 287 output << typeDecl->genTypeString() << " " << typeDecl->get_name(); … … 283 296 } 284 297 285 void CodeGenerator:: visit( Designation * designation ) {298 void CodeGenerator::postvisit( Designation * designation ) { 286 299 std::list< Expression * > designators = designation->get_designators(); 287 300 if ( designators.size() == 0 ) return; … … 290 303 // if expression is a NameExpr or VariableExpr, then initializing aggregate member 291 304 output << "."; 292 des->accept( * this);305 des->accept( *visitor ); 293 306 } else { 294 307 // otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt 295 308 output << "["; 296 des->accept( * this);309 des->accept( *visitor ); 297 310 output << "]"; 298 311 } // if … … 301 314 } 302 315 303 void CodeGenerator:: visit( SingleInit * init ) {304 init->get_value()->accept( * this);305 } 306 307 void CodeGenerator:: visit( ListInit * init ) {316 void CodeGenerator::postvisit( SingleInit * init ) { 317 init->get_value()->accept( *visitor ); 318 } 319 320 void CodeGenerator::postvisit( ListInit * init ) { 308 321 auto initBegin = init->begin(); 309 322 auto initEnd = init->end(); … … 313 326 output << "{ "; 314 327 for ( ; initBegin != initEnd && desigBegin != desigEnd; ) { 315 (*desigBegin)->accept( * this);316 (*initBegin)->accept( * this);328 (*desigBegin)->accept( *visitor ); 329 (*initBegin)->accept( *visitor ); 317 330 ++initBegin, ++desigBegin; 318 331 if ( initBegin != initEnd ) { … … 324 337 } 325 338 326 void CodeGenerator:: visit( __attribute__((unused)) ConstructorInit * init ){339 void CodeGenerator::postvisit( __attribute__((unused)) ConstructorInit * init ){ 327 340 assertf( ! genC, "ConstructorInit nodes should not reach code generation." ); 328 341 // pseudo-output for constructor/destructor pairs 329 342 output << "<ctorinit>{" << std::endl << ++indent << "ctor: "; 330 maybeAccept( init->get_ctor(), * this);343 maybeAccept( init->get_ctor(), *visitor ); 331 344 output << ", " << std::endl << indent << "dtor: "; 332 maybeAccept( init->get_dtor(), * this);345 maybeAccept( init->get_dtor(), *visitor ); 333 346 output << std::endl << --indent << "}"; 334 347 } 335 348 336 void CodeGenerator:: visit( Constant * constant ) {349 void CodeGenerator::postvisit( Constant * constant ) { 337 350 output << constant->get_value() ; 338 351 } 339 352 340 353 // *** Expressions 341 void CodeGenerator:: visit( ApplicationExpr * applicationExpr ) {354 void CodeGenerator::postvisit( ApplicationExpr * applicationExpr ) { 342 355 extension( applicationExpr ); 343 356 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) { … … 348 361 case OT_INDEX: 349 362 assert( applicationExpr->get_args().size() == 2 ); 350 (*arg++)->accept( * this);363 (*arg++)->accept( *visitor ); 351 364 output << "["; 352 (*arg)->accept( * this);365 (*arg)->accept( *visitor ); 353 366 output << "]"; 354 367 break; … … 365 378 // effects, so must still output this expression 366 379 output << "("; 367 (*arg++)->accept( * this);380 (*arg++)->accept( *visitor ); 368 381 output << ") /* " << opInfo.inputName << " */"; 369 382 } else if ( applicationExpr->get_args().size() == 2 ) { 370 383 // intrinsic two parameter constructors are essentially bitwise assignment 371 384 output << "("; 372 (*arg++)->accept( * this);385 (*arg++)->accept( *visitor ); 373 386 output << opInfo.symbol; 374 (*arg)->accept( * this);387 (*arg)->accept( *visitor ); 375 388 output << ") /* " << opInfo.inputName << " */"; 376 389 } else { … … 385 398 output << "("; 386 399 output << opInfo.symbol; 387 (*arg)->accept( * this);400 (*arg)->accept( *visitor ); 388 401 output << ")"; 389 402 break; … … 392 405 case OT_POSTFIXASSIGN: 393 406 assert( applicationExpr->get_args().size() == 1 ); 394 (*arg)->accept( * this);407 (*arg)->accept( *visitor ); 395 408 output << opInfo.symbol; 396 409 break; … … 401 414 assert( applicationExpr->get_args().size() == 2 ); 402 415 output << "("; 403 (*arg++)->accept( * this);416 (*arg++)->accept( *visitor ); 404 417 output << opInfo.symbol; 405 (*arg)->accept( * this);418 (*arg)->accept( *visitor ); 406 419 output << ")"; 407 420 break; … … 413 426 } // switch 414 427 } else { 415 varExpr->accept( * this);428 varExpr->accept( *visitor ); 416 429 output << "("; 417 430 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() ); … … 419 432 } // if 420 433 } else { 421 applicationExpr->get_function()->accept( * this);434 applicationExpr->get_function()->accept( *visitor ); 422 435 output << "("; 423 436 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() ); … … 426 439 } 427 440 428 void CodeGenerator:: visit( UntypedExpr * untypedExpr ) {441 void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) { 429 442 extension( untypedExpr ); 430 443 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { … … 435 448 case OT_INDEX: 436 449 assert( untypedExpr->get_args().size() == 2 ); 437 (*arg++)->accept( * this);450 (*arg++)->accept( *visitor ); 438 451 output << "["; 439 (*arg)->accept( * this);452 (*arg)->accept( *visitor ); 440 453 output << "]"; 441 454 break; … … 450 463 // effects, so must still output this expression 451 464 output << "("; 452 (*arg++)->accept( * this);465 (*arg++)->accept( *visitor ); 453 466 output << ") /* " << opInfo.inputName << " */"; 454 467 } else if ( untypedExpr->get_args().size() == 2 ) { 455 468 // intrinsic two parameter constructors are essentially bitwise assignment 456 469 output << "("; 457 (*arg++)->accept( * this);470 (*arg++)->accept( *visitor ); 458 471 output << opInfo.symbol; 459 (*arg)->accept( * this);472 (*arg)->accept( *visitor ); 460 473 output << ") /* " << opInfo.inputName << " */"; 461 474 } else { 462 475 // no constructors with 0 or more than 2 parameters 463 assert( false ); 476 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." ); 477 output << "("; 478 (*arg++)->accept( *visitor ); 479 output << opInfo.symbol << "{ "; 480 genCommaList( arg, untypedExpr->get_args().end() ); 481 output << "}) /* " << opInfo.inputName << " */"; 464 482 } // if 465 483 break; … … 471 489 output << "("; 472 490 output << opInfo.symbol; 473 (*arg)->accept( * this);491 (*arg)->accept( *visitor ); 474 492 output << ")"; 475 493 break; … … 478 496 case OT_POSTFIXASSIGN: 479 497 assert( untypedExpr->get_args().size() == 1 ); 480 (*arg)->accept( * this);498 (*arg)->accept( *visitor ); 481 499 output << opInfo.symbol; 482 500 break; … … 486 504 assert( untypedExpr->get_args().size() == 2 ); 487 505 output << "("; 488 (*arg++)->accept( * this);506 (*arg++)->accept( *visitor ); 489 507 output << opInfo.symbol; 490 (*arg)->accept( * this);508 (*arg)->accept( *visitor ); 491 509 output << ")"; 492 510 break; … … 499 517 if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2 500 518 assert( untypedExpr->get_args().size() == 2 ); 501 (*untypedExpr->get_args().begin())->accept( * this);519 (*untypedExpr->get_args().begin())->accept( *visitor ); 502 520 output << " ... "; 503 (*--untypedExpr->get_args().end())->accept( * this);521 (*--untypedExpr->get_args().end())->accept( *visitor ); 504 522 } else { // builtin routines 505 nameExpr->accept( * this);523 nameExpr->accept( *visitor ); 506 524 output << "("; 507 525 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); … … 510 528 } // if 511 529 } else { 512 untypedExpr->get_function()->accept( * this);530 untypedExpr->get_function()->accept( *visitor ); 513 531 output << "("; 514 532 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); … … 517 535 } 518 536 519 void CodeGenerator:: visit( RangeExpr * rangeExpr ) {520 rangeExpr->get_low()->accept( * this);537 void CodeGenerator::postvisit( RangeExpr * rangeExpr ) { 538 rangeExpr->get_low()->accept( *visitor ); 521 539 output << " ... "; 522 rangeExpr->get_high()->accept( * this);523 } 524 525 void CodeGenerator:: visit( NameExpr * nameExpr ) {540 rangeExpr->get_high()->accept( *visitor ); 541 } 542 543 void CodeGenerator::postvisit( NameExpr * nameExpr ) { 526 544 extension( nameExpr ); 527 545 OperatorInfo opInfo; … … 534 552 } 535 553 536 void CodeGenerator:: visit( AddressExpr * addressExpr ) {554 void CodeGenerator::postvisit( AddressExpr * addressExpr ) { 537 555 extension( addressExpr ); 538 556 output << "(&"; 539 addressExpr->arg->accept( * this);557 addressExpr->arg->accept( *visitor ); 540 558 output << ")"; 541 559 } 542 560 543 void CodeGenerator:: visit( LabelAddressExpr *addressExpr ) {561 void CodeGenerator::postvisit( LabelAddressExpr *addressExpr ) { 544 562 extension( addressExpr ); 545 563 output << "(&&" << addressExpr->arg << ")"; 546 564 } 547 565 548 void CodeGenerator:: visit( CastExpr * castExpr ) {566 void CodeGenerator::postvisit( CastExpr * castExpr ) { 549 567 extension( castExpr ); 550 568 output << "("; … … 559 577 output << ")"; 560 578 } // if 561 castExpr->get_arg()->accept( * this);579 castExpr->get_arg()->accept( *visitor ); 562 580 output << ")"; 563 581 } 564 582 565 void CodeGenerator:: visit( VirtualCastExpr * castExpr ) {583 void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) { 566 584 assertf( ! genC, "VirtualCastExpr should not reach code generation." ); 567 585 extension( castExpr ); 568 586 output << "(virtual "; 569 castExpr->get_arg()->accept( * this);587 castExpr->get_arg()->accept( *visitor ); 570 588 output << ")"; 571 589 } 572 590 573 void CodeGenerator:: visit( UntypedMemberExpr * memberExpr ) {591 void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) { 574 592 assertf( ! genC, "UntypedMemberExpr should not reach code generation." ); 575 593 extension( memberExpr ); 576 memberExpr->get_aggregate()->accept( * this);594 memberExpr->get_aggregate()->accept( *visitor ); 577 595 output << "."; 578 memberExpr->get_member()->accept( * this);579 } 580 581 void CodeGenerator:: visit( MemberExpr * memberExpr ) {596 memberExpr->get_member()->accept( *visitor ); 597 } 598 599 void CodeGenerator::postvisit( MemberExpr * memberExpr ) { 582 600 extension( memberExpr ); 583 memberExpr->get_aggregate()->accept( * this);601 memberExpr->get_aggregate()->accept( *visitor ); 584 602 output << "." << mangleName( memberExpr->get_member() ); 585 603 } 586 604 587 void CodeGenerator:: visit( VariableExpr * variableExpr ) {605 void CodeGenerator::postvisit( VariableExpr * variableExpr ) { 588 606 extension( variableExpr ); 589 607 OperatorInfo opInfo; … … 595 613 } 596 614 597 void CodeGenerator:: visit( ConstantExpr * constantExpr ) {615 void CodeGenerator::postvisit( ConstantExpr * constantExpr ) { 598 616 assert( constantExpr->get_constant() ); 599 617 extension( constantExpr ); 600 constantExpr->get_constant()->accept( * this);601 } 602 603 void CodeGenerator:: visit( SizeofExpr * sizeofExpr ) {618 constantExpr->get_constant()->accept( *visitor ); 619 } 620 621 void CodeGenerator::postvisit( SizeofExpr * sizeofExpr ) { 604 622 extension( sizeofExpr ); 605 623 output << "sizeof("; … … 607 625 output << genType( sizeofExpr->get_type(), "", pretty, genC ); 608 626 } else { 609 sizeofExpr->get_expr()->accept( * this);627 sizeofExpr->get_expr()->accept( *visitor ); 610 628 } // if 611 629 output << ")"; 612 630 } 613 631 614 void CodeGenerator:: visit( AlignofExpr * alignofExpr ) {632 void CodeGenerator::postvisit( AlignofExpr * alignofExpr ) { 615 633 // use GCC extension to avoid bumping std to C11 616 634 extension( alignofExpr ); … … 619 637 output << genType( alignofExpr->get_type(), "", pretty, genC ); 620 638 } else { 621 alignofExpr->get_expr()->accept( * this);639 alignofExpr->get_expr()->accept( *visitor ); 622 640 } // if 623 641 output << ")"; 624 642 } 625 643 626 void CodeGenerator:: visit( UntypedOffsetofExpr * offsetofExpr ) {644 void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) { 627 645 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." ); 628 646 output << "offsetof("; … … 632 650 } 633 651 634 void CodeGenerator:: visit( OffsetofExpr * offsetofExpr ) {652 void CodeGenerator::postvisit( OffsetofExpr * offsetofExpr ) { 635 653 // use GCC builtin 636 654 output << "__builtin_offsetof("; … … 640 658 } 641 659 642 void CodeGenerator:: visit( OffsetPackExpr * offsetPackExpr ) {660 void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) { 643 661 assertf( ! genC, "OffsetPackExpr should not reach code generation." ); 644 662 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")"; 645 663 } 646 664 647 void CodeGenerator:: visit( LogicalExpr * logicalExpr ) {665 void CodeGenerator::postvisit( LogicalExpr * logicalExpr ) { 648 666 extension( logicalExpr ); 649 667 output << "("; 650 logicalExpr->get_arg1()->accept( * this);668 logicalExpr->get_arg1()->accept( *visitor ); 651 669 if ( logicalExpr->get_isAnd() ) { 652 670 output << " && "; … … 654 672 output << " || "; 655 673 } // if 656 logicalExpr->get_arg2()->accept( * this);674 logicalExpr->get_arg2()->accept( *visitor ); 657 675 output << ")"; 658 676 } 659 677 660 void CodeGenerator:: visit( ConditionalExpr * conditionalExpr ) {678 void CodeGenerator::postvisit( ConditionalExpr * conditionalExpr ) { 661 679 extension( conditionalExpr ); 662 680 output << "("; 663 conditionalExpr->get_arg1()->accept( * this);681 conditionalExpr->get_arg1()->accept( *visitor ); 664 682 output << " ? "; 665 conditionalExpr->get_arg2()->accept( * this);683 conditionalExpr->get_arg2()->accept( *visitor ); 666 684 output << " : "; 667 conditionalExpr->get_arg3()->accept( * this);685 conditionalExpr->get_arg3()->accept( *visitor ); 668 686 output << ")"; 669 687 } 670 688 671 void CodeGenerator:: visit( CommaExpr * commaExpr ) {689 void CodeGenerator::postvisit( CommaExpr * commaExpr ) { 672 690 extension( commaExpr ); 673 691 output << "("; … … 676 694 commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) ); 677 695 } 678 commaExpr->get_arg1()->accept( * this);696 commaExpr->get_arg1()->accept( *visitor ); 679 697 output << " , "; 680 commaExpr->get_arg2()->accept( * this);698 commaExpr->get_arg2()->accept( *visitor ); 681 699 output << ")"; 682 700 } 683 701 684 void CodeGenerator:: visit( TupleAssignExpr * tupleExpr ) {702 void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) { 685 703 assertf( ! genC, "TupleAssignExpr should not reach code generation." ); 686 tupleExpr->stmtExpr->accept( * this);687 } 688 689 void CodeGenerator:: visit( UntypedTupleExpr * tupleExpr ) {704 tupleExpr->stmtExpr->accept( *visitor ); 705 } 706 707 void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) { 690 708 assertf( ! genC, "UntypedTupleExpr should not reach code generation." ); 691 709 extension( tupleExpr ); … … 695 713 } 696 714 697 void CodeGenerator:: visit( TupleExpr * tupleExpr ) {715 void CodeGenerator::postvisit( TupleExpr * tupleExpr ) { 698 716 assertf( ! genC, "TupleExpr should not reach code generation." ); 699 717 extension( tupleExpr ); … … 703 721 } 704 722 705 void CodeGenerator:: visit( TupleIndexExpr * tupleExpr ) {723 void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) { 706 724 assertf( ! genC, "TupleIndexExpr should not reach code generation." ); 707 725 extension( tupleExpr ); 708 tupleExpr->get_tuple()->accept( * this);726 tupleExpr->get_tuple()->accept( *visitor ); 709 727 output << "." << tupleExpr->get_index(); 710 728 } 711 729 712 void CodeGenerator:: visit( TypeExpr * typeExpr ) {730 void CodeGenerator::postvisit( TypeExpr * typeExpr ) { 713 731 // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl; 714 732 // assertf( ! genC, "TypeExpr should not reach code generation." ); … … 718 736 } 719 737 720 void CodeGenerator:: visit( AsmExpr * asmExpr ) {738 void CodeGenerator::postvisit( AsmExpr * asmExpr ) { 721 739 if ( asmExpr->get_inout() ) { 722 740 output << "[ "; 723 asmExpr->get_inout()->accept( * this);741 asmExpr->get_inout()->accept( *visitor ); 724 742 output << " ] "; 725 743 } // if 726 asmExpr->get_constraint()->accept( * this);744 asmExpr->get_constraint()->accept( *visitor ); 727 745 output << " ( "; 728 asmExpr->get_operand()->accept( * this);746 asmExpr->get_operand()->accept( *visitor ); 729 747 output << " )"; 730 748 } 731 749 732 void CodeGenerator:: visit( CompoundLiteralExpr *compLitExpr ) {750 void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) { 733 751 assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) ); 734 752 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")"; 735 compLitExpr->get_initializer()->accept( * this);736 } 737 738 void CodeGenerator:: visit( UniqueExpr * unqExpr ) {753 compLitExpr->get_initializer()->accept( *visitor ); 754 } 755 756 void CodeGenerator::postvisit( UniqueExpr * unqExpr ) { 739 757 assertf( ! genC, "Unique expressions should not reach code generation." ); 740 758 output << "unq<" << unqExpr->get_id() << ">{ "; 741 unqExpr->get_expr()->accept( * this);759 unqExpr->get_expr()->accept( *visitor ); 742 760 output << " }"; 743 761 } 744 762 745 void CodeGenerator:: visit( StmtExpr * stmtExpr ) {763 void CodeGenerator::postvisit( StmtExpr * stmtExpr ) { 746 764 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids(); 747 765 updateLocation( stmtExpr ); … … 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 ) {861 void CodeGenerator::postvisit( IfStmt * ifStmt ) { 839 862 updateLocation( ifStmt ); 840 863 output << "if ( "; 841 ifStmt->get_condition()->accept( * this);864 ifStmt->get_condition()->accept( *visitor ); 842 865 output << " ) "; 843 866 844 ifStmt->get_thenPart()->accept( * this);867 ifStmt->get_thenPart()->accept( *visitor ); 845 868 846 869 if ( ifStmt->get_elsePart() != 0) { 847 870 output << " else "; 848 ifStmt->get_elsePart()->accept( * this);849 } // if 850 } 851 852 void CodeGenerator:: visit( SwitchStmt * switchStmt ) {871 ifStmt->get_elsePart()->accept( *visitor ); 872 } // if 873 } 874 875 void CodeGenerator::postvisit( SwitchStmt * switchStmt ) { 853 876 updateLocation( switchStmt ); 854 877 output << "switch ( " ; 855 switchStmt->get_condition()->accept( * this);878 switchStmt->get_condition()->accept( *visitor ); 856 879 output << " ) "; 857 880 858 881 output << "{" << std::endl; 859 882 ++indent; 860 acceptAll( switchStmt->get_statements(), * this);883 acceptAll( switchStmt->get_statements(), *visitor ); 861 884 --indent; 862 885 output << indent << "}"; 863 886 } 864 887 865 void CodeGenerator:: visit( CaseStmt * caseStmt ) {888 void CodeGenerator::postvisit( CaseStmt * caseStmt ) { 866 889 updateLocation( caseStmt ); 867 890 if ( caseStmt->isDefault()) { … … 869 892 } else { 870 893 output << "case "; 871 caseStmt->get_condition()->accept( * this);894 caseStmt->get_condition()->accept( *visitor ); 872 895 } // if 873 896 output << ":\n"; … … 878 901 for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end(); i++) { 879 902 output << indent << printLabels( (*i)->get_labels() ) ; 880 (*i)->accept( * this);903 (*i)->accept( *visitor ); 881 904 output << endl; 882 905 } // for … … 884 907 } 885 908 886 void CodeGenerator:: visit( BranchStmt * branchStmt ) {909 void CodeGenerator::postvisit( BranchStmt * branchStmt ) { 887 910 switch ( branchStmt->get_type()) { 888 911 case BranchStmt::Goto: … … 892 915 if ( branchStmt->get_computedTarget() != 0 ) { 893 916 output << "goto *"; 894 branchStmt->get_computedTarget()->accept( * this);917 branchStmt->get_computedTarget()->accept( *visitor ); 895 918 } // if 896 919 } // if … … 906 929 } 907 930 908 void CodeGenerator:: visit( ReturnStmt * returnStmt ) {931 void CodeGenerator::postvisit( ReturnStmt * returnStmt ) { 909 932 output << "return "; 910 maybeAccept( returnStmt->get_expr(), * this);933 maybeAccept( returnStmt->get_expr(), *visitor ); 911 934 output << ";"; 912 935 } 913 936 914 void CodeGenerator:: visit( ThrowStmt * throwStmt ) {937 void CodeGenerator::postvisit( ThrowStmt * throwStmt ) { 915 938 assertf( ! genC, "Throw statements should not reach code generation." ); 916 939 … … 919 942 if (throwStmt->get_expr()) { 920 943 output << " "; 921 throwStmt->get_expr()->accept( * this);944 throwStmt->get_expr()->accept( *visitor ); 922 945 } 923 946 if (throwStmt->get_target()) { 924 947 output << " _At "; 925 throwStmt->get_target()->accept( * this);948 throwStmt->get_target()->accept( *visitor ); 926 949 } 927 950 output << ";"; 928 951 } 929 952 930 void CodeGenerator:: visit( WhileStmt * whileStmt ) {953 void CodeGenerator::postvisit( WhileStmt * whileStmt ) { 931 954 if ( whileStmt->get_isDoWhile() ) { 932 955 output << "do" ; 933 956 } else { 934 957 output << "while (" ; 935 whileStmt->get_condition()->accept( * this);958 whileStmt->get_condition()->accept( *visitor ); 936 959 output << ")"; 937 960 } // if … … 939 962 940 963 output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() ); 941 whileStmt->get_body()->accept( * this);964 whileStmt->get_body()->accept( *visitor ); 942 965 943 966 output << indent; … … 945 968 if ( whileStmt->get_isDoWhile() ) { 946 969 output << " while (" ; 947 whileStmt->get_condition()->accept( * this);970 whileStmt->get_condition()->accept( *visitor ); 948 971 output << ");"; 949 972 } // if 950 973 } 951 974 952 void CodeGenerator:: visit( ForStmt * forStmt ) {975 void CodeGenerator::postvisit( ForStmt * forStmt ) { 953 976 // initialization is always hoisted, so don't bother doing anything with that 954 977 output << "for (;"; 955 978 956 979 if ( forStmt->get_condition() != 0 ) { 957 forStmt->get_condition()->accept( * this);980 forStmt->get_condition()->accept( *visitor ); 958 981 } // if 959 982 output << ";"; … … 962 985 // cast the top-level expression to void to reduce gcc warnings. 963 986 Expression * expr = new CastExpr( forStmt->get_increment() ); 964 expr->accept( * this);987 expr->accept( *visitor ); 965 988 } // if 966 989 output << ") "; … … 968 991 if ( forStmt->get_body() != 0 ) { 969 992 output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() ); 970 forStmt->get_body()->accept( * this);971 } // if 972 } 973 974 void CodeGenerator:: visit( __attribute__((unused)) NullStmt * nullStmt ) {993 forStmt->get_body()->accept( *visitor ); 994 } // if 995 } 996 997 void CodeGenerator::postvisit( __attribute__((unused)) NullStmt * nullStmt ) { 975 998 //output << indent << CodeGenerator::printLabels( nullStmt->get_labels() ); 976 999 output << "/* null statement */ ;"; 977 1000 } 978 1001 979 void CodeGenerator:: visit( DeclStmt * declStmt ) {980 declStmt->get_decl()->accept( * this);1002 void CodeGenerator::postvisit( DeclStmt * declStmt ) { 1003 declStmt->get_decl()->accept( *visitor ); 981 1004 982 1005 if ( doSemicolon( declStmt->get_decl() ) ) { 983 1006 output << ";"; 984 1007 } // if 1008 } 1009 1010 void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) { 1011 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." ); 1012 stmt->callStmt->accept( *visitor ); 985 1013 } 986 1014 -
src/CodeGen/CodeGenerator.h
re06be49 ra9a4771 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 ); … … 34 34 CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false ); 35 35 36 //*** Turn off visit_children for all nodes 37 void previsit( BaseSyntaxNode * ); 38 39 //*** Error for unhandled node types 40 void postvisit( BaseSyntaxNode * ); 41 36 42 //*** 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 );43 void postvisit( StructDecl * ); 44 void postvisit( FunctionDecl * ); 45 void postvisit( ObjectDecl * ); 46 void postvisit( UnionDecl *aggregateDecl ); 47 void postvisit( EnumDecl *aggregateDecl ); 48 void postvisit( TraitDecl *aggregateDecl ); 49 void postvisit( TypedefDecl *typeDecl ); 50 void postvisit( TypeDecl *typeDecl ); 45 51 46 52 //*** Initializer 47 v irtual voidvisit( Designation * );48 v irtual voidvisit( SingleInit * );49 v irtual voidvisit( ListInit * );50 v irtual voidvisit( ConstructorInit * );53 void postvisit( Designation * ); 54 void postvisit( SingleInit * ); 55 void postvisit( ListInit * ); 56 void postvisit( ConstructorInit * ); 51 57 52 58 //*** Constant 53 v irtual voidvisit( Constant * );59 void postvisit( Constant * ); 54 60 55 61 //*** 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 * ); 62 void postvisit( ApplicationExpr *applicationExpr ); 63 void postvisit( UntypedExpr *untypedExpr ); 64 void postvisit( RangeExpr * rangeExpr ); 65 void postvisit( NameExpr *nameExpr ); 66 void postvisit( AddressExpr *addressExpr ); 67 void postvisit( LabelAddressExpr *addressExpr ); 68 void postvisit( CastExpr *castExpr ); 69 void postvisit( VirtualCastExpr *castExpr ); 70 void postvisit( UntypedMemberExpr *memberExpr ); 71 void postvisit( MemberExpr *memberExpr ); 72 void postvisit( VariableExpr *variableExpr ); 73 void postvisit( ConstantExpr *constantExpr ); 74 void postvisit( SizeofExpr *sizeofExpr ); 75 void postvisit( AlignofExpr *alignofExpr ); 76 void postvisit( UntypedOffsetofExpr *offsetofExpr ); 77 void postvisit( OffsetofExpr *offsetofExpr ); 78 void postvisit( OffsetPackExpr *offsetPackExpr ); 79 void postvisit( LogicalExpr *logicalExpr ); 80 void postvisit( ConditionalExpr *conditionalExpr ); 81 void postvisit( CommaExpr *commaExpr ); 82 void postvisit( CompoundLiteralExpr *compLitExpr ); 83 void postvisit( UniqueExpr * ); 84 void postvisit( TupleAssignExpr * tupleExpr ); 85 void postvisit( UntypedTupleExpr *tupleExpr ); 86 void postvisit( TupleExpr *tupleExpr ); 87 void postvisit( TupleIndexExpr * tupleExpr ); 88 void postvisit( TypeExpr *typeExpr ); 89 void postvisit( AsmExpr * ); 90 void postvisit( StmtExpr * ); 91 void postvisit( ConstructorExpr * ); 85 92 86 93 //*** 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 * ); 94 void postvisit( CompoundStmt * ); 95 void postvisit( ExprStmt * ); 96 void postvisit( AsmStmt * ); 97 void postvisit( AsmDecl * ); // special: statement in declaration context 98 void postvisit( IfStmt * ); 99 void postvisit( SwitchStmt * ); 100 void postvisit( CaseStmt * ); 101 void postvisit( BranchStmt * ); 102 void postvisit( ReturnStmt * ); 103 void postvisit( ThrowStmt * ); 104 void postvisit( WhileStmt * ); 105 void postvisit( ForStmt * ); 106 void postvisit( NullStmt * ); 107 void postvisit( DeclStmt * ); 108 void postvisit( ImplicitCtorDtorStmt * ); 101 109 102 110 void genAttributes( std::list< Attribute * > & attributes ); … … 140 148 if ( begin == end ) return; 141 149 for ( ;; ) { 142 (*begin++)->accept( * this);150 (*begin++)->accept( *visitor ); 143 151 if ( begin == end ) break; 144 152 output << ", "; // separator -
src/CodeGen/GenType.cc
re06be49 ra9a4771 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
re06be49 ra9a4771 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 ) ) { … … 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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 // 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 " : "";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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 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
re06be49 ra9a4771 26 26 27 27 virtual void accept( Visitor & v ) = 0; 28 virtual void print( std::ostream & os, int indent = 0 ) const = 0; 28 29 }; 29 30 -
src/tests/.expect/dtor-early-exit-ERR1.txt
re06be49 ra9a4771 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
re06be49 ra9a4771 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.