Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rd104b02 r0dd18fd  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jul 25 15:29:00 2017
    13 // Update Count     : 486
     12// Last Modified On : Fri Aug 18 15:34:00 2017
     13// Update Count     : 488
    1414//
    1515#include "CodeGenerator.h"
     
    7979        }
    8080
    81         CodeGenerator::LineMarker::LineMarker(
    82                         CodeLocation const & loc, bool toPrint) :
    83                 loc(loc), toPrint(toPrint)
    84         {}
    85 
    86         CodeGenerator::LineMarker CodeGenerator::lineDirective(
    87                         BaseSyntaxNode const * node) {
    88                 return LineMarker(node->location, lineMarks);
    89         }
    90 
    91         std::ostream & operator<<(std::ostream & out,
    92                         CodeGenerator::LineMarker const & marker) {
    93                 if (marker.toPrint && marker.loc.isSet()) {
    94                         return out << "\n# " << marker.loc.linenumber << " \""
    95                                 << marker.loc.filename << "\"\n";
    96                 } else if (marker.toPrint) {
    97                         return out << "\n/* Missing CodeLocation */\n";
    98                 } else {
    99                 return out;
     81        /* Using updateLocation at the beginning of a node and nextLine
     82         * within a node should become the method of formating.
     83         */
     84        void CodeGenerator::updateLocation( CodeLocation const & to ) {
     85                if ( !lineMarks ) {
     86                        return;
     87                } else if ( currentLocation.followedBy( to, 0 ) ) {
     88                        return;
     89                } else if ( currentLocation.followedBy( to, 1 ) ) {
     90                        output << "\n" << indent;
     91                        currentLocation.linenumber += 1;
     92                } else if ( currentLocation.followedBy( to, 2 ) ) {
     93                        output << "\n\n" << indent;
     94                        currentLocation.linenumber += 2;
     95                } else {
     96                        output << "\n# " << to.linenumber << " \"" << to.filename
     97                               << "\"\n" << indent;
     98                        currentLocation = to;
     99                }
     100                output << std::flush;
     101        }
     102
     103        void CodeGenerator::updateLocation( BaseSyntaxNode const * to ) {
     104                updateLocation( to->location );
     105        }
     106
     107        void CodeGenerator::nextLine() {
     108                if ( !lineMarks ) {
     109                        output << "\n" << indent << std::flush;
    100110                }
    101111        }
     
    182192                        genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
    183193                        output << ")" << endl;
    184                         output << indent;
    185194                }
    186195
     
    195204                        ++indent;
    196205                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) {
    197                                 output << lineDirective( *i ) << indent;
     206                                updateLocation( *i );
    198207                                (*i)->accept( *this );
    199208                                output << ";" << endl;
     
    218227        void CodeGenerator::visit( EnumDecl * enumDecl ) {
    219228                extension( enumDecl );
    220                 output << lineDirective ( enumDecl );
     229                updateLocation( enumDecl );
    221230                output << "enum ";
    222231                genAttributes( enumDecl->get_attributes() );
     
    234243                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
    235244                                assert( obj );
    236                                 output << lineDirective( obj ) << indent << mangleName( obj );
     245                                updateLocation( obj );
     246                                output << mangleName( obj );
    237247                                if ( obj->get_init() ) {
    238248                                        output << " = ";
     
    252262        void CodeGenerator::visit( TypedefDecl * typeDecl ) {
    253263                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
    254                 output << lineDirective( typeDecl );
     264                updateLocation( typeDecl );
    255265                output << "typedef ";
    256266                output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
     
    322332        void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){
    323333                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 << "}";
     334                // xxx - generate something reasonable for constructor/destructor pairs
     335                output << "<ctorinit>";
    330336        }
    331337
     
    341347                        if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
    342348                                std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
     349                                switch ( opInfo.type ) {
     350                                  case OT_PREFIXASSIGN:
     351                                  case OT_POSTFIXASSIGN:
     352                                  case OT_INFIXASSIGN:
     353                                  case OT_CTOR:
     354                                  case OT_DTOR:
     355                                        {
     356                                                assert( arg != applicationExpr->get_args().end() );
     357                                                if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
     358                                                        // remove & from first assignment/ctor argument
     359                                                        *arg = addrExpr->get_arg();
     360                                                } else {
     361                                                        // no address-of operator, so must be a pointer - add dereference
     362                                                        // NOTE: if the assertion starts to trigger, check that the application expr isn't being shared.
     363                                                        // Since its arguments are modified here, this assertion most commonly triggers when the application
     364                                                        // is visited multiple times.
     365                                                        UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) );
     366                                                        newExpr->get_args().push_back( *arg );
     367                                                        Type * type = InitTweak::getPointerBase( (*arg)->get_result() );
     368                                                        assertf( type, "First argument to a derefence must be a pointer. Ensure that expressions are not being shared." );
     369                                                        newExpr->set_result( type->clone() );
     370                                                        *arg = newExpr;
     371                                                } // if
     372                                                break;
     373                                        }
     374
     375                                  default:
     376                                        // do nothing
     377                                        ;
     378                                } // switch
     379
    343380                                switch ( opInfo.type ) {
    344381                                  case OT_INDEX:
     
    547584                if ( castExpr->get_result()->isVoid() ) {
    548585                        output << "(void)" ;
    549                 } else {
    550                         // at least one result type of cast.
    551                         // Note: previously, lvalue casts were skipped. Since it's now impossible for the user to write
    552                         // an lvalue cast, this has been taken out.
     586                } else if ( ! castExpr->get_result()->get_lvalue() ) {
     587                        // at least one result type of cast, but not an lvalue
    553588                        output << "(";
    554589                        output << genType( castExpr->get_result(), "", pretty, genC );
    555590                        output << ")";
     591                } else {
     592                        // otherwise, the cast is to an lvalue type, so the cast should be dropped, since the result of a cast is
     593                        // never an lvalue in C
    556594                } // if
    557595                castExpr->get_arg()->accept( *this );
     
    668706                extension( commaExpr );
    669707                output << "(";
    670                 if ( genC ) {
    671                         // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.
    672                         commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
    673                 }
    674708                commaExpr->get_arg1()->accept( *this );
    675709                output << " , ";
    676710                commaExpr->get_arg2()->accept( *this );
    677711                output << ")";
    678         }
    679 
    680         void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) {
    681                 assertf( ! genC, "TupleAssignExpr should not reach code generation." );
    682                 tupleExpr->stmtExpr->accept( *this );
    683712        }
    684713
     
    732761        }
    733762
    734         void CodeGenerator::visit( UniqueExpr * unqExpr ) {
    735                 assertf( ! genC, "Unique expressions should not reach code generation." );
    736                 output << "unq<" << unqExpr->get_id() << ">{ ";
    737                 unqExpr->get_expr()->accept( *this );
    738                 output << " }";
    739         }
    740 
    741763        void CodeGenerator::visit( StmtExpr * stmtExpr ) {
    742764                std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    743                 output << lineDirective( stmtExpr) << "({" << std::endl;
     765                updateLocation( stmtExpr );
     766                output << "({" << std::endl;
    744767                ++indent;
    745768                unsigned int numStmts = stmts.size();
    746769                unsigned int i = 0;
    747770                for ( Statement * stmt : stmts ) {
    748                         output << lineDirective( stmt ) << indent;
    749                         output << printLabels( stmt->get_labels() );
     771                        updateLocation( stmt );
     772            output << printLabels( stmt->get_labels() );
    750773                        if ( i+1 == numStmts ) {
    751774                                // last statement in a statement expression needs to be handled specially -
     
    792815        void CodeGenerator::visit( ExprStmt * exprStmt ) {
    793816                assert( exprStmt );
     817                Expression * expr = exprStmt->get_expr();
    794818                if ( genC ) {
    795819                        // cast the top-level expression to void to reduce gcc warnings.
    796                         exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
     820                        expr = new CastExpr( expr );
    797821                }
    798                 exprStmt->get_expr()->accept( *this );
     822                expr->accept( *this );
    799823                output << ";";
    800824        }
     
    832856
    833857        void CodeGenerator::visit( IfStmt * ifStmt ) {
    834                 output << lineDirective( ifStmt );
     858                updateLocation( ifStmt );
    835859                output << "if ( ";
    836860                ifStmt->get_condition()->accept( *this );
     
    846870
    847871        void CodeGenerator::visit( SwitchStmt * switchStmt ) {
    848                 output << lineDirective( switchStmt );
     872                updateLocation( switchStmt );
    849873                output << "switch ( " ;
    850874                switchStmt->get_condition()->accept( *this );
     
    859883
    860884        void CodeGenerator::visit( CaseStmt * caseStmt ) {
    861                 output << lineDirective( caseStmt );
    862                 output << indent;
     885                updateLocation( caseStmt );
    863886                if ( caseStmt->isDefault()) {
    864887                        output << "default";
Note: See TracChangeset for help on using the changeset viewer.