Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r03e5d14 r7baed7d  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 06 15:40:35 2016
    13 // Update Count     : 243
     12// Last Modified On : Fri May 06 16:01:00 2016
     13// Update Count     : 255
    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;
     
    6770        string mangleName( DeclarationWithType *decl ) {
    6871                if ( decl->get_mangleName() != "" ) {
    69                         return decl->get_mangleName();
     72                        // need to incorporate scope level in order to differentiate names for destructors
     73                        return decl->get_scopedMangleName();
    7074                } else {
    7175                        return decl->get_name();
    7276                } // if
    7377        }
     78
     79        void CodeGenerator::genAttributes( std::list< Attribute * > & attributes ) {
     80                if ( ! attributes.empty() ) {
     81                        output << "__attribute__ ((";
     82                        for ( Attribute *& attr : attributes ) {
     83                                if ( ! attr->empty() ) {
     84                                        output << attr->get_name() << "(";
     85                                        genCommaList( attr->get_parameters().begin(), attr->get_parameters().end() );
     86                                        output << ")";
     87                                }
     88                                output << ",";
     89                        }
     90                        output << ")) ";
     91                }
     92        }
     93
    7494
    7595        //*** Declarations
    7696        void CodeGenerator::visit( FunctionDecl *functionDecl ) {
    77                 // generalize this
    78                 FunctionDecl::Attribute attr = functionDecl->get_attribute();
    79                 switch ( attr.type ) {
    80                         case FunctionDecl::Attribute::Constructor:
    81                                 output << "__attribute__ ((constructor";
    82                                 if ( attr.priority != FunctionDecl::Attribute::Default ) {
    83                                         output << "(" << attr.priority << ")";
    84                                 }
    85                                 output << ")) ";
    86                                 break;
    87                         case FunctionDecl::Attribute::Destructor:
    88                                 output << "__attribute__ ((destructor";
    89                                 if ( attr.priority != FunctionDecl::Attribute::Default ) {
    90                                         output << "(" << attr.priority << ")";
    91                                 }
    92                                 output << ")) ";
    93                                 break;
    94                         default:
    95                                 break;
    96                 }
     97                genAttributes( functionDecl->get_attributes() );
     98
    9799                handleStorageClass( functionDecl );
    98100                if ( functionDecl->get_isInline() ) {
     
    233235                printDesignators( init->get_designators() );
    234236                output << "{ ";
    235                 genCommaList( init->begin_initializers(), init->end_initializers() );
     237                if ( init->begin_initializers() == init->end_initializers() ) {
     238                        // illegal to leave initializer list empty for scalar initializers,
     239                        // but always legal to have 0
     240                        output << "0";
     241                } else {
     242                        genCommaList( init->begin_initializers(), init->end_initializers() );
     243                }
    236244                output << " }";
    237245        }
     
    251259                                  case OT_POSTFIXASSIGN:
    252260                                  case OT_INFIXASSIGN:
     261                                  case OT_CTOR:
     262                                  case OT_DTOR:
    253263                                        {
    254264                                                assert( arg != applicationExpr->get_args().end() );
    255265                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    256 
     266                                                        // remove & from first assignment/ctor argument
    257267                                                        *arg = addrExpr->get_arg();
    258268                                                } else {
     269                                                        // no address-of operator, so must be a pointer - add dereference
    259270                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    260271                                                        newExpr->get_args().push_back( *arg );
     272                                                        assert( (*arg)->get_results().size() == 1 );
     273                                                        Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() );
     274                                                        assert( type );
     275                                                        newExpr->get_results().push_back( type );
    261276                                                        *arg = newExpr;
    262277                                                } // if
     
    283298                                        break;
    284299
     300                                  case OT_CTOR:
     301                                  case OT_DTOR:
     302                                        if ( applicationExpr->get_args().size() == 1 ) {
     303                                                // the expression fed into a single parameter constructor or destructor
     304                                                // may contain side effects, so must still output this expression
     305                                                output << "(";
     306                                                (*arg++)->accept( *this );
     307                                                output << ") /* " << opInfo.inputName << " */";
     308                                        } else if ( applicationExpr->get_args().size() == 2 ) {
     309                                                // intrinsic two parameter constructors are essentially bitwise assignment
     310                                                output << "(";
     311                                                (*arg++)->accept( *this );
     312                                                output << opInfo.symbol;
     313                                                (*arg)->accept( *this );
     314                                                output << ") /* " << opInfo.inputName << " */";
     315                                        } else {
     316                                                // no constructors with 0 or more than 2 parameters
     317                                                assert( false );
     318                                        }
     319                                        break;
     320
    285321                                  case OT_PREFIX:
    286322                                  case OT_PREFIXASSIGN:
     
    298334                                        output << opInfo.symbol;
    299335                                        break;
     336
    300337
    301338                                  case OT_INFIX:
     
    344381                                  case OT_CALL:
    345382                                        assert( false );
     383
     384
     385                                  case OT_CTOR:
     386                                  case OT_DTOR:
     387                                        if ( untypedExpr->get_args().size() == 1 ) {
     388                                                // the expression fed into a single parameter constructor or destructor
     389                                                // may contain side effects, so must still output this expression
     390                                                output << "(";
     391                                                (*arg++)->accept( *this );
     392                                                output << ") /* " << opInfo.inputName << " */";
     393                                        } else if ( untypedExpr->get_args().size() == 2 ) {
     394                                                // intrinsic two parameter constructors are essentially bitwise assignment
     395                                                output << "(";
     396                                                (*arg++)->accept( *this );
     397                                                output << opInfo.symbol;
     398                                                (*arg)->accept( *this );
     399                                                output << ") /* " << opInfo.inputName << " */";
     400                                        } else {
     401                                                // no constructors with 0 or more than 2 parameters
     402                                                assert( false );
     403                                        }
    346404                                        break;
    347405
     
    558616
    559617        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    560                 // I don't see why this check is necessary.
    561                 // If this starts to cause problems then put it back in,
    562                 // with an explanation
    563618                assert( exprStmt );
    564 
    565                 // if ( exprStmt != 0 ) {
    566                 exprStmt->get_expr()->accept( *this );
    567                 output << ";" ;
    568                 // } // if
     619                // cast the top-level expression to void to reduce gcc warnings.
     620                Expression * expr = new CastExpr( exprStmt->get_expr() );
     621                expr->accept( *this );
     622                output << ";";
    569623        }
    570624
     
    675729
    676730        void CodeGenerator::visit( WhileStmt *whileStmt ) {
    677                 if ( whileStmt->get_isDoWhile() )
     731                if ( whileStmt->get_isDoWhile() ) {
    678732                        output << "do" ;
    679                 else {
     733                } else {
    680734                        output << "while (" ;
    681735                        whileStmt->get_condition()->accept( *this );
     
    701755                output << "for (;";
    702756
    703                 if ( forStmt->get_condition() != 0 )
     757                if ( forStmt->get_condition() != 0 ) {
    704758                        forStmt->get_condition()->accept( *this );
     759                }
    705760                output << ";";
    706761
    707                 if ( forStmt->get_increment() != 0 )
    708                         forStmt->get_increment()->accept( *this );
     762                if ( forStmt->get_increment() != 0 ) {
     763                        // cast the top-level expression to void to reduce gcc warnings.
     764                        Expression * expr = new CastExpr( forStmt->get_increment() );
     765                        expr->accept( *this );
     766                }
    709767                output << ") ";
    710768
Note: See TracChangeset for help on using the changeset viewer.