Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    re04ef3a r888cbe4  
    2626#include "SynTree/Statement.h"
    2727#include "SynTree/Type.h"
     28#include "SynTree/Attribute.h"
    2829
    2930#include "Common/utility.h"
     
    3334#include "OperatorTable.h"
    3435#include "GenType.h"
     36
     37#include "InitTweak/InitTweak.h"
    3538
    3639using namespace std;
     
    4548        }
    4649
    47         ostream & CodeGenerator::Indenter::operator()( ostream & output ) {
     50        ostream & CodeGenerator::Indenter::operator()( ostream & output ) const {
    4851          return output << string( cg.cur_indent, ' ' );
    4952        }
    5053
    51         ostream & operator<<( ostream & output, CodeGenerator::Indenter &indent ) {
     54        ostream & operator<<( ostream & output, const CodeGenerator::Indenter &indent ) {
    5255                return indent( output );
    5356        }
    5457
    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 ) { }
    5674
    5775        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 ) {
    5977                //output << std::string( init );
    6078        }
    6179
    6280        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 ) {
    6482                //output << std::string( init );
    6583        }
     
    7492        }
    7593
     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
    76110        //*** Declarations
    77111        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
    98114                handleStorageClass( functionDecl );
    99115                if ( functionDecl->get_isInline() ) {
     
    270286                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    271287                                                        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 );
    272292                                                        *arg = newExpr;
    273293                                                } // if
     
    298318                                        if ( applicationExpr->get_args().size() == 1 ) {
    299319                                                // the expression fed into a single parameter constructor or destructor
    300                                                 // may contain side effects - output as a void expression
    301                                                 output << "((void)(";
     320                                                // may contain side effects, so must still output this expression
     321                                                output << "(";
    302322                                                (*arg++)->accept( *this );
    303                                                 output << ")) /* " << opInfo.inputName << " */";
     323                                                output << ") /* " << opInfo.inputName << " */";
    304324                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    305325                                                // intrinsic two parameter constructors are essentially bitwise assignment
     
    384404                                        if ( untypedExpr->get_args().size() == 1 ) {
    385405                                                // the expression fed into a single parameter constructor or destructor
    386                                                 // may contain side effects - output as a void expression
    387                                                 output << "((void)(";
     406                                                // may contain side effects, so must still output this expression
     407                                                output << "(";
    388408                                                (*arg++)->accept( *this );
    389                                                 output << ")) /* " << opInfo.inputName << " */";
     409                                                output << ") /* " << opInfo.inputName << " */";
    390410                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    391411                                                // intrinsic two parameter constructors are essentially bitwise assignment
     
    626646
    627647        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
    631648                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 << ";";
    637653        }
    638654
     
    743759
    744760        void CodeGenerator::visit( WhileStmt *whileStmt ) {
    745                 if ( whileStmt->get_isDoWhile() )
     761                if ( whileStmt->get_isDoWhile() ) {
    746762                        output << "do" ;
    747                 else {
     763                } else {
    748764                        output << "while (" ;
    749765                        whileStmt->get_condition()->accept( *this );
     
    769785                output << "for (;";
    770786
    771                 if ( forStmt->get_condition() != 0 )
     787                if ( forStmt->get_condition() != 0 ) {
    772788                        forStmt->get_condition()->accept( *this );
     789                }
    773790                output << ";";
    774791
    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                }
    777797                output << ") ";
    778798
     
    794814                        output << ";";
    795815                } // 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;
    806816        }
    807817
Note: See TracChangeset for help on using the changeset viewer.