Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rafc1045 r356189a  
    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
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:32:16 2016
    13 // Update Count     : 243
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 17:10:21 2016
     13// Update Count     : 255
    1414//
    1515
     
    6767        string mangleName( DeclarationWithType *decl ) {
    6868                if ( decl->get_mangleName() != "" ) {
    69                         return decl->get_mangleName();
     69                        // need to incorporate scope level in order to differentiate names for destructors
     70                        return decl->get_scopedMangleName();
    7071                } else {
    7172                        return decl->get_name();
     
    99100                handleStorageClass( objectDecl );
    100101                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    101        
     102
    102103                if ( objectDecl->get_init() ) {
    103104                        output << " = ";
     
    113114                if ( aggDecl->get_name() != "" )
    114115                        output << aggDecl->get_name();
    115        
     116
    116117                std::list< Declaration * > &memb = aggDecl->get_members();
    117118
     
    119120                        output << " {" << endl;
    120121
    121                         cur_indent += CodeGenerator::tabsize; 
     122                        cur_indent += CodeGenerator::tabsize;
    122123                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    123                                 output << indent; 
     124                                output << indent;
    124125                                (*i)->accept( *this );
    125126                                output << ";" << endl;
    126127                        }
    127128
    128                         cur_indent -= CodeGenerator::tabsize; 
     129                        cur_indent -= CodeGenerator::tabsize;
    129130
    130131                        output << indent << "}";
     
    141142                handleAggregate( aggregateDecl );
    142143        }
    143  
     144
    144145        void CodeGenerator::visit( EnumDecl *aggDecl ) {
    145146                output << "enum ";
     
    147148                if ( aggDecl->get_name() != "" )
    148149                        output << aggDecl->get_name();
    149        
     150
    150151                std::list< Declaration* > &memb = aggDecl->get_members();
    151152
     
    153154                        output << " {" << endl;
    154155
    155                         cur_indent += CodeGenerator::tabsize; 
     156                        cur_indent += CodeGenerator::tabsize;
    156157                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    157158                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    158159                                assert( obj );
    159                                 output << indent << mangleName( obj ); 
     160                                output << indent << mangleName( obj );
    160161                                if ( obj->get_init() ) {
    161162                                        output << " = ";
     
    165166                        } // for
    166167
    167                         cur_indent -= CodeGenerator::tabsize; 
     168                        cur_indent -= CodeGenerator::tabsize;
    168169
    169170                        output << indent << "}";
    170171                } // if
    171172        }
    172  
     173
    173174        void CodeGenerator::visit( TraitDecl *aggregateDecl ) {}
    174  
     175
    175176        void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    176177                output << "typedef ";
    177178                output << genType( typeDecl->get_base(), typeDecl->get_name() );
    178179        }
    179  
     180
    180181        void CodeGenerator::visit( TypeDecl *typeDecl ) {
    181182                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     
    213214                printDesignators( init->get_designators() );
    214215                output << "{ ";
    215                 genCommaList( init->begin_initializers(), init->end_initializers() );
     216                if ( init->begin_initializers() == init->end_initializers() ) {
     217                        // illegal to leave initializer list empty for scalar initializers,
     218                        // but always legal to have 0
     219                        output << "0";
     220                } else {
     221                        genCommaList( init->begin_initializers(), init->end_initializers() );
     222                }
    216223                output << " }";
    217224        }
    218225
    219         void CodeGenerator::visit( Constant *constant ) { 
     226        void CodeGenerator::visit( Constant *constant ) {
    220227                output << constant->get_value() ;
    221228        }
     
    231238                                  case OT_POSTFIXASSIGN:
    232239                                  case OT_INFIXASSIGN:
     240                                  case OT_CTOR:
    233241                                        {
    234242                                                assert( arg != applicationExpr->get_args().end() );
    235243                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    236                
     244                                                        // remove & from first assignment/ctor argument
    237245                                                        *arg = addrExpr->get_arg();
    238246                                                } else {
     247                                                        // no address-of operator, so must be a pointer - add dereference
    239248                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    240249                                                        newExpr->get_args().push_back( *arg );
     
    243252                                                break;
    244253                                        }
    245              
     254
    246255                                  default:
    247256                                        // do nothing
    248257                                        ;
    249258                                }
    250            
     259
    251260                                switch ( opInfo.type ) {
    252261                                  case OT_INDEX:
     
    257266                                        output << "]";
    258267                                        break;
    259              
     268
    260269                                  case OT_CALL:
    261270                                        // there are no intrinsic definitions of the function call operator
    262271                                        assert( false );
    263272                                        break;
    264              
     273
     274                                  case OT_CTOR:
     275                                        if ( applicationExpr->get_args().size() == 1 ) {
     276                                                // the expression fed into a single parameter constructor may contain
     277                                                // side effects - output as a void expression
     278                                                output << "((void)(";
     279                                                (*arg++)->accept( *this );
     280                                                output << ")) /* ?{} */";
     281                                        } else if ( applicationExpr->get_args().size() == 2 ) {
     282                                                // intrinsic constructors are essentially bitwise assignment
     283                                                output << "(";
     284                                                (*arg++)->accept( *this );
     285                                                output << opInfo.symbol;
     286                                                (*arg)->accept( *this );
     287                                                output << ") /* ?{} */";
     288                                        } else {
     289                                                // not constructors with 0 or more than 2 parameters
     290                                                assert( false );
     291                                        }
     292                                        break;
     293
     294                                  case OT_DTOR:
     295                                  // intrinsic destructors do nothing - don't generate any code
     296                                  output << " /* " << dynamic_cast<VariableExpr*>(applicationExpr->get_function())->get_var()->get_name() << " */";
     297                                  break;
     298
    265299                                  case OT_PREFIX:
    266300                                  case OT_PREFIXASSIGN:
     
    271305                                        output << ")";
    272306                                        break;
    273              
     307
    274308                                  case OT_POSTFIX:
    275309                                  case OT_POSTFIXASSIGN:
     
    278312                                        output << opInfo.symbol;
    279313                                        break;
     314
    280315
    281316                                  case OT_INFIX:
     
    288323                                        output << ")";
    289324                                        break;
    290              
     325
    291326                                  case OT_CONSTANT:
    292327                                  case OT_LABELADDRESS:
     
    307342                } // if
    308343        }
    309  
     344
    310345        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    311346                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    321356                                        output << "]";
    322357                                        break;
    323              
     358
    324359                                  case OT_CALL:
    325360                                        assert( false );
    326                                         break;
    327              
     361
     362                                        case OT_CTOR:
     363                                        case OT_DTOR:
     364                                        // intrinsic constructors should never be called
     365                                        // intrinsic destructors do nothing
     366                                        break;
     367
    328368                                  case OT_PREFIX:
    329369                                  case OT_PREFIXASSIGN:
     
    335375                                        output << ")";
    336376                                        break;
    337              
     377
    338378                                  case OT_POSTFIX:
    339379                                  case OT_POSTFIXASSIGN:
     
    342382                                        output << opInfo.symbol;
    343383                                        break;
    344  
     384
    345385                                  case OT_INFIX:
    346386                                  case OT_INFIXASSIGN:
     
    352392                                        output << ")";
    353393                                        break;
    354                                        
     394
    355395                                  case OT_CONSTANT:
    356396                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    370410                } // if
    371411        }
    372  
     412
    373413        void CodeGenerator::visit( NameExpr *nameExpr ) {
    374414                OperatorInfo opInfo;
     
    380420                } // if
    381421        }
    382  
     422
    383423        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    384424                output << "(&";
     
    409449                output << ")";
    410450        }
    411  
     451
    412452        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    413453                assert( false );
    414454        }
    415  
     455
    416456        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    417457                memberExpr->get_aggregate()->accept( *this );
    418458                output << "." << mangleName( memberExpr->get_member() );
    419459        }
    420  
     460
    421461        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    422462                OperatorInfo opInfo;
     
    427467                } // if
    428468        }
    429  
     469
    430470        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    431471                assert( constantExpr->get_constant() );
    432472                constantExpr->get_constant()->accept( *this );
    433473        }
    434  
     474
    435475        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    436476                output << "sizeof(";
     
    469509                assert( false && "OffsetPackExpr should not reach code generation" );
    470510        }
    471  
     511
    472512        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    473513                output << "(";
     
    481521                output << ")";
    482522        }
    483  
     523
    484524        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    485525                output << "(";
     
    491531                output << ")";
    492532        }
    493  
     533
    494534        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    495535                output << "(";
     
    499539                output << ")";
    500540        }
    501  
     541
    502542        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    503  
     543
    504544        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    505545
     
    532572                        }
    533573                }
    534                 cur_indent -= CodeGenerator::tabsize; 
     574                cur_indent -= CodeGenerator::tabsize;
    535575
    536576                output << indent << "}";
     
    538578
    539579        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, 
     580                // I don't see why this check is necessary.
     581                // If this starts to cause problems then put it back in,
    542582                // with an explanation
    543583                assert( exprStmt );
     
    589629                switchStmt->get_condition()->accept( *this );
    590630                output << " ) ";
    591                
     631
    592632                output << "{" << std::endl;
    593633                cur_indent += CodeGenerator::tabsize;
     
    609649                } // if
    610650                output << ":\n";
    611                
     651
    612652                std::list<Statement *> sts = caseStmt->get_statements();
    613653
     
    626666                        if ( ! branchStmt->get_target().empty() )
    627667                                output << "goto " << branchStmt->get_target();
    628                         else { 
     668                        else {
    629669                                if ( branchStmt->get_computedTarget() != 0 ) {
    630670                                        output << "goto *";
     
    677717
    678718        void CodeGenerator::visit( ForStmt *forStmt ) {
    679                 // initialization is always hoisted, so don't 
    680                 // bother doing anything with that 
     719                // initialization is always hoisted, so don't
     720                // bother doing anything with that
    681721                output << "for (;";
    682722
     
    702742        void CodeGenerator::visit( DeclStmt *declStmt ) {
    703743                declStmt->get_decl()->accept( *this );
    704        
     744
    705745                if ( doSemicolon( declStmt->get_decl() ) ) {
    706746                        output << ";";
Note: See TracChangeset for help on using the changeset viewer.