Changes in src/CodeGen/CodeGenerator.cc [8a6cf7e:a5f0529]
- File:
-
- 1 edited
-
src/CodeGen/CodeGenerator.cc (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r8a6cf7e ra5f0529 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hu Jun 8 16:00:00 201713 // Update Count : 48 512 // Last Modified On : Tus Jul 25 15:29:00 2017 13 // Update Count : 486 14 14 // 15 #include "CodeGenerator.h" 15 16 16 17 #include <cassert> // for assert, assertf 17 18 #include <list> // for _List_iterator, list, list<>::it... 18 19 19 #include "CodeGenerator.h"20 20 #include "Common/SemanticError.h" // for SemanticError 21 21 #include "Common/UniqueName.h" // for UniqueName … … 64 64 } // extension 65 65 66 ostream & CodeGenerator::Indenter::operator()( ostream & output ) const { 67 return output << string( cg.cur_indent, ' ' ); 68 } 69 70 ostream & operator<<( ostream & output, const CodeGenerator::Indenter &indent ) { 71 return indent( output ); 72 } 73 66 74 CodeGenerator::LabelPrinter & CodeGenerator::LabelPrinter::operator()( std::list< Label > & l ) { 67 75 labels = &l; … … 101 109 } 102 110 103 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}111 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {} 104 112 105 113 string CodeGenerator::mangleName( DeclarationWithType * decl ) { … … 182 190 genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() ); 183 191 output << ")" << endl; 184 output << indent;185 192 } 186 193 … … 193 200 output << " {" << endl; 194 201 195 ++indent;202 cur_indent += CodeGenerator::tabsize; 196 203 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) { 197 204 output << lineDirective( *i ) << indent; … … 200 207 } // for 201 208 202 --indent;209 cur_indent -= CodeGenerator::tabsize; 203 210 204 211 output << indent << "}"; … … 230 237 output << " {" << endl; 231 238 232 ++indent;239 cur_indent += CodeGenerator::tabsize; 233 240 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 234 241 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); … … 242 249 } // for 243 250 244 --indent;251 cur_indent -= CodeGenerator::tabsize; 245 252 246 253 output << indent << "}"; … … 322 329 void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){ 323 330 assertf( ! genC, "ConstructorInit nodes should not reach code generation." ); 324 // pseudo-output for constructor/destructor pairs 325 output << "<ctorinit>{" << std::endl << ++indent << "ctor: "; 326 maybeAccept( init->get_ctor(), *this ); 327 output << ", " << std::endl << indent << "dtor: "; 328 maybeAccept( init->get_dtor(), *this ); 329 output << std::endl << --indent << "}"; 331 // xxx - generate something reasonable for constructor/destructor pairs 332 output << "<ctorinit>"; 330 333 } 331 334 … … 341 344 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) { 342 345 std::list< Expression* >::iterator arg = applicationExpr->get_args().begin(); 346 switch ( opInfo.type ) { 347 case OT_PREFIXASSIGN: 348 case OT_POSTFIXASSIGN: 349 case OT_INFIXASSIGN: 350 case OT_CTOR: 351 case OT_DTOR: 352 { 353 assert( arg != applicationExpr->get_args().end() ); 354 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) { 355 // remove & from first assignment/ctor argument 356 *arg = addrExpr->get_arg(); 357 } else { 358 // no address-of operator, so must be a pointer - add dereference 359 // NOTE: if the assertion starts to trigger, check that the application expr isn't being shared. 360 // Since its arguments are modified here, this assertion most commonly triggers when the application 361 // is visited multiple times. 362 UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 363 newExpr->get_args().push_back( *arg ); 364 Type * type = InitTweak::getPointerBase( (*arg)->get_result() ); 365 assertf( type, "First argument to a derefence must be a pointer. Ensure that expressions are not being shared." ); 366 newExpr->set_result( type->clone() ); 367 *arg = newExpr; 368 } // if 369 break; 370 } 371 372 default: 373 // do nothing 374 ; 375 } // switch 376 343 377 switch ( opInfo.type ) { 344 378 case OT_INDEX: … … 560 594 } 561 595 596 void CodeGenerator::visit( VirtualCastExpr * castExpr ) { 597 assertf( ! genC, "VirtualCastExpr should not reach code generation." ); 598 extension( castExpr ); 599 output << "(virtual "; 600 castExpr->get_arg()->accept( *this ); 601 output << ")"; 602 } 603 562 604 void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) { 563 605 assertf( ! genC, "UntypedMemberExpr should not reach code generation." ); … … 661 703 extension( commaExpr ); 662 704 output << "("; 663 if ( genC ) {664 // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.665 commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );666 }667 705 commaExpr->get_arg1()->accept( *this ); 668 706 output << " , "; … … 723 761 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids(); 724 762 output << lineDirective( stmtExpr) << "({" << std::endl; 725 ++indent;763 cur_indent += CodeGenerator::tabsize; 726 764 unsigned int numStmts = stmts.size(); 727 765 unsigned int i = 0; 728 766 for ( Statement * stmt : stmts ) { 729 767 output << lineDirective( stmt ) << indent; 730 output << printLabels( stmt->get_labels() );768 output << printLabels( stmt->get_labels() ); 731 769 if ( i+1 == numStmts ) { 732 770 // last statement in a statement expression needs to be handled specially - … … 746 784 ++i; 747 785 } 748 --indent;786 cur_indent -= CodeGenerator::tabsize; 749 787 output << indent << "})"; 750 788 } … … 755 793 output << "{" << endl; 756 794 757 ++indent;795 cur_indent += CodeGenerator::tabsize; 758 796 759 797 for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end(); i++ ) { … … 766 804 } // if 767 805 } // for 768 --indent;806 cur_indent -= CodeGenerator::tabsize; 769 807 770 808 output << indent << "}"; … … 773 811 void CodeGenerator::visit( ExprStmt * exprStmt ) { 774 812 assert( exprStmt ); 813 Expression * expr = exprStmt->get_expr(); 775 814 if ( genC ) { 776 815 // cast the top-level expression to void to reduce gcc warnings. 777 expr Stmt->set_expr( new CastExpr( exprStmt->get_expr() ));816 expr = new CastExpr( expr ); 778 817 } 779 expr Stmt->get_expr()->accept( *this );818 expr->accept( *this ); 780 819 output << ";"; 781 820 } … … 833 872 834 873 output << "{" << std::endl; 835 ++indent;874 cur_indent += CodeGenerator::tabsize; 836 875 acceptAll( switchStmt->get_statements(), *this ); 837 --indent;876 cur_indent -= CodeGenerator::tabsize; 838 877 output << indent << "}"; 839 878 } … … 852 891 std::list<Statement *> sts = caseStmt->get_statements(); 853 892 854 ++indent;893 cur_indent += CodeGenerator::tabsize; 855 894 for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end(); i++) { 856 895 output << indent << printLabels( (*i)->get_labels() ) ; … … 858 897 output << endl; 859 898 } // for 860 --indent;899 cur_indent -= CodeGenerator::tabsize; 861 900 } 862 901
Note:
See TracChangeset
for help on using the changeset viewer.