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