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