Changes in / [ac1ed49:c14cff1]


Ignore:
Location:
src
Files:
2 added
33 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rac1ed49 rc14cff1  
    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 : Mon Jan 25 21:22:00 2016
    13 // Update Count     : 242
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Feb 09 13:24:40 2016
     13// Update Count     : 255
    1414//
    1515
     
    9898                handleStorageClass( objectDecl );
    9999                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    100        
     100
    101101                if ( objectDecl->get_init() ) {
    102102                        output << " = ";
     
    112112                if ( aggDecl->get_name() != "" )
    113113                        output << aggDecl->get_name();
    114        
     114
    115115                std::list< Declaration * > &memb = aggDecl->get_members();
    116116
     
    118118                        output << " {" << endl;
    119119
    120                         cur_indent += CodeGenerator::tabsize; 
     120                        cur_indent += CodeGenerator::tabsize;
    121121                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    122                                 output << indent; 
     122                                output << indent;
    123123                                (*i)->accept( *this );
    124124                                output << ";" << endl;
    125125                        }
    126126
    127                         cur_indent -= CodeGenerator::tabsize; 
     127                        cur_indent -= CodeGenerator::tabsize;
    128128
    129129                        output << indent << "}";
     
    140140                handleAggregate( aggregateDecl );
    141141        }
    142  
     142
    143143        void CodeGenerator::visit( EnumDecl *aggDecl ) {
    144144                output << "enum ";
     
    146146                if ( aggDecl->get_name() != "" )
    147147                        output << aggDecl->get_name();
    148        
     148
    149149                std::list< Declaration* > &memb = aggDecl->get_members();
    150150
     
    152152                        output << " {" << endl;
    153153
    154                         cur_indent += CodeGenerator::tabsize; 
     154                        cur_indent += CodeGenerator::tabsize;
    155155                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    156156                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    157157                                assert( obj );
    158                                 output << indent << mangleName( obj ); 
     158                                output << indent << mangleName( obj );
    159159                                if ( obj->get_init() ) {
    160160                                        output << " = ";
     
    164164                        } // for
    165165
    166                         cur_indent -= CodeGenerator::tabsize; 
     166                        cur_indent -= CodeGenerator::tabsize;
    167167
    168168                        output << indent << "}";
    169169                } // if
    170170        }
    171  
     171
    172172        void CodeGenerator::visit( ContextDecl *aggregateDecl ) {}
    173  
     173
    174174        void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    175175                output << "typedef ";
    176176                output << genType( typeDecl->get_base(), typeDecl->get_name() );
    177177        }
    178  
     178
    179179        void CodeGenerator::visit( TypeDecl *typeDecl ) {
    180180                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     
    216216        }
    217217
    218         void CodeGenerator::visit( Constant *constant ) { 
     218        void CodeGenerator::visit( Constant *constant ) {
    219219                output << constant->get_value() ;
    220220        }
     
    233233                                                assert( arg != applicationExpr->get_args().end() );
    234234                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    235                
     235
    236236                                                        *arg = addrExpr->get_arg();
    237237                                                } else {
     
    242242                                                break;
    243243                                        }
    244              
     244
    245245                                  default:
    246246                                        // do nothing
    247247                                        ;
    248248                                }
    249            
     249
    250250                                switch ( opInfo.type ) {
    251251                                  case OT_INDEX:
     
    256256                                        output << "]";
    257257                                        break;
    258              
     258
    259259                                  case OT_CALL:
    260                                         // there are no intrinsic definitions of the function call operator
     260                                        // there are no intrinsic definitions of the function call operator or constructors or destructors
    261261                                        assert( false );
    262262                                        break;
    263              
     263
     264                                  case OT_CTOR:
     265                                  // it's just an optimization to disallow this, so for now let it through
     266                                  // since it makes autogenerating constructors a lot easier
     267                                varExpr->accept( *this );
     268                                        output << "(";
     269                                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     270                                        output << ")";
     271
     272                                  // intrinsic constructors should never be called directly - they should be transformed back into Initializer nodes
     273                                  // assert(false);
     274                                  break;
     275
     276                                  case OT_DTOR:
     277                                  // intrinsic destructors do nothing - don't generate any code
     278                                  output << " // " << dynamic_cast<VariableExpr*>(applicationExpr->get_function())->get_var()->get_name() << endl;
     279                                  break;
     280
    264281                                  case OT_PREFIX:
    265282                                  case OT_PREFIXASSIGN:
     
    270287                                        output << ")";
    271288                                        break;
    272              
     289
    273290                                  case OT_POSTFIX:
    274291                                  case OT_POSTFIXASSIGN:
     
    277294                                        output << opInfo.symbol;
    278295                                        break;
     296
    279297
    280298                                  case OT_INFIX:
     
    287305                                        output << ")";
    288306                                        break;
    289              
     307
    290308                                  case OT_CONSTANT:
    291309                                  case OT_LABELADDRESS:
     
    306324                } // if
    307325        }
    308  
     326
    309327        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    310328                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    320338                                        output << "]";
    321339                                        break;
    322              
     340
    323341                                  case OT_CALL:
    324342                                        assert( false );
    325                                         break;
    326              
     343
     344                                        case OT_CTOR:
     345                                        case OT_DTOR:
     346                                        // intrinsic constructors should never be called
     347                                        // intrinsic destructors do nothing
     348                                        break;
     349
    327350                                  case OT_PREFIX:
    328351                                  case OT_PREFIXASSIGN:
     
    334357                                        output << ")";
    335358                                        break;
    336              
     359
    337360                                  case OT_POSTFIX:
    338361                                  case OT_POSTFIXASSIGN:
     
    341364                                        output << opInfo.symbol;
    342365                                        break;
    343  
     366
    344367                                  case OT_INFIX:
    345368                                  case OT_INFIXASSIGN:
     
    351374                                        output << ")";
    352375                                        break;
    353                                        
     376
    354377                                  case OT_CONSTANT:
    355378                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    369392                } // if
    370393        }
    371  
     394
    372395        void CodeGenerator::visit( NameExpr *nameExpr ) {
    373396                OperatorInfo opInfo;
     
    379402                } // if
    380403        }
    381  
     404
    382405        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    383406                output << "(&";
     
    408431                output << ")";
    409432        }
    410  
     433
    411434        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    412435                assert( false );
    413436        }
    414  
     437
    415438        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    416439                memberExpr->get_aggregate()->accept( *this );
    417440                output << "." << mangleName( memberExpr->get_member() );
    418441        }
    419  
     442
    420443        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    421444                OperatorInfo opInfo;
     
    426449                } // if
    427450        }
    428  
     451
    429452        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    430453                assert( constantExpr->get_constant() );
    431454                constantExpr->get_constant()->accept( *this );
    432455        }
    433  
     456
    434457        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    435458                output << "sizeof(";
     
    464487                output << ")";
    465488        }
    466  
     489
    467490        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    468491                output << "(";
     
    476499                output << ")";
    477500        }
    478  
     501
    479502        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    480503                output << "(";
     
    486509                output << ")";
    487510        }
    488  
     511
    489512        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    490513                output << "(";
     
    494517                output << ")";
    495518        }
    496  
     519
    497520        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    498  
     521
    499522        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    500523
     
    527550                        }
    528551                }
    529                 cur_indent -= CodeGenerator::tabsize; 
     552                cur_indent -= CodeGenerator::tabsize;
    530553
    531554                output << indent << "}";
     
    533556
    534557        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    535                 // I don't see why this check is necessary. 
    536                 // If this starts to cause problems then put it back in, 
     558                // I don't see why this check is necessary.
     559                // If this starts to cause problems then put it back in,
    537560                // with an explanation
    538561                assert( exprStmt );
     
    584607                switchStmt->get_condition()->accept( *this );
    585608                output << " ) ";
    586                
     609
    587610                output << "{" << std::endl;
    588611                cur_indent += CodeGenerator::tabsize;
     
    604627                } // if
    605628                output << ":\n";
    606                
     629
    607630                std::list<Statement *> sts = caseStmt->get_statements();
    608631
     
    621644                        if ( ! branchStmt->get_target().empty() )
    622645                                output << "goto " << branchStmt->get_target();
    623                         else { 
     646                        else {
    624647                                if ( branchStmt->get_computedTarget() != 0 ) {
    625648                                        output << "goto *";
     
    672695
    673696        void CodeGenerator::visit( ForStmt *forStmt ) {
    674                 // initialization is always hoisted, so don't 
    675                 // bother doing anything with that 
     697                // initialization is always hoisted, so don't
     698                // bother doing anything with that
    676699                output << "for (;";
    677700
     
    697720        void CodeGenerator::visit( DeclStmt *declStmt ) {
    698721                declStmt->get_decl()->accept( *this );
    699        
     722
    700723                if ( doSemicolon( declStmt->get_decl() ) ) {
    701724                        output << ";";
  • src/CodeGen/OperatorTable.cc

    rac1ed49 rc14cff1  
    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                         }, // ~?{}, -?{}, !?{}, $?{}, ??{}, ^?{}, ?destroy, ?delete
    2325                        {       "?()",          "",             "_operator_call",                               OT_CALL                         },
    2426                        {       "?++",          "++",   "_operator_postincr",                   OT_POSTFIXASSIGN        },
  • src/CodeGen/OperatorTable.h

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    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
     
    401401
    402402                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     403                        std::list<Expression*> noDesignators;
    403404                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
    404405
     
    419420                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
    420421                                }
    421                                 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
    422                         }
    423                         arrayTemp->set_init( new ListInit( inits ) );
     422                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ), noDesignators ) );
     423                        }
     424                        arrayTemp->set_init( new ListInit( inits, noDesignators ) );
    424425
    425426                        // return variable pointing to temporary
     
    13711372
    13721373                                        std::list<Expression*> designators;
    1373                                         objectDecl->set_init( new SingleInit( alloc, designators ) );
     1374                                        objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
    13741375                                }
    13751376                        }
     
    14121413                        return derefdVar;
    14131414                }
    1414                
     1415
    14151416                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
    14161417                        // mutate, exiting early if no longer MemberExpr
  • src/GenPoly/Specialize.cc

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    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 : Tue Feb 09 15:12:29 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 "GenPoly/PolyMutator.h"
    2326
    2427namespace InitTweak {
     
    2629                const std::list<Label> noLabels;
    2730        }
    28        
    29         class RemoveInit : public Mutator {
     31
     32        class RemoveInit : public GenPoly::PolyMutator {
    3033          public:
     34                /// removes and replaces initialization for polymorphic value objects
     35                /// with assignment (TODO: constructor) statements.
     36                /// also consistently allocates a temporary variable for the return value
     37                /// of a function so that anything which the resolver decides can be assigned
     38                /// into the return type of a function can be returned.
     39                static void removeInitializers( std::list< Declaration * > &translationUnit );
     40
    3141                RemoveInit();
    32                 virtual ObjectDecl * mutate(ObjectDecl *objDecl);
     42                virtual ObjectDecl * mutate( ObjectDecl *objDecl );
    3343                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    3444
    3545                virtual Statement * mutate( ReturnStmt * returnStmt );
    36                
    37                 virtual CompoundStmt * mutate(CompoundStmt * compoundStmt);
    38                
     46
    3947          protected:
    40                 std::list< Statement* > stmtsToAddBefore;
    41                 std::list< Statement* > stmtsToAddAfter;
    42                 void mutateStatementList( std::list< Statement* > &statements );
    43 
    4448                std::list<DeclarationWithType*> returnVals;
    4549                UniqueName tempNamer;
     
    4751        };
    4852
    49         void tweak( std::list< Declaration * > translationUnit ) {
     53        class CtorDtor : public GenPoly::PolyMutator {
     54          public:
     55                /// create constructor and destructor statements for object declarations.
     56                /// Destructors are inserted directly into the code, whereas constructors
     57                /// will be added in after the resolver has run so that the initializer expression
     58                /// is only removed if a constructor is found
     59                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
     60
     61                CtorDtor() : inFunction( false ) {}
     62
     63                virtual ObjectDecl * mutate( ObjectDecl * );
     64                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
     65                virtual Declaration* mutate( StructDecl *aggregateDecl );
     66                virtual Declaration* mutate( UnionDecl *aggregateDecl );
     67                virtual Declaration* mutate( EnumDecl *aggregateDecl );
     68                virtual Declaration* mutate( ContextDecl *aggregateDecl );
     69                virtual TypeDecl* mutate( TypeDecl *typeDecl );
     70                virtual Declaration* mutate( TypedefDecl *typeDecl );
     71
     72                virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
     73
     74          protected:
     75                bool inFunction;
     76
     77                // to be added before block ends - use push_front so order is correct
     78                std::list< Statement * > destructorStmts;
     79        };
     80
     81        void tweak( std::list< Declaration * > & translationUnit ) {
     82                RemoveInit::removeInitializers( translationUnit );
     83                CtorDtor::generateCtorDtor( translationUnit );
     84        }
     85
     86        void RemoveInit::removeInitializers( std::list< Declaration * > & translationUnit ) {
    5087                RemoveInit remover;
    5188                mutateAll( translationUnit, remover );
     
    5390
    5491        RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {}
    55        
    56         void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) {
    57                 for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    58                         if ( ! stmtsToAddAfter.empty() ) {
    59                                 statements.splice( i, stmtsToAddAfter );
    60                         } // if
    61                         *i = (*i)->acceptMutator( *this );
    62                         if ( ! stmtsToAddBefore.empty() ) {
    63                                 statements.splice( i, stmtsToAddBefore );
    64                         } // if
    65                 } // for
    66                 if ( ! stmtsToAddAfter.empty() ) {
    67                         statements.splice( statements.end(), stmtsToAddAfter );
    68                 } // if
    69         }
    70 
    71         CompoundStmt *RemoveInit::mutate(CompoundStmt *compoundStmt) {
    72                 mutateStatementList( compoundStmt->get_kids() );
    73                 return compoundStmt;
    74         }
    7592
    7693        // in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
     
    7996                if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) {
    8097                        if (SingleInit * single = dynamic_cast<SingleInit*>(objDecl->get_init())) {
    81                                 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     98                                // xxx this can be more complicated - consider ListInit
     99                                UntypedExpr *assign = new UntypedExpr( new NameExpr( "?{}" ) );
    82100                                assign->get_args().push_back( new AddressExpr (new NameExpr( objDecl->get_name() ) ) );
    83101                                assign->get_args().push_back( single->get_value()->clone() );
     
    93111                // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
    94112                // is being returned
     113                // xxx - this should construct rather than assign
    95114                if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue()  ) {
    96115                        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                        
     116                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     117
    99118                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    100119                        assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
    101120                        assign->get_args().push_back( returnStmt->get_expr() );
    102                         stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
     121                        stmtsToAdd.push_back(new ExprStmt(noLabels, assign));
    103122
    104123                        returnStmt->set_expr( new VariableExpr( newObj ) );
     
    110129                std::list<DeclarationWithType*> oldReturnVals = returnVals;
    111130                std::string oldFuncName = funcName;
    112                
     131
    113132                FunctionType * type = functionDecl->get_functionType();
    114133                returnVals = type->get_returnVals();
     
    119138                return decl;
    120139        }
     140
     141
     142        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
     143                CtorDtor ctordtor;
     144                mutateAll( translationUnit, ctordtor );
     145        }
     146
     147        namespace {
     148                bool tryConstruct( ObjectDecl * objDecl ) {
     149                        // xxx - handle designations
     150                        return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
     151                                (objDecl->get_init() == NULL ||
     152                                ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ));
     153                }
     154
     155                Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
     156                        UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
     157                        expr->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
     158                        expr->get_args().splice( expr->get_args().end(), args );
     159                        return expr;
     160                }
     161
     162                class InitExpander : public Visitor {
     163                  public:
     164                  InitExpander() {}
     165                  // ~InitExpander() {}
     166                        virtual void visit( SingleInit * singleInit );
     167                        virtual void visit( ListInit * listInit );
     168                        std::list< Expression * > argList;
     169                };
     170
     171                void InitExpander::visit( SingleInit * singleInit ) {
     172                        argList.push_back( singleInit->get_value()->clone() );
     173                }
     174
     175                void InitExpander::visit( ListInit * listInit ) {
     176                        // xxx - for now, assume no nested list inits
     177                        std::list<Initializer*>::iterator it = listInit->begin_initializers();
     178                        for ( ; it != listInit->end_initializers(); ++it ) {
     179                                (*it)->accept( *this );
     180                        }
     181                }
     182
     183                std::list< Expression * > makeInitList( Initializer * init ) {
     184                        InitExpander expander;
     185                        maybeAccept( init, expander );
     186                        return expander.argList;
     187                }
     188        }
     189
     190        ObjectDecl * CtorDtor::mutate( ObjectDecl * objDecl ) {
     191                // hands off if designated or if @=
     192                if ( tryConstruct( objDecl ) ) {
     193                        if ( inFunction ) {
     194                                Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
     195                                Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
     196
     197                                // need to remember init expression, in case no ctors exist
     198                                // if ctor does exist, want to use ctor expression instead of init
     199                                // push this decision to the resolver
     200                                objDecl->set_init( new ConstructorInit( ctor, objDecl->get_init() ) );
     201                                destructorStmts.push_front( new ExprStmt( noLabels, dtor ) );
     202                        } else {
     203                                // xxx - find a way to construct/destruct globals
     204                                // hack: implicit "static" initialization routine for each struct type? or something similar?
     205                                // --ties into module system
     206                        }
     207                }
     208                return objDecl;
     209        }
     210
     211        DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
     212                // parameters should not be constructed and destructed, so don't mutate FunctionType
     213                bool oldInFunc = inFunction;
     214                mutateAll( functionDecl->get_oldDecls(), *this );
     215                inFunction = true;
     216                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     217                inFunction = oldInFunc;
     218                return functionDecl;
     219        }
     220
     221        CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
     222                CompoundStmt * ret = PolyMutator::mutate( compoundStmt );
     223                std::list< Statement * > &statements = ret->get_kids();
     224                if ( ! destructorStmts.empty() ) {
     225                        // TODO: adding to the end of a block isn't sufficient, since
     226                        // return/break/goto should trigger destructor when block is left.
     227                        statements.splice( statements.end(), destructorStmts );
     228                } // if
     229                return ret;
     230        }
     231
     232        // should not traverse into any of these declarations to find objects
     233        // that need to be constructed or destructed
     234        Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
     235        Declaration* CtorDtor::mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
     236        Declaration* CtorDtor::mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
     237        Declaration* CtorDtor::mutate( ContextDecl *aggregateDecl ) { return aggregateDecl; }
     238        TypeDecl* CtorDtor::mutate( TypeDecl *typeDecl ) { return typeDecl; }
     239        Declaration* CtorDtor::mutate( TypedefDecl *typeDecl ) { return typeDecl; }
     240
    121241} // namespace InitTweak
    122242
  • src/InitTweak/RemoveInit.h

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    125125        GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
    126126        InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT) \
     127        InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT) \
    127128        Parser/driver_cfa_cpp-parser.$(OBJEXT) \
    128129        Parser/driver_cfa_cpp-lex.$(OBJEXT) \
     
    349350        GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
    350351        GenPoly/InstantiateGeneric.cc GenPoly/DeclMutator.cc \
    351         InitTweak/RemoveInit.cc Parser/parser.yy Parser/lex.ll \
    352         Parser/TypedefTable.cc Parser/ParseNode.cc \
     352        InitTweak/RemoveInit.cc InitTweak/FixInit.cc Parser/parser.yy \
     353        Parser/lex.ll Parser/TypedefTable.cc Parser/ParseNode.cc \
    353354        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
    354355        Parser/StatementNode.cc Parser/InitializerNode.cc \
     
    412413          esac; \
    413414        done; \
    414         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
     415        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
    415416        $(am__cd) $(top_srcdir) && \
    416           $(AUTOMAKE) --gnu src/Makefile
     417          $(AUTOMAKE) --foreign src/Makefile
    417418.PRECIOUS: Makefile
    418419Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
     
    570571InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT):  \
    571572        InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
     573InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     574        InitTweak/$(DEPDIR)/$(am__dirstamp)
    572575Parser/parser.h: Parser/parser.cc
    573576        @if test ! -f $@; then rm -f Parser/parser.cc; else :; fi
     
    804807        -rm -f GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT)
    805808        -rm -f GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT)
     809        -rm -f InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT)
    806810        -rm -f InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT)
    807811        -rm -f Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT)
     
    912916@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    913917@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
     918@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po@am__quote@
    914919@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Po@am__quote@
    915920@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@
     
    14111416@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`
    14121417
     1418InitTweak/driver_cfa_cpp-FixInit.o: InitTweak/FixInit.cc
     1419@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
     1420@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
     1421@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.o' libtool=no @AMDEPBACKSLASH@
     1422@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1423@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
     1424
     1425InitTweak/driver_cfa_cpp-FixInit.obj: InitTweak/FixInit.cc
     1426@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`
     1427@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
     1428@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.obj' libtool=no @AMDEPBACKSLASH@
     1429@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1430@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`
     1431
    14131432Parser/driver_cfa_cpp-parser.o: Parser/parser.cc
    14141433@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
  • src/Parser/DeclarationNode.cc

    rac1ed49 rc14cff1  
    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 : Tue Jul 14 14:46:32 2015
    13 // Update Count     : 126
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Jan 07 13:18:02 2016
     13// Update Count     : 130
    1414//
    1515
     
    9696                os << endl << string( indent + 2, ' ' ) << "with initializer ";
    9797                initializer->printOneLine( os );
     98                os << " maybe constructed? " << initializer->get_maybeConstructed();
     99
    98100        } // if
    99101
     
    357359        } // if
    358360}
    359          
     361
    360362DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
    361363        if ( q ) {
     
    508510                assert( false );
    509511        } // switch
    510        
     512
    511513        return this;
    512514}
     
    619621                assert( a->type->kind == TypeData::Array );
    620622                TypeData *lastArray = findLast( a->type );
    621                 if ( type ) { 
     623                if ( type ) {
    622624                        switch ( type->kind ) {
    623625                          case TypeData::Aggregate:
     
    663665        } // if
    664666}
    665        
     667
    666668DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
    667669        type = addIdListToType( type, ids );
     
    868870Type *DeclarationNode::buildType() const {
    869871        assert( type );
    870  
     872
    871873        switch ( type->kind ) {
    872874          case TypeData::Enum:
  • src/Parser/InitializerNode.cc

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ParseNode.h -- 
     7// ParseNode.h --
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:28:16 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Feb  1 13:32:32 2016
    13 // Update Count     : 184
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Feb 09 13:23:34 2016
     13// Update Count     : 185
    1414//
    1515
     
    177177        enum Type { TupleC, Comma, TupleFieldSel, // n-adic
    178178                                // triadic
    179                                 Cond, NCond, 
     179                                Cond, NCond,
    180180                                // diadic
    181                                 SizeOf, AlignOf, OffsetOf, Attr, CompLit, Plus, Minus, Mul, Div, Mod, Or, And, 
    182                                 BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq, 
     181                                SizeOf, AlignOf, OffsetOf, Attr, CompLit, Plus, Minus, Mul, Div, Mod, Or, And,
     182                                BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
    183183                                Assign, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
    184184                                Index, FieldSel, PFieldSel, Range,
    185185                                // monadic
    186186                                UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
     187                                Ctor, Dtor,
    187188        };
    188189
     
    309310        ValofExprNode( const ValofExprNode &other );
    310311        ~ValofExprNode();
    311  
     312
    312313        virtual ValofExprNode *clone() const { return new ValofExprNode( *this ); }
    313314
     
    332333        enum TypeClass { Type, Dtype, Ftype };
    333334
    334         static const char *storageName[]; 
     335        static const char *storageName[];
    335336        static const char *qualifierName[];
    336337        static const char *basicTypeName[];
     
    422423class StatementNode : public ParseNode {
    423424  public:
    424         enum Type { Exp,   If,        Switch,  Case,    Default,  Choose,   Fallthru, 
     425        enum Type { Exp,   If,        Switch,  Case,    Default,  Choose,   Fallthru,
    425426                                While, Do,        For,
    426427                                Goto,  Continue,  Break,   Return,  Throw,
     
    520521        ExpressionNode *get_designators() const { return designator; }
    521522
     523        InitializerNode *set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
     524        bool get_maybeConstructed() const { return maybeConstructed; }
     525
    522526        InitializerNode *next_init() const { return kids; }
    523527
     
    531535        ExpressionNode *designator; // may be list
    532536        InitializerNode *kids;
     537        bool maybeConstructed;
    533538};
    534539
  • src/Parser/TypeData.cc

    rac1ed49 rc14cff1  
    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 : Tue Jul 14 14:57:23 2015
    13 // Update Count     : 32
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Jan 14 10:43:42 2016
     13// Update Count     : 36
    1414//
    1515
     
    436436        for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
    437437                if ( (*i)->get_kind() == TypeDecl::Any ) {
     438                        // add assertion parameters to `type' tyvars
     439                        // add assignment operator:  T * ?=?(T *, T)
    438440                        FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    439441                        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 ) );
     
    441443                        assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
    442444                        (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) );
     445
     446                        // add default ctor:  void ?{}(T *)
     447                        FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
     448                        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 ) );
     449                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
     450
     451                        // add copy ctor:  void ?{}(T *, T)
     452                        FunctionType *copyCtorType = new FunctionType( Type::Qualifiers(), false );
     453                        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 ) );
     454                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
     455                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
     456
     457                        // add dtor:  void ^?{}(T *)
     458                        FunctionType *dtorType = new FunctionType( Type::Qualifiers(), false );
     459                        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 ) );
     460                        (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) );
    443461                } // if
    444462        } // for
  • src/Parser/parser.cc

    rac1ed49 rc14cff1  
    22
    33/* Bison implementation for Yacc-like parsers in C
    4    
     4
    55      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    6    
     6
    77   This program is free software: you can redistribute it and/or modify
    88   it under the terms of the GNU General Public License as published by
    99   the Free Software Foundation, either version 3 of the License, or
    1010   (at your option) any later version.
    11    
     11
    1212   This program is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515   GNU General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     
    2727   Bison output files to be licensed under the GNU General Public
    2828   License without this special exception.
    29    
     29
    3030   This special exception was added by the Free Software Foundation in
    3131   version 2.2 of Bison.  */
     
    73537353
    73547354/* Line 1806 of yacc.c  */
    7355 #line 1690 "parser.yy"
    7356     { (yyval.in) = (yyvsp[(2) - (2)].in); }
     7355#line 1684 "parser.yy"
     7356    { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
    73577357    break;
    73587358
  • src/Parser/parser.yy

    rac1ed49 rc14cff1  
    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 : Mon Feb  1 18:22:42 2016
    1313// Update Count     : 1483
    14 // 
     14//
    1515
    1616// This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C
     
    16881688                { $$ = $2; }
    16891689        | ATassign initializer
    1690                 { $$ = $2; }
     1690                { $$ = $2->set_maybeConstructed( false ); }
    16911691        ;
    16921692
  • src/ResolvExpr/Resolver.cc

    rac1ed49 rc14cff1  
    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 : Tue Feb  9 21:57:52 2016
    13 // Update Count     : 179
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Jan 14 16:45:32 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 );
     
    251253                        forStmt->set_condition( newExpr );
    252254                } // if
    253                
     255
    254256                if ( forStmt->get_increment() ) {
    255257                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     
    265267                delete switchStmt->get_condition();
    266268                switchStmt->set_condition( newExpr );
    267  
     269
    268270                visitor.Visitor::visit( switchStmt );
    269271        }
     
    307309        bool isCharType( T t ) {
    308310                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    309                         return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 
     311                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
    310312                                bt->get_kind() == BasicType::UnsignedChar;
    311313                }
     
    319321                                string n = ne->get_name();
    320322                                if (n == "0") {
    321                                         initContext = new BasicType(Type::Qualifiers(), 
     323                                        initContext = new BasicType(Type::Qualifiers(),
    322324                                                                                                BasicType::SignedInt);
    323325                                } else {
     
    325327                                        initContext = decl->get_type();
    326328                                }
    327                         } else if (ConstantExpr * e = 
     329                        } else if (ConstantExpr * e =
    328330                                           dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
    329331                                Constant *c = e->get_constant();
     
    348350                                                        singleInit->set_value( ce->get_arg() );
    349351                                                        ce->set_arg( NULL );
    350                                                         delete ce;                                                                     
     352                                                        delete ce;
    351353                                                }
    352354                                        }
     
    464466#endif
    465467        }
     468
     469        // ConstructorInit - fall back on C-style initializer
     470        void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
     471                // could not find valid constructor, or found an intrinsic constructor
     472                // fall back on C-style initializer
     473                delete ctorInit->get_ctor();
     474                ctorInit->set_ctor( NULL );
     475                maybeAccept( ctorInit->get_init(), *this );
     476        }
     477
     478        void Resolver::visit( ConstructorInit *ctorInit ) {
     479                TypeEnvironment env;
     480                AlternativeFinder finder( *this, env );
     481                finder.find( ctorInit->get_ctor() );
     482
     483                if ( finder.get_alternatives().size() == 0 ) {
     484                        fallbackInit( ctorInit );
     485                } else if ( finder.get_alternatives().size() == 1 ) {
     486                        Alternative &choice = finder.get_alternatives().front();
     487                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( choice.expr ) ) {
     488                                if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
     489                                        if ( LinkageSpec::isOverridable( function->get_var()->get_linkage() ) ) {
     490                                                // if the constructor that was found is intrinsic or autogenerated, reset to C-style
     491                                                // initializer so that code generation is easy to handle
     492                                                fallbackInit( ctorInit );
     493                                                return;
     494                                        }
     495                                }
     496                        }
     497                        // found a constructor - can get rid of C-style initializer
     498                        Expression *newExpr = choice.expr->clone();
     499                        finishExpr( newExpr, choice.env );
     500                        ctorInit->set_ctor( newExpr );
     501                        delete ctorInit->get_init();
     502                        ctorInit->set_init( NULL );
     503                } else {
     504                        // too many constructors found
     505                        assert(false);
     506                }
     507        }
    466508} // namespace ResolvExpr
    467509
  • src/SymTab/Validate.cc

    rac1ed49 rc14cff1  
    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 Jan 27 22:03:12 2016
    13 // Update Count     : 225
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Feb 22 12:26:37 2016
     13// Update Count     : 297
    1414//
    1515
     
    202202        };
    203203
     204        class VerifyCtorDtor : public Visitor {
     205        public:
     206                /// ensure that constructors and destructors have at least one
     207                /// parameter, the first of which must be a pointer, and no
     208                /// return values.
     209                static void verify( std::list< Declaration * > &translationUnit );
     210
     211                // VerifyCtorDtor() {}
     212
     213                virtual void visit( FunctionDecl *funcDecl );
     214        private:
     215        };
     216
    204217        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    205218                Pass1 pass1;
     
    213226                AutogenerateRoutines::autogenerateRoutines( translationUnit );
    214227                acceptAll( translationUnit, pass3 );
     228                VerifyCtorDtor::verify( translationUnit );
    215229        }
    216230
     
    521535
    522536        template< typename OutputIterator >
    523         void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
     537        void makeScalarFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
    524538                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    525539                // unnamed bit fields are not copied as they cannot be accessed
    526540                if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
    527541
    528                 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     542                // want to be able to generate assignment, ctor, and dtor generically,
     543                // so fname is either ?=?, ?{}, or ^?{}
     544                UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    529545
    530546                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     
    533549                // do something special for unnamed members
    534550                Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    535                 assignExpr->get_args().push_back( dstselect );
     551                fExpr->get_args().push_back( dstselect );
    536552
    537553                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    538                 assignExpr->get_args().push_back( srcselect );
    539 
    540                 *out++ = new ExprStmt( noLabels, assignExpr );
     554                fExpr->get_args().push_back( srcselect );
     555
     556                *out++ = new ExprStmt( noLabels, fExpr );
    541557        }
    542558
    543559        template< typename OutputIterator >
    544         void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
     560        void makeArrayFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, std::string fname, OutputIterator out ) {
    545561                static UniqueName indexName( "_index" );
    546562
     
    565581                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    566582
    567                 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     583                // want to be able to generate assignment, ctor, and dtor generically,
     584                // so fname is either ?=?, ?{}, or ^?{}
     585                UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    568586
    569587                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     
    574592                dstIndex->get_args().push_back( dstselect );
    575593                dstIndex->get_args().push_back( new VariableExpr( index ) );
    576                 assignExpr->get_args().push_back( dstIndex );
     594                fExpr->get_args().push_back( dstIndex );
    577595
    578596                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     
    580598                srcIndex->get_args().push_back( srcselect );
    581599                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 ) );
     600                fExpr->get_args().push_back( srcIndex );
     601
     602                *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) );
    585603        }
    586604
     
    732750                                        // assign to both destination and return value
    733751                                        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() ) );
     752                                                makeArrayFunction( srcParam, dstParam, fixedMember, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
     753                                                makeArrayFunction( srcParam, returnVal, fixedMember, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    736754                                        } 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() ) );
     755                                                makeScalarFunction( srcParam, dstParam, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
     756                                                makeScalarFunction( srcParam, returnVal, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    739757                                        } // if
    740758                                } else {
    741759                                        // assign to destination
    742760                                        if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    743                                                 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
     761                                                makeArrayFunction( srcParam, dstParam, dwt, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    744762                                        } else {
    745                                                 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
     763                                                makeScalarFunction( srcParam, dstParam, dwt, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    746764                                        } // if
    747765                                } // if
     
    753771        }
    754772
    755         Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
     773        void makeStructCtorDtor( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
     774                FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
     775
     776                // Make function polymorphic in same parameters as generic struct, if applicable
     777                bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
     778                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
     779                std::list< Expression* > structParams;  // List of matching parameters to put on types
     780                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
     781                        isGeneric = true;
     782                        TypeDecl *typeParam = (*param)->clone();
     783                        ctorType->get_forall().push_back( typeParam );
     784                        structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
     785                }
     786
     787                ObjectDecl *thisParam = new ObjectDecl( "_this", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
     788                ctorType->get_parameters().push_back( thisParam );
     789
     790                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
     791                // because each unit generates copies of the default routines for each aggregate.
     792                FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, 0, true, false );
     793                FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType->clone(), 0, true, false );
     794                FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType->clone(), 0, true, false );
     795                ctorDecl->fixUniqueId();
     796                copyCtorDecl->fixUniqueId();
     797                dtorDecl->fixUniqueId();
     798
     799                // add definitions
     800                // TODO: add in calls to default constructors and destructors for fields
     801                ctorDecl->set_statements( new CompoundStmt( noLabels ) );
     802                copyCtorDecl->set_statements( new CompoundStmt( noLabels ) );
     803                dtorDecl->set_statements( new CompoundStmt( noLabels ) );
     804                declsToAdd.push_back( ctorDecl );
     805                declsToAdd.push_back( copyCtorDecl );
     806                declsToAdd.push_back( dtorDecl );
     807
     808                ObjectDecl * srcParam = new ObjectDecl( "_other", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
     809                copyCtorDecl->get_functionType()->get_parameters().push_back( srcParam );
     810                for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
     811                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
     812                                // query the type qualifiers of this field and skip assigning it if it is marked const.
     813                                // If it is an array type, we need to strip off the array layers to find its qualifiers.
     814                                Type * type = dwt->get_type();
     815                                while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     816                                        type = at->get_base();
     817                                }
     818
     819                                if ( type->get_qualifiers().isConst ) {
     820                                        // don't assign const members
     821                                        continue;
     822                                }
     823
     824                                if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
     825                                        makeArrayFunction( srcParam, thisParam, dwt, array, "?{}", back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
     826                                        // if ( isGeneric ) makeArrayFunction( srcParam, returnVal, dwt, array, back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
     827                                } else {
     828                                        makeScalarFunction( srcParam, thisParam, dwt, "?{}", back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
     829                                        // if ( isGeneric ) makeScalarCtor( srcParam, returnVal, dwt, back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
     830                                } // if
     831                        } // if
     832                } // for
     833                // if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     834        }
     835
     836        void makeUnionFunctions( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
    756837                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    757838
     
    767848                }
    768849
     850                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
     851                assignType->get_parameters().push_back( dstParam );
     852
     853                // default ctor/dtor need only first parameter
     854                FunctionType * ctorType = assignType->clone();
     855                FunctionType * dtorType = assignType->clone();
     856
     857                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     858                assignType->get_parameters().push_back( srcParam );
     859
     860                // copy ctor needs both parameters
     861                FunctionType * copyCtorType = assignType->clone();
     862
     863                // assignment needs both and return value
    769864                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    770865                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 );
    777866
    778867                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    779868                // because each unit generates copies of the default routines for each aggregate.
    780869                FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
     870                FunctionDecl *ctorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );
     871                FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, NULL, true, false );
     872                FunctionDecl *dtorDecl = new FunctionDecl( "^?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );
     873
    781874                assignDecl->fixUniqueId();
     875                ctorDecl->fixUniqueId();
     876                copyCtorDecl->fixUniqueId();
     877                dtorDecl->fixUniqueId();
    782878
    783879                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    784880                if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    785                
     881
    786882                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    787883
    788                 return assignDecl;
     884                // body of assignment and copy ctor is the same
     885                copyCtorDecl->set_statements( assignDecl->get_statements()->clone() );
     886
     887                declsToAdd.push_back( assignDecl );
     888                declsToAdd.push_back( ctorDecl );
     889                declsToAdd.push_back( copyCtorDecl );
     890                declsToAdd.push_back( dtorDecl );
    789891        }
    790892
     
    802904                        StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    803905                        structInst.set_baseStruct( structDecl );
     906
    804907                        declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) );
     908                        makeStructCtorDtor( structDecl, &structInst, functionNesting, declsToAdd );
    805909                        structsDone.insert( structDecl->get_name() );
    806910                } // if
     
    811915                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    812916                        unionInst.set_baseUnion( unionDecl );
    813                         declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) );
     917                        makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAdd );
    814918                } // if
    815919        }
     
    10801184        }
    10811185
     1186        void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
     1187                VerifyCtorDtor verifier;
     1188                acceptAll( translationUnit, verifier );
     1189        }
     1190
     1191        void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
     1192                FunctionType * funcType = funcDecl->get_functionType();
     1193                std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
     1194                std::list< DeclarationWithType * > &params = funcType->get_parameters();
     1195
     1196                if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
     1197                        if ( params.size() == 0 ) {
     1198                                throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
     1199                        }
     1200                        if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
     1201                                throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
     1202                        }
     1203                        if ( returnVals.size() != 0 ) {
     1204                                throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
     1205                        }
     1206                }
     1207
     1208                Visitor::visit( funcDecl );
     1209                // original idea: modify signature of ctor/dtors and insert appropriate return statements
     1210                // to cause desired behaviour
     1211                // new idea: add comma exprs to every ctor call to produce first parameter.
     1212                // this requires some memoization of the first parameter, because it can be a
     1213                // complicated expression with side effects (see: malloc). idea: add temporary variable
     1214                // that is assigned address of constructed object in ctor argument position and
     1215                // return the temporary. It should also be done after all implicit ctors are
     1216                // added, so not in this pass!
     1217        }
    10821218} // namespace SymTab
    10831219
  • src/SynTree/Declaration.h

    rac1ed49 rc14cff1  
    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
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Dec 09 14:08:22 2015
    13 // Update Count     : 32
     12// Last Modified On : Wed Jan 13 16:11:49 2016
     13// Update Count     : 36
    1414//
    1515
  • src/SynTree/Initializer.cc

    rac1ed49 rc14cff1  
    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 Jan 13 15:31:45 2016
     13// Update Count     : 28
    1414//
    1515
     
    1818#include "Common/utility.h"
    1919
    20 Initializer::Initializer() {}
     20Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
    2121
    2222Initializer::~Initializer() {}
     
    3131void Initializer::print( std::ostream &os, int indent ) {}
    3232
    33 SingleInit::SingleInit( Expression *v, std::list< Expression *> &_designators ) : value ( v ), designators( _designators ) {
     33SingleInit::SingleInit( Expression *v, std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) {
    3434}
    3535
    36 SingleInit::SingleInit( const SingleInit &other ) : value ( other.value ) {
     36SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( other.value ) {
    3737        cloneAll(other.designators, designators );
    3838}
     
    5454}
    5555
    56 ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators )
    57         : initializers( _initializers ), designators( _designators ) {
     56ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators, bool maybeConstructed )
     57        : Initializer( maybeConstructed), initializers( _initializers ), designators( _designators ) {
    5858}
    5959
     
    6565
    6666void ListInit::print( std::ostream &os, int indent ) {
    67         os << std::endl << std::string(indent, ' ') << "Compound initializer:  "; 
     67        os << std::endl << std::string(indent, ' ') << "Compound initializer:  ";
    6868        if ( ! designators.empty() ) {
    6969                os << std::string(indent + 2, ' ' ) << "designated by: [";
    7070                for ( std::list < Expression * >::iterator i = designators.begin();
    7171                          i != designators.end(); i++ ) {
    72                         ( *i )->print(os, indent + 4 ); 
     72                        ( *i )->print(os, indent + 4 );
    7373                } // for
    74        
     74
    7575                os << std::string(indent + 2, ' ' ) << "]";
    7676        } // if
    7777
    78         for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ ) 
     78        for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ )
    7979                (*i)->print( os, indent + 2 );
    8080}
     81
     82
     83ConstructorInit::ConstructorInit( Expression * ctor, Initializer * init ) : Initializer( true ), ctor( ctor ), init( init ) {}
     84ConstructorInit::~ConstructorInit() {
     85        delete ctor;
     86        delete init;
     87}
     88
     89ConstructorInit *ConstructorInit::clone() const {
     90        return new ConstructorInit( *this );
     91}
     92
     93void ConstructorInit::print( std::ostream &os, int indent ) {
     94        os << std::endl << std::string(indent, ' ') << "Constructor initializer: ";
     95        if ( ctor ) {
     96                os << " initially constructed with ";
     97                ctor->print( os, indent+2 );
     98        } // if
     99
     100        if ( init ) {
     101                os << " with fallback C-style initializer: ";
     102                init->print( os, indent+2 );
     103        }
     104}
     105
     106
    81107// Local Variables: //
    82108// tab-width: 4 //
  • src/SynTree/Initializer.h

    rac1ed49 rc14cff1  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Initializer.h -- 
     7// Initializer.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 09:03:48 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Feb 09 14:40:15 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, 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( std::list<Initializer*> &,
     85                          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( Expression * ctor, Initializer * init );
     110        virtual ~ConstructorInit();
     111
     112        void set_ctor( Expression * newValue ) { ctor = newValue; }
     113        Expression * get_ctor() const { return ctor; }
     114        void set_init( Initializer * newValue ) { init = newValue; }
     115        Initializer * get_init() const { return init; }
     116
     117        virtual ConstructorInit *clone() const;
     118        virtual void accept( Visitor &v ) { v.visit( this ); }
     119        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     120        virtual void print( std::ostream &os, int indent = 0 );
     121
     122  private:
     123        Expression * ctor;
     124        // C-style initializer made up of SingleInit and ListInit nodes to use as a fallback
     125        // if an appropriate constructor definition is not found by the resolver
     126        Initializer * init;
     127};
     128
    102129#endif // INITIALIZER_H
    103130
  • src/SynTree/Mutator.cc

    rac1ed49 rc14cff1  
    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 : Sat Jul 25 19:21:33 2015
    13 // Update Count     : 11
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jan 13 15:32:29 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

    rac1ed49 rc14cff1  
    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 : Thu Nov 19 22:26:16 2015
    13 // Update Count     : 8
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jan 13 15:24:26 2016
     13// Update Count     : 9
    1414//
    1515#include <cassert>
     
    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

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    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 : Thu Jul 23 23:25:04 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jan 13 15:28:41 2016
     13// Update Count     : 4
    1414//
    1515
     
    102102class SingleInit;
    103103class ListInit;
     104class ConstructorInit;
    104105
    105106class Subrange;
  • src/SynTree/Visitor.cc

    rac1ed49 rc14cff1  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Visitor.cc -- 
     7// Visitor.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 24 16:11:05 2015
    13 // Update Count     : 15
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jan 13 15:27:23 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

    rac1ed49 rc14cff1  
    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 : Mon Jan 25 21:20:44 2016
    13 // Update Count     : 5
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Feb 09 13:20:48 2016
     13// Update Count     : 6
    1414//
    1515
     
    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

    rac1ed49 rc14cff1  
    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

    rac1ed49 rc14cff1  
    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
     
    6060        ${CC} ${CFLAGS} -c -o $@ $<
    6161
    62 libs = stdlib iostream fstream iterator
     62libs = # stdlib iostream fstream iterator  # temporarily getting rid of these until ctor/dtor autogen works
    6363libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c}
    6464
  • src/libcfa/Makefile.in

    rac1ed49 rc14cff1  
    8383libcfa_a_AR = $(AR) $(ARFLAGS)
    8484libcfa_a_LIBADD =
    85 am__objects_1 = stdlib.$(OBJEXT) iostream.$(OBJEXT) fstream.$(OBJEXT) \
    86         iterator.$(OBJEXT)
     85am__objects_1 =
    8786am_libcfa_a_OBJECTS = libcfa-prelude.$(OBJEXT) $(am__objects_1)
    8887libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
     
    110109AWK = @AWK@
    111110BACKEND_CC = @BACKEND_CC@
    112 CC = ${abs_top_srcdir}/src/driver/cfa 
     111CC = ${abs_top_srcdir}/src/driver/cfa
    113112CCDEPMODE = @CCDEPMODE@
    114113CFA_BINDIR = @CFA_BINDIR@
     
    213212MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} \
    214213        ${addprefix ${libdir}/,${lib_LIBRARIES}} ${includedir}/*
    215 libs = stdlib iostream fstream iterator
     214libs = # stdlib iostream fstream iterator  # temporarily getting rid of these until ctor/dtor autogen works
    216215libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c}
    217216cheaders = bfd bfdlink demangle dialog evdns evhttp evrpc expat fcntl form gcrypt math
     
    293292        -rm -f *.tab.c
    294293
    295 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstream.Po@am__quote@
    296 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iostream.Po@am__quote@
    297 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iterator.Po@am__quote@
    298294@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa-prelude.Po@am__quote@
    299 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@
    300295
    301296.c.obj:
  • src/libcfa/prelude.cf

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

    rac1ed49 rc14cff1  
    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 : Tue Feb 09 13:28:11 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 ) {
     
    334350        std::list< Declaration * > decls;
    335351        if ( noprotop ) {
    336                 filter( translationUnit.begin(), translationUnit.end(), 
     352                filter( translationUnit.begin(), translationUnit.end(),
    337353                                std::back_inserter( decls ), notPrelude );
    338354        } else {
Note: See TracChangeset for help on using the changeset viewer.