Changes in / [3aba311:a5a71d0]


Ignore:
Location:
src
Files:
4 added
39 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r3aba311 ra5a71d0  
    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 : Mon Apr 04 17:08:06 2016
     13// Update Count     : 255
    1414//
    1515
     
    9999                handleStorageClass( objectDecl );
    100100                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    101        
     101
    102102                if ( objectDecl->get_init() ) {
    103103                        output << " = ";
     
    113113                if ( aggDecl->get_name() != "" )
    114114                        output << aggDecl->get_name();
    115        
     115
    116116                std::list< Declaration * > &memb = aggDecl->get_members();
    117117
     
    119119                        output << " {" << endl;
    120120
    121                         cur_indent += CodeGenerator::tabsize; 
     121                        cur_indent += CodeGenerator::tabsize;
    122122                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    123                                 output << indent; 
     123                                output << indent;
    124124                                (*i)->accept( *this );
    125125                                output << ";" << endl;
    126126                        }
    127127
    128                         cur_indent -= CodeGenerator::tabsize; 
     128                        cur_indent -= CodeGenerator::tabsize;
    129129
    130130                        output << indent << "}";
     
    141141                handleAggregate( aggregateDecl );
    142142        }
    143  
     143
    144144        void CodeGenerator::visit( EnumDecl *aggDecl ) {
    145145                output << "enum ";
     
    147147                if ( aggDecl->get_name() != "" )
    148148                        output << aggDecl->get_name();
    149        
     149
    150150                std::list< Declaration* > &memb = aggDecl->get_members();
    151151
     
    153153                        output << " {" << endl;
    154154
    155                         cur_indent += CodeGenerator::tabsize; 
     155                        cur_indent += CodeGenerator::tabsize;
    156156                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    157157                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    158158                                assert( obj );
    159                                 output << indent << mangleName( obj ); 
     159                                output << indent << mangleName( obj );
    160160                                if ( obj->get_init() ) {
    161161                                        output << " = ";
     
    165165                        } // for
    166166
    167                         cur_indent -= CodeGenerator::tabsize; 
     167                        cur_indent -= CodeGenerator::tabsize;
    168168
    169169                        output << indent << "}";
    170170                } // if
    171171        }
    172  
     172
    173173        void CodeGenerator::visit( TraitDecl *aggregateDecl ) {}
    174  
     174
    175175        void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    176176                output << "typedef ";
    177177                output << genType( typeDecl->get_base(), typeDecl->get_name() );
    178178        }
    179  
     179
    180180        void CodeGenerator::visit( TypeDecl *typeDecl ) {
    181181                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     
    213213                printDesignators( init->get_designators() );
    214214                output << "{ ";
    215                 genCommaList( init->begin_initializers(), init->end_initializers() );
     215                if ( init->begin_initializers() == init->end_initializers() ) {
     216                        // illegal to leave initializer list empty for scalar initializers,
     217                        // but always legal to have 0
     218                        output << "0";
     219                } else {
     220                        genCommaList( init->begin_initializers(), init->end_initializers() );
     221                }
    216222                output << " }";
    217223        }
    218224
    219         void CodeGenerator::visit( Constant *constant ) { 
     225        void CodeGenerator::visit( Constant *constant ) {
    220226                output << constant->get_value() ;
    221227        }
     
    234240                                                assert( arg != applicationExpr->get_args().end() );
    235241                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    236                
     242
    237243                                                        *arg = addrExpr->get_arg();
    238244                                                } else {
     
    243249                                                break;
    244250                                        }
    245              
     251
    246252                                  default:
    247253                                        // do nothing
    248254                                        ;
    249255                                }
    250            
     256
    251257                                switch ( opInfo.type ) {
    252258                                  case OT_INDEX:
     
    257263                                        output << "]";
    258264                                        break;
    259              
     265
    260266                                  case OT_CALL:
    261                                         // there are no intrinsic definitions of the function call operator
     267                                        // there are no intrinsic definitions of the function call operator or constructors or destructors
    262268                                        assert( false );
    263269                                        break;
    264              
     270
     271                                  case OT_CTOR:
     272                                  // it's just an optimization to disallow this, so for now let it through
     273                                  // since it makes autogenerating constructors a lot easier
     274                                varExpr->accept( *this );
     275                                        output << "(";
     276                                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     277                                        output << ")";
     278
     279                                  // intrinsic constructors should never be called directly - they should be transformed back into Initializer nodes
     280                                  // assert(false);
     281                                  break;
     282
     283                                  case OT_DTOR:
     284                                  // intrinsic destructors do nothing - don't generate any code
     285                                  output << " /* " << dynamic_cast<VariableExpr*>(applicationExpr->get_function())->get_var()->get_name() << " */";
     286                                  break;
     287
    265288                                  case OT_PREFIX:
    266289                                  case OT_PREFIXASSIGN:
     
    271294                                        output << ")";
    272295                                        break;
    273              
     296
    274297                                  case OT_POSTFIX:
    275298                                  case OT_POSTFIXASSIGN:
     
    278301                                        output << opInfo.symbol;
    279302                                        break;
     303
    280304
    281305                                  case OT_INFIX:
     
    288312                                        output << ")";
    289313                                        break;
    290              
     314
    291315                                  case OT_CONSTANT:
    292316                                  case OT_LABELADDRESS:
     
    307331                } // if
    308332        }
    309  
     333
    310334        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    311335                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    321345                                        output << "]";
    322346                                        break;
    323              
     347
    324348                                  case OT_CALL:
    325349                                        assert( false );
    326                                         break;
    327              
     350
     351                                        case OT_CTOR:
     352                                        case OT_DTOR:
     353                                        // intrinsic constructors should never be called
     354                                        // intrinsic destructors do nothing
     355                                        break;
     356
    328357                                  case OT_PREFIX:
    329358                                  case OT_PREFIXASSIGN:
     
    335364                                        output << ")";
    336365                                        break;
    337              
     366
    338367                                  case OT_POSTFIX:
    339368                                  case OT_POSTFIXASSIGN:
     
    342371                                        output << opInfo.symbol;
    343372                                        break;
    344  
     373
    345374                                  case OT_INFIX:
    346375                                  case OT_INFIXASSIGN:
     
    352381                                        output << ")";
    353382                                        break;
    354                                        
     383
    355384                                  case OT_CONSTANT:
    356385                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    370399                } // if
    371400        }
    372  
     401
    373402        void CodeGenerator::visit( NameExpr *nameExpr ) {
    374403                OperatorInfo opInfo;
     
    380409                } // if
    381410        }
    382  
     411
    383412        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    384413                output << "(&";
     
    409438                output << ")";
    410439        }
    411  
     440
    412441        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    413442                assert( false );
    414443        }
    415  
     444
    416445        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    417446                memberExpr->get_aggregate()->accept( *this );
    418447                output << "." << mangleName( memberExpr->get_member() );
    419448        }
    420  
     449
    421450        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    422451                OperatorInfo opInfo;
     
    427456                } // if
    428457        }
    429  
     458
    430459        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    431460                assert( constantExpr->get_constant() );
    432461                constantExpr->get_constant()->accept( *this );
    433462        }
    434  
     463
    435464        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    436465                output << "sizeof(";
     
    465494                output << ")";
    466495        }
    467  
     496
    468497        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    469498                output << "(";
     
    477506                output << ")";
    478507        }
    479  
     508
    480509        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    481510                output << "(";
     
    487516                output << ")";
    488517        }
    489  
     518
    490519        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    491520                output << "(";
     
    495524                output << ")";
    496525        }
    497  
     526
    498527        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    499  
     528
    500529        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    501530
     
    528557                        }
    529558                }
    530                 cur_indent -= CodeGenerator::tabsize; 
     559                cur_indent -= CodeGenerator::tabsize;
    531560
    532561                output << indent << "}";
     
    534563
    535564        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    536                 // I don't see why this check is necessary. 
    537                 // If this starts to cause problems then put it back in, 
     565                // I don't see why this check is necessary.
     566                // If this starts to cause problems then put it back in,
    538567                // with an explanation
    539568                assert( exprStmt );
     
    585614                switchStmt->get_condition()->accept( *this );
    586615                output << " ) ";
    587                
     616
    588617                output << "{" << std::endl;
    589618                cur_indent += CodeGenerator::tabsize;
     
    605634                } // if
    606635                output << ":\n";
    607                
     636
    608637                std::list<Statement *> sts = caseStmt->get_statements();
    609638
     
    622651                        if ( ! branchStmt->get_target().empty() )
    623652                                output << "goto " << branchStmt->get_target();
    624                         else { 
     653                        else {
    625654                                if ( branchStmt->get_computedTarget() != 0 ) {
    626655                                        output << "goto *";
     
    673702
    674703        void CodeGenerator::visit( ForStmt *forStmt ) {
    675                 // initialization is always hoisted, so don't 
    676                 // bother doing anything with that 
     704                // initialization is always hoisted, so don't
     705                // bother doing anything with that
    677706                output << "for (;";
    678707
     
    698727        void CodeGenerator::visit( DeclStmt *declStmt ) {
    699728                declStmt->get_decl()->accept( *this );
    700        
     729
    701730                if ( doSemicolon( declStmt->get_decl() ) ) {
    702731                        output << ";";
  • src/CodeGen/OperatorTable.cc

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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 : Tue Feb 09 14:39:52 2016
     13// Update Count     : 295
    1414//
    1515
     
    744744
    745745                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     746                        std::list<Expression*> noDesignators;
    746747                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
    747748
     
    762763                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
    763764                                }
    764                                 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
    765                         }
    766                         arrayTemp->set_init( new ListInit( inits ) );
     765                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ), noDesignators ) );
     766                        }
     767                        arrayTemp->set_init( new ListInit( inits, noDesignators ) );
    767768
    768769                        // return variable pointing to temporary
     
    19031904
    19041905                                        std::list<Expression*> designators;
    1905                                         objectDecl->set_init( new SingleInit( alloc, designators ) );
     1906                                        objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
    19061907                                }
    19071908                        }
     
    19441945                        return derefdVar;
    19451946                }
    1946                
     1947
    19471948                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
    19481949                        // mutate, exiting early if no longer MemberExpr
  • src/GenPoly/CopyParams.cc

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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 : Mon Apr 04 17:18:03 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                virtual ObjectDecl * mutate( ObjectDecl *objDecl );
    3345                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    3446
    3547                virtual Statement * mutate( ReturnStmt * returnStmt );
    36                
    37                 virtual CompoundStmt * mutate(CompoundStmt * compoundStmt);
    38                
     48
    3949          protected:
    40                 std::list< Statement* > stmtsToAddBefore;
    41                 std::list< Statement* > stmtsToAddAfter;
    42                 void mutateStatementList( std::list< Statement* > &statements );
    43 
    4450                std::list<DeclarationWithType*> returnVals;
    4551                UniqueName tempNamer;
     
    4753        };
    4854
    49         void tweak( std::list< Declaration * > translationUnit ) {
     55        class CtorDtor : public GenPoly::PolyMutator {
     56          public:
     57                /// create constructor and destructor statements for object declarations.
     58                /// Destructors are inserted directly into the code, whereas constructors
     59                /// will be added in after the resolver has run so that the initializer expression
     60                /// is only removed if a constructor is found
     61                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
     62
     63                CtorDtor() : inFunction( false ) {}
     64
     65                virtual ObjectDecl * mutate( ObjectDecl * );
     66                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
     67                virtual Declaration* mutate( StructDecl *aggregateDecl );
     68                virtual Declaration* mutate( UnionDecl *aggregateDecl );
     69                virtual Declaration* mutate( EnumDecl *aggregateDecl );
     70                virtual Declaration* mutate( TraitDecl *aggregateDecl );
     71                virtual TypeDecl* mutate( TypeDecl *typeDecl );
     72                virtual Declaration* mutate( TypedefDecl *typeDecl );
     73
     74          protected:
     75                bool inFunction;
     76        };
     77
     78        void tweak( std::list< Declaration * > & translationUnit ) {
     79                RemoveInit::removeInitializers( translationUnit );
     80                CtorDtor::generateCtorDtor( translationUnit );
     81        }
     82
     83        void RemoveInit::removeInitializers( std::list< Declaration * > & translationUnit ) {
    5084                RemoveInit remover;
    5185                mutateAll( translationUnit, remover );
     
    5387
    5488        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         }
    7589
    7690        // in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
     
    7993                if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) {
    8094                        if (SingleInit * single = dynamic_cast<SingleInit*>(objDecl->get_init())) {
    81                                 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     95                                // xxx this can be more complicated - consider ListInit
     96                                UntypedExpr *assign = new UntypedExpr( new NameExpr( "?{}" ) );
    8297                                assign->get_args().push_back( new AddressExpr (new NameExpr( objDecl->get_name() ) ) );
    8398                                assign->get_args().push_back( single->get_value()->clone() );
     
    94109                // is being returned
    95110                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));
     111                        // ensure return value is not destructed by explicitly creating
     112                        // an empty SingleInit node wherein maybeConstruct is false
     113                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), new ListInit( std::list<Initializer*>(), noDesignators, false ) );
     114                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     115
     116                        // and explicitly create the constructor expression separately
     117                        UntypedExpr *construct = new UntypedExpr( new NameExpr( "?{}" ) );
     118                        construct->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
     119                        construct->get_args().push_back( returnStmt->get_expr() );
     120                        stmtsToAdd.push_back(new ExprStmt(noLabels, construct));
    103121
    104122                        returnStmt->set_expr( new VariableExpr( newObj ) );
     
    110128                std::list<DeclarationWithType*> oldReturnVals = returnVals;
    111129                std::string oldFuncName = funcName;
    112                
     130
    113131                FunctionType * type = functionDecl->get_functionType();
    114132                returnVals = type->get_returnVals();
     
    119137                return decl;
    120138        }
     139
     140
     141        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
     142                CtorDtor ctordtor;
     143                mutateAll( translationUnit, ctordtor );
     144        }
     145
     146        namespace {
     147                bool tryConstruct( ObjectDecl * objDecl ) {
     148                        // xxx - handle designations
     149                        return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
     150                                (objDecl->get_init() == NULL ||
     151                                ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ));
     152                }
     153
     154                Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
     155                        UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
     156                        expr->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
     157                        expr->get_args().splice( expr->get_args().end(), args );
     158                        return expr;
     159                }
     160
     161                class InitExpander : public Visitor {
     162                  public:
     163                  InitExpander() {}
     164                  // ~InitExpander() {}
     165                        virtual void visit( SingleInit * singleInit );
     166                        virtual void visit( ListInit * listInit );
     167                        std::list< Expression * > argList;
     168                };
     169
     170                void InitExpander::visit( SingleInit * singleInit ) {
     171                        argList.push_back( singleInit->get_value()->clone() );
     172                }
     173
     174                void InitExpander::visit( ListInit * listInit ) {
     175                        // xxx - for now, assume no nested list inits
     176                        std::list<Initializer*>::iterator it = listInit->begin_initializers();
     177                        for ( ; it != listInit->end_initializers(); ++it ) {
     178                                (*it)->accept( *this );
     179                        }
     180                }
     181
     182                std::list< Expression * > makeInitList( Initializer * init ) {
     183                        InitExpander expander;
     184                        maybeAccept( init, expander );
     185                        return expander.argList;
     186                }
     187        }
     188
     189        ObjectDecl * CtorDtor::mutate( ObjectDecl * objDecl ) {
     190                // hands off if designated or if @=
     191                if ( tryConstruct( objDecl ) ) {
     192                        if ( inFunction ) {
     193                                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
     194                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
     195                                        // TODO: walk initializer and generate appropriate copy ctor if element has initializer
     196                                        std::list< Statement * > ctor;
     197                                        std::list< Statement * > dtor;
     198
     199                                        SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
     200                                        SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
     201
     202                                        // Currently makeArrayFunction produces a single Statement - a CompoundStmt
     203                                        // which  wraps everything that needs to happen. As such, it's technically
     204                                        // possible to use a Statement ** in the above calls, but this is inherently
     205                                        // unsafe, so instead we take the slightly less efficient route, but will be
     206                                        // immediately informed if somehow the above assumption is broken. In this case,
     207                                        // we could always wrap the list of statements at this point with a CompoundStmt,
     208                                        // but it seems reasonable at the moment for this to be done by makeArrayFunction
     209                                        // itself
     210                                        assert( ctor.size() == 1 );
     211                                        assert( dtor.size() == 1 );
     212
     213                                        objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     214                                } else {
     215                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
     216                                        Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
     217                                        Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
     218
     219                                        // need to remember init expression, in case no ctors exist
     220                                        // if ctor does exist, want to use ctor expression instead of init
     221                                        // push this decision to the resolver
     222                                        ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
     223                                        ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
     224                                        objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) );
     225                                }
     226                        } else {
     227                                // xxx - find a way to construct/destruct globals
     228                                // hack: implicit "static" initialization routine for each struct type? or something similar?
     229                                // --ties into module system
     230                                // this can be done by mangling main and replacing it with our own main which calls each
     231                                // module initialization routine in some decided order (order given in link command?)
     232                                // and finally calls mangled main
     233                        }
     234                }
     235                return objDecl;
     236        }
     237
     238        DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
     239                // parameters should not be constructed and destructed, so don't mutate FunctionType
     240                bool oldInFunc = inFunction;
     241                mutateAll( functionDecl->get_oldDecls(), *this );
     242                inFunction = true;
     243                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     244                inFunction = oldInFunc;
     245                return functionDecl;
     246        }
     247
     248        // should not traverse into any of these declarations to find objects
     249        // that need to be constructed or destructed
     250        Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
     251        Declaration* CtorDtor::mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
     252        Declaration* CtorDtor::mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
     253        Declaration* CtorDtor::mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
     254        TypeDecl* CtorDtor::mutate( TypeDecl *typeDecl ) { return typeDecl; }
     255        Declaration* CtorDtor::mutate( TypedefDecl *typeDecl ) { return typeDecl; }
     256
    121257} // namespace InitTweak
    122258
  • src/InitTweak/RemoveInit.h

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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 : Mon Mar 21 21:04:23 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 04 17:09:46 2016
    1313// Update Count     : 142
    1414//
     
    9797                os << endl << string( indent + 2, ' ' ) << "with initializer ";
    9898                initializer->printOneLine( os );
     99                os << " maybe constructed? " << initializer->get_maybeConstructed();
     100
    99101        } // if
    100102
     
    369371        } // if
    370372}
    371          
     373
    372374DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
    373375        if ( q ) {
     
    520522                assert( false );
    521523        } // switch
    522        
     524
    523525        return this;
    524526}
     
    631633                assert( a->type->kind == TypeData::Array );
    632634                TypeData *lastArray = findLast( a->type );
    633                 if ( type ) { 
     635                if ( type ) {
    634636                        switch ( type->kind ) {
    635637                          case TypeData::Aggregate:
     
    675677        } // if
    676678}
    677        
     679
    678680DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
    679681        type = addIdListToType( type, ids );
     
    880882Type *DeclarationNode::buildType() const {
    881883        assert( type );
    882  
     884
    883885        switch ( type->kind ) {
    884886          case TypeData::Enum:
  • src/Parser/InitializerNode.cc

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Apr 04 17:04:22 2016
     12// Last Modified On : Mon Apr 04 17:10:10 2016
    1313// Update Count     : 190
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    74157415/* Line 1806 of yacc.c  */
    74167416#line 1694 "parser.yy"
    7417     { (yyval.in) = (yyvsp[(2) - (2)].in); }
     7417    { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
    74187418    break;
    74197419
  • src/Parser/parser.yy

    r3aba311 ra5a71d0  
    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 : Thu Mar 24 16:16:16 2016
    1313// Update Count     : 1498
    14 // 
     14//
    1515
    1616// This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C
     
    16921692                { $$ = $2; }
    16931693        | ATassign initializer
    1694                 { $$ = $2; }
     1694                { $$ = $2->set_maybeConstructed( false ); }
    16951695        ;
    16961696
  • src/ResolvExpr/Resolver.cc

    r3aba311 ra5a71d0  
    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 : Mon Apr 04 17:11:54 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 & );
     62          void fallbackInit( ConstructorInit * ctorInit );
    6163
    6264                std::list< Type * > functionReturn;
     
    9597                        return newExpr;
    9698                }
    97  
     99
    98100                Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    99101                        TypeEnvironment env;
     
    126128                        } // if
    127129                }
    128  
     130
    129131                Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    130132                        TypeEnvironment env;
     
    159161                        return newExpr;
    160162                }
    161  
    162         }
    163  
     163
     164        }
     165
    164166        void Resolver::visit( ObjectDecl *objectDecl ) {
    165167                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     
    258260                        forStmt->set_condition( newExpr );
    259261                } // if
    260                
     262
    261263                if ( forStmt->get_increment() ) {
    262264                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     
    272274                delete switchStmt->get_condition();
    273275                switchStmt->set_condition( newExpr );
    274  
     276
    275277                visitor.Visitor::visit( switchStmt );
    276278        }
     
    314316        bool isCharType( T t ) {
    315317                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    316                         return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 
     318                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
    317319                                bt->get_kind() == BasicType::UnsignedChar;
    318320                }
     
    326328                                string n = ne->get_name();
    327329                                if (n == "0") {
    328                                         initContext = new BasicType(Type::Qualifiers(), 
     330                                        initContext = new BasicType(Type::Qualifiers(),
    329331                                                                                                BasicType::SignedInt);
    330332                                } else {
     
    332334                                        initContext = decl->get_type();
    333335                                }
    334                         } else if (ConstantExpr * e = 
     336                        } else if (ConstantExpr * e =
    335337                                           dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
    336338                                Constant *c = e->get_constant();
     
    355357                                                        singleInit->set_value( ce->get_arg() );
    356358                                                        ce->set_arg( NULL );
    357                                                         delete ce;                                                                     
     359                                                        delete ce;
    358360                                                }
    359361                                        }
     
    471473#endif
    472474        }
     475
     476        // ConstructorInit - fall back on C-style initializer
     477        void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
     478                // could not find valid constructor, or found an intrinsic constructor
     479                // fall back on C-style initializer
     480                delete ctorInit->get_ctor();
     481                ctorInit->set_ctor( NULL );
     482                maybeAccept( ctorInit->get_init(), *this );
     483        }
     484
     485        void Resolver::visit( ConstructorInit *ctorInit ) {
     486                TypeEnvironment env;
     487                try {
     488                        maybeAccept( ctorInit->get_ctor(), *this );
     489                        maybeAccept( ctorInit->get_dtor(), *this );
     490                } catch ( SemanticError ) {
     491                        // no alternatives for the constructor initializer - fallback on C-style initializer
     492                        // xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
     493                        fallbackInit( ctorInit );
     494                        return;
     495                }
     496
     497                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * > ( ctorInit->get_ctor() ) ) {
     498                        ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
     499                        assert( appExpr );
     500                        VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() );
     501                        assert( function );
     502                        if ( LinkageSpec::isOverridable( function->get_var()->get_linkage() ) ) {
     503                                // if the constructor that was found is intrinsic or autogenerated, reset to C-style
     504                                // initializer so that code generation is easy to handle
     505                                fallbackInit( ctorInit );
     506                                return;
     507                        }
     508                }
     509                // found a constructor - can get rid of C-style initializer
     510                delete ctorInit->get_init();
     511                ctorInit->set_init( NULL );
     512        }
    473513} // namespace ResolvExpr
    474514
  • src/SymTab/AddVisit.h

    r3aba311 ra5a71d0  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AddVisit.h -- 
     7// AddVisit.h --
    88//
    99// Author           : Richard C. Bilson
     
    8585                maybeAccept( cathStmt->get_decl(), visitor );
    8686        }
     87
     88        template< typename Visitor >
     89        void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
     90                std::list< Declaration * >::iterator i = translationUnit.begin();
     91                while ( i != translationUnit.end() ) {
     92                        (*i)->accept( visitor );
     93                        std::list< Declaration * >::iterator next = i;
     94                        next++;
     95                        if ( ! visitor.get_declsToAdd().empty() ) {
     96                                translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
     97                        } // if
     98                        i = next;
     99                } // while
     100        }
    87101} // namespace SymTab
    88102
  • src/SymTab/Validate.cc

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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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 04 17:14:00 2016
     13// Update Count     : 36
    1414//
    1515
  • src/SynTree/Initializer.cc

    r3aba311 ra5a71d0  
    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 : Wed Apr 06 16:15:32 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
     112
    81113// Local Variables: //
    82114// tab-width: 4 //
  • src/SynTree/Initializer.h

    r3aba311 ra5a71d0  
    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 : Wed Mar 30 13:22:08 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, 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, 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
    102132#endif // INITIALIZER_H
    103133
  • src/SynTree/Mutator.cc

    r3aba311 ra5a71d0  
    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 : Wed Mar  2 17:28:20 2016
    13 // Update Count     : 12
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 04 17:14:20 2016
     13// Update Count     : 15
    1414//
    1515
     
    437437}
    438438
     439Initializer *Mutator::mutate( ConstructorInit *ctorInit ) {
     440        ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
     441        ctorInit->set_init( maybeMutate( ctorInit->get_init(), *this ) );
     442        return ctorInit;
     443}
     444
    439445Subrange *Mutator::mutate( Subrange *subrange ) {
    440446        return subrange;
  • src/SynTree/Mutator.h

    r3aba311 ra5a71d0  
    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 : Wed Mar  2 17:33:11 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 04 17:14:44 2016
    1313// Update Count     : 9
    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 );
     
    9494        virtual Initializer* mutate( SingleInit *singleInit );
    9595        virtual Initializer* mutate( ListInit *listInit );
     96        virtual Initializer* mutate( ConstructorInit *ctorInit );
    9697
    9798        virtual Subrange *mutate( Subrange *subrange );
  • src/SynTree/ObjectDecl.cc

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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 : Wed Mar  2 17:29:00 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 04 17:16:09 2016
    1313// Update Count     : 4
    1414//
     
    102102class SingleInit;
    103103class ListInit;
     104class ConstructorInit;
    104105
    105106class Subrange;
  • src/SynTree/Visitor.cc

    r3aba311 ra5a71d0  
    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 : Wed Mar  2 17:29:23 2016
    13 // Update Count     : 16
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 04 17:16:25 2016
     13// Update Count     : 18
    1414//
    1515
     
    368368}
    369369
     370void Visitor::visit( ConstructorInit *ctorInit ) {
     371        maybeAccept( ctorInit->get_ctor(), *this );
     372        maybeAccept( ctorInit->get_init(), *this );
     373}
     374
    370375void Visitor::visit( Subrange *subrange ) {}
    371376
  • src/SynTree/Visitor.h

    r3aba311 ra5a71d0  
    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 : Wed Mar  2 17:33:35 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 04 17:16:36 2016
    1313// Update Count     : 6
    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 );
     
    9494        virtual void visit( SingleInit *singleInit );
    9595        virtual void visit( ListInit *listInit );
     96        virtual void visit( ConstructorInit *ctorInit );
    9697
    9798        virtual void visit( Subrange *subrange );
  • src/initialization.txt

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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
  • src/libcfa/Makefile.in

    r3aba311 ra5a71d0  
    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@
  • src/libcfa/iostream.c

    r3aba311 ra5a71d0  
    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 : Mon Mar  7 13:51:23 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 06 14:42:52 2016
    1313// Update Count     : 227
    1414//
     
    171171
    172172
    173 forall( dtype ostype | ostream( ostype ) ) 
     173forall( dtype ostype | ostream( ostype ) )
    174174ostype * ?|?( ostype *os, ostype * (* manip)( ostype * ) ) {
    175175        return manip( os );
    176176} // ?|?
    177177
    178 forall( dtype ostype | ostream( ostype ) ) 
     178forall( dtype ostype | ostream( ostype ) )
    179179ostype * endl( ostype * os ) {
    180180        os | '\n';
     
    184184} // endl
    185185
    186 forall( dtype ostype | ostream( ostype ) ) 
     186forall( dtype ostype | ostream( ostype ) )
    187187ostype * sepOn( ostype * os ) {
    188188        sepOn( os );
     
    190190} // sepOn
    191191
    192 forall( dtype ostype | ostream( ostype ) ) 
     192forall( dtype ostype | ostream( ostype ) )
    193193ostype * sepOff( ostype * os ) {
    194194        sepOff( os );
     
    310310} // ?|?
    311311
    312 _Istream_str1 str( char * s ) { _Istream_str1 s = { s }; return s; }
     312_Istream_str1 str( char * str ) { _Istream_str1 s = { str }; return s; }
    313313forall( dtype istype | istream( istype ) )
    314314istype * ?|?( istype * is, _Istream_str1 str ) {
     
    317317} // str
    318318
    319 _Istream_str2 str( char * s, int size ) { _Istream_str2 s = { s, size }; return s; }
     319_Istream_str2 str( char * str, int size ) { _Istream_str2 s = { str, size }; return s; }
    320320forall( dtype istype | istream( istype ) )
    321321istype * ?|?( istype * is, _Istream_str2 str ) {
  • src/libcfa/prelude.cf

    r3aba311 ra5a71d0  
    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

    r3aba311 ra5a71d0  
    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 : Thu Mar 31 14:00:12 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"
     
    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 ) {
     
    314330        } // try
    315331
     332        deleteAll( translationUnit );
    316333        return 0;
    317334} // main
     
    334351        std::list< Declaration * > decls;
    335352        if ( noprotop ) {
    336                 filter( translationUnit.begin(), translationUnit.end(), 
     353                filter( translationUnit.begin(), translationUnit.end(),
    337354                                std::back_inserter( decls ), notPrelude );
    338355        } else {
Note: See TracChangeset for help on using the changeset viewer.