Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r03e5d14 r10a7775  
    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
     
    3434#include "GenType.h"
    3535
     36#include "InitTweak/InitTweak.h"
     37
    3638using namespace std;
    3739
     
    6769        string mangleName( DeclarationWithType *decl ) {
    6870                if ( decl->get_mangleName() != "" ) {
    69                         return decl->get_mangleName();
     71                        // need to incorporate scope level in order to differentiate names for destructors
     72                        return decl->get_scopedMangleName();
    7073                } else {
    7174                        return decl->get_name();
     
    233236                printDesignators( init->get_designators() );
    234237                output << "{ ";
    235                 genCommaList( init->begin_initializers(), init->end_initializers() );
     238                if ( init->begin_initializers() == init->end_initializers() ) {
     239                        // illegal to leave initializer list empty for scalar initializers,
     240                        // but always legal to have 0
     241                        output << "0";
     242                } else {
     243                        genCommaList( init->begin_initializers(), init->end_initializers() );
     244                }
    236245                output << " }";
    237246        }
     
    248257                                std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
    249258                                switch ( opInfo.type ) {
     259                                  case OT_CTOR:
     260                                  case OT_DTOR:
     261                                        {
     262                                                // if the first argument's type is const then GCC complains. In this
     263                                                // case, output an explicit ctor/dtor call and exit, rather than following
     264                                                // the normal path
     265                                                assert( arg != applicationExpr->get_args().end() );
     266                                                assert( (*arg)->get_results().size() >= 1 );
     267                                                Type * baseType = InitTweak::getPointerBase( (*arg)->get_results().front() );
     268                                                if ( baseType->get_isConst() ) {
     269                                                        // cast away the qualifiers, to eliminate warnings
     270                                                        Type * newType = baseType->clone();
     271                                                        newType->get_qualifiers() = Type::Qualifiers();
     272                                                        *arg = new CastExpr( *arg, new PointerType( Type::Qualifiers(), newType ) );
     273                                                        varExpr->accept( *this );
     274                                                        output << "(";
     275                                                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     276                                                        output << ")";
     277                                                        return;
     278                                                }
     279                                        }
     280                                        // intentional fallthrough - instrinsic ctor/dtor for non-const objects should
     281                                        // be handled the same way as assignment
    250282                                  case OT_PREFIXASSIGN:
    251283                                  case OT_POSTFIXASSIGN:
     
    254286                                                assert( arg != applicationExpr->get_args().end() );
    255287                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    256 
     288                                                        // remove & from first assignment/ctor argument
    257289                                                        *arg = addrExpr->get_arg();
    258290                                                } else {
     291                                                        // no address-of operator, so must be a pointer - add dereference
    259292                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    260293                                                        newExpr->get_args().push_back( *arg );
     294                                                        assert( (*arg)->get_results().size() == 1 );
     295                                                        Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() );
     296                                                        assert( type );
     297                                                        newExpr->get_results().push_back( type );
    261298                                                        *arg = newExpr;
    262299                                                } // if
     
    283320                                        break;
    284321
     322                                  case OT_CTOR:
     323                                  case OT_DTOR:
     324                                        if ( applicationExpr->get_args().size() == 1 ) {
     325                                                // the expression fed into a single parameter constructor or destructor
     326                                                // may contain side effects - output as a void expression
     327                                                output << "((void)(";
     328                                                (*arg++)->accept( *this );
     329                                                output << ")) /* " << opInfo.inputName << " */";
     330                                        } else if ( applicationExpr->get_args().size() == 2 ) {
     331                                                // intrinsic two parameter constructors are essentially bitwise assignment
     332                                                output << "(";
     333                                                (*arg++)->accept( *this );
     334                                                output << opInfo.symbol;
     335                                                (*arg)->accept( *this );
     336                                                output << ") /* " << opInfo.inputName << " */";
     337                                        } else {
     338                                                // no constructors with 0 or more than 2 parameters
     339                                                assert( false );
     340                                        }
     341                                        break;
     342
    285343                                  case OT_PREFIX:
    286344                                  case OT_PREFIXASSIGN:
     
    298356                                        output << opInfo.symbol;
    299357                                        break;
     358
    300359
    301360                                  case OT_INFIX:
     
    344403                                  case OT_CALL:
    345404                                        assert( false );
     405
     406
     407                                  case OT_CTOR:
     408                                  case OT_DTOR:
     409                                        if ( untypedExpr->get_args().size() == 1 ) {
     410                                                // the expression fed into a single parameter constructor or destructor
     411                                                // may contain side effects - output as a void expression
     412                                                output << "((void)(";
     413                                                (*arg++)->accept( *this );
     414                                                output << ")) /* " << opInfo.inputName << " */";
     415                                        } else if ( untypedExpr->get_args().size() == 2 ) {
     416                                                // intrinsic two parameter constructors are essentially bitwise assignment
     417                                                output << "(";
     418                                                (*arg++)->accept( *this );
     419                                                output << opInfo.symbol;
     420                                                (*arg)->accept( *this );
     421                                                output << ") /* " << opInfo.inputName << " */";
     422                                        } else {
     423                                                // no constructors with 0 or more than 2 parameters
     424                                                assert( false );
     425                                        }
    346426                                        break;
    347427
Note: See TracChangeset for help on using the changeset viewer.