Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r8a6cf7e ra5f0529  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Jun  8 16:00:00 2017
    13 // Update Count     : 485
     12// Last Modified On : Tus Jul 25 15:29:00 2017
     13// Update Count     : 486
    1414//
     15#include "CodeGenerator.h"
    1516
    1617#include <cassert>                   // for assert, assertf
    1718#include <list>                      // for _List_iterator, list, list<>::it...
    1819
    19 #include "CodeGenerator.h"
    2020#include "Common/SemanticError.h"    // for SemanticError
    2121#include "Common/UniqueName.h"       // for UniqueName
     
    6464        } // extension
    6565
     66        ostream & CodeGenerator::Indenter::operator()( ostream & output ) const {
     67          return output << string( cg.cur_indent, ' ' );
     68        }
     69
     70        ostream & operator<<( ostream & output, const CodeGenerator::Indenter &indent ) {
     71                return indent( output );
     72        }
     73
    6674        CodeGenerator::LabelPrinter & CodeGenerator::LabelPrinter::operator()( std::list< Label > & l ) {
    6775                labels = &l;
     
    101109        }
    102110
    103         CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
     111        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
    104112
    105113        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
     
    182190                        genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
    183191                        output << ")" << endl;
    184                         output << indent;
    185192                }
    186193
     
    193200                        output << " {" << endl;
    194201
    195                         ++indent;
     202                        cur_indent += CodeGenerator::tabsize;
    196203                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) {
    197204                                output << lineDirective( *i ) << indent;
     
    200207                        } // for
    201208
    202                         --indent;
     209                        cur_indent -= CodeGenerator::tabsize;
    203210
    204211                        output << indent << "}";
     
    230237                        output << " {" << endl;
    231238
    232                         ++indent;
     239                        cur_indent += CodeGenerator::tabsize;
    233240                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    234241                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
     
    242249                        } // for
    243250
    244                         --indent;
     251                        cur_indent -= CodeGenerator::tabsize;
    245252
    246253                        output << indent << "}";
     
    322329        void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){
    323330                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 << "}";
     331                // xxx - generate something reasonable for constructor/destructor pairs
     332                output << "<ctorinit>";
    330333        }
    331334
     
    341344                        if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
    342345                                std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
     346                                switch ( opInfo.type ) {
     347                                  case OT_PREFIXASSIGN:
     348                                  case OT_POSTFIXASSIGN:
     349                                  case OT_INFIXASSIGN:
     350                                  case OT_CTOR:
     351                                  case OT_DTOR:
     352                                        {
     353                                                assert( arg != applicationExpr->get_args().end() );
     354                                                if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
     355                                                        // remove & from first assignment/ctor argument
     356                                                        *arg = addrExpr->get_arg();
     357                                                } else {
     358                                                        // no address-of operator, so must be a pointer - add dereference
     359                                                        // NOTE: if the assertion starts to trigger, check that the application expr isn't being shared.
     360                                                        // Since its arguments are modified here, this assertion most commonly triggers when the application
     361                                                        // is visited multiple times.
     362                                                        UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) );
     363                                                        newExpr->get_args().push_back( *arg );
     364                                                        Type * type = InitTweak::getPointerBase( (*arg)->get_result() );
     365                                                        assertf( type, "First argument to a derefence must be a pointer. Ensure that expressions are not being shared." );
     366                                                        newExpr->set_result( type->clone() );
     367                                                        *arg = newExpr;
     368                                                } // if
     369                                                break;
     370                                        }
     371
     372                                  default:
     373                                        // do nothing
     374                                        ;
     375                                } // switch
     376
    343377                                switch ( opInfo.type ) {
    344378                                  case OT_INDEX:
     
    560594        }
    561595
     596        void CodeGenerator::visit( VirtualCastExpr * castExpr ) {
     597                assertf( ! genC, "VirtualCastExpr should not reach code generation." );
     598                extension( castExpr );
     599                output << "(virtual ";
     600                castExpr->get_arg()->accept( *this );
     601                output << ")";
     602        }
     603
    562604        void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
    563605                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
     
    661703                extension( commaExpr );
    662704                output << "(";
    663                 if ( genC ) {
    664                         // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.
    665                         commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
    666                 }
    667705                commaExpr->get_arg1()->accept( *this );
    668706                output << " , ";
     
    723761                std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    724762                output << lineDirective( stmtExpr) << "({" << std::endl;
    725                 ++indent;
     763                cur_indent += CodeGenerator::tabsize;
    726764                unsigned int numStmts = stmts.size();
    727765                unsigned int i = 0;
    728766                for ( Statement * stmt : stmts ) {
    729767                        output << lineDirective( stmt ) << indent;
    730                         output << printLabels( stmt->get_labels() );
     768            output << printLabels( stmt->get_labels() );
    731769                        if ( i+1 == numStmts ) {
    732770                                // last statement in a statement expression needs to be handled specially -
     
    746784                        ++i;
    747785                }
    748                 --indent;
     786                cur_indent -= CodeGenerator::tabsize;
    749787                output << indent << "})";
    750788        }
     
    755793                output << "{" << endl;
    756794
    757                 ++indent;
     795                cur_indent += CodeGenerator::tabsize;
    758796
    759797                for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++ ) {
     
    766804                        } // if
    767805                } // for
    768                 --indent;
     806                cur_indent -= CodeGenerator::tabsize;
    769807
    770808                output << indent << "}";
     
    773811        void CodeGenerator::visit( ExprStmt * exprStmt ) {
    774812                assert( exprStmt );
     813                Expression * expr = exprStmt->get_expr();
    775814                if ( genC ) {
    776815                        // cast the top-level expression to void to reduce gcc warnings.
    777                         exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
     816                        expr = new CastExpr( expr );
    778817                }
    779                 exprStmt->get_expr()->accept( *this );
     818                expr->accept( *this );
    780819                output << ";";
    781820        }
     
    833872
    834873                output << "{" << std::endl;
    835                 ++indent;
     874                cur_indent += CodeGenerator::tabsize;
    836875                acceptAll( switchStmt->get_statements(), *this );
    837                 --indent;
     876                cur_indent -= CodeGenerator::tabsize;
    838877                output << indent << "}";
    839878        }
     
    852891                std::list<Statement *> sts = caseStmt->get_statements();
    853892
    854                 ++indent;
     893                cur_indent += CodeGenerator::tabsize;
    855894                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    856895                        output << indent << printLabels( (*i)->get_labels() )  ;
     
    858897                        output << endl;
    859898                } // for
    860                 --indent;
     899                cur_indent -= CodeGenerator::tabsize;
    861900        }
    862901
Note: See TracChangeset for help on using the changeset viewer.