Changes in / [37f0da8:70a06f6]


Ignore:
Location:
src
Files:
4 added
47 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r37f0da8 r70a06f6  
    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 15:40:00 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        }
     
    234241                                                assert( arg != applicationExpr->get_args().end() );
    235242                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    236                
     243
    237244                                                        *arg = addrExpr->get_arg();
    238245                                                } else {
     
    243250                                                break;
    244251                                        }
    245              
     252
    246253                                  default:
    247254                                        // do nothing
    248255                                        ;
    249256                                }
    250            
     257
    251258                                switch ( opInfo.type ) {
    252259                                  case OT_INDEX:
     
    257264                                        output << "]";
    258265                                        break;
    259              
     266
    260267                                  case OT_CALL:
    261                                         // there are no intrinsic definitions of the function call operator
     268                                        // there are no intrinsic definitions of the function call operator or constructors or destructors
    262269                                        assert( false );
    263270                                        break;
    264              
     271
     272                                  case OT_CTOR:
     273                                  // it's just an optimization to disallow this, so for now let it through
     274                                  // since it makes autogenerating constructors a lot easier
     275                                varExpr->accept( *this );
     276                                        output << "(";
     277                                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     278                                        output << ")";
     279
     280                                  // intrinsic constructors should never be called directly - they should be transformed back into Initializer nodes
     281                                  // assert(false);
     282                                  break;
     283
     284                                  case OT_DTOR:
     285                                  // intrinsic destructors do nothing - don't generate any code
     286                                  output << " /* " << dynamic_cast<VariableExpr*>(applicationExpr->get_function())->get_var()->get_name() << " */";
     287                                  break;
     288
    265289                                  case OT_PREFIX:
    266290                                  case OT_PREFIXASSIGN:
     
    271295                                        output << ")";
    272296                                        break;
    273              
     297
    274298                                  case OT_POSTFIX:
    275299                                  case OT_POSTFIXASSIGN:
     
    278302                                        output << opInfo.symbol;
    279303                                        break;
     304
    280305
    281306                                  case OT_INFIX:
     
    288313                                        output << ")";
    289314                                        break;
    290              
     315
    291316                                  case OT_CONSTANT:
    292317                                  case OT_LABELADDRESS:
     
    307332                } // if
    308333        }
    309  
     334
    310335        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    311336                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    321346                                        output << "]";
    322347                                        break;
    323              
     348
    324349                                  case OT_CALL:
    325350                                        assert( false );
    326                                         break;
    327              
     351
     352                                        case OT_CTOR:
     353                                        case OT_DTOR:
     354                                        // intrinsic constructors should never be called
     355                                        // intrinsic destructors do nothing
     356                                        break;
     357
    328358                                  case OT_PREFIX:
    329359                                  case OT_PREFIXASSIGN:
     
    335365                                        output << ")";
    336366                                        break;
    337              
     367
    338368                                  case OT_POSTFIX:
    339369                                  case OT_POSTFIXASSIGN:
     
    342372                                        output << opInfo.symbol;
    343373                                        break;
    344  
     374
    345375                                  case OT_INFIX:
    346376                                  case OT_INFIXASSIGN:
     
    352382                                        output << ")";
    353383                                        break;
    354                                        
     384
    355385                                  case OT_CONSTANT:
    356386                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    370400                } // if
    371401        }
    372  
     402
    373403        void CodeGenerator::visit( NameExpr *nameExpr ) {
    374404                OperatorInfo opInfo;
     
    380410                } // if
    381411        }
    382  
     412
    383413        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    384414                output << "(&";
     
    409439                output << ")";
    410440        }
    411  
     441
    412442        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    413443                assert( false );
    414444        }
    415  
     445
    416446        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    417447                memberExpr->get_aggregate()->accept( *this );
    418448                output << "." << mangleName( memberExpr->get_member() );
    419449        }
    420  
     450
    421451        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    422452                OperatorInfo opInfo;
     
    427457                } // if
    428458        }
    429  
     459
    430460        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    431461                assert( constantExpr->get_constant() );
    432462                constantExpr->get_constant()->accept( *this );
    433463        }
    434  
     464
    435465        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    436466                output << "sizeof(";
     
    469499                assert( false && "OffsetPackExpr should not reach code generation" );
    470500        }
    471  
     501
    472502        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    473503                output << "(";
     
    481511                output << ")";
    482512        }
    483  
     513
    484514        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    485515                output << "(";
     
    491521                output << ")";
    492522        }
    493  
     523
    494524        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    495525                output << "(";
     
    499529                output << ")";
    500530        }
    501  
     531
    502532        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    503  
     533
    504534        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    505535
     
    532562                        }
    533563                }
    534                 cur_indent -= CodeGenerator::tabsize; 
     564                cur_indent -= CodeGenerator::tabsize;
    535565
    536566                output << indent << "}";
     
    538568
    539569        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, 
     570                // I don't see why this check is necessary.
     571                // If this starts to cause problems then put it back in,
    542572                // with an explanation
    543573                assert( exprStmt );
     
    589619                switchStmt->get_condition()->accept( *this );
    590620                output << " ) ";
    591                
     621
    592622                output << "{" << std::endl;
    593623                cur_indent += CodeGenerator::tabsize;
     
    609639                } // if
    610640                output << ":\n";
    611                
     641
    612642                std::list<Statement *> sts = caseStmt->get_statements();
    613643
     
    626656                        if ( ! branchStmt->get_target().empty() )
    627657                                output << "goto " << branchStmt->get_target();
    628                         else { 
     658                        else {
    629659                                if ( branchStmt->get_computedTarget() != 0 ) {
    630660                                        output << "goto *";
     
    677707
    678708        void CodeGenerator::visit( ForStmt *forStmt ) {
    679                 // initialization is always hoisted, so don't 
    680                 // bother doing anything with that 
     709                // initialization is always hoisted, so don't
     710                // bother doing anything with that
    681711                output << "for (;";
    682712
     
    702732        void CodeGenerator::visit( DeclStmt *declStmt ) {
    703733                declStmt->get_decl()->accept( *this );
    704        
     734
    705735                if ( doSemicolon( declStmt->get_decl() ) ) {
    706736                        output << ";";
  • src/CodeGen/FixNames.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixNames.cc -- 
     7// FixNames.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 : Mon May 18 23:36:42 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 11 15:38:10 2016
    1313// Update Count     : 1
    1414//
     
    2626                virtual void visit( ObjectDecl *objectDecl );
    2727                virtual void visit( FunctionDecl *functionDecl );
     28
     29                virtual void visit( CompoundStmt *compoundStmt );
     30
     31          private:
     32                int scopeLevel = 1;
     33
     34                void fixDWT( DeclarationWithType *dwt );
    2835        };
    2936
     
    3340        }
    3441
    35         void fixDWT( DeclarationWithType *dwt ) {
     42        void FixNames::fixDWT( DeclarationWithType *dwt ) {
    3643                if ( dwt->get_name() != "" ) {
    3744                        if ( LinkageSpec::isDecoratable( dwt->get_linkage() ) ) {
    3845                                dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
     46                                dwt->set_scopeLevel( scopeLevel );
    3947                        } // if
    4048                } // if
     
    5058                fixDWT( functionDecl );
    5159        }
     60
     61        void FixNames::visit( CompoundStmt *compoundStmt ) {
     62                scopeLevel++;
     63                Visitor::visit( compoundStmt );
     64                scopeLevel--;
     65        }
    5266} // namespace CodeGen
    5367
  • src/CodeGen/OperatorTable.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // OperatorTable.cc -- 
     7// OperatorTable.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 : Tue Jun 23 17:41:14 2015
    13 // Update Count     : 5
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Oct 06 15:26:34 2015
     13// Update Count     : 9
    1414//
    1515
     
    2121                const OperatorInfo tableValues[] = {
    2222                        {       "?[?]",         "",             "_operator_index",                              OT_INDEX                        },
     23                        {       "?{}",          "",             "_constructor",                                 OT_CTOR                         },
     24                        {       "^?{}",         "",             "_destructor",                                  OT_DTOR                         },
    2325                        {       "?()",          "",             "_operator_call",                               OT_CALL                         },
    2426                        {       "?++",          "++",   "_operator_postincr",                   OT_POSTFIXASSIGN        },
  • src/CodeGen/OperatorTable.h

    r37f0da8 r70a06f6  
    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 : Tue Jun 23 16:09:27 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jun 24 16:17:57 2015
     13// Update Count     : 5
    1414//
    1515
     
    2222        enum OperatorType {
    2323                OT_INDEX,
     24                OT_CTOR,
     25                OT_DTOR,
    2426                OT_CALL,
    2527                OT_PREFIX,
  • src/GenPoly/Box.cc

    r37f0da8 r70a06f6  
    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 : Fri Feb  5 16:45:07 2016
    13 // Update Count     : 286
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:57:46 2016
     13// Update Count     : 295
    1414//
    1515
     
    133133                        Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
    134134                                TypeList typeList( params );
    135                                
     135
    136136                                // scan scopes for matches to the key
    137137                                for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
     
    160160                        virtual Declaration *mutate( UnionDecl *unionDecl );
    161161                };
    162                
     162
    163163                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    164164                class Pass1 : public PolyMutator {
     
    208208                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
    209209                        ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    210                        
     210
    211211                        DeclarationWithType *retval;
    212212                        bool useRetval;
     
    226226                        virtual Type *mutate( PointerType *pointerType );
    227227                        virtual Type *mutate( FunctionType *funcType );
    228                        
     228
    229229                  private:
    230230                        void addAdapters( FunctionType *functionType );
     
    297297                        /// Exits the type-variable scope
    298298                        void endTypeScope();
    299                        
     299
    300300                        ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
    301301                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
     
    351351                PolyGenericCalculator polyCalculator;
    352352                Pass3 pass3;
    353                
     353
    354354                layoutBuilder.mutateDeclarationList( translationUnit );
    355355                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     
    370370                return functionDecl;
    371371        }
    372        
     372
    373373        /// Get a list of type declarations that will affect a layout function
    374374        std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
     
    380380                        }
    381381                }
    382                
     382
    383383                return otypeDecls;
    384384        }
     
    387387        void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
    388388                BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    389                
     389
    390390                for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    391391                        TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
     
    444444                return makeCond( ifCond, ifExpr );
    445445        }
    446        
     446
    447447        /// adds an expression to a compound statement
    448448        void addExpr( CompoundStmt *stmts, Expression *expr ) {
     
    454454                stmts->get_kids().push_back( stmt );
    455455        }
    456        
     456
    457457        Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    458458                // do not generate layout function for "empty" tag structs
     
    467467                BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    468468                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    469                
     469
    470470                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    471471                layoutFnType->get_parameters().push_back( sizeParam );
     
    497497                                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
    498498                        }
    499                        
     499
    500500                        // place current size in the current offset index
    501501                        addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
     
    505505                        // add member size to current size
    506506                        addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    507                        
     507
    508508                        // take max of member alignment and global alignment
    509509                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
     
    515515                return structDecl;
    516516        }
    517        
     517
    518518        Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    519519                // do not generate layout function for "empty" tag unions
    520520                if ( unionDecl->get_members().empty() ) return unionDecl;
    521                
     521
    522522                // get parameters that can change layout, exiting early if none
    523523                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
     
    528528                BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    529529                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    530                
     530
    531531                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    532532                layoutFnType->get_parameters().push_back( sizeParam );
     
    545545                        assert( dwt );
    546546                        Type *memberType = dwt->get_type();
    547                        
     547
    548548                        // take max member size and global size
    549549                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    550                        
     550
    551551                        // take max of member alignment and global alignment
    552552                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
     
    558558                return unionDecl;
    559559        }
    560        
     560
    561561        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    562562
     
    619619                        return 0;
    620620                }
    621                
     621
    622622                /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
    623623                /// Only picks assignments where neither parameter is cv-qualified
     
    631631                                                Type *paramType2 = funType->get_parameters().back()->get_type();
    632632                                                if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
    633                                                
     633
    634634                                                if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
    635635                                                        Type *baseType1 = pointerType->get_base();
     
    803803                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
    804804                        }
    805                        
     805
    806806                        // add type information args for presently unseen types in parameter list
    807807                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
     
    882882                        assert( env );
    883883                        Type *concrete = replaceWithConcrete( appExpr, polyType );
    884                         // add out-parameter for return value   
     884                        // add out-parameter for return value
    885885                        return addRetParam( appExpr, function, concrete, arg );
    886886                }
     
    13661366                        return new VariableExpr( functionObj );
    13671367                }
    1368                
     1368
    13691369                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    13701370                        if ( retval && returnStmt->get_expr() ) {
     
    18861886                                }
    18871887                        }
    1888                        
     1888
    18891889                        Type *ret = Mutator::mutate( funcType );
    18901890
     
    19051905
    19061906                                        std::list<Expression*> designators;
    1907                                         objectDecl->set_init( new SingleInit( alloc, designators ) );
     1907                                        objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
    19081908                                }
    19091909                        }
     
    19461946                        return derefdVar;
    19471947                }
    1948                
     1948
    19491949                Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
    19501950                        // mutate, exiting early if no longer MemberExpr
     
    21442144                        Type *ty = offsetofExpr->get_type();
    21452145                        if ( ! findGeneric( ty ) ) return offsetofExpr;
    2146                        
     2146
    21472147                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
    21482148                                // replace offsetof expression by index into offset array
  • src/GenPoly/CopyParams.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CopyParams.cc -- 
     7// CopyParams.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
     11// Last Modified By : Rob Schluntz
    1212// Last Modified On : Tue May 19 07:33:31 2015
    1313// Update Count     : 1
     
    2929          public:
    3030                CopyParams();
    31  
     31
    3232                virtual void visit( FunctionDecl *funcDecl );
    3333                virtual void visit( AddressExpr *addrExpr );
     
    5050                if ( funcDecl->get_statements() ) {
    5151                        funcDecl->get_statements()->accept( *this );
    52        
     52
    5353                        if ( ! modVars.empty() ) {
    5454                                std::map< std::string, DeclarationWithType* > assignOps;
     
    5757                                        if ( (*tyVar)->get_kind() == TypeDecl::Any ) {
    5858                                                assert( !(*tyVar)->get_assertions().empty() );
     59                                                assert( (*tyVar)->get_assertions().front()->get_name() == "?=?" );
    5960                                                assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front();
    6061                                        } // if
  • src/GenPoly/Specialize.cc

    r37f0da8 r70a06f6  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jan 20 12:40:33 2016
    13 // Update Count     : 18
     12// Last Modified On : Wed Jan 20 13:00:00 2016
     13// Update Count     : 24
    1414//
    1515
     
    142142
    143143        Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
    144                 assert( ! actual->get_results().empty() );
     144                assert( ! actual->get_results().empty() ); // using front, should have this assert
    145145                if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
    146146                        FunctionType *funType;
  • src/InitTweak/InitModel.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InitModel.cc -- 
     7// InitModel.cc --
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 16:37:08 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Jan 07 13:38:46 2016
     13// Update Count     : 5
    1414//
    1515
     
    198198                assert(init == 0 && single != 0);
    199199                std::list< Expression * > empty;
    200                 init = new SingleInit( single->get_expr(), empty );
     200                init = new SingleInit( single->get_expr(), empty, false ); // cannot be constructed
    201201                return;
    202202        }
     
    214214                        } // if
    215215
    216                 init = new ListInit( contents );
     216                std::list< Expression * > desig;
     217                init = new ListInit( contents, desig, false ); // cannot be constructed
    217218                return;
    218219        }
  • src/InitTweak/RemoveInit.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // RemoveInit.cc -- 
     7// RemoveInit.cc --
    88//
    99// Author           : Rob Schluntz
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec 15 15:37:26 2015
    13 // Update Count     : 15
    14 //
    15 
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:09:36 2016
     13// Update Count     : 166
     14//
     15
     16#include <stack>
     17#include <list>
    1618#include "RemoveInit.h"
    1719#include "SynTree/Declaration.h"
     
    2123#include "SynTree/Initializer.h"
    2224#include "SynTree/Mutator.h"
     25#include "SymTab/Autogen.h"
     26#include "GenPoly/PolyMutator.h"
    2327
    2428namespace InitTweak {
    2529        namespace {
    2630                const std::list<Label> noLabels;
    27         }
    28        
    29         class RemoveInit : public Mutator {
     31                const std::list<Expression *> noDesignators;
     32        }
     33
     34        class RemoveInit : public GenPoly::PolyMutator {
    3035          public:
     36                /// removes and replaces initialization for polymorphic value objects
     37                /// with assignment (TODO: constructor) statements.
     38                /// also consistently allocates a temporary variable for the return value
     39                /// of a function so that anything which the resolver decides can be assigned
     40                /// into the return type of a function can be returned.
     41                static void removeInitializers( std::list< Declaration * > &translationUnit );
     42
    3143                RemoveInit();
    32                 virtual ObjectDecl * mutate(ObjectDecl *objDecl);
     44
     45                virtual ObjectDecl * mutate( ObjectDecl *objDecl );
    3346                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    3447
    3548                virtual Statement * mutate( ReturnStmt * returnStmt );
    36                
    37                 virtual CompoundStmt * mutate(CompoundStmt * compoundStmt);
    38                
     49
    3950          protected:
    40                 std::list< Statement* > stmtsToAddBefore;
    41                 std::list< Statement* > stmtsToAddAfter;
    42                 void mutateStatementList( std::list< Statement* > &statements );
    43 
    4451                std::list<DeclarationWithType*> returnVals;
    4552                UniqueName tempNamer;
     
    4754        };
    4855
    49         void tweak( std::list< Declaration * > translationUnit ) {
     56        class CtorDtor : public GenPoly::PolyMutator {
     57          public:
     58                /// create constructor and destructor statements for object declarations.
     59                /// Destructors are inserted directly into the code, whereas constructors
     60                /// will be added in after the resolver has run so that the initializer expression
     61                /// is only removed if a constructor is found
     62                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
     63
     64                CtorDtor() : inFunction( false ) {}
     65
     66                virtual DeclarationWithType * mutate( ObjectDecl * );
     67                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
     68                virtual Declaration* mutate( StructDecl *aggregateDecl );
     69                virtual Declaration* mutate( UnionDecl *aggregateDecl );
     70                virtual Declaration* mutate( EnumDecl *aggregateDecl );
     71                virtual Declaration* mutate( TraitDecl *aggregateDecl );
     72                virtual TypeDecl* mutate( TypeDecl *typeDecl );
     73                virtual Declaration* mutate( TypedefDecl *typeDecl );
     74
     75                virtual Type * mutate( FunctionType *funcType );
     76
     77          protected:
     78                bool inFunction;
     79        };
     80
     81        void tweak( std::list< Declaration * > & translationUnit ) {
     82                RemoveInit::removeInitializers( translationUnit );
     83                CtorDtor::generateCtorDtor( translationUnit );
     84        }
     85
     86        void RemoveInit::removeInitializers( std::list< Declaration * > & translationUnit ) {
    5087                RemoveInit remover;
    5188                mutateAll( translationUnit, remover );
     
    5390
    5491        RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {}
    55        
    56         void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) {
    57                 for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    58                         if ( ! stmtsToAddAfter.empty() ) {
    59                                 statements.splice( i, stmtsToAddAfter );
    60                         } // if
    61                         *i = (*i)->acceptMutator( *this );
    62                         if ( ! stmtsToAddBefore.empty() ) {
    63                                 statements.splice( i, stmtsToAddBefore );
    64                         } // if
    65                 } // for
    66                 if ( ! stmtsToAddAfter.empty() ) {
    67                         statements.splice( statements.end(), stmtsToAddAfter );
    68                 } // if
    69         }
    70 
    71         CompoundStmt *RemoveInit::mutate(CompoundStmt *compoundStmt) {
    72                 mutateStatementList( compoundStmt->get_kids() );
    73                 return compoundStmt;
    74         }
    7592
    7693        // in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
     
    7996                if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) {
    8097                        if (SingleInit * single = dynamic_cast<SingleInit*>(objDecl->get_init())) {
    81                                 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    82                                 assign->get_args().push_back( new AddressExpr (new NameExpr( objDecl->get_name() ) ) );
     98                                // xxx this can be more complicated - consider ListInit
     99                                UntypedExpr *assign = new UntypedExpr( new NameExpr( "?{}" ) );
     100                                assign->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    83101                                assign->get_args().push_back( single->get_value()->clone() );
    84102                                stmtsToAddAfter.push_back(new ExprStmt(noLabels, assign));
     
    93111                // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
    94112                // is being returned
    95                 if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue()  ) {
    96                         ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), 0 );
    97                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    98                        
    99                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    100                         assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
    101                         assign->get_args().push_back( returnStmt->get_expr() );
    102                         stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
     113                if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue() ) {
     114                        // ensure return value is not destructed by explicitly creating
     115                        // an empty SingleInit node wherein maybeConstruct is false
     116                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), new ListInit( std::list<Initializer*>(), noDesignators, false ) );
     117                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     118
     119                        // and explicitly create the constructor expression separately
     120                        UntypedExpr *construct = new UntypedExpr( new NameExpr( "?{}" ) );
     121                        construct->get_args().push_back( new AddressExpr( new VariableExpr( newObj ) ) );
     122                        construct->get_args().push_back( returnStmt->get_expr() );
     123                        stmtsToAdd.push_back(new ExprStmt(noLabels, construct));
    103124
    104125                        returnStmt->set_expr( new VariableExpr( newObj ) );
     
    110131                std::list<DeclarationWithType*> oldReturnVals = returnVals;
    111132                std::string oldFuncName = funcName;
    112                
     133
    113134                FunctionType * type = functionDecl->get_functionType();
    114135                returnVals = type->get_returnVals();
     
    119140                return decl;
    120141        }
     142
     143
     144        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
     145                CtorDtor ctordtor;
     146                mutateAll( translationUnit, ctordtor );
     147        }
     148
     149        namespace {
     150                bool tryConstruct( ObjectDecl * objDecl ) {
     151                        // xxx - handle designations
     152                        return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
     153                                (objDecl->get_init() == NULL ||
     154                                ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ));
     155                }
     156
     157                Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
     158                        UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
     159                        expr->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
     160                        expr->get_args().splice( expr->get_args().end(), args );
     161                        return expr;
     162                }
     163
     164                class InitExpander : public Visitor {
     165                  public:
     166                  InitExpander() {}
     167                  // ~InitExpander() {}
     168                        virtual void visit( SingleInit * singleInit );
     169                        virtual void visit( ListInit * listInit );
     170                        std::list< Expression * > argList;
     171                };
     172
     173                void InitExpander::visit( SingleInit * singleInit ) {
     174                        argList.push_back( singleInit->get_value()->clone() );
     175                }
     176
     177                void InitExpander::visit( ListInit * listInit ) {
     178                        // xxx - for now, assume no nested list inits
     179                        std::list<Initializer*>::iterator it = listInit->begin_initializers();
     180                        for ( ; it != listInit->end_initializers(); ++it ) {
     181                                (*it)->accept( *this );
     182                        }
     183                }
     184
     185                std::list< Expression * > makeInitList( Initializer * init ) {
     186                        InitExpander expander;
     187                        maybeAccept( init, expander );
     188                        return expander.argList;
     189                }
     190        }
     191
     192        DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
     193                // hands off if designated or if @=
     194                if ( tryConstruct( objDecl ) ) {
     195                        if ( inFunction ) {
     196                                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
     197                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
     198                                        // TODO: walk initializer and generate appropriate copy ctor if element has initializer
     199                                        std::list< Statement * > ctor;
     200                                        std::list< Statement * > dtor;
     201
     202                                        SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
     203                                        SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
     204
     205                                        // Currently makeArrayFunction produces a single Statement - a CompoundStmt
     206                                        // which  wraps everything that needs to happen. As such, it's technically
     207                                        // possible to use a Statement ** in the above calls, but this is inherently
     208                                        // unsafe, so instead we take the slightly less efficient route, but will be
     209                                        // immediately informed if somehow the above assumption is broken. In this case,
     210                                        // we could always wrap the list of statements at this point with a CompoundStmt,
     211                                        // but it seems reasonable at the moment for this to be done by makeArrayFunction
     212                                        // itself
     213                                        assert( ctor.size() == 1 );
     214                                        assert( dtor.size() == 1 );
     215
     216                                        objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     217                                } else {
     218                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
     219                                        Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
     220                                        Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
     221
     222                                        // need to remember init expression, in case no ctors exist
     223                                        // if ctor does exist, want to use ctor expression instead of init
     224                                        // push this decision to the resolver
     225                                        ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
     226                                        ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
     227                                        objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) );
     228                                }
     229                        } else {
     230                                // xxx - find a way to construct/destruct globals
     231                                // hack: implicit "static" initialization routine for each struct type? or something similar?
     232                                // --ties into module system
     233                                // this can be done by mangling main and replacing it with our own main which calls each
     234                                // module initialization routine in some decided order (order given in link command?)
     235                                // and finally calls mangled main
     236                        }
     237                }
     238                return Mutator::mutate( objDecl );
     239        }
     240
     241        DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
     242                // parameters should not be constructed and destructed, so don't mutate FunctionType
     243                bool oldInFunc = inFunction;
     244                mutateAll( functionDecl->get_oldDecls(), *this );
     245                inFunction = true;
     246                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     247                inFunction = oldInFunc;
     248                return functionDecl;
     249        }
     250
     251        // should not traverse into any of these declarations to find objects
     252        // that need to be constructed or destructed
     253        Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
     254        Declaration* CtorDtor::mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
     255        Declaration* CtorDtor::mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
     256        Declaration* CtorDtor::mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
     257        TypeDecl* CtorDtor::mutate( TypeDecl *typeDecl ) { return typeDecl; }
     258        Declaration* CtorDtor::mutate( TypedefDecl *typeDecl ) { return typeDecl; }
     259        Type* CtorDtor::mutate( FunctionType *funcType ) { return funcType; }
     260
    121261} // namespace InitTweak
    122262
  • src/InitTweak/RemoveInit.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // RemoveInit.h -- 
     7// RemoveInit.h --
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 27 17:00:47 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Jan 11 16:02:44 2016
     13// Update Count     : 3
    1414//
    1515
     
    2626namespace InitTweak {
    2727        /// Adds assignment statements for polymorphic type initializers
    28         void tweak( std::list< Declaration * > translationUnit );
    29 } // namespace 
     28        void tweak( std::list< Declaration * > & translationUnit );
     29} // namespace
    3030
    3131#endif // GENPOLY_POLYMUTATOR_H
  • src/InitTweak/module.mk

    r37f0da8 r70a06f6  
    1111## Created On       : Mon Jun  1 17:49:17 2015
    1212## Last Modified By : Rob Schluntz
    13 ## Last Modified On : Mon Jan 11 14:40:16 2016
    14 ## Update Count     : 2
     13## Last Modified On : Wed Jan 13 16:29:03 2016
     14## Update Count     : 3
    1515###############################################################################
    1616
    17 SRC += InitTweak/RemoveInit.cc
    18 
     17SRC += InitTweak/RemoveInit.cc \
     18        InitTweak/FixInit.cc
  • src/MakeLibCfa.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // MakeLibCfa.cc -- 
     7// MakeLibCfa.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 10:33:33 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 26 16:52:59 2015
    13 // Update Count     : 14
    14 // 
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Jan 19 13:20:26 2016
     13// Update Count     : 40
     14//
    1515
    1616#include "MakeLibCfa.h"
     
    2929                void visit( FunctionDecl* funcDecl );
    3030                void visit( ObjectDecl* objDecl );
    31  
     31
    3232                std::list< Declaration* > &get_newDecls() { return newDecls; }
    3333          private:
     
    4343        void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) {
    4444                if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    45  
     45
    4646                FunctionDecl *funcDecl = origFuncDecl->clone();
    4747                CodeGen::OperatorInfo opInfo;
     
    5454                assert( param != funcDecl->get_functionType()->get_parameters().end() );
    5555
    56                 if ( (*param)->get_name() == "" ) {
    57                         (*param)->set_name( paramNamer.newName() );
    58                         (*param)->set_linkage( LinkageSpec::C );
    59                 } // if
     56                for ( ; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
     57                        if ( (*param)->get_name() == "" ) {
     58                                (*param)->set_name( paramNamer.newName() );
     59                                (*param)->set_linkage( LinkageSpec::C );
     60                        }
     61                        newExpr->get_args().push_back( new VariableExpr( *param ) );
     62                } // for
     63
     64                funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
     65                newDecls.push_back( funcDecl );
    6066
    6167                switch ( opInfo.type ) {
     
    6571                  case CodeGen::OT_POSTFIX:
    6672                  case CodeGen::OT_INFIX:
    67                         newExpr->get_args().push_back( new VariableExpr( *param ) );
    68                         break;
    6973                  case CodeGen::OT_PREFIXASSIGN:
    7074                  case CodeGen::OT_POSTFIXASSIGN:
    7175                  case CodeGen::OT_INFIXASSIGN:
    72                         {
    73                                 newExpr->get_args().push_back( new VariableExpr( *param ) );
    74                                 // UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    75                                 // deref->get_args().push_back( new VariableExpr( *param ) );
    76                                 // newExpr->get_args().push_back( deref );
     76                                funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
    7777                                break;
    78                         }
     78                  case CodeGen::OT_CTOR:
     79                        // ctors don't return a value
     80                        if ( funcDecl->get_functionType()->get_parameters().size() == 1 ) {
     81                                // intrinsic default constructors should do nothing
     82                                // delete newExpr;
     83                                break;
     84                        } else {
     85                                assert( funcDecl->get_functionType()->get_parameters().size() == 2 );
     86                                // anything else is a single parameter constructor that is effectively a C-style assignment
     87                                // delete newExpr->get_function();
     88                                assert(newExpr->get_args().size()==2);
     89                                newExpr->set_function( new NameExpr( "?=?" ) );
     90                                funcDecl->get_statements()->get_kids().push_back( new ExprStmt( std::list< Label >(), newExpr ) );
     91                        }
     92                        break;
     93                  case CodeGen::OT_DTOR:
     94                        // intrinsic destructors should do nothing
     95                        // delete newExpr;
     96                        break;
    7997                  case CodeGen::OT_CONSTANT:
    8098                  case CodeGen::OT_LABELADDRESS:
     
    82100                        assert( false );
    83101                } // switch
    84 
    85                 for ( param++; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
    86                         if ( (*param)->get_name() == "" ) {
    87                                 (*param)->set_name( paramNamer.newName() );
    88                                 (*param)->set_linkage( LinkageSpec::C );
    89                         }
    90                         newExpr->get_args().push_back( new VariableExpr( *param ) );
    91                 } // for
    92                 funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
    93                 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
    94                 newDecls.push_back( funcDecl );
    95102        }
    96103
    97104        void MakeLibCfa::visit( ObjectDecl* origObjDecl ) {
    98105                if ( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    99  
     106
    100107                ObjectDecl *objDecl = origObjDecl->clone();
    101108                assert( ! objDecl->get_init() );
    102109                std::list< Expression* > noDesignators;
    103                 objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators ) );
     110                objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators, false ) ); // cannot be constructed
    104111                newDecls.push_back( objDecl );
    105112        }
    106113} // namespace LibCfa
    107 
    108 // Local Variables: //
    109 // tab-width: 4 //
    110 // mode: c++ //
    111 // compile-command: "make install" //
    112 // End: //
  • src/Makefile.in

    r37f0da8 r70a06f6  
    124124        GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
    125125        InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT) \
     126        InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT) \
    126127        Parser/driver_cfa_cpp-parser.$(OBJEXT) \
    127128        Parser/driver_cfa_cpp-lex.$(OBJEXT) \
     
    159160        SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) \
    160161        SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT) \
     162        SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \
    161163        SynTree/driver_cfa_cpp-Type.$(OBJEXT) \
    162164        SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) \
     
    346348        GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
    347349        GenPoly/DeclMutator.cc InitTweak/RemoveInit.cc \
    348         Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
    349         Parser/ParseNode.cc Parser/DeclarationNode.cc \
    350         Parser/ExpressionNode.cc Parser/StatementNode.cc \
    351         Parser/InitializerNode.cc Parser/TypeData.cc \
    352         Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \
     350        InitTweak/FixInit.cc Parser/parser.yy Parser/lex.ll \
     351        Parser/TypedefTable.cc Parser/ParseNode.cc \
     352        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
     353        Parser/StatementNode.cc Parser/InitializerNode.cc \
     354        Parser/TypeData.cc Parser/LinkageSpec.cc \
     355        Parser/parseutility.cc Parser/Parser.cc \
    353356        ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
    354357        ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
     
    362365        SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    363366        SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
    364         SynTree/Type.cc SynTree/VoidType.cc SynTree/BasicType.cc \
    365         SynTree/PointerType.cc SynTree/ArrayType.cc \
    366         SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
    367         SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
     367        SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
     368        SynTree/BasicType.cc SynTree/PointerType.cc \
     369        SynTree/ArrayType.cc SynTree/FunctionType.cc \
     370        SynTree/ReferenceToType.cc SynTree/TupleType.cc \
     371        SynTree/TypeofType.cc SynTree/AttrType.cc \
    368372        SynTree/VarArgsType.cc SynTree/Constant.cc \
    369373        SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    563567InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT):  \
    564568        InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
     569InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     570        InitTweak/$(DEPDIR)/$(am__dirstamp)
    565571Parser/parser.h: Parser/parser.cc
    566572        @if test ! -f $@; then rm -f Parser/parser.cc; else :; fi
     
    670676SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT): SymTab/$(am__dirstamp) \
    671677        SymTab/$(DEPDIR)/$(am__dirstamp)
     678SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \
     679        SymTab/$(DEPDIR)/$(am__dirstamp)
    672680SynTree/$(am__dirstamp):
    673681        @$(MKDIR_P) SynTree
     
    792800        -rm -f GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT)
    793801        -rm -f GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT)
     802        -rm -f InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT)
    794803        -rm -f InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT)
    795804        -rm -f Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT)
     
    822831        -rm -f ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT)
    823832        -rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT)
     833        -rm -f SymTab/driver_cfa_cpp-Autogen.$(OBJEXT)
    824834        -rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT)
    825835        -rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT)
     
    897907@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    898908@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
     909@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po@am__quote@
    899910@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Po@am__quote@
    900911@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@
     
    927938@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po@am__quote@
    928939@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@
     940@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po@am__quote@
    929941@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@
    930942@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@
     
    13801392@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-RemoveInit.obj `if test -f 'InitTweak/RemoveInit.cc'; then $(CYGPATH_W) 'InitTweak/RemoveInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/RemoveInit.cc'; fi`
    13811393
     1394InitTweak/driver_cfa_cpp-FixInit.o: InitTweak/FixInit.cc
     1395@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc
     1396@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
     1397@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.o' libtool=no @AMDEPBACKSLASH@
     1398@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1399@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc
     1400
     1401InitTweak/driver_cfa_cpp-FixInit.obj: InitTweak/FixInit.cc
     1402@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi`
     1403@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
     1404@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.obj' libtool=no @AMDEPBACKSLASH@
     1405@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1406@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi`
     1407
    13821408Parser/driver_cfa_cpp-parser.o: Parser/parser.cc
    13831409@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parser.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo -c -o Parser/driver_cfa_cpp-parser.o `test -f 'Parser/parser.cc' || echo '$(srcdir)/'`Parser/parser.cc
     
    18691895@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    18701896@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`
     1897
     1898SymTab/driver_cfa_cpp-Autogen.o: SymTab/Autogen.cc
     1899@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc
     1900@am__fastdepCXX_TRUE@   $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
     1901@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.o' libtool=no @AMDEPBACKSLASH@
     1902@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1903@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc
     1904
     1905SymTab/driver_cfa_cpp-Autogen.obj: SymTab/Autogen.cc
     1906@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi`
     1907@am__fastdepCXX_TRUE@   $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
     1908@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.obj' libtool=no @AMDEPBACKSLASH@
     1909@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1910@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi`
    18711911
    18721912SynTree/driver_cfa_cpp-Type.o: SynTree/Type.cc
  • src/Parser/DeclarationNode.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // DeclarationNode.cc -- 
     7// DeclarationNode.cc --
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 12:34:05 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr 13 16:53:17 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:38:09 2016
    1313// Update Count     : 161
    1414//
     
    9797                os << endl << string( indent + 2, ' ' ) << "with initializer ";
    9898                initializer->printOneLine( os );
     99                os << " maybe constructed? " << initializer->get_maybeConstructed();
     100
    99101        } // if
    100102
     
    353355        } // if
    354356}
    355          
     357
    356358DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
    357359        if ( q ) {
     
    504506                assert( false );
    505507        } // switch
    506        
     508
    507509        return this;
    508510}
     
    615617                assert( a->type->kind == TypeData::Array );
    616618                TypeData *lastArray = findLast( a->type );
    617                 if ( type ) { 
     619                if ( type ) {
    618620                        switch ( type->kind ) {
    619621                          case TypeData::Aggregate:
     
    659661        } // if
    660662}
    661        
     663
    662664DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
    663665        type = addIdListToType( type, ids );
     
    864866Type *DeclarationNode::buildType() const {
    865867        assert( type );
    866  
     868
    867869        switch ( type->kind ) {
    868870          case TypeData::Enum:
  • src/Parser/InitializerNode.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InitializerNode.cc -- 
    8 // 
     7// InitializerNode.cc --
     8//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:20:24 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Oct  8 17:18:55 2015
    13 // Update Count     : 4
    14 // 
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Jan 07 13:32:57 2016
     13// Update Count     : 13
     14//
    1515
    1616#include <cassert>
     
    2323
    2424InitializerNode::InitializerNode( ExpressionNode *_expr, bool aggrp, ExpressionNode *des )
    25         : expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 ) {
     25        : expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 ), maybeConstructed( true ) {
    2626        if ( aggrp )
    2727                kids = dynamic_cast< InitializerNode *>( get_link() );
     
    3232
    3333InitializerNode::InitializerNode( InitializerNode *init, bool aggrp, ExpressionNode *des )
    34         : expr( 0 ), aggregate( aggrp ), designator( des ), kids( 0 ) {
     34        : expr( 0 ), aggregate( aggrp ), designator( des ), kids( 0 ), maybeConstructed( true ) {
    3535        if ( init != 0 )
    3636                set_link(init);
     
    9191                } // if
    9292
    93                 return new ListInit( initlist, designlist );
     93                return new ListInit( initlist, designlist, maybeConstructed );
    9494        } else {
    9595                std::list< Expression *> designators;
     
    9999
    100100                if ( get_expression() != 0)
    101                         return new SingleInit( get_expression()->build(), designators );
     101                        return new SingleInit( get_expression()->build(), designators, maybeConstructed );
    102102        } // if
    103103
  • src/Parser/ParseNode.h

    r37f0da8 r70a06f6  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Apr 11 11:50:52 2016
     12// Last Modified On : Thu Apr 14 15:37:52 2016
    1313// Update Count     : 205
    1414//
     
    185185                                // monadic
    186186                                UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
     187                                Ctor, Dtor,
    187188        };
    188189
     
    525526        ExpressionNode *get_designators() const { return designator; }
    526527
     528        InitializerNode *set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
     529        bool get_maybeConstructed() const { return maybeConstructed; }
     530
    527531        InitializerNode *next_init() const { return kids; }
    528532
     
    536540        ExpressionNode *designator; // may be list
    537541        InitializerNode *kids;
     542        bool maybeConstructed;
    538543};
    539544
  • src/Parser/TypeData.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeData.cc -- 
     7// TypeData.cc --
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:12:51 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:26:45 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 06 16:57:53 2016
    1313// Update Count     : 49
    1414//
     
    449449        for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
    450450                if ( (*i)->get_kind() == TypeDecl::Any ) {
     451                        // add assertion parameters to `type' tyvars in reverse order
     452                        // add dtor:  void ^?{}(T *)
     453                        FunctionType *dtorType = new FunctionType( Type::Qualifiers(), false );
     454                        dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     455                        (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) );
     456
     457                        // add copy ctor:  void ?{}(T *, T)
     458                        FunctionType *copyCtorType = new FunctionType( Type::Qualifiers(), false );
     459                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     460                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
     461                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
     462
     463                        // add default ctor:  void ?{}(T *)
     464                        FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
     465                        ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     466                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
     467
     468                        // add assignment operator:  T * ?=?(T *, T)
    451469                        FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    452470                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     
    902920                if ( cur->get_enumeratorValue() != NULL ) {
    903921                        ObjectDecl *member = dynamic_cast<ObjectDecl *>(*members);
    904                         member->set_init( new SingleInit( maybeBuild< Expression >( cur->get_enumeratorValue() ) ) );
     922                        member->set_init( new SingleInit( maybeBuild< Expression >( cur->get_enumeratorValue() ), std::list< Expression * >() ) );
    905923                } // if
    906924        } // for
  • src/Parser/parser.cc

    r37f0da8 r70a06f6  
    74687468/* Line 1806 of yacc.c  */
    74697469#line 1704 "parser.yy"
    7470     { (yyval.in) = (yyvsp[(2) - (2)].in); }
     7470    { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
    74717471    break;
    74727472
  • src/Parser/parser.yy

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // cfa.y -- 
    8 // 
     7// cfa.y --
     8//
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
     
    1212// Last Modified On : Wed Apr 13 16:58:43 2016
    1313// Update Count     : 1519
    14 // 
     14//
    1515
    1616// This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C
     
    17021702                { $$ = $2; }
    17031703        | ATassign initializer
    1704                 { $$ = $2; }
     1704                { $$ = $2->set_maybeConstructed( false ); }
    17051705        ;
    17061706
  • src/ResolvExpr/Resolver.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Resolver.cc -- 
     7// Resolver.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 24 16:43:11 2016
    13 // Update Count     : 181
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 11:18:12 2016
     13// Update Count     : 203
    1414//
    1515
     
    3333          public:
    3434                Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
    35  
     35
    3636                virtual void visit( FunctionDecl *functionDecl );
    3737                virtual void visit( ObjectDecl *functionDecl );
     
    5454                virtual void visit( SingleInit *singleInit );
    5555                virtual void visit( ListInit *listInit );
     56                virtual void visit( ConstructorInit *ctorInit );
    5657          private:
    5758        typedef std::list< Initializer * >::iterator InitIterator;
     
    5960          void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
    6061          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
    61 
     62          void fallbackInit( ConstructorInit * ctorInit );
    6263                std::list< Type * > functionReturn;
    6364                Type *initContext;
     
    8283        }
    8384
     85
    8486        namespace {
    8587                void finishExpr( Expression *expr, const TypeEnvironment &env ) {
     
    8789                        env.makeSubstitution( *expr->get_env() );
    8890                }
    89 
    90                 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    91                         global_renamer.reset();
    92                         TypeEnvironment env;
    93                         Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    94                         finishExpr( newExpr, env );
    95                         return newExpr;
    96                 }
    97  
     91        } // namespace
     92
     93        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     94                global_renamer.reset();
     95                TypeEnvironment env;
     96                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
     97                finishExpr( newExpr, env );
     98                return newExpr;
     99        }
     100
     101        namespace {
    98102                Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    99103                        TypeEnvironment env;
     
    126130                        } // if
    127131                }
    128  
     132
    129133                Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    130134                        TypeEnvironment env;
     
    159163                        return newExpr;
    160164                }
    161  
    162         }
    163  
     165
     166        }
     167
    164168        void Resolver::visit( ObjectDecl *objectDecl ) {
    165169                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     
    258262                        forStmt->set_condition( newExpr );
    259263                } // if
    260                
     264
    261265                if ( forStmt->get_increment() ) {
    262266                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     
    272276                delete switchStmt->get_condition();
    273277                switchStmt->set_condition( newExpr );
    274  
     278
    275279                visitor.Visitor::visit( switchStmt );
    276280        }
     
    314318        bool isCharType( T t ) {
    315319                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    316                         return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 
     320                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
    317321                                bt->get_kind() == BasicType::UnsignedChar;
    318322                }
     
    326330                                string n = ne->get_name();
    327331                                if (n == "0") {
    328                                         initContext = new BasicType(Type::Qualifiers(), 
     332                                        initContext = new BasicType(Type::Qualifiers(),
    329333                                                                                                BasicType::SignedInt);
    330334                                } else {
     
    332336                                        initContext = decl->get_type();
    333337                                }
    334                         } else if (ConstantExpr * e = 
     338                        } else if (ConstantExpr * e =
    335339                                           dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
    336340                                Constant *c = e->get_constant();
     
    355359                                                        singleInit->set_value( ce->get_arg() );
    356360                                                        ce->set_arg( NULL );
    357                                                         delete ce;                                                                     
     361                                                        delete ce;
    358362                                                }
    359363                                        }
     
    471475#endif
    472476        }
     477
     478        // ConstructorInit - fall back on C-style initializer
     479        void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
     480                // could not find valid constructor, or found an intrinsic constructor
     481                // fall back on C-style initializer
     482                delete ctorInit->get_ctor();
     483                ctorInit->set_ctor( NULL );
     484                maybeAccept( ctorInit->get_init(), *this );
     485        }
     486
     487        void Resolver::visit( ConstructorInit *ctorInit ) {
     488                try {
     489                        maybeAccept( ctorInit->get_ctor(), *this );
     490                        maybeAccept( ctorInit->get_dtor(), *this );
     491                } catch ( SemanticError ) {
     492                        // no alternatives for the constructor initializer - fallback on C-style initializer
     493                        // xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
     494                        fallbackInit( ctorInit );
     495                        return;
     496                }
     497
     498                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * > ( ctorInit->get_ctor() ) ) {
     499                        ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
     500                        assert( appExpr );
     501                        VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() );
     502                        assert( function );
     503                        if ( LinkageSpec::isOverridable( function->get_var()->get_linkage() ) ) {
     504                                // if the constructor that was found is intrinsic or autogenerated, reset to C-style
     505                                // initializer so that code generation is easy to handle
     506                                fallbackInit( ctorInit );
     507                                return;
     508                        }
     509                }
     510                // found a constructor - can get rid of C-style initializer
     511                delete ctorInit->get_init();
     512                ctorInit->set_init( NULL );
     513        }
    473514} // namespace ResolvExpr
    474515
  • src/ResolvExpr/Resolver.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Resolver.h -- 
     7// Resolver.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:18:34 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 12:19:32 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:06:53 2016
    1313// Update Count     : 2
    1414//
     
    2424        void resolve( std::list< Declaration * > translationUnit );
    2525        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
     26        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
    2627} // namespace ResolvExpr
    2728
  • src/SymTab/AddVisit.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AddVisit.h -- 
     7// AddVisit.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 16:14:32 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr  7 14:42:21 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:52:42 2016
    1313// Update Count     : 5
    1414//
     
    4848        //      maybeAccept( caseStmt->get_condition(), visitor );
    4949        // }
     50
     51        template< typename Visitor >
     52        void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
     53                std::list< Declaration * >::iterator i = translationUnit.begin();
     54                while ( i != translationUnit.end() ) {
     55                        (*i)->accept( visitor );
     56                        std::list< Declaration * >::iterator next = i;
     57                        next++;
     58                        if ( ! visitor.get_declsToAdd().empty() ) {
     59                                translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
     60                        } // if
     61                        i = next;
     62                } // while
     63        }
     64
    5065} // namespace SymTab
    5166
  • src/SymTab/Validate.cc

    r37f0da8 r70a06f6  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr 13 16:39:30 2016
    13 // Update Count     : 251
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:37:23 2016
     13// Update Count     : 297
    1414//
    1515
     
    5656#include "MakeLibCfa.h"
    5757#include "TypeEquality.h"
     58#include "Autogen.h"
    5859#include "ResolvExpr/typeops.h"
    5960
     
    122123
    123124                const Indexer *indexer;
    124         };
    125 
    126         class AutogenerateRoutines : public Visitor {
    127           public:
    128                 /// Generates assignment operators for aggregate types as required
    129                 static void autogenerateRoutines( std::list< Declaration * > &translationUnit );
    130 
    131                 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    132 
    133                 virtual void visit( EnumDecl *enumDecl );
    134                 virtual void visit( StructDecl *structDecl );
    135                 virtual void visit( UnionDecl *structDecl );
    136                 virtual void visit( TypeDecl *typeDecl );
    137                 virtual void visit( TraitDecl *ctxDecl );
    138                 virtual void visit( FunctionDecl *functionDecl );
    139 
    140                 virtual void visit( FunctionType *ftype );
    141                 virtual void visit( PointerType *ftype );
    142 
    143                 virtual void visit( CompoundStmt *compoundStmt );
    144                 virtual void visit( SwitchStmt *switchStmt );
    145                 virtual void visit( ChooseStmt *chooseStmt );
    146                 // virtual void visit( CaseStmt *caseStmt );
    147 
    148                 AutogenerateRoutines() : functionNesting( 0 ) {}
    149           private:
    150                 template< typename StmtClass > void visitStatement( StmtClass *stmt );
    151 
    152                 std::list< Declaration * > declsToAdd;
    153                 std::set< std::string > structsDone;
    154                 unsigned int functionNesting;                   // current level of nested functions
    155125        };
    156126
     
    192162                template<typename AggDecl>
    193163                void addImplicitTypedef( AggDecl * aggDecl );
    194                
     164
    195165                typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
    196166                TypedefMap typedefNames;
    197167                int scopeLevel;
    198168        };
     169
     170        class VerifyCtorDtor : public Visitor {
     171        public:
     172                /// ensure that constructors and destructors have at least one
     173                /// parameter, the first of which must be a pointer, and no
     174                /// return values.
     175                static void verify( std::list< Declaration * > &translationUnit );
     176
     177                virtual void visit( FunctionDecl *funcDecl );
     178};
    199179
    200180        class CompoundLiteral : public GenPoly::DeclMutator {
     
    217197                ReturnChecker::checkFunctionReturns( translationUnit );
    218198                mutateAll( translationUnit, compoundliteral );
    219                 AutogenerateRoutines::autogenerateRoutines( translationUnit );
     199                autogenerateRoutines( translationUnit );
    220200                acceptAll( translationUnit, pass3 );
     201                VerifyCtorDtor::verify( translationUnit );
    221202        }
    222203
     
    228209                type->accept( pass2 );
    229210                type->accept( pass3 );
    230         }
    231 
    232         template< typename Visitor >
    233         void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
    234                 std::list< Declaration * >::iterator i = translationUnit.begin();
    235                 while ( i != translationUnit.end() ) {
    236                         (*i)->accept( visitor );
    237                         std::list< Declaration * >::iterator next = i;
    238                         next++;
    239                         if ( ! visitor.get_declsToAdd().empty() ) {
    240                                 translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
    241                         } // if
    242                         i = next;
    243                 } // while
    244211        }
    245212
     
    503470        }
    504471
    505         static const std::list< std::string > noLabels;
    506 
    507         void AutogenerateRoutines::autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    508                 AutogenerateRoutines visitor;
    509                 acceptAndAdd( translationUnit, visitor, false );
    510         }
    511 
    512         template< typename OutputIterator >
    513         void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
    514                 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    515                 // unnamed bit fields are not copied as they cannot be accessed
    516                 if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
    517 
    518                 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    519 
    520                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    521                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    522 
    523                 // do something special for unnamed members
    524                 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    525                 assignExpr->get_args().push_back( dstselect );
    526 
    527                 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    528                 assignExpr->get_args().push_back( srcselect );
    529 
    530                 *out++ = new ExprStmt( noLabels, assignExpr );
    531         }
    532 
    533         template< typename OutputIterator >
    534         void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
    535                 static UniqueName indexName( "_index" );
    536 
    537                 // for a flexible array member nothing is done -- user must define own assignment
    538                 if ( ! array->get_dimension() ) return;
    539 
    540                 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
    541                 *out++ = new DeclStmt( noLabels, index );
    542 
    543                 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    544                 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    545                 init->get_args().push_back( new NameExpr( "0" ) );
    546                 Statement *initStmt = new ExprStmt( noLabels, init );
    547                 std::list<Statement *> initList;
    548                 initList.push_back( initStmt );
    549 
    550                 UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
    551                 cond->get_args().push_back( new VariableExpr( index ) );
    552                 cond->get_args().push_back( array->get_dimension()->clone() );
    553 
    554                 UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
    555                 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    556 
    557                 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    558 
    559                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    560                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    561 
    562                 Expression *dstselect = new MemberExpr( member, derefExpr );
    563                 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
    564                 dstIndex->get_args().push_back( dstselect );
    565                 dstIndex->get_args().push_back( new VariableExpr( index ) );
    566                 assignExpr->get_args().push_back( dstIndex );
    567 
    568                 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    569                 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    570                 srcIndex->get_args().push_back( srcselect );
    571                 srcIndex->get_args().push_back( new VariableExpr( index ) );
    572                 assignExpr->get_args().push_back( srcIndex );
    573 
    574                 *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) );
    575         }
    576 
    577         template< typename OutputIterator >
    578         void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
    579                 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    580                 copy->get_args().push_back( new VariableExpr( dstParam ) );
    581                 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    582                 copy->get_args().push_back( new SizeofExpr( unionType ) );
    583 
    584                 *out++ = new ExprStmt( noLabels, copy );
    585         }
    586 
    587         //E ?=?(E volatile*, int),
    588         //  ?=?(E _Atomic volatile*, int);
    589         void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
    590                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    591 
    592                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    593                 assignType->get_returnVals().push_back( returnVal );
    594 
    595                 // need two assignment operators with different types
    596                 FunctionType * assignType2 = assignType->clone();
    597 
    598                 // E ?=?(E volatile *, E)
    599                 Type *etype = refType->clone();
    600                 // etype->get_qualifiers() += Type::Qualifiers(false, true, false, false, false, false);
    601 
    602                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), etype ), 0 );
    603                 assignType->get_parameters().push_back( dstParam );
    604 
    605                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, etype->clone(), 0 );
    606                 assignType->get_parameters().push_back( srcParam );
    607 
    608                 // E ?=?(E volatile *, int)
    609                 assignType2->get_parameters().push_back( dstParam->clone() );
    610                 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
    611                 ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
    612                 assignType2->get_parameters().push_back( srcParam2 );
    613 
    614                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    615                 // because each unit generates copies of the default routines for each aggregate.
    616 
    617                 // since there is no definition, these should not be inline
    618                 // make these intrinsic so that the code generator does not make use of them
    619                 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, 0, false, false );
    620                 assignDecl->fixUniqueId();
    621                 FunctionDecl *assignDecl2 = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType2, 0, false, false );
    622                 assignDecl2->fixUniqueId();
    623 
    624                 // these should be built in the same way that the prelude
    625                 // functions are, so build a list containing the prototypes
    626                 // and allow MakeLibCfa to autogenerate the bodies.
    627                 std::list< Declaration * > assigns;
    628                 assigns.push_back( assignDecl );
    629                 assigns.push_back( assignDecl2 );
    630 
    631                 LibCfa::makeLibCfa( assigns );
    632 
    633                 // need to remove the prototypes, since this may be nested in a routine
    634                 for (int start = 0, end = assigns.size()/2; start < end; start++) {
    635                         delete assigns.front();
    636                         assigns.pop_front();
    637                 } // for
    638 
    639                 declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
    640         }
    641 
    642         /// Clones a reference type, replacing any parameters it may have with a clone of the provided list
    643         template< typename GenericInstType >
    644         GenericInstType *cloneWithParams( GenericInstType *refType, const std::list< Expression* >& params ) {
    645                 GenericInstType *clone = refType->clone();
    646                 clone->get_parameters().clear();
    647                 cloneAll( params, clone->get_parameters() );
    648                 return clone;
    649         }
    650 
    651         /// Creates a new type decl that's the same as src, but renamed and with only the ?=? assertion (for complete types only)
    652         TypeDecl *cloneAndRename( TypeDecl *src, const std::string &name ) {
    653                 TypeDecl *dst = new TypeDecl( name, src->get_storageClass(), 0, src->get_kind() );
    654 
    655                 if ( src->get_kind() == TypeDecl::Any ) {
    656                         // just include assignment operator assertion
    657                         TypeInstType *assignParamType = new TypeInstType( Type::Qualifiers(), name, dst );
    658                         FunctionType *assignFunctionType = new FunctionType( Type::Qualifiers(), false );
    659                         assignFunctionType->get_returnVals().push_back(
    660                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType->clone(), 0 ) );
    661                         assignFunctionType->get_parameters().push_back(
    662                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), assignParamType->clone() ), 0 ) );
    663                         assignFunctionType->get_parameters().push_back(
    664                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType, 0 ) );
    665                         FunctionDecl *assignAssert = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignFunctionType, 0, false, false );
    666                         dst->get_assertions().push_back( assignAssert );
    667                 }
    668 
    669                 return dst;
    670         }
    671 
    672         Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
    673                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    674 
    675                 // Make function polymorphic in same parameters as generic struct, if applicable
    676                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    677                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    678                 std::list< Expression* > structParams;  // List of matching parameters to put on types
    679                 TypeSubstitution genericSubs; // Substitutions to make to member types of struct
    680                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    681                         isGeneric = true;
    682                         TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    683                         assignType->get_forall().push_back( typeParam );
    684                         TypeInstType *newParamType = new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam );
    685                         genericSubs.add( (*param)->get_name(), newParamType );
    686                         structParams.push_back( new TypeExpr( newParamType ) );
    687                 }
    688 
    689                 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    690                 assignType->get_returnVals().push_back( returnVal );
    691 
    692                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
    693                 assignType->get_parameters().push_back( dstParam );
    694 
    695                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    696                 assignType->get_parameters().push_back( srcParam );
    697 
    698                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    699                 // because each unit generates copies of the default routines for each aggregate.
    700                 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    701                 assignDecl->fixUniqueId();
    702 
    703                 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    704                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    705                                 // query the type qualifiers of this field and skip assigning it if it is marked const.
    706                                 // If it is an array type, we need to strip off the array layers to find its qualifiers.
    707                                 Type * type = dwt->get_type();
    708                                 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    709                                         type = at->get_base();
    710                                 }
    711 
    712                                 if ( type->get_qualifiers().isConst ) {
    713                                         // don't assign const members
    714                                         continue;
    715                                 }
    716 
    717                                 if ( isGeneric ) {
    718                                         // rewrite member type in terms of the type variables on this operator
    719                                         DeclarationWithType *fixedMember = dwt->clone();
    720                                         genericSubs.apply( fixedMember );
    721 
    722                                         // assign to both destination and return value
    723                                         if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
    724                                                 makeArrayAssignment( srcParam, dstParam, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    725                                                 makeArrayAssignment( srcParam, returnVal, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    726                                         } else {
    727                                                 makeScalarAssignment( srcParam, dstParam, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
    728                                                 makeScalarAssignment( srcParam, returnVal, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
    729                                         } // if
    730                                 } else {
    731                                         // assign to destination
    732                                         if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    733                                                 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    734                                         } else {
    735                                                 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    736                                         } // if
    737                                 } // if
    738                         } // if
    739                 } // for
    740                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    741 
    742                 return assignDecl;
    743         }
    744 
    745         Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
    746                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    747 
    748                 // Make function polymorphic in same parameters as generic union, if applicable
    749                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
    750                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    751                 std::list< Expression* > unionParams;  // List of matching parameters to put on types
    752                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    753                         isGeneric = true;
    754                         TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    755                         assignType->get_forall().push_back( typeParam );
    756                         unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    757                 }
    758 
    759                 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    760                 assignType->get_returnVals().push_back( returnVal );
    761 
    762                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
    763                 assignType->get_parameters().push_back( dstParam );
    764 
    765                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    766                 assignType->get_parameters().push_back( srcParam );
    767 
    768                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    769                 // because each unit generates copies of the default routines for each aggregate.
    770                 FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    771                 assignDecl->fixUniqueId();
    772 
    773                 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    774                 if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    775                
    776                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    777 
    778                 return assignDecl;
    779         }
    780 
    781         void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
    782                 if ( ! enumDecl->get_members().empty() ) {
    783                         EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
    784                         // enumInst->set_baseEnum( enumDecl );
    785                         // declsToAdd.push_back(
    786                         makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd );
    787                 }
    788         }
    789 
    790         void AutogenerateRoutines::visit( StructDecl *structDecl ) {
    791                 if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    792                         StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    793                         structInst.set_baseStruct( structDecl );
    794                         declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) );
    795                         structsDone.insert( structDecl->get_name() );
    796                 } // if
    797         }
    798 
    799         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
    800                 if ( ! unionDecl->get_members().empty() ) {
    801                         UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    802                         unionInst.set_baseUnion( unionDecl );
    803                         declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) );
    804                 } // if
    805         }
    806 
    807         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    808                 CompoundStmt *stmts = 0;
    809                 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
    810                 typeInst->set_baseType( typeDecl );
    811                 ObjectDecl *src = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
    812                 ObjectDecl *dst = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
    813                 if ( typeDecl->get_base() ) {
    814                         stmts = new CompoundStmt( std::list< Label >() );
    815                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    816                         assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
    817                         assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
    818                         stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
    819                 } // if
    820                 FunctionType *type = new FunctionType( Type::Qualifiers(), false );
    821                 type->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
    822                 type->get_parameters().push_back( dst );
    823                 type->get_parameters().push_back( src );
    824                 FunctionDecl *func = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false, false );
    825                 declsToAdd.push_back( func );
    826         }
    827 
    828         void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
    829                 for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
    830                         statements.insert( i, new DeclStmt( noLabels, *decl ) );
    831                 } // for
    832                 declsToAdd.clear();
    833         }
    834 
    835         void AutogenerateRoutines::visit( FunctionType *) {
    836                 // ensure that we don't add assignment ops for types defined as part of the function
    837         }
    838 
    839         void AutogenerateRoutines::visit( PointerType *) {
    840                 // ensure that we don't add assignment ops for types defined as part of the pointer
    841         }
    842 
    843         void AutogenerateRoutines::visit( TraitDecl *) {
    844                 // ensure that we don't add assignment ops for types defined as part of the context
    845         }
    846 
    847         template< typename StmtClass >
    848         inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
    849                 std::set< std::string > oldStructs = structsDone;
    850                 addVisit( stmt, *this );
    851                 structsDone = oldStructs;
    852         }
    853 
    854         void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
    855                 maybeAccept( functionDecl->get_functionType(), *this );
    856                 acceptAll( functionDecl->get_oldDecls(), *this );
    857                 functionNesting += 1;
    858                 maybeAccept( functionDecl->get_statements(), *this );
    859                 functionNesting -= 1;
    860         }
    861 
    862         void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
    863                 visitStatement( compoundStmt );
    864         }
    865 
    866         void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
    867                 visitStatement( switchStmt );
    868         }
    869 
    870         void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
    871                 visitStatement( switchStmt );
    872         }
    873 
    874         // void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
    875         //      visitStatement( caseStmt );
    876         // }
    877 
    878472        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
    879473                ReturnChecker checker;
     
    1032626                return aggDecl;
    1033627        }
    1034        
     628
    1035629        template<typename AggDecl>
    1036630        void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
     
    1071665        }
    1072666
     667        void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
     668                VerifyCtorDtor verifier;
     669                acceptAll( translationUnit, verifier );
     670        }
     671
     672        void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
     673                FunctionType * funcType = funcDecl->get_functionType();
     674                std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
     675                std::list< DeclarationWithType * > &params = funcType->get_parameters();
     676
     677                if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
     678                        if ( params.size() == 0 ) {
     679                                throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
     680                        }
     681                        if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
     682                                throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
     683                        }
     684                        if ( returnVals.size() != 0 ) {
     685                                throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
     686                        }
     687                }
     688
     689                Visitor::visit( funcDecl );
     690                // original idea: modify signature of ctor/dtors and insert appropriate return statements
     691                // to cause desired behaviour
     692                // new idea: add comma exprs to every ctor call to produce first parameter.
     693                // this requires some memoization of the first parameter, because it can be a
     694                // complicated expression with side effects (see: malloc). idea: add temporary variable
     695                // that is assigned address of constructed object in ctor argument position and
     696                // return the temporary. It should also be done after all implicit ctors are
     697                // added, so not in this pass!
     698        }
     699
    1073700        DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
    1074701                storageclass = objectDecl->get_storageClass();
  • src/SymTab/module.mk

    r37f0da8 r70a06f6  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Richard C. Bilson
     
    2020       SymTab/FixFunction.cc \
    2121       SymTab/ImplementationType.cc \
    22        SymTab/TypeEquality.cc
     22       SymTab/TypeEquality.cc \
     23       SymTab/Autogen.cc
  • src/SynTree/CommaExpr.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CommaExpr.cc -- 
     7// CommaExpr.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 : Mon May 18 08:09:58 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 06 17:07:54 2016
    1313// Update Count     : 1
    1414//
     
    2020CommaExpr::CommaExpr( Expression *arg1, Expression *arg2, Expression *_aname )
    2121                : Expression( _aname ), arg1( arg1 ), arg2( arg2 ) {
     22        // xxx - result of a comma expression is never an lvalue, so should set lvalue
     23        // to false on all result types
    2224        cloneAll( arg2->get_results(), get_results() );
    2325}
  • src/SynTree/CompoundStmt.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc -- 
     7// XXX.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 : Tue Jun 23 11:37:49 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 06 14:35:37 2016
    1313// Update Count     : 3
    1414//
     
    1818#include <algorithm>
    1919#include <functional>
     20#include "Expression.h"
     21#include "Declaration.h"
    2022
    2123using std::string;
    2224using std::endl;
     25
     26class VarExprReplacer : public Visitor {
     27public:
     28  typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;
     29private:
     30  const DeclMap & declMap;
     31public:
     32  VarExprReplacer( const DeclMap & declMap ) : declMap( declMap ) {}
     33
     34  // replace variable with new node from decl map
     35  virtual void visit( VariableExpr * varExpr ) {
     36    if ( declMap.count( varExpr->get_var() ) ) {
     37      varExpr->set_var( declMap.at( varExpr->get_var() ) );
     38    }
     39  }
     40};
     41
    2342
    2443CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) {
     
    2746CompoundStmt::CompoundStmt( const CompoundStmt &other ) : Statement( other ) {
    2847        cloneAll( other.kids, kids );
     48
     49  // when cloning a compound statement, we may end up cloning declarations which
     50  // are referred to by VariableExprs throughout the block. Cloning a VariableExpr
     51  // does a shallow copy, so the VariableExpr will end up pointing to the original
     52  // declaration. If the original declaration is deleted, e.g. because the original
     53  // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case,
     54  // find all DeclarationWithType nodes (since a VariableExpr must point to a
     55  // DeclarationWithType) in the original CompoundStmt and map them to the cloned
     56  // node in the new CompoundStmt ('this'), then replace the Declarations referred to
     57  // by each VariableExpr according to the constructed map. Note that only the declarations
     58  // in the current level are collected into the map, because child CompoundStmts will
     59  // recursively execute this routine. There may be more efficient ways of doing
     60  // this.
     61  VarExprReplacer::DeclMap declMap;
     62  std::list< Statement * >::const_iterator origit = other.kids.begin();
     63  for ( Statement * s : kids ) {
     64    assert( origit != other.kids.end() );
     65    if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( s ) ) {
     66      DeclStmt * origDeclStmt = dynamic_cast< DeclStmt * >( *origit );
     67      assert( origDeclStmt );
     68      if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * > ( declStmt->get_decl() ) ) {
     69        DeclarationWithType * origdwt = dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() );
     70        assert( origdwt );
     71        declMap[ origdwt ] = dwt;
     72      }
     73    }
     74  }
     75  if ( ! declMap.empty() ) {
     76    VarExprReplacer replacer( declMap );
     77    accept( replacer );
     78  }
    2979}
    3080
  • src/SynTree/Declaration.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Declaration.h -- 
     7// Declaration.h --
    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:28:11 2016
    13 // Update Count     : 33
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 11 16:55:12 2016
     13// Update Count     : 36
    1414//
    1515
     
    2222#include "Parser/LinkageSpec.h"
    2323#include "Parser/ParseNode.h"
     24#include <string>
    2425
    2526class Declaration {
     
    6768        void set_mangleName( std::string newValue ) { mangleName = newValue; }
    6869
     70        std::string get_scopedMangleName() const { return mangleName + "_" + std::to_string(scopeLevel); }
     71
     72        int get_scopeLevel() const { return scopeLevel; }
     73        void set_scopeLevel( int newValue ) { scopeLevel = newValue; }
     74
    6975        virtual DeclarationWithType *clone() const = 0;
    7076        virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0;
     
    7581        // this represents the type with all types and typedefs expanded it is generated by SymTab::Validate::Pass2
    7682        std::string mangleName;
     83        // need to remember the scope level at which the variable was declared, so that
     84        // shadowed identifiers can be accessed
     85        int scopeLevel = 0;
    7786};
    7887
  • src/SynTree/DeclarationWithType.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // DeclarationWithType.cc -- 
     7// DeclarationWithType.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 : Sat Jun 13 08:08:07 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 11 15:35:27 2016
    1313// Update Count     : 3
    1414//
     
    2323
    2424DeclarationWithType::DeclarationWithType( const DeclarationWithType &other )
    25                 : Declaration( other ), mangleName( other.mangleName ) {
     25                : Declaration( other ), mangleName( other.mangleName ), scopeLevel( other.scopeLevel ) {
    2626}
    2727
  • src/SynTree/Expression.cc

    r37f0da8 r70a06f6  
    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 : Fri Apr  8 17:16:23 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:33:12 2016
    1313// Update Count     : 40
    1414//
     
    7979
    8080VariableExpr::VariableExpr( DeclarationWithType *_var, Expression *_aname ) : Expression( _aname ), var( _var ) {
     81        assert( var );
     82        assert( var->get_type() );
    8183        add_result( var->get_type()->clone() );
    8284        for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
     
    454456}
    455457
     458
     459ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) {
     460        assert( callExpr );
     461        cloneAll( callExpr->get_results(), results );
     462}
     463
     464ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) {
     465        cloneAll( other.results, results );
     466        cloneAll( other.copyCtors, copyCtors );
     467        cloneAll( other.tempDecls, tempDecls );
     468        cloneAll( other.returnDecls, returnDecls );
     469        cloneAll( other.dtors, dtors );
     470}
     471
     472ImplicitCopyCtorExpr::~ImplicitCopyCtorExpr() {
     473        delete callExpr;
     474        deleteAll( copyCtors );
     475        deleteAll( tempDecls );
     476        deleteAll( returnDecls );
     477        deleteAll( dtors );
     478}
     479
     480void ImplicitCopyCtorExpr::print( std::ostream &os, int indent ) const {
     481        os << std::string( indent, ' ' ) <<  "Implicit Copy Constructor Expression: " << std::endl;
     482        assert( callExpr );
     483        callExpr->print( os, indent + 2 );
     484        os << std::endl << std::string( indent, ' ' ) << "with temporaries:" << std::endl;
     485        printAll(tempDecls, os, indent+2);
     486        os << std::endl << std::string( indent, ' ' ) << "with copyCtors:" << std::endl;
     487        printAll(copyCtors, os, indent+2);
     488        Expression::print( os, indent );
     489}
     490
    456491UntypedValofExpr::UntypedValofExpr( const UntypedValofExpr & other ) : Expression( other ), body ( maybeClone( other.body ) ) {}
    457492
  • src/SynTree/Expression.h

    r37f0da8 r70a06f6  
    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 : Fri Apr  8 17:18:06 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:40:56 2016
    1313// Update Count     : 21
    1414//
     
    2222#include "Mutator.h"
    2323#include "Constant.h"
     24#include "Common/UniqueName.h"
    2425
    2526/// Expression is the root type for all expressions
     
    559560};
    560561
     562/// ImplicitCopyCtorExpr represents the application of a function to a set of parameters,
     563/// along with a set of copy constructor calls, one for each argument.
     564class ImplicitCopyCtorExpr : public Expression {
     565public:
     566        ImplicitCopyCtorExpr( ApplicationExpr * callExpr );
     567        ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other );
     568        virtual ~ImplicitCopyCtorExpr();
     569
     570        ApplicationExpr *get_callExpr() const { return callExpr; }
     571        void set_callExpr( ApplicationExpr *newValue ) { callExpr = newValue; }
     572
     573        std::list< Expression * > & get_copyCtors() { return copyCtors; }
     574        void set_copyCtors( std::list< Expression * > newValue ) { copyCtors = newValue; }
     575
     576        std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
     577        void set_tempDecls( std::list< ObjectDecl * > newValue ) { tempDecls = newValue; }
     578
     579        std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; }
     580        void set_returnDecls( std::list< ObjectDecl * > newValue ) { returnDecls = newValue; }
     581
     582        std::list< Expression * > & get_dtors() { return dtors; }
     583        void set_dtors( std::list< Expression * > newValue ) { dtors = newValue; }
     584
     585        virtual ImplicitCopyCtorExpr *clone() const { return new ImplicitCopyCtorExpr( *this ); }
     586        virtual void accept( Visitor &v ) { v.visit( this ); }
     587        virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     588        virtual void print( std::ostream &os, int indent = 0 ) const;
     589  private:
     590        ApplicationExpr * callExpr;
     591        std::list< Expression * > copyCtors;
     592        std::list< ObjectDecl * > tempDecls;
     593        std::list< ObjectDecl * > returnDecls;
     594        std::list< Expression * > dtors;
     595};
     596
    561597/// ValofExpr represents a GCC 'lambda expression'
    562598class UntypedValofExpr : public Expression {
  • src/SynTree/Initializer.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Initializer.cc -- 
     7// Initializer.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Aug 12 14:05:25 2015
    13 // Update Count     : 14
     12// Last Modified On : Mon Apr 11 17:36:10 2016
     13// Update Count     : 28
    1414//
    1515
    1616#include "Initializer.h"
    1717#include "Expression.h"
     18#include "Statement.h"
    1819#include "Common/utility.h"
    1920
    20 Initializer::Initializer() {}
     21Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
    2122
    2223Initializer::~Initializer() {}
     
    3132void Initializer::print( std::ostream &os, int indent ) {}
    3233
    33 SingleInit::SingleInit( Expression *v, std::list< Expression *> &_designators ) : value ( v ), designators( _designators ) {
     34SingleInit::SingleInit( Expression *v, const std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) {
    3435}
    3536
    36 SingleInit::SingleInit( const SingleInit &other ) : value ( other.value ) {
     37SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) {
    3738        cloneAll(other.designators, designators );
    3839}
     
    5455}
    5556
    56 ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators )
    57         : initializers( _initializers ), designators( _designators ) {
     57ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed )
     58        : Initializer( maybeConstructed), initializers( _initializers ), designators( _designators ) {
    5859}
    5960
     
    6566
    6667void ListInit::print( std::ostream &os, int indent ) {
    67         os << std::endl << std::string(indent, ' ') << "Compound initializer:  "; 
     68        os << std::endl << std::string(indent, ' ') << "Compound initializer:  ";
    6869        if ( ! designators.empty() ) {
    6970                os << std::string(indent + 2, ' ' ) << "designated by: [";
    7071                for ( std::list < Expression * >::iterator i = designators.begin();
    7172                          i != designators.end(); i++ ) {
    72                         ( *i )->print(os, indent + 4 ); 
     73                        ( *i )->print(os, indent + 4 );
    7374                } // for
    74        
     75
    7576                os << std::string(indent + 2, ' ' ) << "]";
    7677        } // if
    7778
    78         for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ ) 
     79        for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ )
    7980                (*i)->print( os, indent + 2 );
    8081}
     82
     83
     84ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {}
     85ConstructorInit::~ConstructorInit() {
     86        delete ctor;
     87        delete init;
     88}
     89
     90ConstructorInit *ConstructorInit::clone() const {
     91        return new ConstructorInit( *this );
     92}
     93
     94void ConstructorInit::print( std::ostream &os, int indent ) {
     95        os << std::endl << std::string(indent, ' ') << "Constructor initializer: ";
     96        if ( ctor ) {
     97                os << " initially constructed with ";
     98                ctor->print( os, indent+2 );
     99        } // if
     100
     101        if ( dtor ) {
     102                os << " destructed with ";
     103                dtor->print( os, indent+2 );
     104        }
     105
     106        if ( init ) {
     107                os << " with fallback C-style initializer: ";
     108                init->print( os, indent+2 );
     109        }
     110}
     111
     112std::ostream & operator<<( std::ostream & out, Initializer * init ) {
     113        init->print( out );
     114        return out;
     115}
     116
    81117// Local Variables: //
    82118// tab-width: 4 //
  • src/SynTree/Initializer.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Initializer.h -- 
     7// Initializer.h --
    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 : Mon May 18 09:03:48 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Apr 12 13:49:13 2016
     13// Update Count     : 19
    1414//
    1515
     
    2727  public:
    2828        //      Initializer( std::string _name = std::string(""), int _pos = 0 );
    29         Initializer( );
     29        Initializer( bool maybeConstructed );
    3030        virtual ~Initializer();
    3131
     
    4343        }
    4444
     45        bool get_maybeConstructed() { return maybeConstructed; }
     46
    4547        virtual Initializer *clone() const = 0;
    4648        virtual void accept( Visitor &v ) = 0;
     
    5052        //      std::string name;
    5153        //      int pos;
     54        bool maybeConstructed;
    5255};
    5356
     
    5558class SingleInit : public Initializer {
    5659  public:
    57         SingleInit( Expression *value, std::list< Expression *> &designators = *(new std::list<Expression *>()) );
     60        SingleInit( Expression *value, const std::list< Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
    5861        SingleInit( const SingleInit &other );
    5962        virtual ~SingleInit();
    60        
     63
    6164        Expression *get_value() { return value; }
    6265        void set_value( Expression *newValue ) { value = newValue; }
     
    7982class ListInit : public Initializer {
    8083  public:
    81         ListInit( std::list<Initializer*> &,
    82                           std::list<Expression *> &designators = *(new std::list<Expression *>()) );
     84        ListInit( const std::list<Initializer*> &initializers,
     85                          const std::list<Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
    8386        virtual ~ListInit();
    8487
     
    100103};
    101104
     105// ConstructorInit represents an initializer that is either a constructor expression or
     106// a C-style initializer.
     107class ConstructorInit : public Initializer {
     108  public:
     109        ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init );
     110        virtual ~ConstructorInit();
     111
     112        void set_ctor( Statement * newValue ) { ctor = newValue; }
     113        Statement * get_ctor() const { return ctor; }
     114        void set_dtor( Statement * newValue ) { dtor = newValue; }
     115        Statement * get_dtor() const { return dtor; }
     116        void set_init( Initializer * newValue ) { init = newValue; }
     117        Initializer * get_init() const { return init; }
     118
     119        virtual ConstructorInit *clone() const;
     120        virtual void accept( Visitor &v ) { v.visit( this ); }
     121        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     122        virtual void print( std::ostream &os, int indent = 0 );
     123
     124  private:
     125        Statement * ctor;
     126        Statement * dtor;
     127        // C-style initializer made up of SingleInit and ListInit nodes to use as a fallback
     128        // if an appropriate constructor definition is not found by the resolver
     129        Initializer * init;
     130};
     131
     132std::ostream & operator<<( std::ostream & out, Initializer * init );
     133
    102134#endif // INITIALIZER_H
    103135
  • src/SynTree/Mutator.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Mutator.cc -- 
     7// Mutator.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 : Fri Apr  1 18:05:16 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:32:19 2016
    1313// Update Count     : 16
    1414//
     
    337337}
    338338
     339Expression* Mutator::mutate( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     340        impCpCtorExpr->set_callExpr( maybeMutate( impCpCtorExpr->get_callExpr(), *this ) );
     341        mutateAll( impCpCtorExpr->get_copyCtors(), *this );
     342        mutateAll( impCpCtorExpr->get_tempDecls(), *this );
     343        return impCpCtorExpr;
     344}
     345
    339346Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) {
    340347        mutateAll( valofExpr->get_results(), *this );
     
    450457}
    451458
     459Initializer *Mutator::mutate( ConstructorInit *ctorInit ) {
     460        ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
     461        ctorInit->set_init( maybeMutate( ctorInit->get_init(), *this ) );
     462        return ctorInit;
     463}
     464
    452465Subrange *Mutator::mutate( Subrange *subrange ) {
    453466        return subrange;
  • src/SynTree/Mutator.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Mutator.h -- 
     7// Mutator.h --
    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 : Fri Apr  1 17:26:56 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:32:00 2016
    1313// Update Count     : 10
    1414//
     
    6262        virtual Expression* mutate( MemberExpr *memberExpr );
    6363        virtual Expression* mutate( VariableExpr *variableExpr );
    64         virtual Expression* mutate( ConstantExpr *constantExpr ); 
     64        virtual Expression* mutate( ConstantExpr *constantExpr );
    6565        virtual Expression* mutate( SizeofExpr *sizeofExpr );
    6666        virtual Expression* mutate( AlignofExpr *alignofExpr );
     
    7676        virtual Expression* mutate( TypeExpr *typeExpr );
    7777        virtual Expression* mutate( AsmExpr *asmExpr );
     78        virtual Expression* mutate( ImplicitCopyCtorExpr *impCpCtorExpr );
    7879        virtual Expression* mutate( UntypedValofExpr *valofExpr );
    7980        virtual Expression* mutate( CompoundLiteralExpr *compLitExpr );
     
    9697        virtual Initializer* mutate( SingleInit *singleInit );
    9798        virtual Initializer* mutate( ListInit *listInit );
     99        virtual Initializer* mutate( ConstructorInit *ctorInit );
    98100
    99101        virtual Subrange *mutate( Subrange *subrange );
  • src/SynTree/ObjectDecl.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ObjectDecl.cc -- 
     7// ObjectDecl.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Sep 29 14:13:01 2015
    13 // Update Count     : 18
     12// Last Modified On : Tue Feb 09 13:21:03 2016
     13// Update Count     : 30
    1414//
    1515
     
    1919#include "Expression.h"
    2020#include "Common/utility.h"
     21#include "Statement.h"
    2122
    2223ObjectDecl::ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, bool isInline, bool isNoreturn )
     
    5859                os << " with initializer ";
    5960                init->print( os, indent );
     61                os << std::string(indent, ' ') << "maybeConstructed? " << init->get_maybeConstructed();
    6062        } // if
    6163
     
    6971#if 0
    7072        if ( get_mangleName() != "") {
    71                 os << get_mangleName() << ": "; 
    72         } else 
     73                os << get_mangleName() << ": ";
     74        } else
    7375#endif
    7476        if ( get_name() != "" ) {
  • src/SynTree/SynTree.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // SynTree.h -- 
     7// SynTree.h --
    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 : Fri Apr  1 16:47:44 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:31:36 2016
    1313// Update Count     : 5
    1414//
     
    8181class TypeExpr;
    8282class AsmExpr;
     83class ImplicitCopyCtorExpr;
    8384class UntypedValofExpr;
    8485class CompoundLiteralExpr;
     
    104105class SingleInit;
    105106class ListInit;
     107class ConstructorInit;
    106108
    107109class Subrange;
  • src/SynTree/Visitor.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Visitor.cc -- 
     7// Visitor.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 : Fri Apr  1 18:05:13 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:31:18 2016
    1313// Update Count     : 18
    1414//
     
    284284}
    285285
     286void Visitor::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     287        maybeAccept( impCpCtorExpr->get_callExpr(), *this );
     288        acceptAll( impCpCtorExpr->get_copyCtors(), *this );
     289        acceptAll( impCpCtorExpr->get_tempDecls(), *this );
     290}
     291
    286292void Visitor::visit( UntypedValofExpr *valofExpr ) {
    287293        acceptAll( valofExpr->get_results(), *this );
     
    379385}
    380386
     387void Visitor::visit( ConstructorInit *ctorInit ) {
     388        maybeAccept( ctorInit->get_ctor(), *this );
     389        maybeAccept( ctorInit->get_init(), *this );
     390}
     391
    381392void Visitor::visit( Subrange *subrange ) {}
    382393
  • src/SynTree/Visitor.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Visitor.h -- 
     7// Visitor.h --
    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 : Fri Apr  1 17:26:55 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:30:58 2016
    1313// Update Count     : 7
    1414//
     
    6262        virtual void visit( MemberExpr *memberExpr );
    6363        virtual void visit( VariableExpr *variableExpr );
    64         virtual void visit( ConstantExpr *constantExpr ); 
     64        virtual void visit( ConstantExpr *constantExpr );
    6565        virtual void visit( SizeofExpr *sizeofExpr );
    6666        virtual void visit( AlignofExpr *alignofExpr );
     
    7676        virtual void visit( TypeExpr *typeExpr );
    7777        virtual void visit( AsmExpr *asmExpr );
     78        virtual void visit( ImplicitCopyCtorExpr *impCpCtorExpr );
    7879        virtual void visit( UntypedValofExpr *valofExpr );
    7980        virtual void visit( CompoundLiteralExpr *compLitExpr );
     
    9697        virtual void visit( SingleInit *singleInit );
    9798        virtual void visit( ListInit *listInit );
     99        virtual void visit( ConstructorInit *ctorInit );
    98100
    99101        virtual void visit( Subrange *subrange );
  • src/examples/vector_int.c

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // vector_int.c -- 
     7// vector_int.c --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 27 18:38:05 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 06 17:18:31 2016
    1313// Update Count     : 3
    1414//
     
    2222#define DEFAULT_CAPACITY 20
    2323
    24 vector_int vector_int_allocate() {
    25         return vector_int_allocate( DEFAULT_CAPACITY );
     24void ?{}( vector_int * vec ) {
     25        vec { DEFAULT_CAPACITY };
    2626}
    2727
    28 vector_int vector_int_allocate( int reserve ) {
    29         vector_int new_vector;
    30         new_vector.last = -1;
    31         new_vector.capacity = reserve;
    32         new_vector.data = malloc( sizeof( int ) * reserve );
    33         return new_vector;
     28void ?{}( vector_int * vec, int reserve ) {
     29        vec->last = -1;
     30        vec->capacity = reserve;
     31        vec->data = malloc( sizeof( int ) * reserve );
    3432}
    3533
    36 void vector_int_deallocate( vector_int vec ) {
    37         free( vec.data );
     34void ^?{}( vector_int * vec ) {
     35        free( vec->data );
    3836}
    3937
  • src/examples/vector_int.h

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // vector_int.h -- 
     7// vector_int.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 27 18:39:05 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 06 17:21:59 2016
    1313// Update Count     : 2
    1414//
     
    2525} vector_int;
    2626
    27 vector_int vector_int_allocate();                                               // allocate vector with default capacity
    28 vector_int vector_int_allocate( int reserve );                  // allocate vector with specified capacity
    29 void vector_int_deallocate( vector_int );                               // deallocate vector's storage
     27void ?{}( vector_int * );                                                               // allocate vector with default capacity
     28void ?{}( vector_int *, int reserve );                                  // allocate vector with specified capacity
     29void ^?{}( vector_int * );                                                              // deallocate vector's storage
    3030
    3131void reserve( vector_int *vec, int reserve );                   // reserve more capacity
  • src/examples/vector_test.c

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // vector_test.c -- 
     7// vector_test.c --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 17 12:23:55 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 06 17:19:07 2016
    1313// Update Count     : 18
    1414//
     
    2020
    2121int main( void ) {
    22         vector_int vec = vector_int_allocate();
     22        vector_int vec;
    2323
    2424        // read in numbers until EOF or error
  • src/initialization.txt

    r37f0da8 r70a06f6  
    3434sure that resolved initializers for all declarations are being
    3535generated.
     36
     37
     38------
     39
     40More recent email: (I am quoted; Richard is the responder)
     41> As far as I'm aware, the only way that I could currently get the correct
     42> results from the unification engine is by feeding it an expression that
     43> looks like "?=?( ((struct Y)x.y).a, 10 )", then picking out the pieces that
     44> I need (namely the correct choice for a). Does this seem like a reasonable
     45> approach to solve this problem?
     46
     47No, unfortunately. Initialization isn't being rewritten as assignment,
     48so you shouldn't allow the particular selection of assignment
     49operators that happen to be in scope (and which may include
     50user-defined operators) to guide the type resolution.
     51
     52I don't think there is any way to rewrite an initializer as a single
     53expression and have the resolver just do the right thing. I see the
     54algorithm as:
     55
     56For each alternative interpretation of the designator:
     57  Construct an expression that casts the initializer to the type of
     58    the designator
     59  Construct an AlternativeFinder and use it to find the lowest cost
     60    interpretation of the expression
     61  Add this interpretation to a list of possibilities
     62Go through the list of possibilities and pick the lowest cost
     63
     64As with many things in the resolver, it's conceptually simple but the
     65implementation may be a bit of a pain. It fits in with functions like
     66findSingleExpression, findIntegralExpression in Resolver.cc, although
     67it will be significantly more complicated than any of the existing
     68ones.
     69
     70
     71
  • src/libcfa/Makefile.am

    r37f0da8 r70a06f6  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## Makefile.am -- 
     8## Makefile.am --
    99##
    1010## Author           : Peter A. Buhr
     
    5151
    5252CFLAGS = -g -Wall -Wno-unused-function -B${abs_top_srcdir}/src/driver -XCFA -t  # TEMPORARY: does not build with -O2
    53 CC = ${abs_top_srcdir}/src/driver/cfa 
     53CC = ${abs_top_srcdir}/src/driver/cfa
    5454
    5555# extension-less header files are overridden by default make rules => explicitly override rule
     
    6767include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders}
    6868
     69CLEANFILES = libcfa-prelude.c
    6970MAINTAINERCLEANFILES += ${includedir}/*
  • src/libcfa/Makefile.in

    r37f0da8 r70a06f6  
    110110AWK = @AWK@
    111111BACKEND_CC = @BACKEND_CC@
    112 CC = ${abs_top_srcdir}/src/driver/cfa 
     112CC = ${abs_top_srcdir}/src/driver/cfa
    113113CCDEPMODE = @CCDEPMODE@
    114114CFA_BINDIR = @CFA_BINDIR@
     
    218218cfaheaders = # limits
    219219include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders}
     220CLEANFILES = libcfa-prelude.c
    220221all: all-am
    221222
     
    455456
    456457clean-generic:
     458        -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
    457459
    458460distclean-generic:
  • src/libcfa/iostream.c

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // iostream.c -- 
     7// iostream.c --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  6 16:13:29 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 16:02:09 2016
    1313// Update Count     : 278
    1414//
     
    193193
    194194
    195 forall( dtype ostype | ostream( ostype ) ) 
     195forall( dtype ostype | ostream( ostype ) )
    196196ostype * ?|?( ostype *os, ostype * (* manip)( ostype * ) ) {
    197197        return manip( os );
    198198} // ?|?
    199199
    200 forall( dtype ostype | ostream( ostype ) ) 
     200forall( dtype ostype | ostream( ostype ) )
    201201ostype * endl( ostype * os ) {
    202202        os | '\n';
     
    206206} // endl
    207207
    208 forall( dtype ostype | ostream( ostype ) ) 
     208forall( dtype ostype | ostream( ostype ) )
    209209ostype * sepOn( ostype * os ) {
    210210        sepOn( os );
     
    212212} // sepOn
    213213
    214 forall( dtype ostype | ostream( ostype ) ) 
     214forall( dtype ostype | ostream( ostype ) )
    215215ostype * sepOff( ostype * os ) {
    216216        sepOff( os );
     
    218218} // sepOff
    219219
    220 forall( dtype ostype | ostream( ostype ) ) 
     220forall( dtype ostype | ostream( ostype ) )
    221221ostype * sepEnable( ostype * os ) {
    222222        sepEnable( os );
     
    224224} // sepEnable
    225225
    226 forall( dtype ostype | ostream( ostype ) ) 
     226forall( dtype ostype | ostream( ostype ) )
    227227ostype * sepDisable( ostype * os ) {
    228228        sepDisable( os );
     
    344344} // ?|?
    345345
    346 _Istream_cstrUC cstr( char * s ) { _Istream_cstrUC s = { s }; return s; }
     346_Istream_cstrUC cstr( char * str ) { _Istream_cstrUC s = { str }; return s; }
    347347forall( dtype istype | istream( istype ) )
    348348istype * ?|?( istype * is, _Istream_cstrUC cstr ) {
     
    351351} // cstr
    352352
    353 _Istream_cstrC cstr( char * s, int size ) { _Istream_cstrC s = { s, size }; return s; }
     353_Istream_cstrC cstr( char * str, int size ) { _Istream_cstrC s = { str, size }; return s; }
    354354forall( dtype istype | istream( istype ) )
    355355istype * ?|?( istype * is, _Istream_cstrC cstr ) {
  • src/libcfa/prelude.cf

    r37f0da8 r70a06f6  
    11# 2 "prelude.cf"  // needed for error messages from this file
    2 //                               -*- Mode: C -*- 
    3 // 
     2//                               -*- Mode: C -*-
     3//
    44// Copyright (C) Glen Ditchfield 1994, 1999
    5 // 
     5//
    66// prelude.cf -- Standard Cforall Preample for C99
    7 // 
     7//
    88// Author           : Glen Ditchfield
    99// Created On       : Sat Nov 29 07:23:41 2014
     
    117117forall( ftype FT ) lvalue FT             *?( FT * );
    118118
    119 _Bool                   +?( _Bool ),                    -?( _Bool ),                    ~?( _Bool );         
    120 signed int              +?( signed int ),               -?( signed int ),               ~?( signed int );           
    121 unsigned int            +?( unsigned int ),             -?( unsigned int ),             ~?( unsigned int );         
    122 signed long int         +?( signed long int ),          -?( signed long int ),          ~?( signed long int );       
    123 unsigned long int       +?( unsigned long int ),        -?( unsigned long int ),        ~?( unsigned long int );             
    124 signed long long int    +?( signed long long int ),     -?( signed long long int ),     ~?( signed long long int );   
    125 unsigned long long int  +?( unsigned long long int ),   -?( unsigned long long int ),   ~?( unsigned long long int ); 
     119_Bool                   +?( _Bool ),                    -?( _Bool ),                    ~?( _Bool );
     120signed int              +?( signed int ),               -?( signed int ),               ~?( signed int );
     121unsigned int            +?( unsigned int ),             -?( unsigned int ),             ~?( unsigned int );
     122signed long int         +?( signed long int ),          -?( signed long int ),          ~?( signed long int );
     123unsigned long int       +?( unsigned long int ),        -?( unsigned long int ),        ~?( unsigned long int );
     124signed long long int    +?( signed long long int ),     -?( signed long long int ),     ~?( signed long long int );
     125unsigned long long int  +?( unsigned long long int ),   -?( unsigned long long int ),   ~?( unsigned long long int );
    126126float                   +?( float ),                    -?( float );
    127127double                  +?( double ),                   -?( double );
     
    627627                        ?+=?( long double _Complex *, long double _Complex ), ?+=?( volatile long double _Complex *, long double _Complex ),
    628628                        ?-=?( long double _Complex *, long double _Complex ), ?-=?( volatile long double _Complex *, long double _Complex );
     629
     630
     631
     632
     633
     634// ------------------------------------------------------------
     635//
     636// Section ??? Constructors and Destructors
     637//
     638// ------------------------------------------------------------
     639
     640// default ctor
     641void    ?{}( _Bool * ),                         ?{}( volatile _Bool * );
     642void    ?{}( char * ),  ?{}( volatile char * );
     643void    ?{}( unsigned char * ), ?{}( volatile unsigned char * );
     644void    ?{}( char signed * ),                   ?{}( volatile char signed * );
     645void    ?{}( int short * ),                             ?{}( volatile int short * );
     646void    ?{}( int short unsigned * ),    ?{}( volatile int short unsigned * );
     647void    ?{}( signed int * ),                    ?{}( volatile signed int * );
     648void    ?{}( unsigned int * ),                  ?{}( volatile unsigned int * );
     649void    ?{}( signed long int * ),               ?{}( volatile signed long int * );
     650void    ?{}( unsigned long int * ),             ?{}( volatile unsigned long int * );
     651void    ?{}( signed long long int * ),          ?{}( volatile signed long long int * );
     652void    ?{}( unsigned long long int * ),        ?{}( volatile unsigned long long int * );
     653void    ?{}( float * ),                         ?{}( volatile float * );
     654void    ?{}( double * ),                        ?{}( volatile double * );
     655void    ?{}( long double * ),                   ?{}( volatile long double * );
     656void    ?{}( float _Complex * ),                ?{}( volatile float _Complex * );
     657void    ?{}( double _Complex * ),               ?{}( volatile double _Complex * );
     658void    ?{}( long double _Complex * ),          ?{}( volatile long double _Complex * );
     659
     660// copy ctor
     661void    ?{}( _Bool *, _Bool ),                                  ?{}( volatile _Bool *, _Bool );
     662void    ?{}( char *, char ),    ?{}( volatile char *, char );
     663void    ?{}( unsigned char *, unsigned char ),                  ?{}( volatile unsigned char *, unsigned char );
     664void    ?{}( char signed *, char signed ),                      ?{}( volatile char signed *, char signed );
     665void    ?{}( int short *, int short ),                          ?{}( volatile int short *, int short );
     666void    ?{}( int short unsigned *, int short unsigned ),        ?{}( volatile int short unsigned *, int short unsigned );
     667void    ?{}( signed int *, signed int),                         ?{}( volatile signed int *, signed int );
     668void    ?{}( unsigned int *, unsigned int),                     ?{}( volatile unsigned int *, unsigned int );
     669void    ?{}( signed long int *, signed long int),               ?{}( volatile signed long int *, signed long int );
     670void    ?{}( unsigned long int *, unsigned long int),           ?{}( volatile unsigned long int *, unsigned long int );
     671void    ?{}( signed long long int *, signed long long int),     ?{}( volatile signed long long int *, signed long long int );
     672void    ?{}( unsigned long long int *, unsigned long long int), ?{}( volatile unsigned long long int *, unsigned long long int );
     673void    ?{}( float *, float),                                   ?{}( volatile float *, float );
     674void    ?{}( double *, double),                                 ?{}( volatile double *, double );
     675void    ?{}( long double *, long double),                       ?{}( volatile long double *, long double );
     676void    ?{}( float _Complex *, float _Complex),                 ?{}( volatile float _Complex *, float _Complex );
     677void    ?{}( double _Complex *, double _Complex),               ?{}( volatile double _Complex *, double _Complex );
     678void    ?{}( long double _Complex *, long double _Complex),     ?{}( volatile long double _Complex *, long double _Complex );
     679
     680// dtor
     681void    ^?{}( _Bool * ),                        ^?{}( volatile _Bool * );
     682void    ^?{}( char * ), ^?{}( volatile char * );
     683void    ^?{}( char unsigned * ),                        ^?{}( volatile char unsigned * );
     684void    ^?{}( char signed * ),                  ^?{}( volatile char signed * );
     685void    ^?{}( int short * ),                            ^?{}( volatile int short * );
     686void    ^?{}( int short unsigned * ),   ^?{}( volatile int short unsigned * );
     687void    ^?{}( signed int * ),                   ^?{}( volatile signed int * );
     688void    ^?{}( unsigned int * ),                 ^?{}( volatile unsigned int * );
     689void    ^?{}( signed long int * ),              ^?{}( volatile signed long int * );
     690void    ^?{}( unsigned long int * ),            ^?{}( volatile unsigned long int * );
     691void    ^?{}( signed long long int * ),         ^?{}( volatile signed long long int * );
     692void    ^?{}( unsigned long long int * ),       ^?{}( volatile unsigned long long int * );
     693void    ^?{}( float * ),                        ^?{}( volatile float * );
     694void    ^?{}( double * ),                       ^?{}( volatile double * );
     695void    ^?{}( long double * ),                  ^?{}( volatile long double * );
     696void    ^?{}( float _Complex * ),               ^?{}( volatile float _Complex * );
     697void    ^?{}( double _Complex * ),              ^?{}( volatile double _Complex * );
     698void    ^?{}( long double _Complex * ),         ^?{}( volatile long double _Complex * );
     699
     700// // default ctor
     701// forall( dtype DT ) void       ?{}(                DT ** );
     702// forall( dtype DT ) void       ?{}( const          DT ** );
     703// forall( dtype DT ) void       ?{}(       volatile DT ** );
     704// forall( dtype DT ) void       ?{}( const volatile DT ** );
     705
     706// // copy ctor
     707// forall( dtype DT ) void       ?{}(                DT **, DT* );
     708// forall( dtype DT ) void       ?{}( const          DT **, DT* );
     709// forall( dtype DT ) void       ?{}(       volatile DT **, DT* );
     710// forall( dtype DT ) void       ?{}( const volatile DT **, DT* );
     711
     712// // dtor
     713// forall( dtype DT ) void      ^?{}(                DT ** );
     714// forall( dtype DT ) void      ^?{}( const          DT ** );
     715// forall( dtype DT ) void      ^?{}(       volatile DT ** );
     716// forall( dtype DT ) void      ^?{}( const volatile DT ** );
     717
     718// copied from assignment section
     719// copy constructors
     720forall( ftype FT ) void ?{}( FT **, FT * );
     721forall( ftype FT ) void ?{}( FT * volatile *, FT * );
     722
     723forall( dtype DT ) void ?{}(                 DT *          *,                   DT * );
     724forall( dtype DT ) void ?{}(                 DT * volatile *,                   DT * );
     725forall( dtype DT ) void ?{}( const           DT *          *,                   DT * );
     726forall( dtype DT ) void ?{}( const           DT * volatile *,                   DT * );
     727forall( dtype DT ) void ?{}( const           DT *          *, const             DT * );
     728forall( dtype DT ) void ?{}( const           DT * volatile *, const             DT * );
     729forall( dtype DT ) void ?{}(       volatile  DT *          *,                   DT * );
     730forall( dtype DT ) void ?{}(       volatile  DT * volatile *,                   DT * );
     731forall( dtype DT ) void ?{}(       volatile  DT *          *,       volatile    DT * );
     732forall( dtype DT ) void ?{}(       volatile  DT * volatile *,       volatile    DT * );
     733
     734forall( dtype DT ) void ?{}( const volatile  DT *          *,                   DT * );
     735forall( dtype DT ) void ?{}( const volatile  DT * volatile *,                   DT * );
     736forall( dtype DT ) void ?{}( const volatile  DT *          *, const             DT * );
     737forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const             DT * );
     738forall( dtype DT ) void ?{}( const volatile  DT *          *,       volatile    DT * );
     739forall( dtype DT ) void ?{}( const volatile  DT * volatile *,       volatile    DT * );
     740forall( dtype DT ) void ?{}( const volatile  DT *          *, const volatile    DT * );
     741forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const volatile    DT * );
     742
     743forall( dtype DT ) void ?{}(                 DT *          *,                   void * );
     744forall( dtype DT ) void ?{}(                 DT * volatile *,                   void * );
     745forall( dtype DT ) void ?{}( const           DT *          *,                   void * );
     746forall( dtype DT ) void ?{}( const           DT * volatile *,                   void * );
     747forall( dtype DT ) void ?{}( const           DT *          *, const             void * );
     748forall( dtype DT ) void ?{}( const           DT * volatile *, const             void * );
     749forall( dtype DT ) void ?{}(       volatile  DT *          *,                   void * );
     750forall( dtype DT ) void ?{}(       volatile  DT * volatile *,                   void * );
     751forall( dtype DT ) void ?{}(       volatile  DT *          *,       volatile    void * );
     752forall( dtype DT ) void ?{}(       volatile  DT * volatile *,       volatile    void * );
     753
     754forall( dtype DT ) void ?{}( const volatile  DT *          *,                   void * );
     755forall( dtype DT ) void ?{}( const volatile  DT * volatile *,                   void * );
     756forall( dtype DT ) void ?{}( const volatile  DT *          *, const             void * );
     757forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const             void * );
     758forall( dtype DT ) void ?{}( const volatile  DT *          *,       volatile    void * );
     759forall( dtype DT ) void ?{}( const volatile  DT * volatile *,       volatile    void * );
     760forall( dtype DT ) void ?{}( const volatile  DT *          *, const volatile    void * );
     761forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const volatile    void * );
     762
     763forall( dtype DT ) void ?{}(                 void *          *,                 DT * );
     764forall( dtype DT ) void ?{}(                 void * volatile *,                 DT * );
     765forall( dtype DT ) void ?{}( const           void *          *,                 DT * );
     766forall( dtype DT ) void ?{}( const           void * volatile *,                 DT * );
     767forall( dtype DT ) void ?{}( const           void *          *, const           DT * );
     768forall( dtype DT ) void ?{}( const           void * volatile *, const           DT * );
     769forall( dtype DT ) void ?{}(        volatile void *          *,                 DT * );
     770forall( dtype DT ) void ?{}(        volatile void * volatile *,                 DT * );
     771forall( dtype DT ) void ?{}(        volatile void *          *,       volatile  DT * );
     772forall( dtype DT ) void ?{}(        volatile void * volatile *,       volatile  DT * );
     773forall( dtype DT ) void ?{}( const volatile void *           *,                 DT * );
     774forall( dtype DT ) void ?{}( const volatile void * volatile *,                  DT * );
     775forall( dtype DT ) void ?{}( const volatile void *           *, const           DT * );
     776forall( dtype DT ) void ?{}( const volatile void * volatile *, const            DT * );
     777forall( dtype DT ) void ?{}( const volatile void *           *,       volatile  DT * );
     778forall( dtype DT ) void ?{}( const volatile void * volatile *,        volatile  DT * );
     779forall( dtype DT ) void ?{}( const volatile void *           *, const volatile  DT * );
     780forall( dtype DT ) void ?{}( const volatile void * volatile *, const volatile   DT * );
     781
     782void    ?{}(                void *          *,                void * );
     783void    ?{}(                void * volatile *,                void * );
     784void    ?{}( const          void *          *,                void * );
     785void    ?{}( const          void * volatile *,                void * );
     786void    ?{}( const          void *          *, const          void * );
     787void    ?{}( const          void * volatile *, const          void * );
     788void    ?{}(       volatile void *          *,                void * );
     789void    ?{}(       volatile void * volatile *,                void * );
     790void    ?{}(       volatile void *          *,       volatile void * );
     791void    ?{}(       volatile void * volatile *,       volatile void * );
     792void    ?{}( const volatile void *          *,                void * );
     793void    ?{}( const volatile void * volatile *,                void * );
     794void    ?{}( const volatile void *          *, const          void * );
     795void    ?{}( const volatile void * volatile *, const          void * );
     796void    ?{}( const volatile void *          *,       volatile void * );
     797void    ?{}( const volatile void * volatile *,       volatile void * );
     798void    ?{}( const volatile void *          *, const volatile void * );
     799void    ?{}( const volatile void * volatile *, const volatile void * );
     800
     801//forall( dtype DT ) void ?{}(              DT *          *, forall( dtype DT2 ) const DT2 * );
     802//forall( dtype DT ) void ?{}(              DT * volatile *, forall( dtype DT2 ) const DT2 * );
     803forall( dtype DT ) void ?{}( const          DT *          *, forall( dtype DT2 ) const DT2 * );
     804forall( dtype DT ) void ?{}( const          DT * volatile *, forall( dtype DT2 ) const DT2 * );
     805//forall( dtype DT ) void ?{}( volatile     DT *          *, forall( dtype DT2 ) const DT2 * );
     806//forall( dtype DT ) void ?{}( volatile     DT * volatile *, forall( dtype DT2 ) const DT2 * );
     807forall( dtype DT ) void ?{}( const volatile DT *          *, forall( dtype DT2 ) const DT2 * );
     808forall( dtype DT ) void ?{}( const volatile DT * volatile *, forall( dtype DT2 ) const DT2 * );
     809
     810forall( ftype FT ) void ?{}( FT *          *, forall( ftype FT2 ) FT2 * );
     811forall( ftype FT ) void ?{}( FT * volatile *, forall( ftype FT2 ) FT2 * );
     812
     813// default ctors
     814forall( ftype FT ) void ?{}( FT *          * );
     815forall( ftype FT ) void ?{}( FT * volatile * );
     816
     817forall( dtype DT ) void ?{}(                 DT *          *);
     818forall( dtype DT ) void ?{}(                 DT * volatile *);
     819forall( dtype DT ) void ?{}( const           DT *          *);
     820forall( dtype DT ) void ?{}( const           DT * volatile *);
     821forall( dtype DT ) void ?{}(       volatile  DT *          *);
     822forall( dtype DT ) void ?{}(       volatile  DT * volatile *);
     823forall( dtype DT ) void ?{}( const volatile  DT *          *);
     824forall( dtype DT ) void ?{}( const volatile  DT * volatile *);
     825
     826void    ?{}(                void *          *);
     827void    ?{}(                void * volatile *);
     828void    ?{}( const          void *          *);
     829void    ?{}( const          void * volatile *);
     830void    ?{}(       volatile void *          *);
     831void    ?{}(       volatile void * volatile *);
     832void    ?{}( const volatile void *          *);
     833void    ?{}( const volatile void * volatile *);
     834
     835// dtors
     836forall( ftype FT ) void ^?{}( FT *         * );
     837forall( ftype FT ) void ^?{}( FT * volatile * );
     838
     839forall( dtype DT ) void ^?{}(                DT *          *);
     840forall( dtype DT ) void ^?{}(                DT * volatile *);
     841forall( dtype DT ) void ^?{}( const          DT *          *);
     842forall( dtype DT ) void ^?{}( const          DT * volatile *);
     843forall( dtype DT ) void ^?{}(      volatile  DT *          *);
     844forall( dtype DT ) void ^?{}(      volatile  DT * volatile *);
     845forall( dtype DT ) void ^?{}( const volatile  DT *         *);
     846forall( dtype DT ) void ^?{}( const volatile  DT * volatile *);
     847
     848void    ^?{}(               void *          *);
     849void    ^?{}(               void * volatile *);
     850void    ^?{}( const         void *          *);
     851void    ^?{}( const         void * volatile *);
     852void    ^?{}(      volatile void *          *);
     853void    ^?{}(      volatile void * volatile *);
     854void    ^?{}( const volatile void *         *);
     855void    ^?{}( const volatile void * volatile *);
  • src/main.cc

    r37f0da8 r70a06f6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // main.cc -- 
     7// main.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Fri May 15 23:12:02 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan 27 22:20:20 2016
    13 // Update Count     : 199
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 11 17:49:38 2016
     13// Update Count     : 200
    1414//
    1515
     
    4141#include "InitTweak/Mutate.h"
    4242#include "InitTweak/RemoveInit.h"
     43#include "InitTweak/FixInit.h"
    4344//#include "Explain/GenProlog.h"
    4445//#include "Try/Visit.h"
     
    5556
    5657static void parse( FILE * input, LinkageSpec::Type t, bool shouldExit = false );
    57 static void dump( std::list< Declaration * > & translationUnit );
     58static void dump( std::list< Declaration * > & translationUnit, std::ostream & out = std::cout );
    5859
    5960bool
    6061        astp = false,
    6162        bresolvep = false,
     63        ctorinitp = false,
    6264        exprp = false,
    6365        expraltp = false,
     
    7476        codegenp = false;
    7577
    76 enum { Ast, Bresolver, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
     78enum { Ast, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
    7779
    7880static struct option long_opts[] = {
    7981        { "ast", no_argument, 0, Ast },
    8082        { "before-resolver", no_argument, 0, Bresolver },
     83        { "ctorinitfix", no_argument, 0, CtorInitFix },
    8184        { "expr", no_argument, 0, Expr },
    8285        { "expralt", no_argument, 0, ExprAlt },
     
    100103
    101104        opterr = 0;                                                                                     // prevent getopt from printing error messages
    102        
     105
    103106        int c;
    104         while ( (c = getopt_long( argc, argv, "abefglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
     107        while ( (c = getopt_long( argc, argv, "abcefFglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
    105108                switch ( c ) {
    106109                  case Ast:
     
    111114                  case 'b':                                                                             // print before resolver steps
    112115                        bresolvep = true;
     116                        break;
     117                        case CtorInitFix:
     118                        case 'c':
     119                        ctorinitp = true;
    113120                        break;
    114121                  case Expr:
     
    187194                        output = new ofstream( argv[ optind ] );
    188195                } // if
    189        
     196
    190197                Parser::get_parser().set_debug( grammarp );
    191198
     
    208215                                        exit( 1 );
    209216                                } // if
    210                    
     217
    211218                                parse( prelude, LinkageSpec::Intrinsic );
    212219                        } // if
    213220                } // if
    214221
    215                 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );     
    216  
     222                parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );
     223
    217224                if ( parsep ) {
    218225                        Parser::get_parser().get_parseTree()->printList( std::cout );
     
    249256                OPTPRINT( "mutate" )
    250257                ControlStruct::mutate( translationUnit );
    251                 OPTPRINT( "fixNames" ) 
     258                OPTPRINT( "fixNames" )
    252259                CodeGen::fixNames( translationUnit );
    253                 OPTPRINT( "tweak" )
     260                OPTPRINT( "tweakInit" )
    254261                InitTweak::tweak( translationUnit );
    255262
     
    268275                if ( exprp ) {
    269276                        dump( translationUnit );
     277                        return 0;
     278                }
     279
     280                OPTPRINT( "fixInit" )
     281                // fix ObjectDecl - replaces ConstructorInit nodes
     282                InitTweak::fix( translationUnit );
     283                if ( ctorinitp ) {
     284                        dump ( translationUnit );
     285                        return 0;
    270286                }
    271287
     
    278294                OPTPRINT( "box" )
    279295                GenPoly::box( translationUnit );
    280                
     296
    281297                // print tree right before code generation
    282298                if ( codegenp ) {
     
    292308        } catch ( SemanticError &e ) {
    293309                if ( errorp ) {
    294                         dump( translationUnit );
     310                        std::cerr << "---AST at error:---" << std::endl;
     311                        dump( translationUnit, std::cerr );
     312                        std::cerr << std::endl << "---End of AST, begin error message:---\n" << std::endl;
    295313                }
    296314                e.print( std::cerr );
     
    314332        } // try
    315333
     334        deleteAll( translationUnit );
    316335        return 0;
    317336} // main
     
    331350}
    332351
    333 static void dump( std::list< Declaration * > & translationUnit ) {
     352static void dump( std::list< Declaration * > & translationUnit, std::ostream & out ) {
    334353        std::list< Declaration * > decls;
    335354        if ( noprotop ) {
    336                 filter( translationUnit.begin(), translationUnit.end(), 
     355                filter( translationUnit.begin(), translationUnit.end(),
    337356                                std::back_inserter( decls ), notPrelude );
    338357        } else {
     
    340359        }
    341360
    342         printAll( decls, std::cout );
     361        printAll( decls, out );
    343362        deleteAll( translationUnit );
    344363}
Note: See TracChangeset for help on using the changeset viewer.