Changeset 7527e63 for src/CodeGen/CodeGenerator.cc
- Timestamp:
- Aug 16, 2016, 3:20:06 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 1f6d4624
- Parents:
- 950f7a7 (diff), 7880579 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r950f7a7 r7527e63 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 15 15:53:15201613 // Update Count : 3 0612 // Last Modified On : Thu Aug 4 13:35:30 2016 13 // Update Count : 352 14 14 // 15 15 … … 45 45 bool wantSpacing( Statement * stmt) { 46 46 return dynamic_cast< IfStmt * >( stmt ) || dynamic_cast< CompoundStmt * >( stmt ) || 47 dynamic_cast< WhileStmt * >( stmt ) || dynamic_cast< ForStmt * > 48 } 49 50 void CodeGenerator::extension( Expression * expr ) {47 dynamic_cast< WhileStmt * >( stmt ) || dynamic_cast< ForStmt * >( stmt ) || dynamic_cast< SwitchStmt *>( stmt ); 48 } 49 50 void CodeGenerator::extension( Expression * expr ) { 51 51 if ( expr->get_extension() ) { 52 52 output << "__extension__ "; … … 54 54 } // extension 55 55 56 void CodeGenerator::extension( Declaration * decl ) {56 void CodeGenerator::extension( Declaration * decl ) { 57 57 if ( decl->get_extension() ) { 58 58 output << "__extension__ "; … … 73 73 } 74 74 75 ostream & operator<<( ostream & output, CodeGenerator::LabelPrinter & printLabels ) {75 ostream & operator<<( ostream & output, CodeGenerator::LabelPrinter & printLabels ) { 76 76 std::list< Label > & labs = *printLabels.labels; 77 77 // l.unique(); // assumes a sorted list. Why not use set? Does order matter? … … 79 79 output << l.get_name() + ": "; 80 80 printLabels.cg.genAttributes( l.get_attributes() ); 81 } 81 } // for 82 82 return output; 83 83 } 84 84 85 CodeGenerator::CodeGenerator( std::ostream & os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ) {}86 87 CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp )85 CodeGenerator::CodeGenerator( std::ostream & os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ) {} 86 87 CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp ) 88 88 : indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ), printLabels( *this ) { 89 89 //output << std::string( init ); 90 90 } 91 91 92 CodeGenerator::CodeGenerator( std::ostream & os, char *init, int indentation, bool infunp )92 CodeGenerator::CodeGenerator( std::ostream & os, char * init, int indentation, bool infunp ) 93 93 : indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ), printLabels( *this ) { 94 94 //output << std::string( init ); 95 95 } 96 96 97 string mangleName( DeclarationWithType * decl ) {97 string mangleName( DeclarationWithType * decl ) { 98 98 if ( decl->get_mangleName() != "" ) { 99 99 // need to incorporate scope level in order to differentiate names for destructors … … 112 112 genCommaList( attr->get_parameters().begin(), attr->get_parameters().end() ); 113 113 output << ")"; 114 } 114 } // if 115 115 output << ","; 116 } 116 } // for 117 117 output << ")) "; 118 } 118 } // if 119 119 } 120 120 121 121 122 122 //*** Declarations 123 void CodeGenerator::visit( FunctionDecl * functionDecl ) {123 void CodeGenerator::visit( FunctionDecl * functionDecl ) { 124 124 extension( functionDecl ); 125 125 genAttributes( functionDecl->get_attributes() ); … … 146 146 } 147 147 148 void CodeGenerator::visit( ObjectDecl * objectDecl ) {148 void CodeGenerator::visit( ObjectDecl * objectDecl ) { 149 149 extension( objectDecl ); 150 genAttributes( objectDecl->get_attributes() ); 151 150 152 handleStorageClass( objectDecl ); 151 153 output << genType( objectDecl->get_type(), mangleName( objectDecl ) ); … … 155 157 objectDecl->get_init()->accept( *this ); 156 158 } // if 159 157 160 if ( objectDecl->get_bitfieldWidth() ) { 158 161 output << ":"; … … 161 164 } 162 165 163 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl ) {166 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl ) { 164 167 if ( aggDecl->get_name() != "" ) 165 168 output << aggDecl->get_name(); 166 169 167 std::list< Declaration * > & memb = aggDecl->get_members();170 std::list< Declaration * > & memb = aggDecl->get_members(); 168 171 if ( ! memb.empty() ) { 169 172 // if ( aggDecl->has_body() ) { 170 // std::list< Declaration * > & memb = aggDecl->get_members();173 // std::list< Declaration * > & memb = aggDecl->get_members(); 171 174 output << " {" << endl; 172 175 173 176 cur_indent += CodeGenerator::tabsize; 174 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) {177 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) { 175 178 output << indent; 176 179 (*i)->accept( *this ); 177 180 output << ";" << endl; 178 } 181 } // for 179 182 180 183 cur_indent -= CodeGenerator::tabsize; … … 184 187 } 185 188 186 void CodeGenerator::visit( StructDecl * structDecl ) {189 void CodeGenerator::visit( StructDecl * structDecl ) { 187 190 extension( structDecl ); 188 191 output << "struct "; … … 190 193 } 191 194 192 void CodeGenerator::visit( UnionDecl * unionDecl ) {195 void CodeGenerator::visit( UnionDecl * unionDecl ) { 193 196 extension( unionDecl ); 194 197 output << "union "; … … 196 199 } 197 200 198 void CodeGenerator::visit( EnumDecl * enumDecl ) {201 void CodeGenerator::visit( EnumDecl * enumDecl ) { 199 202 extension( enumDecl ); 200 203 output << "enum "; … … 210 213 cur_indent += CodeGenerator::tabsize; 211 214 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 212 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );215 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); 213 216 assert( obj ); 214 217 output << indent << mangleName( obj ); … … 226 229 } 227 230 228 void CodeGenerator::visit( TraitDecl * traitDecl ) {}229 230 void CodeGenerator::visit( TypedefDecl * typeDecl ) {231 void CodeGenerator::visit( TraitDecl * traitDecl ) {} 232 233 void CodeGenerator::visit( TypedefDecl * typeDecl ) { 231 234 assert( false && "Typedefs are removed and substituted in earlier passes." ); 232 235 //output << "typedef "; … … 234 237 } 235 238 236 void CodeGenerator::visit( TypeDecl * typeDecl ) {239 void CodeGenerator::visit( TypeDecl * typeDecl ) { 237 240 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes, 238 241 // still to be done … … 257 260 (*iter)->accept( *this ); 258 261 output << "]"; 259 } 260 } 262 } // if 263 } // for 261 264 output << " = "; 262 265 } 263 266 264 void CodeGenerator::visit( SingleInit * init ) {267 void CodeGenerator::visit( SingleInit * init ) { 265 268 printDesignators( init->get_designators() ); 266 269 init->get_value()->accept( *this ); 267 270 } 268 271 269 void CodeGenerator::visit( ListInit * init ) {272 void CodeGenerator::visit( ListInit * init ) { 270 273 printDesignators( init->get_designators() ); 271 274 output << "{ "; 272 if ( init->begin _initializers() == init->end_initializers() ) {275 if ( init->begin() == init->end() ) { 273 276 // illegal to leave initializer list empty for scalar initializers, but always legal to have 0 274 277 output << "0"; 275 278 } else { 276 genCommaList( init->begin _initializers(), init->end_initializers() );277 } 279 genCommaList( init->begin(), init->end() ); 280 } // if 278 281 output << " }"; 279 282 } 280 283 281 void CodeGenerator::visit( Constant * constant ) {284 void CodeGenerator::visit( Constant * constant ) { 282 285 output << constant->get_value() ; 283 286 } 284 287 285 288 //*** Expressions 286 void CodeGenerator::visit( ApplicationExpr * applicationExpr ) {289 void CodeGenerator::visit( ApplicationExpr * applicationExpr ) { 287 290 extension( applicationExpr ); 288 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {291 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) { 289 292 OperatorInfo opInfo; 290 293 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) { … … 298 301 { 299 302 assert( arg != applicationExpr->get_args().end() ); 300 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {303 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) { 301 304 // remove & from first assignment/ctor argument 302 305 *arg = addrExpr->get_arg(); 303 306 } else { 304 307 // no address-of operator, so must be a pointer - add dereference 305 UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) );308 UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 306 309 newExpr->get_args().push_back( *arg ); 307 310 assert( (*arg)->get_results().size() == 1 ); … … 317 320 // do nothing 318 321 ; 319 } 322 } // switch 320 323 321 324 switch ( opInfo.type ) { … … 351 354 // no constructors with 0 or more than 2 parameters 352 355 assert( false ); 353 } 356 } // if 354 357 break; 355 358 … … 385 388 // there are no intrinsic definitions of 0/1 or label addresses as functions 386 389 assert( false ); 387 } 390 } // switch 388 391 } else { 389 392 varExpr->accept( *this ); … … 400 403 } 401 404 402 void CodeGenerator::visit( UntypedExpr * untypedExpr ) {405 void CodeGenerator::visit( UntypedExpr * untypedExpr ) { 403 406 extension( untypedExpr ); 404 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {407 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { 405 408 OperatorInfo opInfo; 406 409 if ( operatorLookup( nameExpr->get_name(), opInfo ) ) { … … 417 420 case OT_CALL: 418 421 assert( false ); 419 420 422 421 423 case OT_CTOR: … … 437 439 // no constructors with 0 or more than 2 parameters 438 440 assert( false ); 439 } 441 } // if 440 442 break; 441 443 … … 470 472 // there are no intrinsic definitions of 0 or 1 as functions 471 473 assert( false ); 472 } 474 } // switch 473 475 } else { 474 nameExpr->accept( *this ); 475 output << "("; 476 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); 477 output << ")"; 476 if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2 477 assert( untypedExpr->get_args().size() == 2 ); 478 (*untypedExpr->get_args().begin())->accept( *this ); 479 output << " ... "; 480 (*--untypedExpr->get_args().end())->accept( *this ); 481 } else { // builtin routines 482 nameExpr->accept( *this ); 483 output << "("; 484 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); 485 output << ")"; 486 } // if 478 487 } // if 479 488 } else { … … 485 494 } 486 495 487 void CodeGenerator::visit( NameExpr *nameExpr ) { 496 void CodeGenerator::visit( RangeExpr * rangeExpr ) { 497 rangeExpr->get_low()->accept( *this ); 498 output << " ... "; 499 rangeExpr->get_high()->accept( *this ); 500 } 501 502 void CodeGenerator::visit( NameExpr * nameExpr ) { 488 503 extension( nameExpr ); 489 504 OperatorInfo opInfo; … … 496 511 } 497 512 498 void CodeGenerator::visit( AddressExpr * addressExpr ) {513 void CodeGenerator::visit( AddressExpr * addressExpr ) { 499 514 extension( addressExpr ); 500 515 output << "(&"; 501 516 // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address 502 if ( VariableExpr * variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {517 if ( VariableExpr * variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) { 503 518 output << mangleName( variableExpr->get_var() ); 504 519 } else { … … 508 523 } 509 524 510 void CodeGenerator::visit( CastExpr * castExpr ) {525 void CodeGenerator::visit( CastExpr * castExpr ) { 511 526 extension( castExpr ); 512 527 output << "("; … … 521 536 // otherwise, the cast is to an lvalue type, so the cast should be dropped, since the result of a cast is 522 537 // never an lvalue in C 523 } 538 } // if 524 539 castExpr->get_arg()->accept( *this ); 525 540 output << ")"; 526 541 } 527 542 528 void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {543 void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) { 529 544 assert( false ); 530 545 } 531 546 532 void CodeGenerator::visit( MemberExpr * memberExpr ) {547 void CodeGenerator::visit( MemberExpr * memberExpr ) { 533 548 extension( memberExpr ); 534 549 memberExpr->get_aggregate()->accept( *this ); … … 536 551 } 537 552 538 void CodeGenerator::visit( VariableExpr * variableExpr ) {553 void CodeGenerator::visit( VariableExpr * variableExpr ) { 539 554 extension( variableExpr ); 540 555 OperatorInfo opInfo; … … 546 561 } 547 562 548 void CodeGenerator::visit( ConstantExpr * constantExpr ) {563 void CodeGenerator::visit( ConstantExpr * constantExpr ) { 549 564 assert( constantExpr->get_constant() ); 550 565 extension( constantExpr ); … … 552 567 } 553 568 554 void CodeGenerator::visit( SizeofExpr * sizeofExpr ) {569 void CodeGenerator::visit( SizeofExpr * sizeofExpr ) { 555 570 extension( sizeofExpr ); 556 571 output << "sizeof("; … … 563 578 } 564 579 565 void CodeGenerator::visit( AlignofExpr * alignofExpr ) {580 void CodeGenerator::visit( AlignofExpr * alignofExpr ) { 566 581 // use GCC extension to avoid bumping std to C11 567 582 extension( alignofExpr ); … … 575 590 } 576 591 577 void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {592 void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) { 578 593 assert( false && "UntypedOffsetofExpr should not reach code generation." ); 579 594 } 580 595 581 void CodeGenerator::visit( OffsetofExpr * offsetofExpr ) {596 void CodeGenerator::visit( OffsetofExpr * offsetofExpr ) { 582 597 // use GCC builtin 583 598 output << "__builtin_offsetof("; … … 587 602 } 588 603 589 void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {604 void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) { 590 605 assert( false && "OffsetPackExpr should not reach code generation." ); 591 606 } 592 607 593 void CodeGenerator::visit( LogicalExpr * logicalExpr ) {608 void CodeGenerator::visit( LogicalExpr * logicalExpr ) { 594 609 extension( logicalExpr ); 595 610 output << "("; … … 604 619 } 605 620 606 void CodeGenerator::visit( ConditionalExpr * conditionalExpr ) {621 void CodeGenerator::visit( ConditionalExpr * conditionalExpr ) { 607 622 extension( conditionalExpr ); 608 623 output << "("; … … 615 630 } 616 631 617 void CodeGenerator::visit( CommaExpr * commaExpr ) {632 void CodeGenerator::visit( CommaExpr * commaExpr ) { 618 633 extension( commaExpr ); 619 634 output << "("; … … 624 639 } 625 640 626 void CodeGenerator::visit( TupleExpr * tupleExpr ) {}627 628 void CodeGenerator::visit( TypeExpr * typeExpr ) {}629 630 void CodeGenerator::visit( AsmExpr * asmExpr ) {641 void CodeGenerator::visit( TupleExpr * tupleExpr ) {} 642 643 void CodeGenerator::visit( TypeExpr * typeExpr ) {} 644 645 void CodeGenerator::visit( AsmExpr * asmExpr ) { 631 646 if ( asmExpr->get_inout() ) { 632 647 output << "[ "; … … 641 656 642 657 //*** Statements 643 void CodeGenerator::visit( CompoundStmt * compoundStmt ) {658 void CodeGenerator::visit( CompoundStmt * compoundStmt ) { 644 659 std::list<Statement*> ks = compoundStmt->get_kids(); 645 660 output << "{" << endl; … … 654 669 if ( wantSpacing( *i ) ) { 655 670 output << endl; 656 } 657 } 671 } // if 672 } // for 658 673 cur_indent -= CodeGenerator::tabsize; 659 674 … … 661 676 } 662 677 663 void CodeGenerator::visit( ExprStmt * exprStmt ) {678 void CodeGenerator::visit( ExprStmt * exprStmt ) { 664 679 assert( exprStmt ); 665 680 // cast the top-level expression to void to reduce gcc warnings. … … 669 684 } 670 685 671 void CodeGenerator::visit( AsmStmt * asmStmt ) {686 void CodeGenerator::visit( AsmStmt * asmStmt ) { 672 687 output << "asm "; 673 688 if ( asmStmt->get_voltile() ) output << "volatile "; … … 692 707 } 693 708 694 void CodeGenerator::visit( IfStmt * ifStmt ) {709 void CodeGenerator::visit( IfStmt * ifStmt ) { 695 710 output << "if ( "; 696 711 ifStmt->get_condition()->accept( *this ); … … 705 720 } 706 721 707 void CodeGenerator::visit( SwitchStmt * switchStmt ) {722 void CodeGenerator::visit( SwitchStmt * switchStmt ) { 708 723 output << "switch ( " ; 709 724 switchStmt->get_condition()->accept( *this ); … … 712 727 output << "{" << std::endl; 713 728 cur_indent += CodeGenerator::tabsize; 714 715 acceptAll( switchStmt->get_branches(), *this ); 716 729 acceptAll( switchStmt->get_statements(), *this ); 717 730 cur_indent -= CodeGenerator::tabsize; 718 719 731 output << indent << "}"; 720 732 } 721 733 722 void CodeGenerator::visit( CaseStmt * caseStmt ) {734 void CodeGenerator::visit( CaseStmt * caseStmt ) { 723 735 output << indent; 724 736 if ( caseStmt->isDefault()) { … … 737 749 (*i)->accept( *this ); 738 750 output << endl; 739 } 751 } // for 740 752 cur_indent -= CodeGenerator::tabsize; 741 753 } 742 754 743 void CodeGenerator::visit( BranchStmt * branchStmt ) {755 void CodeGenerator::visit( BranchStmt * branchStmt ) { 744 756 switch ( branchStmt->get_type()) { 745 757 case BranchStmt::Goto: … … 759 771 output << "continue"; 760 772 break; 761 } 773 } // switch 762 774 output << ";"; 763 775 } 764 776 765 777 766 void CodeGenerator::visit( ReturnStmt * returnStmt ) {778 void CodeGenerator::visit( ReturnStmt * returnStmt ) { 767 779 output << "return "; 768 780 maybeAccept( returnStmt->get_expr(), *this ); … … 770 782 } 771 783 772 void CodeGenerator::visit( WhileStmt * whileStmt ) {784 void CodeGenerator::visit( WhileStmt * whileStmt ) { 773 785 if ( whileStmt->get_isDoWhile() ) { 774 786 output << "do" ; … … 792 804 } 793 805 794 void CodeGenerator::visit( ForStmt * forStmt ) {806 void CodeGenerator::visit( ForStmt * forStmt ) { 795 807 // initialization is always hoisted, so don't bother doing anything with that 796 808 output << "for (;"; … … 798 810 if ( forStmt->get_condition() != 0 ) { 799 811 forStmt->get_condition()->accept( *this ); 800 } 812 } // if 801 813 output << ";"; 802 814 … … 805 817 Expression * expr = new CastExpr( forStmt->get_increment() ); 806 818 expr->accept( *this ); 807 } 819 } // if 808 820 output << ") "; 809 821 … … 814 826 } 815 827 816 void CodeGenerator::visit( NullStmt * nullStmt ) {828 void CodeGenerator::visit( NullStmt * nullStmt ) { 817 829 //output << indent << CodeGenerator::printLabels( nullStmt->get_labels() ); 818 830 output << "/* null statement */ ;"; 819 831 } 820 832 821 void CodeGenerator::visit( DeclStmt * declStmt ) {833 void CodeGenerator::visit( DeclStmt * declStmt ) { 822 834 declStmt->get_decl()->accept( *this ); 823 835 … … 827 839 } 828 840 829 void CodeGenerator::handleStorageClass( Declaration * decl ) {841 void CodeGenerator::handleStorageClass( Declaration * decl ) { 830 842 switch ( decl->get_storageClass() ) { 831 843 case DeclarationNode::Extern:
Note:
See TracChangeset
for help on using the changeset viewer.