Changes in src/CodeGen/CodeGenerator.cc [e04ef3a:888cbe4]
- File:
-
- 1 edited
-
src/CodeGen/CodeGenerator.cc (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
re04ef3a r888cbe4 26 26 #include "SynTree/Statement.h" 27 27 #include "SynTree/Type.h" 28 #include "SynTree/Attribute.h" 28 29 29 30 #include "Common/utility.h" … … 33 34 #include "OperatorTable.h" 34 35 #include "GenType.h" 36 37 #include "InitTweak/InitTweak.h" 35 38 36 39 using namespace std; … … 45 48 } 46 49 47 ostream & CodeGenerator::Indenter::operator()( ostream & output ) {50 ostream & CodeGenerator::Indenter::operator()( ostream & output ) const { 48 51 return output << string( cg.cur_indent, ' ' ); 49 52 } 50 53 51 ostream & operator<<( ostream & output, CodeGenerator::Indenter &indent ) {54 ostream & operator<<( ostream & output, const CodeGenerator::Indenter &indent ) { 52 55 return indent( output ); 53 56 } 54 57 55 CodeGenerator::CodeGenerator( std::ostream &os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ) { } 58 CodeGenerator::LabelPrinter & CodeGenerator::LabelPrinter::operator()( std::list< Label > & l ) { 59 labels = &l; 60 return *this; 61 } 62 63 ostream & operator<<( ostream & output, CodeGenerator::LabelPrinter &printLabels ) { 64 std::list< Label > & labs = *printLabels.labels; 65 // l.unique(); // assumes a sorted list. Why not use set? Does order matter? 66 for ( Label & l : labs ) { 67 output << l.get_name() + ": "; 68 printLabels.cg.genAttributes( l.get_attributes() ); 69 } 70 return output; 71 } 72 73 CodeGenerator::CodeGenerator( std::ostream &os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ) { } 56 74 57 75 CodeGenerator::CodeGenerator( std::ostream &os, std::string init, int indentation, bool infunp ) 58 : indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ) {76 : indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ), printLabels( *this ) { 59 77 //output << std::string( init ); 60 78 } 61 79 62 80 CodeGenerator::CodeGenerator( std::ostream &os, char *init, int indentation, bool infunp ) 63 : indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ) {81 : indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ), printLabels( *this ) { 64 82 //output << std::string( init ); 65 83 } … … 74 92 } 75 93 94 void CodeGenerator::genAttributes( std::list< Attribute * > & attributes ) { 95 if ( ! attributes.empty() ) { 96 output << "__attribute__ (("; 97 for ( Attribute *& attr : attributes ) { 98 if ( ! attr->empty() ) { 99 output << attr->get_name() << "("; 100 genCommaList( attr->get_parameters().begin(), attr->get_parameters().end() ); 101 output << ")"; 102 } 103 output << ","; 104 } 105 output << ")) "; 106 } 107 } 108 109 76 110 //*** Declarations 77 111 void CodeGenerator::visit( FunctionDecl *functionDecl ) { 78 // generalize this 79 FunctionDecl::Attribute attr = functionDecl->get_attribute(); 80 switch ( attr.type ) { 81 case FunctionDecl::Attribute::Constructor: 82 output << "__attribute__ ((constructor"; 83 if ( attr.priority != FunctionDecl::Attribute::Default ) { 84 output << "(" << attr.priority << ")"; 85 } 86 output << ")) "; 87 break; 88 case FunctionDecl::Attribute::Destructor: 89 output << "__attribute__ ((destructor"; 90 if ( attr.priority != FunctionDecl::Attribute::Default ) { 91 output << "(" << attr.priority << ")"; 92 } 93 output << ")) "; 94 break; 95 default: 96 break; 97 } 112 genAttributes( functionDecl->get_attributes() ); 113 98 114 handleStorageClass( functionDecl ); 99 115 if ( functionDecl->get_isInline() ) { … … 270 286 UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 271 287 newExpr->get_args().push_back( *arg ); 288 assert( (*arg)->get_results().size() == 1 ); 289 Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() ); 290 assert( type ); 291 newExpr->get_results().push_back( type ); 272 292 *arg = newExpr; 273 293 } // if … … 298 318 if ( applicationExpr->get_args().size() == 1 ) { 299 319 // the expression fed into a single parameter constructor or destructor 300 // may contain side effects - output as a voidexpression301 output << "( (void)(";320 // may contain side effects, so must still output this expression 321 output << "("; 302 322 (*arg++)->accept( *this ); 303 output << ") )/* " << opInfo.inputName << " */";323 output << ") /* " << opInfo.inputName << " */"; 304 324 } else if ( applicationExpr->get_args().size() == 2 ) { 305 325 // intrinsic two parameter constructors are essentially bitwise assignment … … 384 404 if ( untypedExpr->get_args().size() == 1 ) { 385 405 // the expression fed into a single parameter constructor or destructor 386 // may contain side effects - output as a voidexpression387 output << "( (void)(";406 // may contain side effects, so must still output this expression 407 output << "("; 388 408 (*arg++)->accept( *this ); 389 output << ") )/* " << opInfo.inputName << " */";409 output << ") /* " << opInfo.inputName << " */"; 390 410 } else if ( untypedExpr->get_args().size() == 2 ) { 391 411 // intrinsic two parameter constructors are essentially bitwise assignment … … 626 646 627 647 void CodeGenerator::visit( ExprStmt *exprStmt ) { 628 // I don't see why this check is necessary.629 // If this starts to cause problems then put it back in,630 // with an explanation631 648 assert( exprStmt ); 632 633 // if ( exprStmt != 0 ) { 634 exprStmt->get_expr()->accept( *this ); 635 output << ";" ; 636 // } // if 649 // cast the top-level expression to void to reduce gcc warnings. 650 Expression * expr = new CastExpr( exprStmt->get_expr() ); 651 expr->accept( *this ); 652 output << ";"; 637 653 } 638 654 … … 743 759 744 760 void CodeGenerator::visit( WhileStmt *whileStmt ) { 745 if ( whileStmt->get_isDoWhile() ) 761 if ( whileStmt->get_isDoWhile() ) { 746 762 output << "do" ; 747 else {763 } else { 748 764 output << "while (" ; 749 765 whileStmt->get_condition()->accept( *this ); … … 769 785 output << "for (;"; 770 786 771 if ( forStmt->get_condition() != 0 ) 787 if ( forStmt->get_condition() != 0 ) { 772 788 forStmt->get_condition()->accept( *this ); 789 } 773 790 output << ";"; 774 791 775 if ( forStmt->get_increment() != 0 ) 776 forStmt->get_increment()->accept( *this ); 792 if ( forStmt->get_increment() != 0 ) { 793 // cast the top-level expression to void to reduce gcc warnings. 794 Expression * expr = new CastExpr( forStmt->get_increment() ); 795 expr->accept( *this ); 796 } 777 797 output << ") "; 778 798 … … 794 814 output << ";"; 795 815 } // if 796 }797 798 std::string CodeGenerator::printLabels( std::list< Label > &l ) {799 std::string str( "" );800 l.unique(); // assumes a sorted list. Why not use set?801 802 for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ )803 str += *i + ": ";804 805 return str;806 816 } 807 817
Note:
See TracChangeset
for help on using the changeset viewer.