Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r0dd18fd rd104b02  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 18 15:34:00 2017
    13 // Update Count     : 488
     12// Last Modified On : Tus Jul 25 15:29:00 2017
     13// Update Count     : 486
    1414//
    1515#include "CodeGenerator.h"
     
    7979        }
    8080
    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;
     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;
    110100                }
    111101        }
     
    192182                        genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
    193183                        output << ")" << endl;
     184                        output << indent;
    194185                }
    195186
     
    204195                        ++indent;
    205196                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) {
    206                                 updateLocation( *i );
     197                                output << lineDirective( *i ) << indent;
    207198                                (*i)->accept( *this );
    208199                                output << ";" << endl;
     
    227218        void CodeGenerator::visit( EnumDecl * enumDecl ) {
    228219                extension( enumDecl );
    229                 updateLocation( enumDecl );
     220                output << lineDirective ( enumDecl );
    230221                output << "enum ";
    231222                genAttributes( enumDecl->get_attributes() );
     
    243234                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
    244235                                assert( obj );
    245                                 updateLocation( obj );
    246                                 output << mangleName( obj );
     236                                output << lineDirective( obj ) << indent << mangleName( obj );
    247237                                if ( obj->get_init() ) {
    248238                                        output << " = ";
     
    262252        void CodeGenerator::visit( TypedefDecl * typeDecl ) {
    263253                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
    264                 updateLocation( typeDecl );
     254                output << lineDirective( typeDecl );
    265255                output << "typedef ";
    266256                output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
     
    332322        void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){
    333323                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
    334                 // xxx - generate something reasonable for constructor/destructor pairs
    335                 output << "<ctorinit>";
     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 << "}";
    336330        }
    337331
     
    347341                        if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
    348342                                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 
    380343                                switch ( opInfo.type ) {
    381344                                  case OT_INDEX:
     
    584547                if ( castExpr->get_result()->isVoid() ) {
    585548                        output << "(void)" ;
    586                 } else if ( ! castExpr->get_result()->get_lvalue() ) {
    587                         // at least one result type of cast, but not an lvalue
     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.
    588553                        output << "(";
    589554                        output << genType( castExpr->get_result(), "", pretty, genC );
    590555                        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
    594556                } // if
    595557                castExpr->get_arg()->accept( *this );
     
    706668                extension( commaExpr );
    707669                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                }
    708674                commaExpr->get_arg1()->accept( *this );
    709675                output << " , ";
    710676                commaExpr->get_arg2()->accept( *this );
    711677                output << ")";
     678        }
     679
     680        void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) {
     681                assertf( ! genC, "TupleAssignExpr should not reach code generation." );
     682                tupleExpr->stmtExpr->accept( *this );
    712683        }
    713684
     
    761732        }
    762733
     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
    763741        void CodeGenerator::visit( StmtExpr * stmtExpr ) {
    764742                std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    765                 updateLocation( stmtExpr );
    766                 output << "({" << std::endl;
     743                output << lineDirective( stmtExpr) << "({" << std::endl;
    767744                ++indent;
    768745                unsigned int numStmts = stmts.size();
    769746                unsigned int i = 0;
    770747                for ( Statement * stmt : stmts ) {
    771                         updateLocation( stmt );
    772             output << printLabels( stmt->get_labels() );
     748                        output << lineDirective( stmt ) << indent;
     749                        output << printLabels( stmt->get_labels() );
    773750                        if ( i+1 == numStmts ) {
    774751                                // last statement in a statement expression needs to be handled specially -
     
    815792        void CodeGenerator::visit( ExprStmt * exprStmt ) {
    816793                assert( exprStmt );
    817                 Expression * expr = exprStmt->get_expr();
    818794                if ( genC ) {
    819795                        // cast the top-level expression to void to reduce gcc warnings.
    820                         expr = new CastExpr( expr );
     796                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
    821797                }
    822                 expr->accept( *this );
     798                exprStmt->get_expr()->accept( *this );
    823799                output << ";";
    824800        }
     
    856832
    857833        void CodeGenerator::visit( IfStmt * ifStmt ) {
    858                 updateLocation( ifStmt );
     834                output << lineDirective( ifStmt );
    859835                output << "if ( ";
    860836                ifStmt->get_condition()->accept( *this );
     
    870846
    871847        void CodeGenerator::visit( SwitchStmt * switchStmt ) {
    872                 updateLocation( switchStmt );
     848                output << lineDirective( switchStmt );
    873849                output << "switch ( " ;
    874850                switchStmt->get_condition()->accept( *this );
     
    883859
    884860        void CodeGenerator::visit( CaseStmt * caseStmt ) {
    885                 updateLocation( caseStmt );
     861                output << lineDirective( caseStmt );
     862                output << indent;
    886863                if ( caseStmt->isDefault()) {
    887864                        output << "default";
Note: See TracChangeset for help on using the changeset viewer.