Changes in src/CodeGen/CodeGenerator.cc [de8d7fb1:3ed994e]
- File:
-
- 1 edited
-
src/CodeGen/CodeGenerator.cc (modified) (39 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rde8d7fb1 r3ed994e 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Oct 19 19:30:38 201913 // Update Count : 50612 // 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( 0, CodeGenerator::tabsize ), output( os ), printLabels( *this ), options( pretty, genC, lineMarks, printExprTypes ), endl( *this ) {} 119 CodeGenerator::CodeGenerator( std::ostream & os, const Options &options ) : indent( 0, 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 // GCC builtins should always be printed unmangled 123 if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name; 124 if ( decl->mangleName != "" ) { 121 if ( pretty ) return decl->get_name(); 122 if ( decl->get_mangleName() != "" ) { 125 123 // need to incorporate scope level in order to differentiate names for destructors 126 124 return decl->get_scopedMangleName(); 127 125 } else { 128 return decl-> name;126 return decl->get_name(); 129 127 } // if 130 128 } … … 134 132 output << "__attribute__ (("; 135 133 for ( list< Attribute * >::iterator attr( attributes.begin() );; ) { 136 output << (*attr)-> name;137 if ( ! (*attr)-> parameters.empty() ) {134 output << (*attr)->get_name(); 135 if ( ! (*attr)->get_parameters().empty() ) { 138 136 output << "("; 139 genCommaList( (*attr)-> parameters.begin(), (*attr)->parameters.end() );137 genCommaList( (*attr)->get_parameters().begin(), (*attr)->get_parameters().end() ); 140 138 output << ")"; 141 139 } // if … … 165 163 previsit( (BaseSyntaxNode *)node ); 166 164 GuardAction( [this, node](){ 167 if ( options.printExprTypes && node->result) {168 output << " /* " << genType( node->result, "", options) << " */ ";165 if ( printExprTypes ) { 166 output << " /* " << genType( node->result, "", pretty, genC ) << " */ "; 169 167 } 170 168 } ); … … 174 172 void CodeGenerator::postvisit( FunctionDecl * functionDecl ) { 175 173 // deleted decls should never be used, so don't print them 176 if ( functionDecl->isDeleted && options.genC ) return;174 if ( functionDecl->isDeleted && genC ) return; 177 175 extension( functionDecl ); 178 176 genAttributes( functionDecl->get_attributes() ); … … 181 179 functionDecl->get_funcSpec().print( output ); 182 180 183 Options subOptions = options; 184 subOptions.anonymousUnused = functionDecl->has_body(); 185 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), subOptions ); 181 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC ); 186 182 187 183 asmName( functionDecl ); … … 197 193 void CodeGenerator::postvisit( ObjectDecl * objectDecl ) { 198 194 // deleted decls should never be used, so don't print them 199 if ( objectDecl->isDeleted && options.genC ) return; 200 201 // gcc allows an empty declarator (no name) for bit-fields and C states: 6.7.2.1 Structure and union specifiers, 202 // point 4, page 113: If the (bit field) value is zero, the declaration shall have no declarator. For anything 203 // else, the anonymous name refers to the anonymous object for plan9 inheritance. 204 if ( objectDecl->get_name().empty() && options.genC && ! objectDecl->get_bitfieldWidth() ) { 195 if ( objectDecl->isDeleted && genC ) return; 196 if (objectDecl->get_name().empty() && genC ) { 205 197 // only generate an anonymous name when generating C code, otherwise it clutters the output too much 206 198 static UniqueName name = { "__anonymous_object" }; 207 199 objectDecl->set_name( name.newName() ); 208 // Stops unused parameter warnings.209 if ( options.anonymousUnused ) {210 objectDecl->attributes.push_back( new Attribute( "unused" ) );211 }212 200 } 213 201 … … 216 204 217 205 handleStorageClass( objectDecl ); 218 output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC );206 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC ); 219 207 220 208 asmName( objectDecl ); … … 235 223 236 224 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) { 237 if( ! aggDecl-> parameters.empty() && ! options.genC ) {225 if( ! aggDecl->get_parameters().empty() && ! genC ) { 238 226 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 239 227 output << "forall("; 240 genCommaList( aggDecl-> parameters.begin(), aggDecl->parameters.end() );228 genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() ); 241 229 output << ")" << endl; 242 230 output << indent; … … 244 232 245 233 output << kind; 246 genAttributes( aggDecl-> attributes);247 output << aggDecl-> name;234 genAttributes( aggDecl->get_attributes() ); 235 output << aggDecl->get_name(); 248 236 249 237 if ( aggDecl->has_body() ) { 250 std::list< Declaration * > & memb = aggDecl-> members;238 std::list< Declaration * > & memb = aggDecl->get_members(); 251 239 output << " {" << endl; 252 240 … … 305 293 306 294 void CodeGenerator::postvisit( TraitDecl * traitDecl ) { 307 assertf( ! options.genC, "TraitDecls should not reach code generation." );295 assertf( ! genC, "TraitDecls should not reach code generation." ); 308 296 extension( traitDecl ); 309 297 handleAggregate( traitDecl, "trait " ); … … 311 299 312 300 void CodeGenerator::postvisit( TypedefDecl * typeDecl ) { 313 assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." );301 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." ); 314 302 output << "typedef "; 315 output << genType( typeDecl->get_base(), typeDecl->get_name(), options) << endl;303 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl; 316 304 } 317 305 318 306 void CodeGenerator::postvisit( TypeDecl * typeDecl ) { 319 assertf( ! options.genC, "TypeDecls should not reach code generation." );307 assertf( ! genC, "TypeDecls should not reach code generation." ); 320 308 output << typeDecl->genTypeString() << " " << typeDecl->name; 321 309 if ( typeDecl->sized ) { … … 382 370 383 371 void CodeGenerator::postvisit( ConstructorInit * init ){ 384 assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." );372 assertf( ! genC, "ConstructorInit nodes should not reach code generation." ); 385 373 // pseudo-output for constructor/destructor pairs 386 374 output << "<ctorinit>{" << endl << ++indent << "ctor: "; … … 518 506 } else { 519 507 // no constructors with 0 or more than 2 parameters 520 assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );508 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." ); 521 509 output << "("; 522 510 (*arg++)->accept( *visitor ); … … 615 603 // an lvalue cast, this has been taken out. 616 604 output << "("; 617 output << genType( castExpr->get_result(), "", options);605 output << genType( castExpr->get_result(), "", pretty, genC ); 618 606 output << ")"; 619 607 } // if … … 623 611 624 612 void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) { 625 assertf( ! options.genC, "KeywordCast should not reach code generation." );613 assertf( ! genC, "KeywordCast should not reach code generation." ); 626 614 extension( castExpr ); 627 615 output << "((" << castExpr->targetString() << " &)"; … … 631 619 632 620 void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) { 633 assertf( ! options.genC, "VirtualCastExpr should not reach code generation." );621 assertf( ! genC, "VirtualCastExpr should not reach code generation." ); 634 622 extension( castExpr ); 635 623 output << "(virtual "; … … 639 627 640 628 void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) { 641 assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." );629 assertf( ! genC, "UntypedMemberExpr should not reach code generation." ); 642 630 extension( memberExpr ); 643 631 memberExpr->get_aggregate()->accept( *visitor ); … … 672 660 output << "sizeof("; 673 661 if ( sizeofExpr->get_isType() ) { 674 output << genType( sizeofExpr->get_type(), "", options);662 output << genType( sizeofExpr->get_type(), "", pretty, genC ); 675 663 } else { 676 664 sizeofExpr->get_expr()->accept( *visitor ); … … 684 672 output << "__alignof__("; 685 673 if ( alignofExpr->get_isType() ) { 686 output << genType( alignofExpr->get_type(), "", options);674 output << genType( alignofExpr->get_type(), "", pretty, genC ); 687 675 } else { 688 676 alignofExpr->get_expr()->accept( *visitor ); … … 692 680 693 681 void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) { 694 assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." );682 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." ); 695 683 output << "offsetof("; 696 output << genType( offsetofExpr->get_type(), "", options);684 output << genType( offsetofExpr->get_type(), "", pretty, genC ); 697 685 output << ", " << offsetofExpr->get_member(); 698 686 output << ")"; … … 702 690 // use GCC builtin 703 691 output << "__builtin_offsetof("; 704 output << genType( offsetofExpr->get_type(), "", options);692 output << genType( offsetofExpr->get_type(), "", pretty, genC ); 705 693 output << ", " << mangleName( offsetofExpr->get_member() ); 706 694 output << ")"; … … 708 696 709 697 void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) { 710 assertf( ! options.genC, "OffsetPackExpr should not reach code generation." );711 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options) << ")";698 assertf( ! genC, "OffsetPackExpr should not reach code generation." ); 699 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")"; 712 700 } 713 701 … … 739 727 extension( commaExpr ); 740 728 output << "("; 741 if ( options.genC ) {729 if ( genC ) { 742 730 // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings. 743 731 commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) ); … … 750 738 751 739 void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) { 752 assertf( ! options.genC, "TupleAssignExpr should not reach code generation." );740 assertf( ! genC, "TupleAssignExpr should not reach code generation." ); 753 741 tupleExpr->stmtExpr->accept( *visitor ); 754 742 } 755 743 756 744 void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) { 757 assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." );745 assertf( ! genC, "UntypedTupleExpr should not reach code generation." ); 758 746 extension( tupleExpr ); 759 747 output << "["; … … 763 751 764 752 void CodeGenerator::postvisit( TupleExpr * tupleExpr ) { 765 assertf( ! options.genC, "TupleExpr should not reach code generation." );753 assertf( ! genC, "TupleExpr should not reach code generation." ); 766 754 extension( tupleExpr ); 767 755 output << "["; … … 771 759 772 760 void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) { 773 assertf( ! options.genC, "TupleIndexExpr should not reach code generation." );761 assertf( ! genC, "TupleIndexExpr should not reach code generation." ); 774 762 extension( tupleExpr ); 775 763 tupleExpr->get_tuple()->accept( *visitor ); … … 778 766 779 767 void CodeGenerator::postvisit( TypeExpr * typeExpr ) { 780 // if ( options.genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;781 // assertf( ! options.genC, "TypeExpr should not reach code generation." );782 if ( ! options.genC ) {783 output << genType( typeExpr->get_type(), "", options);768 // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl; 769 // assertf( ! genC, "TypeExpr should not reach code generation." ); 770 if ( ! genC ) { 771 output<< genType( typeExpr->get_type(), "", pretty, genC ); 784 772 } 785 773 } … … 799 787 void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) { 800 788 assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) ); 801 output << "(" << genType( compLitExpr->get_result(), "", options) << ")";789 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")"; 802 790 compLitExpr->get_initializer()->accept( *visitor ); 803 791 } 804 792 805 793 void CodeGenerator::postvisit( UniqueExpr * unqExpr ) { 806 assertf( ! options.genC, "Unique expressions should not reach code generation." );794 assertf( ! genC, "Unique expressions should not reach code generation." ); 807 795 output << "unq<" << unqExpr->get_id() << ">{ "; 808 796 unqExpr->get_expr()->accept( *visitor ); … … 840 828 841 829 void CodeGenerator::postvisit( ConstructorExpr * expr ) { 842 assertf( ! options.genC, "Unique expressions should not reach code generation." );830 assertf( ! genC, "Unique expressions should not reach code generation." ); 843 831 expr->callExpr->accept( *visitor ); 844 832 } 845 833 846 834 void CodeGenerator::postvisit( DeletedExpr * expr ) { 847 assertf( ! options.genC, "Deleted expressions should not reach code generation." );835 assertf( ! genC, "Deleted expressions should not reach code generation." ); 848 836 expr->expr->accept( *visitor ); 849 837 } 850 838 851 void CodeGenerator::postvisit( DefaultArgExpr * arg ) {852 assertf( ! options.genC, "Default argument expressions should not reach code generation." );853 arg->expr->accept( *visitor );854 }855 856 839 void CodeGenerator::postvisit( GenericExpr * expr ) { 857 assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." );840 assertf( ! genC, "C11 _Generic expressions should not reach code generation." ); 858 841 output << "_Generic("; 859 842 expr->control->accept( *visitor ); … … 865 848 output << "default: "; 866 849 } else { 867 output << genType( assoc.type, "", options) << ": ";850 output << genType( assoc.type, "", pretty, genC ) << ": "; 868 851 } 869 852 assoc.expr->accept( *visitor ); … … 900 883 void CodeGenerator::postvisit( ExprStmt * exprStmt ) { 901 884 assert( exprStmt ); 902 if ( options.genC ) {885 if ( genC ) { 903 886 // cast the top-level expression to void to reduce gcc warnings. 904 887 exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) ); … … 1010 993 case BranchStmt::FallThrough: 1011 994 case BranchStmt::FallThroughDefault: 1012 assertf( ! options.genC, "fallthru should not reach code generation." );995 assertf( ! genC, "fallthru should not reach code generation." ); 1013 996 output << "fallthru"; 1014 997 break; 1015 998 } // switch 1016 999 // print branch target for labelled break/continue/fallthru in debug mode 1017 if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) {1000 if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) { 1018 1001 if ( ! branchStmt->get_target().empty() ) { 1019 1002 output << " " << branchStmt->get_target(); … … 1032 1015 1033 1016 void CodeGenerator::postvisit( ThrowStmt * throwStmt ) { 1034 assertf( ! options.genC, "Throw statements should not reach code generation." );1017 assertf( ! genC, "Throw statements should not reach code generation." ); 1035 1018 1036 1019 output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ? … … 1047 1030 } 1048 1031 void CodeGenerator::postvisit( CatchStmt * stmt ) { 1049 assertf( ! options.genC, "Catch statements should not reach code generation." );1032 assertf( ! genC, "Catch statements should not reach code generation." ); 1050 1033 1051 1034 output << ((stmt->get_kind() == CatchStmt::Terminate) ? … … 1064 1047 1065 1048 void CodeGenerator::postvisit( WaitForStmt * stmt ) { 1066 assertf( ! options.genC, "Waitfor statements should not reach code generation." );1049 assertf( ! genC, "Waitfor statements should not reach code generation." ); 1067 1050 1068 1051 bool first = true; … … 1110 1093 1111 1094 void CodeGenerator::postvisit( WithStmt * with ) { 1112 if ( ! options.genC ) {1095 if ( ! genC ) { 1113 1096 output << "with ( "; 1114 1097 genCommaList( with->exprs.begin(), with->exprs.end() ); … … 1176 1159 1177 1160 void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) { 1178 assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." );1161 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." ); 1179 1162 stmt->callStmt->accept( *visitor ); 1180 1163 }
Note:
See TracChangeset
for help on using the changeset viewer.