Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r888cbe4 re04ef3a  
    2626#include "SynTree/Statement.h"
    2727#include "SynTree/Type.h"
    28 #include "SynTree/Attribute.h"
    2928
    3029#include "Common/utility.h"
     
    3433#include "OperatorTable.h"
    3534#include "GenType.h"
    36 
    37 #include "InitTweak/InitTweak.h"
    3835
    3936using namespace std;
     
    4845        }
    4946
    50         ostream & CodeGenerator::Indenter::operator()( ostream & output ) const {
     47        ostream & CodeGenerator::Indenter::operator()( ostream & output ) {
    5148          return output << string( cg.cur_indent, ' ' );
    5249        }
    5350
    54         ostream & operator<<( ostream & output, const CodeGenerator::Indenter &indent ) {
     51        ostream & operator<<( ostream & output, CodeGenerator::Indenter &indent ) {
    5552                return indent( output );
    5653        }
    5754
    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 ) { }
    7456
    7557        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 ) {
    7759                //output << std::string( init );
    7860        }
    7961
    8062        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 ) {
    8264                //output << std::string( init );
    8365        }
     
    9274        }
    9375
    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 
    11076        //*** Declarations
    11177        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                }
    11498                handleStorageClass( functionDecl );
    11599                if ( functionDecl->get_isInline() ) {
     
    286270                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    287271                                                        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 );
    292272                                                        *arg = newExpr;
    293273                                                } // if
     
    318298                                        if ( applicationExpr->get_args().size() == 1 ) {
    319299                                                // the expression fed into a single parameter constructor or destructor
    320                                                 // may contain side effects, so must still output this expression
    321                                                 output << "(";
     300                                                // may contain side effects - output as a void expression
     301                                                output << "((void)(";
    322302                                                (*arg++)->accept( *this );
    323                                                 output << ") /* " << opInfo.inputName << " */";
     303                                                output << ")) /* " << opInfo.inputName << " */";
    324304                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    325305                                                // intrinsic two parameter constructors are essentially bitwise assignment
     
    404384                                        if ( untypedExpr->get_args().size() == 1 ) {
    405385                                                // the expression fed into a single parameter constructor or destructor
    406                                                 // may contain side effects, so must still output this expression
    407                                                 output << "(";
     386                                                // may contain side effects - output as a void expression
     387                                                output << "((void)(";
    408388                                                (*arg++)->accept( *this );
    409                                                 output << ") /* " << opInfo.inputName << " */";
     389                                                output << ")) /* " << opInfo.inputName << " */";
    410390                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    411391                                                // intrinsic two parameter constructors are essentially bitwise assignment
     
    646626
    647627        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
    648631                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
    653637        }
    654638
     
    759743
    760744        void CodeGenerator::visit( WhileStmt *whileStmt ) {
    761                 if ( whileStmt->get_isDoWhile() ) {
     745                if ( whileStmt->get_isDoWhile() )
    762746                        output << "do" ;
    763                 } else {
     747                else {
    764748                        output << "while (" ;
    765749                        whileStmt->get_condition()->accept( *this );
     
    785769                output << "for (;";
    786770
    787                 if ( forStmt->get_condition() != 0 ) {
     771                if ( forStmt->get_condition() != 0 )
    788772                        forStmt->get_condition()->accept( *this );
    789                 }
    790773                output << ";";
    791774
    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 );
    797777                output << ") ";
    798778
     
    814794                        output << ";";
    815795                } // 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;
    816806        }
    817807
Note: See TracChangeset for help on using the changeset viewer.