Changes in src/CodeGen/CodeGenerator.cc [76f7fc7:0b3b2ae]
- File:
-
- 1 edited
-
src/CodeGen/CodeGenerator.cc (modified) (37 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r76f7fc7 r0b3b2ae 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr May 2 10:47:00 201913 // Update Count : 49 711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat May 5 09:08:32 2018 13 // Update Count : 494 14 14 // 15 15 #include "CodeGenerator.h" … … 83 83 void CodeGenerator::updateLocation( CodeLocation const & to ) { 84 84 // skip if linemarks shouldn't appear or if codelocation is unset 85 if ( ! options.lineMarks || to.isUnset() ) return;85 if ( !lineMarks || to.isUnset() ) return; 86 86 87 87 if ( currentLocation.followedBy( to, 0 ) ) { … … 116 116 } 117 117 118 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), options( pretty, genC, lineMarks, printExprTypes ), endl( *this ) {} 119 CodeGenerator::CodeGenerator( std::ostream & os, const Options &options ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), options(options), endl( *this ) {} 118 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), printExprTypes( printExprTypes ), endl( *this ) {} 120 119 121 120 string CodeGenerator::mangleName( DeclarationWithType * decl ) { 122 121 // GCC builtins should always be printed unmangled 123 if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name;122 if ( pretty || decl->linkage.is_gcc_builtin ) return decl->name; 124 123 if ( decl->mangleName != "" ) { 125 124 // need to incorporate scope level in order to differentiate names for destructors … … 165 164 previsit( (BaseSyntaxNode *)node ); 166 165 GuardAction( [this, node](){ 167 if ( options.printExprTypes && node->result ) {168 output << " /* " << genType( node->result, "", options) << " */ ";166 if ( printExprTypes && node->result ) { 167 output << " /* " << genType( node->result, "", pretty, genC ) << " */ "; 169 168 } 170 169 } ); … … 174 173 void CodeGenerator::postvisit( FunctionDecl * functionDecl ) { 175 174 // deleted decls should never be used, so don't print them 176 if ( functionDecl->isDeleted && options.genC ) return;175 if ( functionDecl->isDeleted && genC ) return; 177 176 extension( functionDecl ); 178 177 genAttributes( functionDecl->get_attributes() ); … … 181 180 functionDecl->get_funcSpec().print( output ); 182 181 183 Options subOptions = options; 184 subOptions.anonymousUnused = functionDecl->has_body(); 185 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), subOptions ); 182 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC ); 186 183 187 184 asmName( functionDecl ); … … 197 194 void CodeGenerator::postvisit( ObjectDecl * objectDecl ) { 198 195 // deleted decls should never be used, so don't print them 199 if ( objectDecl->isDeleted && options.genC ) return;200 if (objectDecl->get_name().empty() && options.genC ) {196 if ( objectDecl->isDeleted && genC ) return; 197 if (objectDecl->get_name().empty() && genC ) { 201 198 // only generate an anonymous name when generating C code, otherwise it clutters the output too much 202 199 static UniqueName name = { "__anonymous_object" }; 203 200 objectDecl->set_name( name.newName() ); 204 // Stops unused parameter warnings.205 if ( options.anonymousUnused ) {206 objectDecl->attributes.push_back( new Attribute( "unused" ) );207 }208 201 } 209 202 … … 212 205 213 206 handleStorageClass( objectDecl ); 214 output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC );207 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC ); 215 208 216 209 asmName( objectDecl ); … … 231 224 232 225 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) { 233 if( ! aggDecl->parameters.empty() && ! options.genC ) {226 if( ! aggDecl->parameters.empty() && ! genC ) { 234 227 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 235 228 output << "forall("; … … 301 294 302 295 void CodeGenerator::postvisit( TraitDecl * traitDecl ) { 303 assertf( ! options.genC, "TraitDecls should not reach code generation." );296 assertf( ! genC, "TraitDecls should not reach code generation." ); 304 297 extension( traitDecl ); 305 298 handleAggregate( traitDecl, "trait " ); … … 307 300 308 301 void CodeGenerator::postvisit( TypedefDecl * typeDecl ) { 309 assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." );302 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." ); 310 303 output << "typedef "; 311 output << genType( typeDecl->get_base(), typeDecl->get_name(), options) << endl;304 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl; 312 305 } 313 306 314 307 void CodeGenerator::postvisit( TypeDecl * typeDecl ) { 315 assertf( ! options.genC, "TypeDecls should not reach code generation." );308 assertf( ! genC, "TypeDecls should not reach code generation." ); 316 309 output << typeDecl->genTypeString() << " " << typeDecl->name; 317 310 if ( typeDecl->sized ) { … … 378 371 379 372 void CodeGenerator::postvisit( ConstructorInit * init ){ 380 assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." );373 assertf( ! genC, "ConstructorInit nodes should not reach code generation." ); 381 374 // pseudo-output for constructor/destructor pairs 382 375 output << "<ctorinit>{" << endl << ++indent << "ctor: "; … … 514 507 } else { 515 508 // no constructors with 0 or more than 2 parameters 516 assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );509 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." ); 517 510 output << "("; 518 511 (*arg++)->accept( *visitor ); … … 611 604 // an lvalue cast, this has been taken out. 612 605 output << "("; 613 output << genType( castExpr->get_result(), "", options);606 output << genType( castExpr->get_result(), "", pretty, genC ); 614 607 output << ")"; 615 608 } // if … … 619 612 620 613 void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) { 621 assertf( ! options.genC, "KeywordCast should not reach code generation." );614 assertf( ! genC, "KeywordCast should not reach code generation." ); 622 615 extension( castExpr ); 623 616 output << "((" << castExpr->targetString() << " &)"; … … 627 620 628 621 void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) { 629 assertf( ! options.genC, "VirtualCastExpr should not reach code generation." );622 assertf( ! genC, "VirtualCastExpr should not reach code generation." ); 630 623 extension( castExpr ); 631 624 output << "(virtual "; … … 635 628 636 629 void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) { 637 assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." );630 assertf( ! genC, "UntypedMemberExpr should not reach code generation." ); 638 631 extension( memberExpr ); 639 632 memberExpr->get_aggregate()->accept( *visitor ); … … 668 661 output << "sizeof("; 669 662 if ( sizeofExpr->get_isType() ) { 670 output << genType( sizeofExpr->get_type(), "", options);663 output << genType( sizeofExpr->get_type(), "", pretty, genC ); 671 664 } else { 672 665 sizeofExpr->get_expr()->accept( *visitor ); … … 680 673 output << "__alignof__("; 681 674 if ( alignofExpr->get_isType() ) { 682 output << genType( alignofExpr->get_type(), "", options);675 output << genType( alignofExpr->get_type(), "", pretty, genC ); 683 676 } else { 684 677 alignofExpr->get_expr()->accept( *visitor ); … … 688 681 689 682 void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) { 690 assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." );683 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." ); 691 684 output << "offsetof("; 692 output << genType( offsetofExpr->get_type(), "", options);685 output << genType( offsetofExpr->get_type(), "", pretty, genC ); 693 686 output << ", " << offsetofExpr->get_member(); 694 687 output << ")"; … … 698 691 // use GCC builtin 699 692 output << "__builtin_offsetof("; 700 output << genType( offsetofExpr->get_type(), "", options);693 output << genType( offsetofExpr->get_type(), "", pretty, genC ); 701 694 output << ", " << mangleName( offsetofExpr->get_member() ); 702 695 output << ")"; … … 704 697 705 698 void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) { 706 assertf( ! options.genC, "OffsetPackExpr should not reach code generation." );707 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options) << ")";699 assertf( ! genC, "OffsetPackExpr should not reach code generation." ); 700 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")"; 708 701 } 709 702 … … 735 728 extension( commaExpr ); 736 729 output << "("; 737 if ( options.genC ) {730 if ( genC ) { 738 731 // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings. 739 732 commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) ); … … 746 739 747 740 void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) { 748 assertf( ! options.genC, "TupleAssignExpr should not reach code generation." );741 assertf( ! genC, "TupleAssignExpr should not reach code generation." ); 749 742 tupleExpr->stmtExpr->accept( *visitor ); 750 743 } 751 744 752 745 void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) { 753 assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." );746 assertf( ! genC, "UntypedTupleExpr should not reach code generation." ); 754 747 extension( tupleExpr ); 755 748 output << "["; … … 759 752 760 753 void CodeGenerator::postvisit( TupleExpr * tupleExpr ) { 761 assertf( ! options.genC, "TupleExpr should not reach code generation." );754 assertf( ! genC, "TupleExpr should not reach code generation." ); 762 755 extension( tupleExpr ); 763 756 output << "["; … … 767 760 768 761 void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) { 769 assertf( ! options.genC, "TupleIndexExpr should not reach code generation." );762 assertf( ! genC, "TupleIndexExpr should not reach code generation." ); 770 763 extension( tupleExpr ); 771 764 tupleExpr->get_tuple()->accept( *visitor ); … … 774 767 775 768 void CodeGenerator::postvisit( TypeExpr * typeExpr ) { 776 // if ( options.genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;777 // assertf( ! options.genC, "TypeExpr should not reach code generation." );778 if ( ! options.genC ) {779 output << genType( typeExpr->get_type(), "", options);769 // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl; 770 // assertf( ! genC, "TypeExpr should not reach code generation." ); 771 if ( ! genC ) { 772 output<< genType( typeExpr->get_type(), "", pretty, genC ); 780 773 } 781 774 } … … 795 788 void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) { 796 789 assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) ); 797 output << "(" << genType( compLitExpr->get_result(), "", options) << ")";790 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")"; 798 791 compLitExpr->get_initializer()->accept( *visitor ); 799 792 } 800 793 801 794 void CodeGenerator::postvisit( UniqueExpr * unqExpr ) { 802 assertf( ! options.genC, "Unique expressions should not reach code generation." );795 assertf( ! genC, "Unique expressions should not reach code generation." ); 803 796 output << "unq<" << unqExpr->get_id() << ">{ "; 804 797 unqExpr->get_expr()->accept( *visitor ); … … 836 829 837 830 void CodeGenerator::postvisit( ConstructorExpr * expr ) { 838 assertf( ! options.genC, "Unique expressions should not reach code generation." );831 assertf( ! genC, "Unique expressions should not reach code generation." ); 839 832 expr->callExpr->accept( *visitor ); 840 833 } 841 834 842 835 void CodeGenerator::postvisit( DeletedExpr * expr ) { 843 assertf( ! options.genC, "Deleted expressions should not reach code generation." );836 assertf( ! genC, "Deleted expressions should not reach code generation." ); 844 837 expr->expr->accept( *visitor ); 845 838 } 846 839 847 840 void CodeGenerator::postvisit( DefaultArgExpr * arg ) { 848 assertf( ! options.genC, "Default argument expressions should not reach code generation." );841 assertf( ! genC, "Default argument expressions should not reach code generation." ); 849 842 arg->expr->accept( *visitor ); 850 843 } 851 844 852 845 void CodeGenerator::postvisit( GenericExpr * expr ) { 853 assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." );846 assertf( ! genC, "C11 _Generic expressions should not reach code generation." ); 854 847 output << "_Generic("; 855 848 expr->control->accept( *visitor ); … … 861 854 output << "default: "; 862 855 } else { 863 output << genType( assoc.type, "", options) << ": ";856 output << genType( assoc.type, "", pretty, genC ) << ": "; 864 857 } 865 858 assoc.expr->accept( *visitor ); … … 896 889 void CodeGenerator::postvisit( ExprStmt * exprStmt ) { 897 890 assert( exprStmt ); 898 if ( options.genC ) {891 if ( genC ) { 899 892 // cast the top-level expression to void to reduce gcc warnings. 900 893 exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) ); … … 1006 999 case BranchStmt::FallThrough: 1007 1000 case BranchStmt::FallThroughDefault: 1008 assertf( ! options.genC, "fallthru should not reach code generation." );1001 assertf( ! genC, "fallthru should not reach code generation." ); 1009 1002 output << "fallthru"; 1010 1003 break; 1011 1004 } // switch 1012 1005 // print branch target for labelled break/continue/fallthru in debug mode 1013 if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) {1006 if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) { 1014 1007 if ( ! branchStmt->get_target().empty() ) { 1015 1008 output << " " << branchStmt->get_target(); … … 1028 1021 1029 1022 void CodeGenerator::postvisit( ThrowStmt * throwStmt ) { 1030 assertf( ! options.genC, "Throw statements should not reach code generation." );1023 assertf( ! genC, "Throw statements should not reach code generation." ); 1031 1024 1032 1025 output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ? … … 1043 1036 } 1044 1037 void CodeGenerator::postvisit( CatchStmt * stmt ) { 1045 assertf( ! options.genC, "Catch statements should not reach code generation." );1038 assertf( ! genC, "Catch statements should not reach code generation." ); 1046 1039 1047 1040 output << ((stmt->get_kind() == CatchStmt::Terminate) ? … … 1060 1053 1061 1054 void CodeGenerator::postvisit( WaitForStmt * stmt ) { 1062 assertf( ! options.genC, "Waitfor statements should not reach code generation." );1055 assertf( ! genC, "Waitfor statements should not reach code generation." ); 1063 1056 1064 1057 bool first = true; … … 1106 1099 1107 1100 void CodeGenerator::postvisit( WithStmt * with ) { 1108 if ( ! options.genC ) {1101 if ( ! genC ) { 1109 1102 output << "with ( "; 1110 1103 genCommaList( with->exprs.begin(), with->exprs.end() ); … … 1172 1165 1173 1166 void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) { 1174 assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." );1167 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." ); 1175 1168 stmt->callStmt->accept( *visitor ); 1176 1169 }
Note:
See TracChangeset
for help on using the changeset viewer.