Changeset 90152a4 for src/CodeGen/CodeGenerator.cc
- Timestamp:
- Aug 27, 2018, 4:40:34 PM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- b7c89aa
- Parents:
- f9feab8 (diff), 305581d (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
rf9feab8 r90152a4 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S un Sep 3 20:42:52 201713 // Update Count : 49 012 // Last Modified On : Sat May 5 09:08:32 2018 13 // Update Count : 494 14 14 // 15 15 #include "CodeGenerator.h" … … 18 18 #include <list> // for _List_iterator, list, list<>::it... 19 19 20 #include "Common/SemanticError.h" // for SemanticError21 20 #include "Common/UniqueName.h" // for UniqueName 22 21 #include "Common/utility.h" // for CodeLocation, toString … … 117 116 } 118 117 119 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), 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 if ( pretty ) return decl->get_name(); 123 if ( decl->get_mangleName() != "" ) { 121 // GCC builtins should always be printed unmangled 122 if ( pretty || decl->linkage.is_gcc_builtin ) return decl->name; 123 if ( decl->mangleName != "" ) { 124 124 // need to incorporate scope level in order to differentiate names for destructors 125 125 return decl->get_scopedMangleName(); 126 126 } else { 127 return decl-> get_name();127 return decl->name; 128 128 } // if 129 129 } … … 133 133 output << "__attribute__ (("; 134 134 for ( list< Attribute * >::iterator attr( attributes.begin() );; ) { 135 output << (*attr)-> get_name();136 if ( ! (*attr)-> get_parameters().empty() ) {135 output << (*attr)->name; 136 if ( ! (*attr)->parameters.empty() ) { 137 137 output << "("; 138 genCommaList( (*attr)-> get_parameters().begin(), (*attr)->get_parameters().end() );138 genCommaList( (*attr)->parameters.begin(), (*attr)->parameters.end() ); 139 139 output << ")"; 140 140 } // if … … 160 160 } 161 161 162 // *** Expression 163 void CodeGenerator::previsit( Expression * node ) { 164 previsit( (BaseSyntaxNode *)node ); 165 GuardAction( [this, node](){ 166 if ( printExprTypes && node->result ) { 167 output << " /* " << genType( node->result, "", pretty, genC ) << " */ "; 168 } 169 } ); 170 } 171 162 172 // *** Declarations 163 173 void CodeGenerator::postvisit( FunctionDecl * functionDecl ) { 174 // deleted decls should never be used, so don't print them 175 if ( functionDecl->isDeleted && genC ) return; 164 176 extension( functionDecl ); 165 177 genAttributes( functionDecl->get_attributes() ); … … 175 187 functionDecl->get_statements()->accept( *visitor ); 176 188 } // if 189 if ( functionDecl->isDeleted ) { 190 output << " = void"; 191 } 177 192 } 178 193 179 194 void CodeGenerator::postvisit( ObjectDecl * objectDecl ) { 195 // deleted decls should never be used, so don't print them 196 if ( objectDecl->isDeleted && genC ) return; 180 197 if (objectDecl->get_name().empty() && genC ) { 181 198 // only generate an anonymous name when generating C code, otherwise it clutters the output too much … … 196 213 objectDecl->get_init()->accept( *visitor ); 197 214 } // if 215 if ( objectDecl->isDeleted ) { 216 output << " = void"; 217 } 198 218 199 219 if ( objectDecl->get_bitfieldWidth() ) { … … 204 224 205 225 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) { 206 genAttributes( aggDecl->get_attributes() ); 207 208 if( ! aggDecl->get_parameters().empty() && ! genC ) { 226 if( ! aggDecl->parameters.empty() && ! genC ) { 209 227 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 210 228 output << "forall("; 211 genCommaList( aggDecl-> get_parameters().begin(), aggDecl->get_parameters().end() );229 genCommaList( aggDecl->parameters.begin(), aggDecl->parameters.end() ); 212 230 output << ")" << endl; 213 231 output << indent; 214 232 } 215 233 216 output << kind << aggDecl->get_name(); 234 output << kind; 235 genAttributes( aggDecl->attributes ); 236 output << aggDecl->name; 217 237 218 238 if ( aggDecl->has_body() ) { 219 std::list< Declaration * > & memb = aggDecl-> get_members();239 std::list< Declaration * > & memb = aggDecl->members; 220 240 output << " {" << endl; 221 241 … … 299 319 output << " }"; 300 320 } 321 } 322 323 void CodeGenerator::postvisit( StaticAssertDecl * assertDecl ) { 324 output << "_Static_assert("; 325 assertDecl->condition->accept( *visitor ); 326 output << ", "; 327 assertDecl->message->accept( *visitor ); 328 output << ")"; 301 329 } 302 330 … … 353 381 354 382 void CodeGenerator::postvisit( Constant * constant ) { 355 output << constant->get_value() 383 output << constant->get_value(); 356 384 } 357 385 … … 570 598 output << "("; 571 599 if ( castExpr->get_result()->isVoid() ) { 572 output << "(void)" 600 output << "(void)"; 573 601 } else { 574 602 // at least one result type of cast. … … 579 607 output << ")"; 580 608 } // if 581 castExpr->get_arg()->accept( *visitor ); 609 castExpr->arg->accept( *visitor ); 610 output << ")"; 611 } 612 613 void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) { 614 assertf( ! genC, "KeywordCast should not reach code generation." ); 615 extension( castExpr ); 616 output << "((" << castExpr->targetString() << " &)"; 617 castExpr->arg->accept( *visitor ); 582 618 output << ")"; 583 619 } … … 764 800 765 801 void CodeGenerator::postvisit( StmtExpr * stmtExpr ) { 766 std::list< Statement * > & stmts = stmtExpr-> get_statements()->get_kids();802 std::list< Statement * > & stmts = stmtExpr->statements->kids; 767 803 output << "({" << endl; 768 804 ++indent; … … 775 811 // cannot cast to void, otherwise the expression statement has no value 776 812 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) { 777 exprStmt-> get_expr()->accept( *visitor );813 exprStmt->expr->accept( *visitor ); 778 814 output << ";" << endl; 779 815 ++i; … … 796 832 expr->callExpr->accept( *visitor ); 797 833 } 834 835 void CodeGenerator::postvisit( DeletedExpr * expr ) { 836 assertf( ! genC, "Deleted expressions should not reach code generation." ); 837 expr->expr->accept( *visitor ); 838 } 839 840 void CodeGenerator::postvisit( DefaultArgExpr * arg ) { 841 assertf( ! genC, "Default argument expressions should not reach code generation." ); 842 arg->expr->accept( *visitor ); 843 } 844 845 void CodeGenerator::postvisit( GenericExpr * expr ) { 846 assertf( ! genC, "C11 _Generic expressions should not reach code generation." ); 847 output << "_Generic("; 848 expr->control->accept( *visitor ); 849 output << ", "; 850 unsigned int numAssocs = expr->associations.size(); 851 unsigned int i = 0; 852 for ( GenericExpr::Association & assoc : expr->associations ) { 853 if (assoc.isDefault) { 854 output << "default: "; 855 } else { 856 output << genType( assoc.type, "", pretty, genC ) << ": "; 857 } 858 assoc.expr->accept( *visitor ); 859 if ( i+1 != numAssocs ) { 860 output << ", "; 861 } 862 i++; 863 } 864 output << ")"; 865 } 866 798 867 799 868 // *** Statements … … 848 917 } // for 849 918 } // if 850 output << " );" 919 output << " );"; 851 920 } 852 921 … … 856 925 output << "( "; 857 926 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor ); 858 output << " )" ; 927 output << " )"; 928 } 929 930 void CodeGenerator::postvisit( DirectiveStmt * dirStmt ) { 931 output << endl << dirStmt->directive; // endl prevents spaces before directive 859 932 } 860 933 … … 873 946 874 947 void CodeGenerator::postvisit( SwitchStmt * switchStmt ) { 875 output << "switch ( " 948 output << "switch ( "; 876 949 switchStmt->get_condition()->accept( *visitor ); 877 950 output << " ) "; … … 899 972 ++indent; 900 973 for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end(); i++) { 901 output << indent << printLabels( (*i)->get_labels() ) 974 output << indent << printLabels( (*i)->get_labels() ) ; 902 975 (*i)->accept( *visitor ); 903 976 output << endl; … … 924 997 output << "continue"; 925 998 break; 999 case BranchStmt::FallThrough: 1000 case BranchStmt::FallThroughDefault: 1001 assertf( ! genC, "fallthru should not reach code generation." ); 1002 output << "fallthru"; 1003 break; 926 1004 } // switch 1005 // print branch target for labelled break/continue/fallthru in debug mode 1006 if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) { 1007 if ( ! branchStmt->get_target().empty() ) { 1008 output << " " << branchStmt->get_target(); 1009 } else if ( branchStmt->get_type() == BranchStmt::FallThrough ) { 1010 output << " default"; 1011 } 1012 } 927 1013 output << ";"; 928 1014 } … … 1023 1109 void CodeGenerator::postvisit( WhileStmt * whileStmt ) { 1024 1110 if ( whileStmt->get_isDoWhile() ) { 1025 output << "do" 1111 output << "do"; 1026 1112 } else { 1027 output << "while (" 1113 output << "while ("; 1028 1114 whileStmt->get_condition()->accept( *visitor ); 1029 1115 output << ")"; … … 1037 1123 1038 1124 if ( whileStmt->get_isDoWhile() ) { 1039 output << " while (" 1125 output << " while ("; 1040 1126 whileStmt->get_condition()->accept( *visitor ); 1041 1127 output << ");";
Note:
See TracChangeset
for help on using the changeset viewer.