Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    re04ef3a r7baed7d  
    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 : Thu Jun  9 13:21:00 2016
    13 // Update Count     : 256
     11// Last Modified By : Rob Schluntz
     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;
     
    7477        }
    7578
     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
     94
    7695        //*** Declarations
    7796        void CodeGenerator::visit( FunctionDecl *functionDecl ) {
    78                 // generalize this
    79                 FunctionDecl::Attribute attr = functionDecl->get_attribute();
    80                 switch ( attr.type ) {
    81                         case FunctionDecl::Attribute::Constructor:
    82                                 output << "__attribute__ ((constructor";
    83                                 if ( attr.priority != FunctionDecl::Attribute::Default ) {
    84                                         output << "(" << attr.priority << ")";
    85                                 }
    86                                 output << ")) ";
    87                                 break;
    88                         case FunctionDecl::Attribute::Destructor:
    89                                 output << "__attribute__ ((destructor";
    90                                 if ( attr.priority != FunctionDecl::Attribute::Default ) {
    91                                         output << "(" << attr.priority << ")";
    92                                 }
    93                                 output << ")) ";
    94                                 break;
    95                         default:
    96                                 break;
    97                 }
     97                genAttributes( functionDecl->get_attributes() );
     98
    9899                handleStorageClass( functionDecl );
    99100                if ( functionDecl->get_isInline() ) {
     
    250251        //*** Expressions
    251252        void CodeGenerator::visit( ApplicationExpr *applicationExpr ) {
    252                 extension( applicationExpr );
    253253                if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
    254254                        OperatorInfo opInfo;
     
    270270                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    271271                                                        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 );
    272276                                                        *arg = newExpr;
    273277                                                } // if
     
    298302                                        if ( applicationExpr->get_args().size() == 1 ) {
    299303                                                // the expression fed into a single parameter constructor or destructor
    300                                                 // may contain side effects - output as a void expression
    301                                                 output << "((void)(";
     304                                                // may contain side effects, so must still output this expression
     305                                                output << "(";
    302306                                                (*arg++)->accept( *this );
    303                                                 output << ")) /* " << opInfo.inputName << " */";
     307                                                output << ") /* " << opInfo.inputName << " */";
    304308                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    305309                                                // intrinsic two parameter constructors are essentially bitwise assignment
     
    362366
    363367        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    364                 extension( untypedExpr );
    365368                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
    366369                        OperatorInfo opInfo;
     
    384387                                        if ( untypedExpr->get_args().size() == 1 ) {
    385388                                                // the expression fed into a single parameter constructor or destructor
    386                                                 // may contain side effects - output as a void expression
    387                                                 output << "((void)(";
     389                                                // may contain side effects, so must still output this expression
     390                                                output << "(";
    388391                                                (*arg++)->accept( *this );
    389                                                 output << ")) /* " << opInfo.inputName << " */";
     392                                                output << ") /* " << opInfo.inputName << " */";
    390393                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    391394                                                // intrinsic two parameter constructors are essentially bitwise assignment
     
    447450
    448451        void CodeGenerator::visit( NameExpr *nameExpr ) {
    449                 extension( nameExpr );
    450452                OperatorInfo opInfo;
    451453                if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
     
    458460
    459461        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    460                 extension( addressExpr );
    461462                output << "(&";
    462463                // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
     
    470471
    471472        void CodeGenerator::visit( CastExpr *castExpr ) {
    472                 extension( castExpr );
    473473                output << "(";
    474474                if ( castExpr->get_results().empty() ) {
     
    493493
    494494        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    495                 extension( memberExpr );
    496495                memberExpr->get_aggregate()->accept( *this );
    497496                output << "." << mangleName( memberExpr->get_member() );
     
    499498
    500499        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    501                 extension( variableExpr );
    502500                OperatorInfo opInfo;
    503501                if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
     
    510508        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    511509                assert( constantExpr->get_constant() );
    512                 extension( constantExpr );
    513510                constantExpr->get_constant()->accept( *this );
    514511        }
    515512
    516513        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    517                 extension( sizeofExpr );
    518514                output << "sizeof(";
    519515                if ( sizeofExpr->get_isType() ) {
     
    526522
    527523        void CodeGenerator::visit( AlignofExpr *alignofExpr ) {
    528                 extension( alignofExpr );
    529524                // use GCC extension to avoid bumping std to C11
    530525                output << "__alignof__(";
     
    542537
    543538        void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) {
    544                 extension( offsetofExpr );
    545539                // use GCC builtin
    546540                output << "__builtin_offsetof(";
     
    555549
    556550        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    557                 extension( logicalExpr );
    558551                output << "(";
    559552                logicalExpr->get_arg1()->accept( *this );
     
    568561
    569562        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    570                 extension( conditionalExpr );
    571563                output << "(";
    572564                conditionalExpr->get_arg1()->accept( *this );
     
    579571
    580572        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    581                 extension( commaExpr );
    582573                output << "(";
    583574                commaExpr->get_arg1()->accept( *this );
     
    592583
    593584        void CodeGenerator::visit( AsmExpr *asmExpr ) {
    594                 extension( asmExpr );
    595585                if ( asmExpr->get_inout() ) {
    596586                        output << "[ ";
     
    626616
    627617        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    628                 // I don't see why this check is necessary.
    629                 // If this starts to cause problems then put it back in,
    630                 // with an explanation
    631618                assert( exprStmt );
    632 
    633                 // if ( exprStmt != 0 ) {
    634                 exprStmt->get_expr()->accept( *this );
    635                 output << ";" ;
    636                 // } // 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 << ";";
    637623        }
    638624
     
    743729
    744730        void CodeGenerator::visit( WhileStmt *whileStmt ) {
    745                 if ( whileStmt->get_isDoWhile() )
     731                if ( whileStmt->get_isDoWhile() ) {
    746732                        output << "do" ;
    747                 else {
     733                } else {
    748734                        output << "while (" ;
    749735                        whileStmt->get_condition()->accept( *this );
     
    769755                output << "for (;";
    770756
    771                 if ( forStmt->get_condition() != 0 )
     757                if ( forStmt->get_condition() != 0 ) {
    772758                        forStmt->get_condition()->accept( *this );
     759                }
    773760                output << ";";
    774761
    775                 if ( forStmt->get_increment() != 0 )
    776                         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                }
    777767                output << ") ";
    778768
Note: See TracChangeset for help on using the changeset viewer.