Changes in src/CodeGen/CodeGenerator.cc [888cbe4:e04ef3a]
- File:
-
- 1 edited
-
src/CodeGen/CodeGenerator.cc (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r888cbe4 re04ef3a 26 26 #include "SynTree/Statement.h" 27 27 #include "SynTree/Type.h" 28 #include "SynTree/Attribute.h"29 28 30 29 #include "Common/utility.h" … … 34 33 #include "OperatorTable.h" 35 34 #include "GenType.h" 36 37 #include "InitTweak/InitTweak.h"38 35 39 36 using namespace std; … … 48 45 } 49 46 50 ostream & CodeGenerator::Indenter::operator()( ostream & output ) const{47 ostream & CodeGenerator::Indenter::operator()( ostream & output ) { 51 48 return output << string( cg.cur_indent, ' ' ); 52 49 } 53 50 54 ostream & operator<<( ostream & output, constCodeGenerator::Indenter &indent ) {51 ostream & operator<<( ostream & output, CodeGenerator::Indenter &indent ) { 55 52 return indent( output ); 56 53 } 57 54 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 ) { } 55 CodeGenerator::CodeGenerator( std::ostream &os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ) { } 74 56 75 57 CodeGenerator::CodeGenerator( std::ostream &os, std::string init, int indentation, bool infunp ) 76 : indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ) , printLabels( *this ){58 : indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ) { 77 59 //output << std::string( init ); 78 60 } 79 61 80 62 CodeGenerator::CodeGenerator( std::ostream &os, char *init, int indentation, bool infunp ) 81 : indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ) , printLabels( *this ){63 : indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ) { 82 64 //output << std::string( init ); 83 65 } … … 92 74 } 93 75 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 110 76 //*** Declarations 111 77 void CodeGenerator::visit( FunctionDecl *functionDecl ) { 112 genAttributes( functionDecl->get_attributes() ); 113 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 } 114 98 handleStorageClass( functionDecl ); 115 99 if ( functionDecl->get_isInline() ) { … … 286 270 UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 287 271 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 );292 272 *arg = newExpr; 293 273 } // if … … 318 298 if ( applicationExpr->get_args().size() == 1 ) { 319 299 // the expression fed into a single parameter constructor or destructor 320 // may contain side effects , so must still output thisexpression321 output << "( ";300 // may contain side effects - output as a void expression 301 output << "((void)("; 322 302 (*arg++)->accept( *this ); 323 output << ") /* " << opInfo.inputName << " */";303 output << ")) /* " << opInfo.inputName << " */"; 324 304 } else if ( applicationExpr->get_args().size() == 2 ) { 325 305 // intrinsic two parameter constructors are essentially bitwise assignment … … 404 384 if ( untypedExpr->get_args().size() == 1 ) { 405 385 // the expression fed into a single parameter constructor or destructor 406 // may contain side effects , so must still output thisexpression407 output << "( ";386 // may contain side effects - output as a void expression 387 output << "((void)("; 408 388 (*arg++)->accept( *this ); 409 output << ") /* " << opInfo.inputName << " */";389 output << ")) /* " << opInfo.inputName << " */"; 410 390 } else if ( untypedExpr->get_args().size() == 2 ) { 411 391 // intrinsic two parameter constructors are essentially bitwise assignment … … 646 626 647 627 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 explanation 648 631 assert( exprStmt ); 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 << ";"; 632 633 // if ( exprStmt != 0 ) { 634 exprStmt->get_expr()->accept( *this ); 635 output << ";" ; 636 // } // if 653 637 } 654 638 … … 759 743 760 744 void CodeGenerator::visit( WhileStmt *whileStmt ) { 761 if ( whileStmt->get_isDoWhile() ) {745 if ( whileStmt->get_isDoWhile() ) 762 746 output << "do" ; 763 }else {747 else { 764 748 output << "while (" ; 765 749 whileStmt->get_condition()->accept( *this ); … … 785 769 output << "for (;"; 786 770 787 if ( forStmt->get_condition() != 0 ) {771 if ( forStmt->get_condition() != 0 ) 788 772 forStmt->get_condition()->accept( *this ); 789 }790 773 output << ";"; 791 774 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 } 775 if ( forStmt->get_increment() != 0 ) 776 forStmt->get_increment()->accept( *this ); 797 777 output << ") "; 798 778 … … 814 794 output << ";"; 815 795 } // 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; 816 806 } 817 807
Note:
See TracChangeset
for help on using the changeset viewer.