Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rafc1045 r4b2589a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator.cc -- 
     7// CodeGenerator.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:32:16 2016
    13 // Update Count     : 243
     12// Last Modified On : Thu Jun  9 13:21:00 2016
     13// Update Count     : 256
    1414//
    1515
     
    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        }
     
    6785        string mangleName( DeclarationWithType *decl ) {
    6886                if ( decl->get_mangleName() != "" ) {
    69                         return decl->get_mangleName();
     87                        // need to incorporate scope level in order to differentiate names for destructors
     88                        return decl->get_scopedMangleName();
    7089                } else {
    7190                        return decl->get_name();
    7291                } // if
    7392        }
     93
     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
    74109
    75110        //*** Declarations
    76111        void CodeGenerator::visit( FunctionDecl *functionDecl ) {
     112                genAttributes( functionDecl->get_attributes() );
     113
    77114                handleStorageClass( functionDecl );
    78115                if ( functionDecl->get_isInline() ) {
     
    99136                handleStorageClass( objectDecl );
    100137                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    101        
     138
    102139                if ( objectDecl->get_init() ) {
    103140                        output << " = ";
     
    113150                if ( aggDecl->get_name() != "" )
    114151                        output << aggDecl->get_name();
    115        
     152
    116153                std::list< Declaration * > &memb = aggDecl->get_members();
    117154
     
    119156                        output << " {" << endl;
    120157
    121                         cur_indent += CodeGenerator::tabsize; 
     158                        cur_indent += CodeGenerator::tabsize;
    122159                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    123                                 output << indent; 
     160                                output << indent;
    124161                                (*i)->accept( *this );
    125162                                output << ";" << endl;
    126163                        }
    127164
    128                         cur_indent -= CodeGenerator::tabsize; 
     165                        cur_indent -= CodeGenerator::tabsize;
    129166
    130167                        output << indent << "}";
     
    141178                handleAggregate( aggregateDecl );
    142179        }
    143  
     180
    144181        void CodeGenerator::visit( EnumDecl *aggDecl ) {
    145182                output << "enum ";
     
    147184                if ( aggDecl->get_name() != "" )
    148185                        output << aggDecl->get_name();
    149        
     186
    150187                std::list< Declaration* > &memb = aggDecl->get_members();
    151188
     
    153190                        output << " {" << endl;
    154191
    155                         cur_indent += CodeGenerator::tabsize; 
     192                        cur_indent += CodeGenerator::tabsize;
    156193                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    157194                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    158195                                assert( obj );
    159                                 output << indent << mangleName( obj ); 
     196                                output << indent << mangleName( obj );
    160197                                if ( obj->get_init() ) {
    161198                                        output << " = ";
     
    165202                        } // for
    166203
    167                         cur_indent -= CodeGenerator::tabsize; 
     204                        cur_indent -= CodeGenerator::tabsize;
    168205
    169206                        output << indent << "}";
    170207                } // if
    171208        }
    172  
     209
    173210        void CodeGenerator::visit( TraitDecl *aggregateDecl ) {}
    174  
     211
    175212        void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    176213                output << "typedef ";
    177214                output << genType( typeDecl->get_base(), typeDecl->get_name() );
    178215        }
    179  
     216
    180217        void CodeGenerator::visit( TypeDecl *typeDecl ) {
    181218                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     
    213250                printDesignators( init->get_designators() );
    214251                output << "{ ";
    215                 genCommaList( init->begin_initializers(), init->end_initializers() );
     252                if ( init->begin_initializers() == init->end_initializers() ) {
     253                        // illegal to leave initializer list empty for scalar initializers,
     254                        // but always legal to have 0
     255                        output << "0";
     256                } else {
     257                        genCommaList( init->begin_initializers(), init->end_initializers() );
     258                }
    216259                output << " }";
    217260        }
    218261
    219         void CodeGenerator::visit( Constant *constant ) { 
     262        void CodeGenerator::visit( Constant *constant ) {
    220263                output << constant->get_value() ;
    221264        }
     
    223266        //*** Expressions
    224267        void CodeGenerator::visit( ApplicationExpr *applicationExpr ) {
     268                extension( applicationExpr );
    225269                if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
    226270                        OperatorInfo opInfo;
     
    231275                                  case OT_POSTFIXASSIGN:
    232276                                  case OT_INFIXASSIGN:
     277                                  case OT_CTOR:
     278                                  case OT_DTOR:
    233279                                        {
    234280                                                assert( arg != applicationExpr->get_args().end() );
    235281                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    236                
     282                                                        // remove & from first assignment/ctor argument
    237283                                                        *arg = addrExpr->get_arg();
    238284                                                } else {
     285                                                        // no address-of operator, so must be a pointer - add dereference
    239286                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    240287                                                        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 );
    241292                                                        *arg = newExpr;
    242293                                                } // if
    243294                                                break;
    244295                                        }
    245              
     296
    246297                                  default:
    247298                                        // do nothing
    248299                                        ;
    249300                                }
    250            
     301
    251302                                switch ( opInfo.type ) {
    252303                                  case OT_INDEX:
     
    257308                                        output << "]";
    258309                                        break;
    259              
     310
    260311                                  case OT_CALL:
    261312                                        // there are no intrinsic definitions of the function call operator
    262313                                        assert( false );
    263314                                        break;
    264              
     315
     316                                  case OT_CTOR:
     317                                  case OT_DTOR:
     318                                        if ( applicationExpr->get_args().size() == 1 ) {
     319                                                // the expression fed into a single parameter constructor or destructor
     320                                                // may contain side effects, so must still output this expression
     321                                                output << "(";
     322                                                (*arg++)->accept( *this );
     323                                                output << ") /* " << opInfo.inputName << " */";
     324                                        } else if ( applicationExpr->get_args().size() == 2 ) {
     325                                                // intrinsic two parameter constructors are essentially bitwise assignment
     326                                                output << "(";
     327                                                (*arg++)->accept( *this );
     328                                                output << opInfo.symbol;
     329                                                (*arg)->accept( *this );
     330                                                output << ") /* " << opInfo.inputName << " */";
     331                                        } else {
     332                                                // no constructors with 0 or more than 2 parameters
     333                                                assert( false );
     334                                        }
     335                                        break;
     336
    265337                                  case OT_PREFIX:
    266338                                  case OT_PREFIXASSIGN:
     
    271343                                        output << ")";
    272344                                        break;
    273              
     345
    274346                                  case OT_POSTFIX:
    275347                                  case OT_POSTFIXASSIGN:
     
    278350                                        output << opInfo.symbol;
    279351                                        break;
     352
    280353
    281354                                  case OT_INFIX:
     
    288361                                        output << ")";
    289362                                        break;
    290              
     363
    291364                                  case OT_CONSTANT:
    292365                                  case OT_LABELADDRESS:
     
    307380                } // if
    308381        }
    309  
     382
    310383        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
     384                extension( untypedExpr );
    311385                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
    312386                        OperatorInfo opInfo;
     
    321395                                        output << "]";
    322396                                        break;
    323              
     397
    324398                                  case OT_CALL:
    325399                                        assert( false );
    326                                         break;
    327              
     400
     401
     402                                  case OT_CTOR:
     403                                  case OT_DTOR:
     404                                        if ( untypedExpr->get_args().size() == 1 ) {
     405                                                // the expression fed into a single parameter constructor or destructor
     406                                                // may contain side effects, so must still output this expression
     407                                                output << "(";
     408                                                (*arg++)->accept( *this );
     409                                                output << ") /* " << opInfo.inputName << " */";
     410                                        } else if ( untypedExpr->get_args().size() == 2 ) {
     411                                                // intrinsic two parameter constructors are essentially bitwise assignment
     412                                                output << "(";
     413                                                (*arg++)->accept( *this );
     414                                                output << opInfo.symbol;
     415                                                (*arg)->accept( *this );
     416                                                output << ") /* " << opInfo.inputName << " */";
     417                                        } else {
     418                                                // no constructors with 0 or more than 2 parameters
     419                                                assert( false );
     420                                        }
     421                                        break;
     422
    328423                                  case OT_PREFIX:
    329424                                  case OT_PREFIXASSIGN:
     
    335430                                        output << ")";
    336431                                        break;
    337              
     432
    338433                                  case OT_POSTFIX:
    339434                                  case OT_POSTFIXASSIGN:
     
    342437                                        output << opInfo.symbol;
    343438                                        break;
    344  
     439
    345440                                  case OT_INFIX:
    346441                                  case OT_INFIXASSIGN:
     
    352447                                        output << ")";
    353448                                        break;
    354                                        
     449
    355450                                  case OT_CONSTANT:
    356451                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    370465                } // if
    371466        }
    372  
     467
    373468        void CodeGenerator::visit( NameExpr *nameExpr ) {
     469                extension( nameExpr );
    374470                OperatorInfo opInfo;
    375471                if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
     
    380476                } // if
    381477        }
    382  
     478
    383479        void CodeGenerator::visit( AddressExpr *addressExpr ) {
     480                extension( addressExpr );
    384481                output << "(&";
    385482                // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
     
    393490
    394491        void CodeGenerator::visit( CastExpr *castExpr ) {
     492                extension( castExpr );
    395493                output << "(";
    396494                if ( castExpr->get_results().empty() ) {
     
    409507                output << ")";
    410508        }
    411  
     509
    412510        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    413511                assert( false );
    414512        }
    415  
     513
    416514        void CodeGenerator::visit( MemberExpr *memberExpr ) {
     515                extension( memberExpr );
    417516                memberExpr->get_aggregate()->accept( *this );
    418517                output << "." << mangleName( memberExpr->get_member() );
    419518        }
    420  
     519
    421520        void CodeGenerator::visit( VariableExpr *variableExpr ) {
     521                extension( variableExpr );
    422522                OperatorInfo opInfo;
    423523                if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
     
    427527                } // if
    428528        }
    429  
     529
    430530        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    431531                assert( constantExpr->get_constant() );
     532                extension( constantExpr );
    432533                constantExpr->get_constant()->accept( *this );
    433534        }
    434  
     535
    435536        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
     537                extension( sizeofExpr );
    436538                output << "sizeof(";
    437539                if ( sizeofExpr->get_isType() ) {
     
    444546
    445547        void CodeGenerator::visit( AlignofExpr *alignofExpr ) {
     548                extension( alignofExpr );
    446549                // use GCC extension to avoid bumping std to C11
    447550                output << "__alignof__(";
     
    459562
    460563        void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) {
     564                extension( offsetofExpr );
    461565                // use GCC builtin
    462566                output << "__builtin_offsetof(";
     
    469573                assert( false && "OffsetPackExpr should not reach code generation" );
    470574        }
    471  
     575
    472576        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
     577                extension( logicalExpr );
    473578                output << "(";
    474579                logicalExpr->get_arg1()->accept( *this );
     
    481586                output << ")";
    482587        }
    483  
     588
    484589        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
     590                extension( conditionalExpr );
    485591                output << "(";
    486592                conditionalExpr->get_arg1()->accept( *this );
     
    491597                output << ")";
    492598        }
    493  
     599
    494600        void CodeGenerator::visit( CommaExpr *commaExpr ) {
     601                extension( commaExpr );
    495602                output << "(";
    496603                commaExpr->get_arg1()->accept( *this );
     
    499606                output << ")";
    500607        }
    501  
     608
    502609        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    503  
     610
    504611        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    505612
    506613        void CodeGenerator::visit( AsmExpr *asmExpr ) {
     614                extension( asmExpr );
    507615                if ( asmExpr->get_inout() ) {
    508616                        output << "[ ";
     
    532640                        }
    533641                }
    534                 cur_indent -= CodeGenerator::tabsize; 
     642                cur_indent -= CodeGenerator::tabsize;
    535643
    536644                output << indent << "}";
     
    538646
    539647        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    540                 // I don't see why this check is necessary.
    541                 // If this starts to cause problems then put it back in,
    542                 // with an explanation
    543648                assert( exprStmt );
    544 
    545                 // if ( exprStmt != 0 ) {
    546                 exprStmt->get_expr()->accept( *this );
    547                 output << ";" ;
    548                 // } // 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 << ";";
    549653        }
    550654
     
    589693                switchStmt->get_condition()->accept( *this );
    590694                output << " ) ";
    591                
     695
    592696                output << "{" << std::endl;
    593697                cur_indent += CodeGenerator::tabsize;
     
    609713                } // if
    610714                output << ":\n";
    611                
     715
    612716                std::list<Statement *> sts = caseStmt->get_statements();
    613717
     
    626730                        if ( ! branchStmt->get_target().empty() )
    627731                                output << "goto " << branchStmt->get_target();
    628                         else { 
     732                        else {
    629733                                if ( branchStmt->get_computedTarget() != 0 ) {
    630734                                        output << "goto *";
     
    646750        void CodeGenerator::visit( ReturnStmt *returnStmt ) {
    647751                output << "return ";
    648 
    649                 // xxx -- check for null expression;
    650                 if ( returnStmt->get_expr() ) {
    651                         returnStmt->get_expr()->accept( *this );
    652                 } // if
     752                maybeAccept( returnStmt->get_expr(), *this );
    653753                output << ";";
    654754        }
    655755
    656756        void CodeGenerator::visit( WhileStmt *whileStmt ) {
    657                 if ( whileStmt->get_isDoWhile() )
     757                if ( whileStmt->get_isDoWhile() ) {
    658758                        output << "do" ;
    659                 else {
     759                } else {
    660760                        output << "while (" ;
    661761                        whileStmt->get_condition()->accept( *this );
     
    677777
    678778        void CodeGenerator::visit( ForStmt *forStmt ) {
    679                 // initialization is always hoisted, so don't 
    680                 // bother doing anything with that 
     779                // initialization is always hoisted, so don't
     780                // bother doing anything with that
    681781                output << "for (;";
    682782
    683                 if ( forStmt->get_condition() != 0 )
     783                if ( forStmt->get_condition() != 0 ) {
    684784                        forStmt->get_condition()->accept( *this );
     785                }
    685786                output << ";";
    686787
    687                 if ( forStmt->get_increment() != 0 )
    688                         forStmt->get_increment()->accept( *this );
     788                if ( forStmt->get_increment() != 0 ) {
     789                        // cast the top-level expression to void to reduce gcc warnings.
     790                        Expression * expr = new CastExpr( forStmt->get_increment() );
     791                        expr->accept( *this );
     792                }
    689793                output << ") ";
    690794
     
    702806        void CodeGenerator::visit( DeclStmt *declStmt ) {
    703807                declStmt->get_decl()->accept( *this );
    704        
     808
    705809                if ( doSemicolon( declStmt->get_decl() ) ) {
    706810                        output << ";";
    707811                } // if
    708         }
    709 
    710         std::string CodeGenerator::printLabels( std::list< Label > &l ) {
    711                 std::string str( "" );
    712                 l.unique(); // assumes a sorted list. Why not use set?
    713 
    714                 for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ )
    715                         str += *i + ": ";
    716 
    717                 return str;
    718812        }
    719813
Note: See TracChangeset for help on using the changeset viewer.