Changes in / [a2d4d1c:4dfa562]


Ignore:
Location:
src
Files:
6 added
24 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    ra2d4d1c r4dfa562  
    443443        void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) {
    444444                extension( untypedExpr );
    445                 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->function ) ) {
     445                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
    446446                        OperatorInfo opInfo;
    447                         if ( operatorLookup( nameExpr->name, opInfo ) ) {
    448                                 std::list< Expression* >::iterator arg = untypedExpr->args.begin();
     447                        if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
     448                                std::list< Expression* >::iterator arg = untypedExpr->get_args().begin();
    449449                                switch ( opInfo.type ) {
    450450                                  case OT_INDEX:
    451                                         assert( untypedExpr->args.size() == 2 );
     451                                        assert( untypedExpr->get_args().size() == 2 );
    452452                                        (*arg++)->accept( *visitor );
    453453                                        output << "[";
     
    461461                                  case OT_CTOR:
    462462                                  case OT_DTOR:
    463                                         if ( untypedExpr->args.size() == 1 ) {
     463                                        if ( untypedExpr->get_args().size() == 1 ) {
    464464                                                // the expression fed into a single parameter constructor or destructor may contain side
    465465                                                // effects, so must still output this expression
     
    480480                                                (*arg++)->accept( *visitor );
    481481                                                output << opInfo.symbol << "{ ";
    482                                                 genCommaList( arg, untypedExpr->args.end() );
     482                                                genCommaList( arg, untypedExpr->get_args().end() );
    483483                                                output << "}) /* " << opInfo.inputName << " */";
    484484                                        } // if
     
    488488                                  case OT_PREFIXASSIGN:
    489489                                  case OT_LABELADDRESS:
    490                                         assert( untypedExpr->args.size() == 1 );
     490                                        assert( untypedExpr->get_args().size() == 1 );
    491491                                        output << "(";
    492492                                        output << opInfo.symbol;
     
    497497                                  case OT_POSTFIX:
    498498                                  case OT_POSTFIXASSIGN:
    499                                         assert( untypedExpr->args.size() == 1 );
     499                                        assert( untypedExpr->get_args().size() == 1 );
    500500                                        (*arg)->accept( *visitor );
    501501                                        output << opInfo.symbol;
     
    504504                                  case OT_INFIX:
    505505                                  case OT_INFIXASSIGN:
    506                                         assert( untypedExpr->args.size() == 2 );
     506                                        assert( untypedExpr->get_args().size() == 2 );
    507507                                        output << "(";
    508508                                        (*arg++)->accept( *visitor );
     
    517517                                } // switch
    518518                        } else {
    519                                 // builtin routines
    520                                 nameExpr->accept( *visitor );
    521                                 output << "(";
    522                                 genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
    523                                 output << ")";
     519                                if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
     520                                        assert( untypedExpr->get_args().size() == 2 );
     521                                        (*untypedExpr->get_args().begin())->accept( *visitor );
     522                                        output << " ... ";
     523                                        (*--untypedExpr->get_args().end())->accept( *visitor );
     524                                } else {                                                                // builtin routines
     525                                        nameExpr->accept( *visitor );
     526                                        output << "(";
     527                                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     528                                        output << ")";
     529                                } // if
    524530                        } // if
    525531                } else {
    526                         untypedExpr->function->accept( *visitor );
     532                        untypedExpr->get_function()->accept( *visitor );
    527533                        output << "(";
    528                         genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
     534                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    529535                        output << ")";
    530536                } // if
     
    532538
    533539        void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
    534                 rangeExpr->low->accept( *visitor );
     540                rangeExpr->get_low()->accept( *visitor );
    535541                output << " ... ";
    536                 rangeExpr->high->accept( *visitor );
     542                rangeExpr->get_high()->accept( *visitor );
    537543        }
    538544
  • src/GenPoly/Box.cc

    ra2d4d1c r4dfa562  
    3232#include "Common/UniqueName.h"           // for UniqueName
    3333#include "Common/utility.h"              // for toString
     34#include "DeclMutator.h"                 // for DeclMutator
    3435#include "FindFunction.h"                // for findFunction, findAndReplace...
    3536#include "GenPoly/ErasableScopedMap.h"   // for ErasableScopedMap<>::const_i...
     
    3839#include "Lvalue.h"                      // for generalizedLvalue
    3940#include "Parser/LinkageSpec.h"          // for C, Spec, Cforall, Intrinsic
     41#include "PolyMutator.h"                 // for PolyMutator
    4042#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
    4143#include "ResolvExpr/typeops.h"          // for typesCompatible
     
    6062                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6163
    62                 class BoxPass {
    63                 protected:
    64                         BoxPass() : scopeTyVars( TypeDecl::Data{} ) {}
    65                         TyVarMap scopeTyVars;
     64                /// Adds layout-generation functions to polymorphic types
     65                class LayoutFunctionBuilder final : public DeclMutator {
     66                        unsigned int functionNesting;  // current level of nested functions
     67                public:
     68                        LayoutFunctionBuilder() : functionNesting( 0 ) {}
     69
     70                        using DeclMutator::mutate;
     71                        virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
     72                        virtual Declaration *mutate( StructDecl *structDecl ) override;
     73                        virtual Declaration *mutate( UnionDecl *unionDecl ) override;
    6674                };
    6775
    68                 /// Adds layout-generation functions to polymorphic types
    69                 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
    70                         unsigned int functionNesting = 0;  // current level of nested functions
    71                 public:
    72                         void previsit( FunctionDecl *functionDecl );
    73                         void previsit( StructDecl *structDecl );
    74                         void previsit( UnionDecl *unionDecl );
    75                 };
    76 
    7776                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    78                 class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
     77                class Pass1 final : public PolyMutator {
    7978                  public:
    8079                        Pass1();
    8180
    82                         void premutate( FunctionDecl * functionDecl );
    83                         void premutate( TypeDecl * typeDecl );
    84                         void premutate( CommaExpr * commaExpr );
    85                         Expression * postmutate( ApplicationExpr * appExpr );
    86                         Expression * postmutate( UntypedExpr *expr );
    87                         void premutate( AddressExpr * addrExpr );
    88                         Expression * postmutate( AddressExpr * addrExpr );
    89                         void premutate( ReturnStmt * returnStmt );
    90                         void premutate( PointerType * pointerType );
    91                         void premutate( FunctionType * functionType );
    92 
    93                         void beginScope();
    94                         void endScope();
     81                        using PolyMutator::mutate;
     82                        virtual Expression *mutate( ApplicationExpr *appExpr ) override;
     83                        virtual Expression *mutate( AddressExpr *addrExpr ) override;
     84                        virtual Expression *mutate( UntypedExpr *expr ) override;
     85                        virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ) override;
     86                        virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
     87                        virtual Expression *mutate( CommaExpr *commaExpr ) override;
     88                        virtual Expression *mutate( ConditionalExpr *condExpr ) override;
     89                        virtual Statement * mutate( ReturnStmt *returnStmt ) override;
     90                        virtual Type *mutate( PointerType *pointerType ) override;
     91                        virtual Type * mutate( FunctionType *functionType ) override;
     92
     93                        virtual void doBeginScope() override;
     94                        virtual void doEndScope() override;
    9595                  private:
    9696                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
     
    129129                /// * Moves polymorphic returns in function types to pointer-type parameters
    130130                /// * adds type size and assertion parameters to parameter lists
    131                 struct Pass2 final : public BoxPass, public WithGuards {
    132                         void handleAggDecl();
    133 
    134                         DeclarationWithType * postmutate( FunctionDecl *functionDecl );
    135                         void premutate( StructDecl *structDecl );
    136                         void premutate( UnionDecl *unionDecl );
    137                         void premutate( TraitDecl *unionDecl );
    138                         void premutate( TypeDecl *typeDecl );
    139                         void premutate( PointerType *pointerType );
    140                         void premutate( FunctionType *funcType );
     131                class Pass2 final : public PolyMutator {
     132                  public:
     133                        template< typename DeclClass >
     134                        DeclClass *handleDecl( DeclClass *decl );
     135                        template< typename AggDecl >
     136                        AggDecl * handleAggDecl( AggDecl * aggDecl );
     137
     138                        typedef PolyMutator Parent;
     139                        using Parent::mutate;
     140                        virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
     141                        virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
     142                        virtual StructDecl *mutate( StructDecl *structDecl ) override;
     143                        virtual UnionDecl *mutate( UnionDecl *unionDecl ) override;
     144                        virtual TraitDecl *mutate( TraitDecl *unionDecl ) override;
     145                        virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
     146                        virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override;
     147                        virtual Type *mutate( PointerType *pointerType ) override;
     148                        virtual Type *mutate( FunctionType *funcType ) override;
    141149
    142150                  private:
     
    150158                /// * Calculates polymorphic offsetof expressions from offset array
    151159                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    152                 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
     160                class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
    153161                public:
    154162                        PolyGenericCalculator();
     
    189197                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    190198                        UniqueName bufNamer;                           ///< Namer for VLA buffers
     199                        TyVarMap scopeTyVars;
    191200                };
    192201
    193202                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
    194                 struct Pass3 final : public BoxPass, public WithGuards {
     203                class Pass3 final : public PolyMutator {
     204                  public:
    195205                        template< typename DeclClass >
    196                         void handleDecl( DeclClass * decl, Type * type );
    197 
    198                         void premutate( ObjectDecl * objectDecl );
    199                         void premutate( FunctionDecl * functionDecl );
    200                         void premutate( TypedefDecl * typedefDecl );
    201                         void premutate( StructDecl * structDecl );
    202                         void premutate( UnionDecl * unionDecl );
    203                         void premutate( TypeDecl * typeDecl );
    204                         void premutate( PointerType * pointerType );
    205                         void premutate( FunctionType * funcType );
     206                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     207
     208                        using PolyMutator::mutate;
     209                        virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
     210                        virtual Declaration *mutate( StructDecl *structDecl ) override;
     211                        virtual Declaration *mutate( UnionDecl *unionDecl ) override;
     212                        virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
     213                        virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override;
     214                        virtual TypeDecl *mutate( TypeDecl *objectDecl ) override;
     215                        virtual Type *mutate( PointerType *pointerType ) override;
     216                        virtual Type *mutate( FunctionType *funcType ) override;
     217                  private:
    206218                };
    207219        } // anonymous namespace
     
    235247
    236248        void box( std::list< Declaration *>& translationUnit ) {
    237                 PassVisitor<LayoutFunctionBuilder> layoutBuilder;
    238                 PassVisitor<Pass1> pass1;
    239                 PassVisitor<Pass2> pass2;
     249                LayoutFunctionBuilder layoutBuilder;
     250                Pass1 pass1;
     251                Pass2 pass2;
    240252                PassVisitor<PolyGenericCalculator> polyCalculator;
    241                 PassVisitor<Pass3> pass3;
    242 
    243                 acceptAll( translationUnit, layoutBuilder );
    244                 mutateAll( translationUnit, pass1 );
    245                 mutateAll( translationUnit, pass2 );
     253                Pass3 pass3;
     254
     255                layoutBuilder.mutateDeclarationList( translationUnit );
     256                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     257                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    246258                mutateAll( translationUnit, polyCalculator );
    247                 mutateAll( translationUnit, pass3 );
     259                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    248260        }
    249261
    250262        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    251263
    252         void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {
    253                 visit_children = false;
    254                 maybeAccept( functionDecl->get_functionType(), *visitor );
     264        DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
     265                functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    255266                ++functionNesting;
    256                 maybeAccept( functionDecl->get_statements(), *visitor );
     267                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    257268                --functionNesting;
     269                return functionDecl;
    258270        }
    259271
     
    344356        }
    345357
    346         void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) {
     358        Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    347359                // do not generate layout function for "empty" tag structs
    348                 visit_children = false;
    349                 if ( structDecl->get_members().empty() ) return;
     360                if ( structDecl->get_members().empty() ) return structDecl;
    350361
    351362                // get parameters that can change layout, exiting early if none
    352363                std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    353                 if ( otypeParams.empty() ) return;
     364                if ( otypeParams.empty() ) return structDecl;
    354365
    355366                // build layout function signature
     
    402413                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    403414
    404                 declsToAddAfter.push_back( layoutDecl );
     415                addDeclarationAfter( layoutDecl );
     416                return structDecl;
    405417        }
    406418
    407         void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) {
     419        Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    408420                // do not generate layout function for "empty" tag unions
    409                 visit_children = false;
    410                 if ( unionDecl->get_members().empty() ) return;
     421                if ( unionDecl->get_members().empty() ) return unionDecl;
    411422
    412423                // get parameters that can change layout, exiting early if none
    413424                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    414                 if ( otypeParams.empty() ) return;
     425                if ( otypeParams.empty() ) return unionDecl;
    415426
    416427                // build layout function signature
     
    445456                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    446457
    447                 declsToAddAfter.push_back( layoutDecl );
     458                addDeclarationAfter( layoutDecl );
     459                return unionDecl;
    448460        }
    449461
     
    489501                Pass1::Pass1() : tempNamer( "_temp" ) {}
    490502
    491                 void Pass1::premutate( FunctionDecl *functionDecl ) {
     503                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    492504                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    493505                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    494                                 GuardScope( scopeTyVars );
    495                                 GuardValue( retval );
     506                                doBeginScope();
     507                                scopeTyVars.beginScope();
     508
     509                                DeclarationWithType *oldRetval = retval;
    496510
    497511                                // process polymorphic return value
    498512                                retval = nullptr;
    499                                 FunctionType *functionType = functionDecl->type;
    500                                 if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) {
    501                                         retval = functionType->returnVals.front();
     513                                if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) {
     514                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    502515
    503516                                        // give names to unnamed return values
    504                                         if ( retval->name == "" ) {
    505                                                 retval->name = "_retparm";
    506                                                 retval->linkage = LinkageSpec::C;
     517                                        if ( retval->get_name() == "" ) {
     518                                                retval->set_name( "_retparm" );
     519                                                retval->set_linkage( LinkageSpec::C );
    507520                                        } // if
    508521                                } // if
    509522
    510                                 makeTyVarMap( functionType, scopeTyVars );
    511 
    512                                 std::list< DeclarationWithType *> &paramList = functionType->parameters;
     523                                FunctionType *functionType = functionDecl->get_functionType();
     524                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
     525
     526                                std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
    513527                                std::list< FunctionType *> functions;
    514                                 for ( Type::ForallList::iterator tyVar = functionType->forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) {
    515                                         for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
     528                                for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
     529                                        for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    516530                                                findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    517531                                        } // for
     
    528542                                        } // if
    529543                                } // for
     544
     545                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
     546
     547                                scopeTyVars.endScope();
     548                                retval = oldRetval;
     549                                doEndScope();
    530550                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    531551                        } // if
    532                 }
    533 
    534                 void Pass1::premutate( TypeDecl *typeDecl ) {
     552                        return functionDecl;
     553                }
     554
     555                TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
    535556                        addToTyVarMap( typeDecl, scopeTyVars );
    536                 }
    537 
    538                 void Pass1::premutate( CommaExpr *commaExpr ) {
     557                        return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
     558                }
     559
     560                Expression *Pass1::mutate( CommaExpr *commaExpr ) {
    539561                        // Attempting to find application expressions that were mutated by the copy constructor passes
    540562                        // to use an explicit return variable, so that the variable can be reused as a parameter to the
     
    552574                                }
    553575                        }
     576
     577                        commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
     578                        commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
     579                        return commaExpr;
     580                }
     581
     582                Expression *Pass1::mutate( ConditionalExpr *condExpr ) {
     583                        condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
     584                        condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
     585                        condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
     586                        return condExpr;
     587
    554588                }
    555589
     
    625659                ObjectDecl *Pass1::makeTemporary( Type *type ) {
    626660                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 );
    627                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
     661                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    628662                        return newObj;
    629663                }
     
    741775                                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 );
    742776                                        newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
    743                                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
     777                                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    744778                                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
    745779                                        assign->get_args().push_back( new VariableExpr( newObj ) );
    746780                                        assign->get_args().push_back( arg );
    747                                         stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) );
     781                                        stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
    748782                                        arg = new AddressExpr( new VariableExpr( newObj ) );
    749783                                } // if
     
    927961                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    928962                                                adapter = answer.first;
    929                                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newAdapter ) );
     963                                                stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
    930964                                        } // if
    931965                                        assert( adapter != adapters.end() );
     
    10841118                }
    10851119
    1086                 Expression *Pass1::postmutate( ApplicationExpr *appExpr ) {
     1120                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    10871121                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    10881122                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    10901124                        // }
    10911125                        // std::cerr << "\n";
    1092 
    1093                         assert( appExpr->function->result );
    1094                         FunctionType * function = getFunctionType( appExpr->function->result );
    1095                         assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
     1126                        appExpr->get_function()->acceptMutator( *this );
     1127                        mutateAll( appExpr->get_args(), *this );
     1128
     1129                        assert( appExpr->get_function()->has_result() );
     1130                        FunctionType * function = getFunctionType( appExpr->get_function()->get_result() );
     1131                        assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() );
    10961132
    10971133                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     
    11461182                }
    11471183
    1148                 Expression * Pass1::postmutate( UntypedExpr *expr ) {
    1149                         if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    1150                                 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
     1184                Expression *Pass1::mutate( UntypedExpr *expr ) {
     1185                        if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
     1186                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    11511187                                        if ( name->get_name() == "*?" ) {
    1152                                                 Expression *ret = expr->args.front();
    1153                                                 expr->args.clear();
     1188                                                Expression *ret = expr->get_args().front();
     1189                                                expr->get_args().clear();
    11541190                                                delete expr;
    1155                                                 return ret;
     1191                                                return ret->acceptMutator( *this );
    11561192                                        } // if
    11571193                                } // if
    11581194                        } // if
    1159                         return expr;
    1160                 }
    1161 
    1162                 void Pass1::premutate( AddressExpr * ) { visit_children = false; }
    1163                 Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
     1195                        return PolyMutator::mutate( expr );
     1196                }
     1197
     1198                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    11641199                        assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );
    11651200
     
    11811216                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    11821217                        // out of the if condition.
    1183                         addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor );
     1218                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    11841219                        // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
    11851220                        bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
     
    11961231                }
    11971232
    1198                 void Pass1::premutate( ReturnStmt *returnStmt ) {
    1199                         if ( retval && returnStmt->expr ) {
    1200                                 assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() );
    1201                                 delete returnStmt->expr;
    1202                                 returnStmt->expr = nullptr;
     1233                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
     1234                        if ( retval && returnStmt->get_expr() ) {
     1235                                assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );
     1236                                delete returnStmt->get_expr();
     1237                                returnStmt->set_expr( 0 );
     1238                        } else {
     1239                                returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
    12031240                        } // if
    1204                 }
    1205 
    1206                 void Pass1::premutate( PointerType *pointerType ) {
    1207                         GuardScope( scopeTyVars );
     1241                        return returnStmt;
     1242                }
     1243
     1244                Type * Pass1::mutate( PointerType *pointerType ) {
     1245                        scopeTyVars.beginScope();
    12081246                        makeTyVarMap( pointerType, scopeTyVars );
    1209                 }
    1210 
    1211                 void Pass1::premutate( FunctionType *functionType ) {
    1212                         GuardScope( scopeTyVars );
     1247
     1248                        Type *ret = Mutator::mutate( pointerType );
     1249
     1250                        scopeTyVars.endScope();
     1251                        return ret;
     1252                }
     1253
     1254                Type * Pass1::mutate( FunctionType *functionType ) {
     1255                        scopeTyVars.beginScope();
    12131256                        makeTyVarMap( functionType, scopeTyVars );
    1214                 }
    1215 
    1216                 void Pass1::beginScope() {
     1257
     1258                        Type *ret = Mutator::mutate( functionType );
     1259
     1260                        scopeTyVars.endScope();
     1261                        return ret;
     1262                }
     1263
     1264                void Pass1::doBeginScope() {
    12171265                        adapters.beginScope();
    12181266                }
    12191267
    1220                 void Pass1::endScope() {
     1268                void Pass1::doEndScope() {
    12211269                        adapters.endScope();
    12221270                }
     
    12451293                }
    12461294
    1247                 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
     1295                template< typename DeclClass >
     1296                DeclClass * Pass2::handleDecl( DeclClass *decl ) {
     1297                        DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) );
     1298
     1299                        return ret;
     1300                }
     1301
     1302                DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
     1303                        functionDecl = strict_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) );
    12481304                        FunctionType * ftype = functionDecl->get_functionType();
    12491305                        if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
     
    12691325                }
    12701326
    1271                 void Pass2::premutate( StructDecl * ) {
     1327                ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) {
     1328                        return handleDecl( objectDecl );
     1329                }
     1330
     1331                template< typename AggDecl >
     1332                AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) {
    12721333                        // prevent tyVars from leaking into containing scope
    1273                         GuardScope( scopeTyVars );
    1274                 }
    1275 
    1276                 void Pass2::premutate( UnionDecl * ) {
    1277                         // prevent tyVars from leaking into containing scope
    1278                         GuardScope( scopeTyVars );
    1279                 }
    1280 
    1281                 void Pass2::premutate( TraitDecl * ) {
    1282                         // prevent tyVars from leaking into containing scope
    1283                         GuardScope( scopeTyVars );
    1284                 }
    1285 
    1286                 void Pass2::premutate( TypeDecl *typeDecl ) {
     1334                        scopeTyVars.beginScope();
     1335                        Parent::mutate( aggDecl );
     1336                        scopeTyVars.endScope();
     1337                        return aggDecl;
     1338                }
     1339
     1340                StructDecl * Pass2::mutate( StructDecl *aggDecl ) {
     1341                        return handleAggDecl( aggDecl );
     1342                }
     1343
     1344                UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) {
     1345                        return handleAggDecl( aggDecl );
     1346                }
     1347
     1348                TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) {
     1349                        return handleAggDecl( aggDecl );
     1350                }
     1351
     1352                TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
    12871353                        addToTyVarMap( typeDecl, scopeTyVars );
    1288                 }
    1289 
    1290                 void Pass2::premutate( PointerType *pointerType ) {
    1291                         GuardScope( scopeTyVars );
     1354                        if ( typeDecl->get_base() ) {
     1355                                return handleDecl( typeDecl );
     1356                        } else {
     1357                                return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) );
     1358                        }
     1359                }
     1360
     1361                TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) {
     1362                        return handleDecl( typedefDecl );
     1363                }
     1364
     1365                Type * Pass2::mutate( PointerType *pointerType ) {
     1366                        scopeTyVars.beginScope();
    12921367                        makeTyVarMap( pointerType, scopeTyVars );
    1293                 }
    1294 
    1295                 void Pass2::premutate( FunctionType *funcType ) {
    1296                         GuardScope( scopeTyVars );
     1368
     1369                        Type *ret = Parent::mutate( pointerType );
     1370
     1371                        scopeTyVars.endScope();
     1372                        return ret;
     1373                }
     1374
     1375                Type *Pass2::mutate( FunctionType *funcType ) {
     1376                        scopeTyVars.beginScope();
     1377
    12971378                        makeTyVarMap( funcType, scopeTyVars );
    12981379
     
    13331414                                // move all assertions into parameter list
    13341415                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
     1416//      *assert = (*assert)->acceptMutator( *this );
    13351417                                        // assertion parameters may not be used in body, pass along with unused attribute.
    13361418                                        (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
     
    13681450                                                }
    13691451                                        }
     1452
    13701453                                        seenTypes.insert( typeName );
    13711454                                }
     
    13751458                        funcType->get_parameters().splice( last, inferredParams );
    13761459                        addAdapters( funcType );
     1460                        mutateAll( funcType->get_returnVals(), *this );
     1461                        mutateAll( funcType->get_parameters(), *this );
     1462
     1463                        scopeTyVars.endScope();
     1464                        return funcType;
    13771465                }
    13781466
     
    13801468
    13811469                PolyGenericCalculator::PolyGenericCalculator()
    1382                         : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}
     1470                        : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {}
    13831471
    13841472                void PolyGenericCalculator::beginTypeScope( Type *ty ) {
     
    17411829
    17421830                template< typename DeclClass >
    1743                 void Pass3::handleDecl( DeclClass * decl, Type * type ) {
    1744                         GuardScope( scopeTyVars );
     1831                DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
     1832                        scopeTyVars.beginScope();
    17451833                        makeTyVarMap( type, scopeTyVars );
     1834
     1835                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     1836                        // ScrubTyVars::scrub( decl, scopeTyVars );
    17461837                        ScrubTyVars::scrubAll( decl );
    1747                 }
    1748 
    1749                 void Pass3::premutate( ObjectDecl * objectDecl ) {
    1750                         handleDecl( objectDecl, objectDecl->type );
    1751                 }
    1752 
    1753                 void Pass3::premutate( FunctionDecl * functionDecl ) {
    1754                         handleDecl( functionDecl, functionDecl->type );
    1755                 }
    1756 
    1757                 void Pass3::premutate( TypedefDecl * typedefDecl ) {
    1758                         handleDecl( typedefDecl, typedefDecl->base );
     1838
     1839                        scopeTyVars.endScope();
     1840                        return ret;
     1841                }
     1842
     1843                ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) {
     1844                        return handleDecl( objectDecl, objectDecl->get_type() );
     1845                }
     1846
     1847                DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) {
     1848                        return handleDecl( functionDecl, functionDecl->get_functionType() );
     1849                }
     1850
     1851                TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) {
     1852                        return handleDecl( typedefDecl, typedefDecl->get_base() );
    17591853                }
    17601854
    17611855                /// Strips the members from a generic aggregate
    1762                 void stripGenericMembers(AggregateDecl * decl) {
    1763                         if ( ! decl->parameters.empty() ) decl->members.clear();
    1764                 }
    1765 
    1766                 void Pass3::premutate( StructDecl * structDecl ) {
     1856                void stripGenericMembers(AggregateDecl* decl) {
     1857                        if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
     1858                }
     1859
     1860                Declaration *Pass3::mutate( StructDecl *structDecl ) {
    17671861                        stripGenericMembers( structDecl );
    1768                 }
    1769 
    1770                 void Pass3::premutate( UnionDecl * unionDecl ) {
     1862                        return structDecl;
     1863                }
     1864
     1865                Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
    17711866                        stripGenericMembers( unionDecl );
    1772                 }
    1773 
    1774                 void Pass3::premutate( TypeDecl * typeDecl ) {
     1867                        return unionDecl;
     1868                }
     1869
     1870                TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
     1871//   Initializer *init = 0;
     1872//   std::list< Expression *> designators;
     1873//   addToTyVarMap( typeDecl, scopeTyVars );
     1874//   if ( typeDecl->get_base() ) {
     1875//     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
     1876//   }
     1877//   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
     1878
    17751879                        addToTyVarMap( typeDecl, scopeTyVars );
    1776                 }
    1777 
    1778                 void Pass3::premutate( PointerType * pointerType ) {
    1779                         GuardScope( scopeTyVars );
     1880                        return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
     1881                }
     1882
     1883                Type * Pass3::mutate( PointerType *pointerType ) {
     1884                        scopeTyVars.beginScope();
    17801885                        makeTyVarMap( pointerType, scopeTyVars );
    1781                 }
    1782 
    1783                 void Pass3::premutate( FunctionType * functionType ) {
    1784                         GuardScope( scopeTyVars );
     1886
     1887                        Type *ret = Mutator::mutate( pointerType );
     1888
     1889                        scopeTyVars.endScope();
     1890                        return ret;
     1891                }
     1892
     1893                Type * Pass3::mutate( FunctionType *functionType ) {
     1894                        scopeTyVars.beginScope();
    17851895                        makeTyVarMap( functionType, scopeTyVars );
     1896
     1897                        Type *ret = Mutator::mutate( functionType );
     1898
     1899                        scopeTyVars.endScope();
     1900                        return ret;
    17861901                }
    17871902        } // anonymous namespace
  • src/GenPoly/Specialize.cc

    ra2d4d1c r4dfa562  
    2222#include <utility>                       // for pair
    2323
    24 #include "Common/PassVisitor.h"
    2524#include "Common/SemanticError.h"        // for SemanticError
    2625#include "Common/UniqueName.h"           // for UniqueName
     
    2928#include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
    3029#include "Parser/LinkageSpec.h"          // for C
     30#include "PolyMutator.h"                 // for PolyMutator
    3131#include "ResolvExpr/FindOpenVars.h"     // for findOpenVars
    3232#include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
     
    4343
    4444namespace GenPoly {
    45         struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
    46                 Expression * postmutate( ApplicationExpr *applicationExpr );
    47                 Expression * postmutate( AddressExpr *castExpr );
    48                 Expression * postmutate( CastExpr *castExpr );
     45        class Specialize final : public PolyMutator {
     46          public:
     47                using PolyMutator::mutate;
     48                virtual Expression * mutate( ApplicationExpr *applicationExpr ) override;
     49                virtual Expression * mutate( AddressExpr *castExpr ) override;
     50                virtual Expression * mutate( CastExpr *castExpr ) override;
     51                // virtual Expression * mutate( LogicalExpr *logicalExpr );
     52                // virtual Expression * mutate( ConditionalExpr *conditionalExpr );
     53                // virtual Expression * mutate( CommaExpr *commaExpr );
    4954
    5055                void handleExplicitParams( ApplicationExpr *appExpr );
     
    199204        }
    200205
    201         struct EnvTrimmer {
     206        struct EnvTrimmer : public Visitor {
    202207                TypeSubstitution * env, * newEnv;
    203208                EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    204                 void previsit( TypeDecl * tyDecl ) {
     209                virtual void visit( TypeDecl * tyDecl ) {
    205210                        // transfer known bindings for seen type variables
    206                         if ( Type * t = env->lookup( tyDecl->name ) ) {
    207                                 newEnv->add( tyDecl->name, t );
     211                        if ( Type * t = env->lookup( tyDecl->get_name() ) ) {
     212                                newEnv->add( tyDecl->get_name(), t );
    208213                        }
    209214                }
     
    214219                if ( env ) {
    215220                        TypeSubstitution * newEnv = new TypeSubstitution();
    216                         PassVisitor<EnvTrimmer> trimmer( env, newEnv );
     221                        EnvTrimmer trimmer( env, newEnv );
    217222                        expr->accept( trimmer );
    218223                        return newEnv;
     
    272277                std::string oldParamPrefix = paramPrefix;
    273278                paramPrefix += "p";
    274                 // save stmtsToAddBefore in oldStmts
     279                // save stmtsToAdd in oldStmts
    275280                std::list< Statement* > oldStmts;
    276                 oldStmts.splice( oldStmts.end(), stmtsToAddBefore );
    277                 appExpr->acceptMutator( *visitor );
     281                oldStmts.splice( oldStmts.end(), stmtsToAdd );
     282                mutate( appExpr );
    278283                paramPrefix = oldParamPrefix;
    279284                // write any statements added for recursive specializations into the thunk body
    280                 thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore );
    281                 // restore oldStmts into stmtsToAddBefore
    282                 stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts );
     285                thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
     286                // restore oldStmts into stmtsToAdd
     287                stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
    283288
    284289                // add return (or valueless expression) to the thunk
    285290                Statement *appStmt;
    286                 if ( funType->returnVals.empty() ) {
     291                if ( funType->get_returnVals().empty() ) {
    287292                        appStmt = new ExprStmt( noLabels, appExpr );
    288293                } else {
    289294                        appStmt = new ReturnStmt( noLabels, appExpr );
    290295                } // if
    291                 thunkFunc->statements->kids.push_back( appStmt );
     296                thunkFunc->get_statements()->get_kids().push_back( appStmt );
    292297
    293298                // add thunk definition to queue of statements to add
    294                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) );
     299                stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
    295300                // return address of thunk function as replacement expression
    296301                return new AddressExpr( new VariableExpr( thunkFunc ) );
     
    299304        void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) {
    300305                // create thunks for the explicit parameters
    301                 assert( appExpr->function->result );
    302                 FunctionType *function = getFunctionType( appExpr->function->result );
     306                assert( appExpr->get_function()->has_result() );
     307                FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
    303308                assert( function );
    304309                std::list< DeclarationWithType* >::iterator formal;
    305310                std::list< Expression* >::iterator actual;
    306311                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    307                         *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
    308                 }
    309         }
    310 
    311         Expression * Specialize::postmutate( ApplicationExpr *appExpr ) {
     312                        *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
     313                }
     314        }
     315
     316        Expression * Specialize::mutate( ApplicationExpr *appExpr ) {
     317                appExpr->get_function()->acceptMutator( *this );
     318                mutateAll( appExpr->get_args(), *this );
     319
    312320                if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) {
    313321                        // create thunks for the inferred parameters
     
    323331        }
    324332
    325         Expression * Specialize::postmutate( AddressExpr *addrExpr ) {
    326                 assert( addrExpr->result );
    327                 addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) );
     333        Expression * Specialize::mutate( AddressExpr *addrExpr ) {
     334                addrExpr->get_arg()->acceptMutator( *this );
     335                assert( addrExpr->has_result() );
     336                addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
    328337                return addrExpr;
    329338        }
    330339
    331         Expression * Specialize::postmutate( CastExpr *castExpr ) {
    332                 if ( castExpr->result->isVoid() ) {
     340        Expression * Specialize::mutate( CastExpr *castExpr ) {
     341                castExpr->get_arg()->acceptMutator( *this );
     342                if ( castExpr->get_result()->isVoid() ) {
    333343                        // can't specialize if we don't have a return value
    334344                        return castExpr;
    335345                }
    336                 Expression *specialized = doSpecialization( castExpr->result, castExpr->arg );
    337                 if ( specialized != castExpr->arg ) {
     346                Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
     347                if ( specialized != castExpr->get_arg() ) {
    338348                        // assume here that the specialization incorporates the cast
    339349                        return specialized;
     
    343353        }
    344354
     355        // Removing these for now. Richard put these in for some reason, but it's not clear why.
     356        // In particular, copy constructors produce a comma expression, and with this code the parts
     357        // of that comma expression are not specialized, which causes problems.
     358
     359        // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
     360        //      return logicalExpr;
     361        // }
     362
     363        // Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
     364        //      return condExpr;
     365        // }
     366
     367        // Expression * Specialize::mutate( CommaExpr *commaExpr ) {
     368        //      return commaExpr;
     369        // }
     370
    345371        void convertSpecializations( std::list< Declaration* >& translationUnit ) {
    346                 PassVisitor<Specialize> spec;
     372                Specialize spec;
    347373                mutateAll( translationUnit, spec );
    348374        }
  • src/GenPoly/module.mk

    ra2d4d1c r4dfa562  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk --
     8## module.mk -- 
    99##
    1010## Author           : Richard C. Bilson
     
    1717SRC += GenPoly/Box.cc \
    1818       GenPoly/GenPoly.cc \
     19       GenPoly/PolyMutator.cc \
    1920       GenPoly/ScrubTyVars.cc \
    2021       GenPoly/Lvalue.cc \
     
    2223       GenPoly/CopyParams.cc \
    2324       GenPoly/FindFunction.cc \
     25       GenPoly/DeclMutator.cc \
    2426       GenPoly/InstantiateGeneric.cc
  • src/InitTweak/FixInit.cc

    ra2d4d1c r4dfa562  
    3636#include "FixGlobalInit.h"             // for fixGlobalInit
    3737#include "GenInit.h"                   // for genCtorDtor
     38#include "GenPoly/DeclMutator.h"       // for DeclMutator
    3839#include "GenPoly/GenPoly.h"           // for getFunctionType
     40#include "GenPoly/PolyMutator.h"       // for PolyMutator
    3941#include "InitTweak.h"                 // for getFunctionName, getCallArg
    4042#include "Parser/LinkageSpec.h"        // for C, Spec, Cforall, isBuiltin
     
    4446#include "SymTab/Indexer.h"            // for Indexer
    4547#include "SymTab/Mangler.h"            // for Mangler
     48#include "SynTree/AddStmtVisitor.h"    // for AddStmtVisitor
    4649#include "SynTree/Attribute.h"         // for Attribute
    4750#include "SynTree/Constant.h"          // for Constant
     
    5558#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution, operator<<
    5659#include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
     60#include "Tuples/Tuples.h"             // for isTtype
    5761
    5862bool ctordtorp = false; // print all debug
     
    183187                };
    184188
    185                 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors> {
     189                class FixCopyCtors final : public GenPoly::PolyMutator {
    186190                  public:
    187191                        FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
     
    190194                        static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );
    191195
    192                         Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr );
    193                         void premutate( StmtExpr * stmtExpr );
    194                         void premutate( UniqueExpr * unqExpr );
     196                        typedef GenPoly::PolyMutator Parent;
     197                        using Parent::mutate;
     198                        virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
     199                        virtual Expression * mutate( UniqueExpr * unqExpr ) override;
     200                        virtual Expression * mutate( StmtExpr * stmtExpr ) override;
    195201
    196202                        UnqCount & unqCount;
     
    237243                };
    238244
    239                 struct FixCtorExprs final : public WithDeclsToAdd, public WithIndexer {
     245                class FixCtorExprs final : public GenPoly::DeclMutator {
     246                  public:
    240247                        /// expands ConstructorExpr nodes into comma expressions, using a temporary for the first argument
    241248                        static void fix( std::list< Declaration * > & translationUnit );
    242249
    243                         Expression * postmutate( ConstructorExpr * ctorExpr );
     250                        using GenPoly::DeclMutator::mutate;
     251                        virtual Expression * mutate( ConstructorExpr * ctorExpr ) override;
    244252                };
    245253        } // namespace
     
    308316
    309317                void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
    310                         PassVisitor<FixCopyCtors> fixer( unqCount );
     318                        FixCopyCtors fixer( unqCount );
    311319                        mutateAll( translationUnit, fixer );
    312320                }
     
    318326
    319327                void FixCtorExprs::fix( std::list< Declaration * > & translationUnit ) {
    320                         PassVisitor<FixCtorExprs> fixer;
    321                         mutateAll( translationUnit, fixer );
     328                        FixCtorExprs fixer;
     329                        fixer.mutateDeclarationList( translationUnit );
    322330                }
    323331
     
    331339                                } else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) {
    332340                                        FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    333                                         assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() );
     341                                        assert( ftype );
    334342                                        if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) {
    335343                                                Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
     
    360368                }
    361369
    362                 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { return ! isConstructable( type ); }
     370                bool ResolveCopyCtors::skipCopyConstruct( Type * type ) {
     371                        return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type );
     372                }
    363373
    364374                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     
    397407                        result = result->clone();
    398408                        env->apply( result );
    399                         ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr );
     409                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    400410                        tmp->get_type()->set_const( false );
    401411
     
    411421                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
    412422                        }
    413 
    414                         // set a unique name for the temporary once it's certain the call is necessary
    415                         tmp->name = tempNamer.newName();
    416423
    417424                        // replace argument to function call with temporary
     
    443450                                result = result->clone();
    444451                                env->apply( result );
    445                                 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
     452                                ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    446453                                ret->get_type()->set_const( false );
    447454                                impCpCtorExpr->get_returnDecls().push_back( ret );
    448455                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    449456                                if ( ! dynamic_cast< ReferenceType * >( result ) ) {
    450                                         // destructing reference returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
     457                                        // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    451458                                        destructRet( ret, impCpCtorExpr );
    452459                                }
     
    465472                                result = result->clone();
    466473                                env->apply( result );
    467                                 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
     474                                ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    468475                                ret->get_type()->set_const( false );
    469476                                stmtExpr->get_returnDecls().push_front( ret );
     
    502509                        } else {
    503510                                // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
    504                                 unqExpr->set_object( ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->get_result()->clone(), nullptr ) );
     511                                unqExpr->set_object( new ObjectDecl( toString("_unq", unqExpr->get_id()), Type::StorageClasses(), LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) );
    505512                                unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
    506513                        }
     
    508515                }
    509516
    510                 Expression * FixCopyCtors::postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     517                Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    511518                        CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    512519
     520                        impCpCtorExpr = strict_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) );
    513521                        std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    514522                        std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
     
    517525                        // add all temporary declarations and their constructors
    518526                        for ( ObjectDecl * obj : tempDecls ) {
    519                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     527                                stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    520528                        } // for
    521529                        for ( ObjectDecl * obj : returnDecls ) {
    522                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     530                                stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    523531                        } // for
    524532
     
    528536                        } // for
    529537
     538                        // xxx - update to work with multiple return values
    530539                        ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
    531540                        Expression * callExpr = impCpCtorExpr->get_callExpr();
     
    560569                }
    561570
    562                 void FixCopyCtors::premutate( StmtExpr * stmtExpr ) {
     571                Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {
    563572                        // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
    564573                        // since temporaries can be shared across sub-expressions, e.g.
    565574                        //   [A, A] f();
    566575                        //   g([A] x, [A] y);
    567                         //   g(f());
     576                        //   f(g());
    568577                        // f is executed once, so the return temporary is shared across the tuple constructors for x and y.
    569                         // Explicitly mutating children instead of mutating the inner compound statment forces the temporaries to be added
    570                         // to the outer context, rather than inside of the statement expression.
    571                         visit_children = false;
    572578                        std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    573579                        for ( Statement *& stmt : stmts ) {
    574                                 stmt = stmt->acceptMutator( *visitor );
     580                                stmt = stmt->acceptMutator( *this );
    575581                        } // for
     582                        // stmtExpr = strict_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
    576583                        assert( stmtExpr->get_result() );
    577584                        Type * result = stmtExpr->get_result();
    578585                        if ( ! result->isVoid() ) {
    579586                                for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
    580                                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     587                                        stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    581588                                } // for
    582589                                // add destructors after current statement
     
    585592                                } // for
    586593                                // must have a non-empty body, otherwise it wouldn't have a result
    587                                 assert( ! stmts.empty() );
     594                                CompoundStmt * body = stmtExpr->get_statements();
     595                                assert( ! body->get_kids().empty() );
    588596                                assert( ! stmtExpr->get_returnDecls().empty() );
    589                                 stmts.push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
     597                                body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
    590598                                stmtExpr->get_returnDecls().clear();
    591599                                stmtExpr->get_dtors().clear();
     
    593601                        assert( stmtExpr->get_returnDecls().empty() );
    594602                        assert( stmtExpr->get_dtors().empty() );
    595                 }
    596 
    597                 void FixCopyCtors::premutate( UniqueExpr * unqExpr ) {
    598                         visit_children = false;
     603                        return stmtExpr;
     604                }
     605
     606                Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
    599607                        unqCount[ unqExpr->get_id() ]--;
    600608                        static std::unordered_map< int, std::list< Statement * > > dtors;
    601609                        static std::unordered_map< int, UniqueExpr * > unqMap;
     610                        static std::unordered_set< int > addDeref;
    602611                        // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
    603612                        if ( unqMap.count( unqExpr->get_id() ) ) {
     
    610619                                        stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    611620                                }
    612                                 return;
    613                         }
    614                         PassVisitor<FixCopyCtors> fixer( unqCount );
     621                                if ( addDeref.count( unqExpr->get_id() ) ) {
     622                                        // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too
     623                                        return UntypedExpr::createDeref( unqExpr );
     624                                }
     625                                return unqExpr;
     626                        }
     627                        FixCopyCtors fixer( unqCount );
    615628                        unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
    616                         stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore );
     629                        stmtsToAdd.splice( stmtsToAdd.end(), fixer.stmtsToAdd );
    617630                        unqMap[unqExpr->get_id()] = unqExpr;
    618631                        if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
    619632                                stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    620633                        } else { // remember dtors for last instance of unique expr
    621                                 dtors[ unqExpr->get_id() ] = fixer.pass.stmtsToAddAfter;
    622                         }
    623                         return;
     634                                dtors[ unqExpr->get_id() ] = fixer.stmtsToAddAfter;
     635                        }
     636                        if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
     637                                // unique expression is now a dereference, because the inner expression is an lvalue returning function call.
     638                                // Normalize the expression by dereferencing the unique expression, rather than the inner expression
     639                                // (i.e. move the dereference out a level)
     640                                assert( getFunctionName( deref ) == "*?" );
     641                                unqExpr->set_expr( getCallArg( deref, 0 ) );
     642                                getCallArg( deref, 0 ) = unqExpr;
     643                                addDeref.insert( unqExpr->get_id() );
     644                                return deref;
     645                        }
     646                        return unqExpr;
    624647                }
    625648
     
    796819                                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    797820                                        Statement * dtor = ctorInit->get_dtor();
    798                                         // don't need to call intrinsic dtor, because it does nothing, but
    799                                         // non-intrinsic dtors must be called
    800821                                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    801                                                 // set dtor location to the object's location for error messages
    802                                                 ctorInit->dtor->location = objDecl->location;
     822                                                // don't need to call intrinsic dtor, because it does nothing, but
     823                                                // non-intrinsic dtors must be called
    803824                                                reverseDeclOrder.front().push_front( objDecl );
    804825                                        } // if
     
    9911012                                        // skip non-DWT members
    9921013                                        if ( ! field ) continue;
    993                                         // skip non-constructable members
    994                                         if ( ! tryConstruct( field ) ) continue;
    9951014                                        // skip handled members
    9961015                                        if ( ! unhandled.count( field ) ) continue;
     
    11231142                }
    11241143
    1125                 Expression * FixCtorExprs::postmutate( ConstructorExpr * ctorExpr ) {
     1144                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
    11261145                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    11271146                        // xxx - is the size check necessary?
     
    11291148
    11301149                        // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary.
    1131                         ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), ctorExpr->get_result()->clone(), nullptr );
    1132                         declsToAddBefore.push_back( tmp );
     1150                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
     1151                        addDeclaration( tmp );
    11331152
    11341153                        // xxx - this can be TupleAssignExpr now. Need to properly handle this case.
     
    11391158                        delete ctorExpr;
    11401159
    1141                         // build assignment and replace constructor's first argument with new temporary
    11421160                        Expression *& firstArg = callExpr->get_args().front();
    1143                         Expression * assign = new UntypedExpr( new NameExpr( "?=?" ), { new AddressExpr( new VariableExpr( tmp ) ), new AddressExpr( firstArg ) } );
     1161
     1162                        // xxx - hack in 'fake' assignment operator until resolver can easily be called in this pass. Once the resolver can be used in PassVisitor, this hack goes away.
     1163
     1164                        // generate the type of assignment operator using the type of tmp minus any reference types
     1165                        Type * type = tmp->get_type()->stripReferences();
     1166                        FunctionType * ftype = SymTab::genAssignType( type );
     1167
     1168                        // generate fake assignment decl and call it using &tmp and &firstArg
     1169                        // since tmp is guaranteed to be a reference and we want to assign pointers
     1170                        FunctionDecl * assignDecl = new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Intrinsic, ftype, nullptr );
     1171                        ApplicationExpr * assign = new ApplicationExpr( VariableExpr::functionPointer( assignDecl ) );
     1172                        assign->get_args().push_back( new AddressExpr( new VariableExpr( tmp ) ) );
     1173                        Expression * addrArg = new AddressExpr( firstArg );
     1174                        // if firstArg has type T&&, then &firstArg has type T*&.
     1175                        // Cast away the reference to a value type so that the argument
     1176                        // matches the assignment's parameter types
     1177                        if ( dynamic_cast<ReferenceType *>( addrArg->get_result() ) ) {
     1178                                addrArg = new CastExpr( addrArg, addrArg->get_result()->stripReferences()->clone() );
     1179                        }
     1180                        assign->get_args().push_back( addrArg );
    11441181                        firstArg = new VariableExpr( tmp );
    1145 
    1146                         // resolve assignment and dispose of new env
    1147                         Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer );
    1148                         delete resolvedAssign->env;
    1149                         resolvedAssign->env = nullptr;
    1150                         delete assign;
    11511182
    11521183                        // for constructor expr:
     
    11571188                        //   T & tmp;
    11581189                        //   &tmp = &x, ?{}(tmp), tmp
    1159                         CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
     1190                        CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
    11601191                        commaExpr->set_env( env );
    11611192                        return commaExpr;
  • src/InitTweak/GenInit.cc

    ra2d4d1c r4dfa562  
    2626#include "Common/UniqueName.h"     // for UniqueName
    2727#include "Common/utility.h"        // for ValueGuard, maybeClone
     28#include "GenPoly/DeclMutator.h"   // for DeclMutator
    2829#include "GenPoly/GenPoly.h"       // for getFunctionType, isPolyType
    2930#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::const_iter...
     
    6162        };
    6263
    63         struct CtorDtor : public WithGuards, public WithShortCircuiting, public WithVisitorRef<CtorDtor>  {
     64        struct CtorDtor : public WithGuards, public WithShortCircuiting  {
    6465                /// create constructor and destructor statements for object declarations.
    6566                /// the actual call statements will be added in after the resolver has run
     
    7475                // that need to be constructed or destructed
    7576                void previsit( StructDecl *aggregateDecl );
    76                 void previsit( AggregateDecl * ) { visit_children = false; }
    77                 void previsit( NamedTypeDecl * ) { visit_children = false; }
    78                 void previsit( FunctionType * ) { visit_children = false; }
     77                void previsit( __attribute__((unused)) UnionDecl    * aggregateDecl ) { visit_children = false; }
     78                void previsit( __attribute__((unused)) EnumDecl     * aggregateDecl ) { visit_children = false; }
     79                void previsit( __attribute__((unused)) TraitDecl    * aggregateDecl ) { visit_children = false; }
     80                void previsit( __attribute__((unused)) TypeDecl     * typeDecl )      { visit_children = false; }
     81                void previsit( __attribute__((unused)) TypedefDecl  * typeDecl )      { visit_children = false; }
     82                void previsit( __attribute__((unused)) FunctionType * funcType )      { visit_children = false; }
    7983
    8084                void previsit( CompoundStmt * compoundStmt );
     
    9296        };
    9397
    94         struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
     98        class HoistArrayDimension final : public GenPoly::DeclMutator {
     99          public:
     100                typedef GenPoly::DeclMutator Parent;
     101
    95102                /// hoist dimension from array types in object declaration so that it uses a single
    96103                /// const variable of type size_t, so that side effecting array dimensions are only
     
    98105                static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
    99106
    100                 void premutate( ObjectDecl * objectDecl );
    101                 DeclarationWithType * postmutate( ObjectDecl * objectDecl );
    102                 void premutate( FunctionDecl *functionDecl );
     107          private:
     108                using Parent::mutate;
     109
     110                virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override;
     111                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
    103112                // should not traverse into any of these declarations to find objects
    104113                // that need to be constructed or destructed
    105                 void premutate( AggregateDecl * ) { visit_children = false; }
    106                 void premutate( NamedTypeDecl * ) { visit_children = false; }
    107                 void premutate( FunctionType * ) { visit_children = false; }
     114                virtual Declaration* mutate( StructDecl *aggregateDecl ) override { return aggregateDecl; }
     115                virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
     116                virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
     117                virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
     118                virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
     119                virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
     120
     121                virtual Type* mutate( FunctionType *funcType ) override { return funcType; }
    108122
    109123                void hoist( Type * type );
     
    114128
    115129        void genInit( std::list< Declaration * > & translationUnit ) {
    116                 fixReturnStatements( translationUnit );
     130                ReturnFixer::makeReturnTemp( translationUnit );
    117131                HoistArrayDimension::hoistArrayDimension( translationUnit );
    118132                CtorDtor::generateCtorDtor( translationUnit );
    119133        }
    120134
    121         void fixReturnStatements( std::list< Declaration * > & translationUnit ) {
     135        void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) {
    122136                PassVisitor<ReturnFixer> fixer;
    123137                mutateAll( translationUnit, fixer );
     
    129143                // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
    130144                // is being returned
    131                 if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
     145                if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) {
    132146                        // explicitly construct the return value using the return expression and the retVal object
    133147                        assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
     
    144158                GuardValue( funcName );
    145159
    146                 ftype = functionDecl->type;
    147                 funcName = functionDecl->name;
     160                ftype = functionDecl->get_functionType();
     161                funcName = functionDecl->get_name();
    148162        }
    149163
     
    151165        // which would be incorrect if it is a side-effecting computation.
    152166        void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
    153                 PassVisitor<HoistArrayDimension> hoister;
    154                 mutateAll( translationUnit, hoister );
    155         }
    156 
    157         void HoistArrayDimension::premutate( ObjectDecl * objectDecl ) {
    158                 GuardValue( storageClasses );
     167                HoistArrayDimension hoister;
     168                hoister.mutateDeclarationList( translationUnit );
     169        }
     170
     171        DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
    159172                storageClasses = objectDecl->get_storageClasses();
    160         }
    161 
    162         DeclarationWithType * HoistArrayDimension::postmutate( ObjectDecl * objectDecl ) {
     173                DeclarationWithType * temp = Parent::mutate( objectDecl );
    163174                hoist( objectDecl->get_type() );
    164                 return objectDecl;
     175                return temp;
    165176        }
    166177
     
    183194
    184195                        arrayType->set_dimension( new VariableExpr( arrayDimension ) );
    185                         declsToAddBefore.push_back( arrayDimension );
     196                        addDeclaration( arrayDimension );
    186197
    187198                        hoist( arrayType->get_base() );
     
    190201        }
    191202
    192         void HoistArrayDimension::premutate( FunctionDecl * ) {
    193                 GuardValue( inFunction );
     203        DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
     204                ValueGuard< bool > oldInFunc( inFunction );
     205                inFunction = true;
     206                DeclarationWithType * decl = Parent::mutate( functionDecl );
     207                return decl;
    194208        }
    195209
     
    200214
    201215        bool CtorDtor::isManaged( Type * type ) const {
    202                 // references are never constructed
     216                // at least for now, references are never constructed
    203217                if ( dynamic_cast< ReferenceType * >( type ) ) return false;
    204218                // need to clear and reset qualifiers when determining if a type is managed
     
    207221                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) {
    208222                        // tuple is also managed if any of its components are managed
    209                         if ( std::any_of( tupleType->types.begin(), tupleType->types.end(), [&](Type * type) { return isManaged( type ); }) ) {
     223                        if ( std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) {
    210224                                return true;
    211225                        }
     
    291305
    292306        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
    293                 visit_children = false;  // do not try and construct parameters or forall parameters
    294307                GuardValue( inFunction );
    295308                inFunction = true;
     
    305318                }
    306319
    307                 maybeAccept( functionDecl->get_statements(), *visitor );
     320                PassVisitor<CtorDtor> newCtorDtor;
     321                newCtorDtor.pass = *this;
     322                maybeAccept( functionDecl->get_statements(), newCtorDtor );
     323                visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
    308324        }
    309325
     
    324340        }
    325341
    326         void CtorDtor::previsit( CompoundStmt * ) {
     342        void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) {
    327343                GuardScope( managedTypes );
    328344        }
  • src/InitTweak/GenInit.h

    ra2d4d1c r4dfa562  
    2525        void genInit( std::list< Declaration * > & translationUnit );
    2626
    27         /// Converts return statements into copy constructor calls on the hidden return variable
    28         void fixReturnStatements( std::list< Declaration * > & translationUnit );
    29 
    30         /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
    31         ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
     27  /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
     28  ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
    3229
    3330        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
  • src/InitTweak/InitTweak.cc

    ra2d4d1c r4dfa562  
     1#include <stddef.h>                // for NULL
    12#include <algorithm>               // for find, all_of
    23#include <cassert>                 // for assertf, assert, strict_dynamic_cast
     
    2223#include "SynTree/Type.h"          // for FunctionType, ArrayType, PointerType
    2324#include "SynTree/Visitor.h"       // for Visitor, maybeAccept
    24 #include "Tuples/Tuples.h"         // for Tuples::isTtype
    2525
    2626class UntypedValofExpr;
     
    184184                        callExpr->get_args().splice( callExpr->get_args().end(), args );
    185185
    186                         *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr );
     186                        *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL );
    187187
    188188                        UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) );
     
    250250        // To accomplish this, generate switch statement, consuming all of expander's elements
    251251        Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
    252                 if ( ! init ) return nullptr;
     252                if ( ! init ) return NULL;
    253253                CompoundStmt * block = new CompoundStmt( noLabels );
    254254                build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
    255255                if ( block->get_kids().empty() ) {
    256256                        delete block;
    257                         return nullptr;
     257                        return NULL;
    258258                } else {
    259                         init = nullptr; // init was consumed in creating the list init
     259                        init = NULL; // init was consumed in creating the list init
    260260                        return block;
    261261                }
    262262        }
    263263
    264         Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
    265                 return nullptr;
     264        Statement * ExprImpl::buildListInit( __attribute((unused)) UntypedExpr * dst, __attribute((unused)) std::list< Expression * > & indices ) {
     265                return NULL;
    266266        }
    267267
     
    270270        }
    271271
    272         bool tryConstruct( DeclarationWithType * dwt ) {
    273                 ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt );
    274                 if ( ! objDecl ) return false;
     272        bool tryConstruct( ObjectDecl * objDecl ) {
    275273                return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    276                         (objDecl->get_init() == nullptr ||
    277                                 ( objDecl->get_init() != nullptr && objDecl->get_init()->get_maybeConstructed() ))
    278                         && ! objDecl->get_storageClasses().is_extern
    279                         && isConstructable( objDecl->type );
    280         }
    281 
    282         bool isConstructable( Type * type ) {
    283                 return ! dynamic_cast< VarArgsType * >( type ) && ! dynamic_cast< ReferenceType * >( type ) && ! dynamic_cast< FunctionType * >( type ) && ! Tuples::isTtype( type );
     274                        (objDecl->get_init() == NULL ||
     275                                ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ))
     276                        && ! objDecl->get_storageClasses().is_extern;
    284277        }
    285278
     
    321314                collectCtorDtorCalls( stmt, matches );
    322315                assert( matches.size() <= 1 );
    323                 return matches.size() == 1 ? matches.front() : nullptr;
     316                return matches.size() == 1 ? matches.front() : NULL;
    324317        }
    325318
     
    366359        ApplicationExpr * isIntrinsicCallExpr( Expression * expr ) {
    367360                ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr );
    368                 if ( ! appExpr ) return nullptr;
     361                if ( ! appExpr ) return NULL;
    369362                DeclarationWithType * function = getCalledFunction( appExpr->get_function() );
    370363                assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() );
    371364                // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
    372365                // will call all member dtors, and some members may have a user defined dtor.
    373                 return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : nullptr;
     366                return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : NULL;
    374367        }
    375368
     
    489482                        return refType->get_base();
    490483                } else {
    491                         return nullptr;
     484                        return NULL;
    492485                }
    493486        }
     
    495488        Type * isPointerType( Type * type ) {
    496489                if ( getPointerBase( type ) ) return type;
    497                 else return nullptr;
     490                else return NULL;
    498491        }
    499492
  • src/InitTweak/InitTweak.h

    ra2d4d1c r4dfa562  
    3333        std::list< Expression * > makeInitList( Initializer * init );
    3434
    35         /// True if the resolver should try to construct dwt
    36         bool tryConstruct( DeclarationWithType * dwt );
    37 
    38         /// True if the type can have a user-defined constructor
    39         bool isConstructable( Type * t );
     35        /// True if the resolver should try to construct objDecl
     36        bool tryConstruct( ObjectDecl * objDecl );
    4037
    4138        /// True if the Initializer contains designations
  • src/Makefile.in

    ra2d4d1c r4dfa562  
    172172        GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
    173173        GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
     174        GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT) \
    174175        GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT) \
    175176        GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \
     
    177178        GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \
    178179        GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \
     180        GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
    179181        GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \
    180182        InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT) \
     
    251253        SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) \
    252254        SynTree/driver_cfa_cpp-Mutator.$(OBJEXT) \
     255        SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT) \
    253256        SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
    254257        SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
     
    494497        ControlStruct/ForExprMutator.cc \
    495498        ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
    496         GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \
    497         GenPoly/Specialize.cc GenPoly/CopyParams.cc \
    498         GenPoly/FindFunction.cc GenPoly/InstantiateGeneric.cc \
     499        GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
     500        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
     501        GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
     502        GenPoly/DeclMutator.cc GenPoly/InstantiateGeneric.cc \
    499503        InitTweak/GenInit.cc InitTweak/FixInit.cc \
    500504        InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \
     
    531535        SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
    532536        SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \
    533         SynTree/TypeSubstitution.cc SynTree/Attribute.cc \
    534         SynTree/VarExprReplacer.cc Tuples/TupleAssignment.cc \
    535         Tuples/TupleExpansion.cc Tuples/Explode.cc \
    536         Virtual/ExpandCasts.cc
     537        SynTree/AddStmtVisitor.cc SynTree/TypeSubstitution.cc \
     538        SynTree/Attribute.cc SynTree/VarExprReplacer.cc \
     539        Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
     540        Tuples/Explode.cc Virtual/ExpandCasts.cc
    537541MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
    538542        ${cfa_cpplib_PROGRAMS}}
     
    713717GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \
    714718        GenPoly/$(DEPDIR)/$(am__dirstamp)
     719GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
     720        GenPoly/$(DEPDIR)/$(am__dirstamp)
    715721GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \
    716722        GenPoly/$(DEPDIR)/$(am__dirstamp)
     
    723729GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT):  \
    724730        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
     731GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
     732        GenPoly/$(DEPDIR)/$(am__dirstamp)
    725733GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT):  \
    726734        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
     
    921929SynTree/driver_cfa_cpp-Mutator.$(OBJEXT): SynTree/$(am__dirstamp) \
    922930        SynTree/$(DEPDIR)/$(am__dirstamp)
     931SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT):  \
     932        SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    923933SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT):  \
    924934        SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
     
    9981008@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@
    9991009@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po@am__quote@
     1010@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po@am__quote@
    10001011@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@
    10011012@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@
    10021013@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@
    10031014@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@
     1015@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po@am__quote@
    10041016@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    10051017@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
     
    10441056@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po@am__quote@
    10451057@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po@am__quote@
     1058@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po@am__quote@
    10461059@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@
    10471060@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po@am__quote@
     
    14371450@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-GenPoly.obj `if test -f 'GenPoly/GenPoly.cc'; then $(CYGPATH_W) 'GenPoly/GenPoly.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/GenPoly.cc'; fi`
    14381451
     1452GenPoly/driver_cfa_cpp-PolyMutator.o: GenPoly/PolyMutator.cc
     1453@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-PolyMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo -c -o GenPoly/driver_cfa_cpp-PolyMutator.o `test -f 'GenPoly/PolyMutator.cc' || echo '$(srcdir)/'`GenPoly/PolyMutator.cc
     1454@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po
     1455@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/PolyMutator.cc' object='GenPoly/driver_cfa_cpp-PolyMutator.o' libtool=no @AMDEPBACKSLASH@
     1456@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1457@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-PolyMutator.o `test -f 'GenPoly/PolyMutator.cc' || echo '$(srcdir)/'`GenPoly/PolyMutator.cc
     1458
     1459GenPoly/driver_cfa_cpp-PolyMutator.obj: GenPoly/PolyMutator.cc
     1460@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-PolyMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo -c -o GenPoly/driver_cfa_cpp-PolyMutator.obj `if test -f 'GenPoly/PolyMutator.cc'; then $(CYGPATH_W) 'GenPoly/PolyMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/PolyMutator.cc'; fi`
     1461@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po
     1462@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/PolyMutator.cc' object='GenPoly/driver_cfa_cpp-PolyMutator.obj' libtool=no @AMDEPBACKSLASH@
     1463@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1464@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-PolyMutator.obj `if test -f 'GenPoly/PolyMutator.cc'; then $(CYGPATH_W) 'GenPoly/PolyMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/PolyMutator.cc'; fi`
     1465
    14391466GenPoly/driver_cfa_cpp-ScrubTyVars.o: GenPoly/ScrubTyVars.cc
    14401467@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-ScrubTyVars.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.o `test -f 'GenPoly/ScrubTyVars.cc' || echo '$(srcdir)/'`GenPoly/ScrubTyVars.cc
     
    15071534@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi`
    15081535
     1536GenPoly/driver_cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc
     1537@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
     1538@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po
     1539@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/DeclMutator.cc' object='GenPoly/driver_cfa_cpp-DeclMutator.o' libtool=no @AMDEPBACKSLASH@
     1540@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1541@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
     1542
     1543GenPoly/driver_cfa_cpp-DeclMutator.obj: GenPoly/DeclMutator.cc
     1544@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
     1545@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po
     1546@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/DeclMutator.cc' object='GenPoly/driver_cfa_cpp-DeclMutator.obj' libtool=no @AMDEPBACKSLASH@
     1547@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1548@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
     1549
    15091550GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc
    15101551@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
     
    25422583@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    25432584@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Mutator.obj `if test -f 'SynTree/Mutator.cc'; then $(CYGPATH_W) 'SynTree/Mutator.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Mutator.cc'; fi`
     2585
     2586SynTree/driver_cfa_cpp-AddStmtVisitor.o: SynTree/AddStmtVisitor.cc
     2587@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddStmtVisitor.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.o `test -f 'SynTree/AddStmtVisitor.cc' || echo '$(srcdir)/'`SynTree/AddStmtVisitor.cc
     2588@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po
     2589@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AddStmtVisitor.cc' object='SynTree/driver_cfa_cpp-AddStmtVisitor.o' libtool=no @AMDEPBACKSLASH@
     2590@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     2591@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.o `test -f 'SynTree/AddStmtVisitor.cc' || echo '$(srcdir)/'`SynTree/AddStmtVisitor.cc
     2592
     2593SynTree/driver_cfa_cpp-AddStmtVisitor.obj: SynTree/AddStmtVisitor.cc
     2594@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddStmtVisitor.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.obj `if test -f 'SynTree/AddStmtVisitor.cc'; then $(CYGPATH_W) 'SynTree/AddStmtVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddStmtVisitor.cc'; fi`
     2595@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po
     2596@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AddStmtVisitor.cc' object='SynTree/driver_cfa_cpp-AddStmtVisitor.obj' libtool=no @AMDEPBACKSLASH@
     2597@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     2598@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.obj `if test -f 'SynTree/AddStmtVisitor.cc'; then $(CYGPATH_W) 'SynTree/AddStmtVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddStmtVisitor.cc'; fi`
    25442599
    25452600SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc
  • src/ResolvExpr/Resolver.cc

    ra2d4d1c r4dfa562  
    9595                PassVisitor<Resolver> resolver;
    9696                acceptAll( translationUnit, resolver );
    97         }
    98 
    99         void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
    100                 PassVisitor<Resolver> resolver( indexer );
    101                 maybeAccept( decl, resolver );
    10297        }
    10398
  • src/ResolvExpr/Resolver.h

    ra2d4d1c r4dfa562  
    2929        /// Checks types and binds syntactic constructs to typed representations
    3030        void resolve( std::list< Declaration * > translationUnit );
    31         void resolveDecl( Declaration *, const SymTab::Indexer &indexer );
    32         Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
    33         Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
     31        Expression * resolveInVoidContext( Expression *expr   , const SymTab::Indexer &indexer );
     32        Expression * findVoidExpression  ( Expression *untyped, const SymTab::Indexer &indexer );
    3433        Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer );
    3534        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
  • src/ResolvExpr/TypeEnvironment.cc

    ra2d4d1c r4dfa562  
    123123                for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    124124                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    125 ///       std::cerr << "adding " << *theVar;
     125///       std::cout << "adding " << *theVar;
    126126                                if ( theClass->type ) {
    127 ///         std::cerr << " bound to ";
    128 ///         theClass->type->print( std::cerr );
    129 ///         std::cerr << std::endl;
     127///         std::cout << " bound to ";
     128///         theClass->type->print( std::cout );
     129///         std::cout << std::endl;
    130130                                        sub.add( *theVar, theClass->type );
    131131                                } else if ( theVar != theClass->vars.begin() ) {
    132132                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    133 ///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
     133///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
    134134                                        sub.add( *theVar, newTypeInst );
    135135                                        delete newTypeInst;
  • src/SymTab/Autogen.cc

    ra2d4d1c r4dfa562  
    1616#include "Autogen.h"
    1717
     18#include <cstddef>                 // for NULL
    1819#include <algorithm>               // for count_if
    1920#include <cassert>                 // for strict_dynamic_cast, assert, assertf
     
    2627#include "AddVisit.h"              // for addVisit
    2728#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
    28 #include "Common/PassVisitor.h"    // for PassVisitor
    2929#include "Common/ScopedMap.h"      // for ScopedMap<>::const_iterator, Scope...
    3030#include "Common/utility.h"        // for cloneAll, operator+
     31#include "GenPoly/DeclMutator.h"   // for DeclMutator
    3132#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
    32 #include "InitTweak/GenInit.h"     // for fixReturnStatements
    33 #include "ResolvExpr/Resolver.h"   // for resolveDecl
    3433#include "SymTab/Mangler.h"        // for Mangler
    3534#include "SynTree/Attribute.h"     // For Attribute
     
    5453        };
    5554
    56         struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting {
     55        class AutogenerateRoutines final : public Visitor {
     56            template< typename Visitor >
     57            friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
     58            template< typename Visitor >
     59            friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor );
     60          public:
     61                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     62
     63                typedef Visitor Parent;
     64                using Parent::visit;
     65
    5766                AutogenerateRoutines();
    5867
    59                 void previsit( EnumDecl * enumDecl );
    60                 void previsit( StructDecl * structDecl );
    61                 void previsit( UnionDecl * structDecl );
    62                 void previsit( TypeDecl * typeDecl );
    63                 void previsit( TraitDecl * traitDecl );
    64                 void previsit( FunctionDecl * functionDecl );
    65 
    66                 void previsit( FunctionType * ftype );
    67                 void previsit( PointerType * ptype );
    68 
    69                 void previsit( CompoundStmt * compoundStmt );
     68                virtual void visit( EnumDecl *enumDecl );
     69                virtual void visit( StructDecl *structDecl );
     70                virtual void visit( UnionDecl *structDecl );
     71                virtual void visit( TypeDecl *typeDecl );
     72                virtual void visit( TraitDecl *ctxDecl );
     73                virtual void visit( FunctionDecl *functionDecl );
     74
     75                virtual void visit( FunctionType *ftype );
     76                virtual void visit( PointerType *ftype );
     77
     78                virtual void visit( CompoundStmt *compoundStmt );
     79                virtual void visit( SwitchStmt *switchStmt );
    7080
    7181          private:
    72                 GenPoly::ScopedSet< std::string > structsDone;
     82                template< typename StmtClass > void visitStatement( StmtClass *stmt );
     83
     84                std::list< Declaration * > declsToAdd, declsToAddAfter;
     85                std::set< std::string > structsDone;
    7386                unsigned int functionNesting = 0;     // current level of nested functions
    7487                /// Note: the following maps could be ScopedSets, but it should be easier to work
     
    8093
    8194        /// generates routines for tuple types.
    82         struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting {
    83                 void previsit( FunctionDecl *functionDecl );
    84 
    85                 void postvisit( TupleType *tupleType );
    86 
    87                 void previsit( CompoundStmt *compoundStmt );
     95        /// Doesn't really need to be a mutator, but it's easier to reuse DeclMutator than it is to use AddVisit
     96        /// or anything we currently have that supports adding new declarations for visitors
     97        class AutogenTupleRoutines : public GenPoly::DeclMutator {
     98          public:
     99                typedef GenPoly::DeclMutator Parent;
     100                using Parent::mutate;
     101
     102                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
     103
     104                virtual Type * mutate( TupleType *tupleType );
     105
     106                virtual CompoundStmt * mutate( CompoundStmt *compoundStmt );
    88107
    89108          private:
     
    93112
    94113        void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    95                 PassVisitor<AutogenerateRoutines> generator;
    96                 acceptAll( translationUnit, generator );
     114                AutogenerateRoutines generator;
     115                acceptAndAdd( translationUnit, generator );
    97116
    98117                // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc.
    99118                // AutogenTupleRoutines tupleGenerator;
    100                 // acceptAll( translationUnit, tupleGenerator );
     119                // tupleGenerator.mutateDeclarationList( translationUnit );
    101120        }
    102121
    103122        bool isUnnamedBitfield( ObjectDecl * obj ) {
    104                 return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
     123                return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
    105124        }
    106125
     
    109128                FunctionDecl * decl = functionDecl->clone();
    110129                delete decl->get_statements();
    111                 decl->set_statements( nullptr );
     130                decl->set_statements( NULL );
    112131                declsToAdd.push_back( decl );
    113132                decl->fixUniqueId();
     
    320339                                assert( ! func->get_functionType()->get_parameters().empty() );
    321340                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    322                                 ObjectDecl * srcParam = nullptr;
     341                                ObjectDecl * srcParam = NULL;
    323342                                if ( func->get_functionType()->get_parameters().size() == 2 ) {
    324343                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     
    327346                                assert( dstParam );
    328347
    329                                 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
     348                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
    330349                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    331350                        } // if
     
    366385                                } else {
    367386                                        // no matching parameter, initialize field with default ctor
    368                                         makeStructMemberOp( dstParam, nullptr, field, func );
     387                                        makeStructMemberOp( dstParam, NULL, field, func );
    369388                                }
    370389                        }
     
    382401        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    383402                // Builtins do not use autogeneration.
    384                 if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
     403                if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
     404                         aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
    385405                        return;
    386406                }
    387407
    388408                // Make function polymorphic in same parameters as generic struct, if applicable
    389                 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
     409                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    390410
    391411                // generate each of the functions based on the supplied FuncData objects
     
    552572                // the order here determines the order that these functions are generated.
    553573                // assignment should come last since it uses copy constructor in return.
    554                 data.emplace_back( "?{}", genDefaultType, constructable );
    555                 data.emplace_back( "?{}", genCopyType, copyable );
    556                 data.emplace_back( "^?{}", genDefaultType, destructable );
    557                 data.emplace_back( "?=?", genAssignType, assignable );
    558         }
    559 
    560         void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) {
    561                 visit_children = false;
     574                data.push_back( FuncData( "?{}", genDefaultType, constructable ) );
     575                data.push_back( FuncData( "?{}", genCopyType, copyable ) );
     576                data.push_back( FuncData( "^?{}", genDefaultType, destructable ) );
     577                data.push_back( FuncData( "?=?", genAssignType, assignable ) );
     578        }
     579
     580        void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
    562581                if ( ! enumDecl->get_members().empty() ) {
    563582                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    567586        }
    568587
    569         void AutogenerateRoutines::previsit( StructDecl * structDecl ) {
    570                 visit_children = false;
    571                 if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) {
    572                         StructInstType structInst( Type::Qualifiers(), structDecl->name );
    573                         for ( TypeDecl * typeDecl : structDecl->parameters ) {
     588        void AutogenerateRoutines::visit( StructDecl *structDecl ) {
     589                if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
     590                        StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
     591                        for ( TypeDecl * typeDecl : structDecl->get_parameters() ) {
    574592                                // need to visit assertions so that they are added to the appropriate maps
    575                                 acceptAll( typeDecl->assertions, *visitor );
    576                                 structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
     593                                acceptAll( typeDecl->get_assertions(), *this );
     594                                structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
    577595                        }
    578596                        structInst.set_baseStruct( structDecl );
    579597                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
    580                         structsDone.insert( structDecl->name );
     598                        structsDone.insert( structDecl->get_name() );
    581599                } // if
    582600        }
    583601
    584         void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
    585                 visit_children = false;
     602        void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
    586603                if ( ! unionDecl->get_members().empty() ) {
    587604                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
     
    602619
    603620        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    604         void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
    605                 visit_children = false;
     621        void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    606622                if ( ! typeDecl->base ) return;
    607623
     
    648664        }
    649665
    650         void AutogenerateRoutines::previsit( FunctionType *) {
     666        void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
     667                for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
     668                        statements.insert( i, new DeclStmt( noLabels, *decl ) );
     669                } // for
     670                declsToAdd.clear();
     671        }
     672
     673        void AutogenerateRoutines::visit( FunctionType *) {
    651674                // ensure that we don't add assignment ops for types defined as part of the function
    652                 visit_children = false;
    653         }
    654 
    655         void AutogenerateRoutines::previsit( PointerType *) {
     675        }
     676
     677        void AutogenerateRoutines::visit( PointerType *) {
    656678                // ensure that we don't add assignment ops for types defined as part of the pointer
    657                 visit_children = false;
    658         }
    659 
    660         void AutogenerateRoutines::previsit( TraitDecl * ) {
     679        }
     680
     681        void AutogenerateRoutines::visit( TraitDecl *) {
    661682                // ensure that we don't add assignment ops for types defined as part of the trait
    662                 visit_children = false;
    663         }
    664 
    665         void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) {
    666                 visit_children = false;
     683        }
     684
     685        template< typename StmtClass >
     686        inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
     687                std::set< std::string > oldStructs = structsDone;
     688                addVisit( stmt, *this );
     689                structsDone = oldStructs;
     690        }
     691
     692        void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
    667693                // record the existence of this function as appropriate
    668694                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     
    671697                insert( functionDecl, destructable, InitTweak::isDestructor );
    672698
    673                 maybeAccept( functionDecl->type, *visitor );
     699                maybeAccept( functionDecl->get_functionType(), *this );
    674700                functionNesting += 1;
    675                 maybeAccept( functionDecl->statements, *visitor );
     701                maybeAccept( functionDecl->get_statements(), *this );
    676702                functionNesting -= 1;
    677703        }
    678704
    679         void AutogenerateRoutines::previsit( CompoundStmt * ) {
    680                 GuardScope( constructable );
    681                 GuardScope( assignable );
    682                 GuardScope( copyable );
    683                 GuardScope( destructable );
    684                 GuardScope( structsDone );
     705        void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
     706                constructable.beginScope();
     707                assignable.beginScope();
     708                copyable.beginScope();
     709                destructable.beginScope();
     710                visitStatement( compoundStmt );
     711                constructable.endScope();
     712                assignable.endScope();
     713                copyable.endScope();
     714                destructable.endScope();
     715        }
     716
     717        void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
     718                visitStatement( switchStmt );
    685719        }
    686720
     
    700734        }
    701735
    702         void AutogenTupleRoutines::postvisit( TupleType * tupleType ) {
     736        Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) {
     737                tupleType = strict_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) );
    703738                std::string mangleName = SymTab::Mangler::mangleType( tupleType );
    704                 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return;
     739                if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType;
    705740                seenTuples.insert( mangleName );
    706741
     
    750785                makeTupleFunctionBody( dtorDecl );
    751786
    752                 declsToAddBefore.push_back( ctorDecl );
    753                 declsToAddBefore.push_back( copyCtorDecl );
    754                 declsToAddBefore.push_back( dtorDecl );
    755                 declsToAddBefore.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
    756         }
    757 
    758         void AutogenTupleRoutines::previsit( FunctionDecl *functionDecl ) {
    759                 visit_children = false;
    760                 maybeAccept( functionDecl->type, *visitor );
     787                addDeclaration( ctorDecl );
     788                addDeclaration( copyCtorDecl );
     789                addDeclaration( dtorDecl );
     790                addDeclaration( assignDecl ); // assignment should come last since it uses copy constructor in return
     791
     792                return tupleType;
     793        }
     794
     795        DeclarationWithType * AutogenTupleRoutines::mutate( FunctionDecl *functionDecl ) {
     796                functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    761797                functionNesting += 1;
    762                 maybeAccept( functionDecl->statements, *visitor );
     798                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    763799                functionNesting -= 1;
    764         }
    765 
    766         void AutogenTupleRoutines::previsit( CompoundStmt * ) {
    767                 GuardScope( seenTuples );
     800                return functionDecl;
     801        }
     802
     803        CompoundStmt * AutogenTupleRoutines::mutate( CompoundStmt *compoundStmt ) {
     804                seenTuples.beginScope();
     805                compoundStmt = strict_dynamic_cast< CompoundStmt * >( Parent::mutate( compoundStmt ) );
     806                seenTuples.endScope();
     807                return compoundStmt;
    768808        }
    769809} // SymTab
  • src/SymTab/FixFunction.cc

    ra2d4d1c r4dfa562  
    2727
    2828        DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
    29                 // can't delete function type because it may contain assertions, so transfer ownership to new object
    3029                ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes() );
    3130                functionDecl->get_attributes().clear();
    32                 functionDecl->type = nullptr;
     31                // can't delete function type because it may contain assertions, but can't transfer ownership without a clone since set_type checks for nullptr
     32                functionDecl->set_type( functionDecl->get_type()->clone() );
    3333                delete functionDecl;
    3434                return pointer;
  • src/SymTab/Indexer.cc

    ra2d4d1c r4dfa562  
    4040
    4141namespace SymTab {
     42        struct NewScope {
     43                NewScope( SymTab::Indexer & indexer ) : indexer( indexer ) { indexer.enterScope(); }
     44                ~NewScope() { indexer.leaveScope(); }
     45                SymTab::Indexer & indexer;
     46        };
     47
     48        template< typename TreeType, typename VisitorType >
     49        inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) {
     50                visitor.enterScope();
     51                maybeAccept( tree, visitor );
     52                visitor.leaveScope();
     53        }
     54
    4255        typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
    4356        typedef std::unordered_map< std::string, MangleTable > IdTable;
     
    185198        }
    186199
    187         Indexer::Indexer() : tables( 0 ), scope( 0 ) {}
    188 
    189         Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {}
    190 
    191         Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) {
     200        Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
     201
     202        Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
     203
     204        Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
    192205                that.tables = 0;
    193206        }
  • src/SymTab/Indexer.h

    ra2d4d1c r4dfa562  
    2626        class Indexer {
    2727          public:
    28                 explicit Indexer();
     28                explicit Indexer( bool useDebug = false );
    2929
    3030                Indexer( const Indexer &that );
     
    7676                void addTrait( TraitDecl *decl );
    7777
    78                 bool doDebug = false; ///< Display debugging trace?
    7978          private:
    8079                struct Impl;
     
    8281                Impl *tables;         ///< Copy-on-write instance of table data structure
    8382                unsigned long scope;  ///< Scope index of this pointer
     83                bool doDebug;         ///< Display debugging trace?
    8484
    8585                /// Takes a new ref to a table (returns null if null)
  • src/SymTab/Mangler.cc

    ra2d4d1c r4dfa562  
    3131
    3232namespace SymTab {
    33         std::string Mangler::mangleType( Type * ty ) {
     33        std::string Mangler::mangleType( Type *ty ) {
    3434                Mangler mangler( false, true );
    3535                maybeAccept( ty, mangler );
     
    4848        }
    4949
    50         void Mangler::mangleDecl( DeclarationWithType * declaration ) {
     50        void Mangler::mangleDecl( DeclarationWithType *declaration ) {
    5151                bool wasTopLevel = isTopLevel;
    5252                if ( isTopLevel ) {
     
    7979        }
    8080
    81         void Mangler::visit( ObjectDecl * declaration ) {
     81        void Mangler::visit( ObjectDecl *declaration ) {
    8282                mangleDecl( declaration );
    8383        }
    8484
    85         void Mangler::visit( FunctionDecl * declaration ) {
     85        void Mangler::visit( FunctionDecl *declaration ) {
    8686                mangleDecl( declaration );
    8787        }
    8888
    89         void Mangler::visit( VoidType * voidType ) {
     89        void Mangler::visit( VoidType *voidType ) {
    9090                printQualifiers( voidType );
    9191                mangleName << "v";
    9292        }
    9393
    94         void Mangler::visit( BasicType * basicType ) {
     94        void Mangler::visit( BasicType *basicType ) {
    9595                static const char *btLetter[] = {
    9696                        "b",    // Bool
     
    121121        }
    122122
    123         void Mangler::visit( PointerType * pointerType ) {
     123        void Mangler::visit( PointerType *pointerType ) {
    124124                printQualifiers( pointerType );
    125125                mangleName << "P";
     
    127127        }
    128128
    129         void Mangler::visit( ArrayType * arrayType ) {
     129        void Mangler::visit( ArrayType *arrayType ) {
    130130                // TODO: encode dimension
    131131                printQualifiers( arrayType );
     
    134134        }
    135135
    136         void Mangler::visit( ReferenceType * refType ) {
     136        void Mangler::visit( ReferenceType *refType ) {
    137137                printQualifiers( refType );
    138138                mangleName << "R";
     
    149149        }
    150150
    151         void Mangler::visit( FunctionType * functionType ) {
     151        void Mangler::visit( FunctionType *functionType ) {
    152152                printQualifiers( functionType );
    153153                mangleName << "F";
     
    160160        }
    161161
    162         void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
     162        void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
    163163                printQualifiers( refType );
    164164
     
    166166        }
    167167
    168         void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) {
     168        void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) {
    169169                printQualifiers( refType );
    170170
     
    189189        }
    190190
    191         void Mangler::visit( StructInstType * aggregateUseType ) {
     191        void Mangler::visit( StructInstType *aggregateUseType ) {
    192192                if ( typeMode ) mangleGenericRef( aggregateUseType, "s" );
    193193                else mangleRef( aggregateUseType, "s" );
    194194        }
    195195
    196         void Mangler::visit( UnionInstType * aggregateUseType ) {
     196        void Mangler::visit( UnionInstType *aggregateUseType ) {
    197197                if ( typeMode ) mangleGenericRef( aggregateUseType, "u" );
    198198                else mangleRef( aggregateUseType, "u" );
    199199        }
    200200
    201         void Mangler::visit( EnumInstType * aggregateUseType ) {
     201        void Mangler::visit( EnumInstType *aggregateUseType ) {
    202202                mangleRef( aggregateUseType, "e" );
    203203        }
    204204
    205         void Mangler::visit( TypeInstType * typeInst ) {
     205        void Mangler::visit( TypeInstType *typeInst ) {
    206206                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    207207                if ( varNum == varNums.end() ) {
     
    231231        }
    232232
    233         void Mangler::visit( TupleType * tupleType ) {
     233        void Mangler::visit( TupleType *tupleType ) {
    234234                printQualifiers( tupleType );
    235235                mangleName << "T";
    236                 acceptAll( tupleType->types, *this );
     236                acceptAll( tupleType->get_types(), *this );
    237237                mangleName << "_";
    238238        }
    239239
    240         void Mangler::visit( VarArgsType * varArgsType ) {
     240        void Mangler::visit( VarArgsType *varArgsType ) {
    241241                printQualifiers( varArgsType );
    242242                mangleName << "VARGS";
    243243        }
    244244
    245         void Mangler::visit( ZeroType * ) {
     245        void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) {
    246246                mangleName << "Z";
    247247        }
    248248
    249         void Mangler::visit( OneType * ) {
     249        void Mangler::visit( __attribute__((unused)) OneType *oneType ) {
    250250                mangleName << "O";
    251251        }
    252252
    253         void Mangler::visit( TypeDecl * decl ) {
     253        void Mangler::visit( TypeDecl *decl ) {
    254254                static const char *typePrefix[] = { "BT", "BD", "BF" };
    255                 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
     255                mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
    256256        }
    257257
     
    262262        }
    263263
    264         void Mangler::printQualifiers( Type * type ) {
     264        void Mangler::printQualifiers( Type *type ) {
    265265                // skip if not including qualifiers
    266266                if ( typeMode ) return;
     
    270270                        int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
    271271                        mangleName << "A";
    272                         for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
     272                        for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    273273                                switch ( (*i)->get_kind() ) {
    274274                                  case TypeDecl::Any:
     
    287287                                        assert( false );
    288288                                } // switch
    289                                 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
    290                                 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
     289                                varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
     290                                for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    291291                                        Mangler sub_mangler( mangleOverridable, typeMode );
    292292                                        sub_mangler.nextVarNum = nextVarNum;
     
    315315//              } // if
    316316                if ( type->get_lvalue() ) {
    317                         // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    318317                        mangleName << "L";
    319                 }
     318                } // if
    320319                if ( type->get_atomic() ) {
    321320                        mangleName << "A";
  • src/SymTab/Validate.cc

    ra2d4d1c r4dfa562  
    5656#include "FixFunction.h"               // for FixFunction
    5757#include "Indexer.h"                   // for Indexer
    58 #include "InitTweak/GenInit.h"         // for fixReturnStatements
    5958#include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
    6059#include "Parser/LinkageSpec.h"        // for C
     
    151150        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    152151        struct ForallPointerDecay final {
    153                 void previsit( ObjectDecl * object );
    154                 void previsit( FunctionDecl * func );
     152                void previsit( ObjectDecl *object );
     153                void previsit( FunctionDecl *func );
    155154        };
    156155
     
    580579
    581580        /// Fix up assertions - flattens assertion lists, removing all trait instances
    582         void forallFixer( std::list< TypeDecl * > & forall, BaseSyntaxNode * node ) {
    583                 for ( TypeDecl * type : forall ) {
     581        void forallFixer( Type * func ) {
     582                for ( TypeDecl * type : func->get_forall() ) {
    584583                        std::list< DeclarationWithType * > asserts;
    585584                        asserts.splice( asserts.end(), type->assertions );
     
    600599                                assertion = assertion->acceptMutator( fixer );
    601600                                if ( fixer.get_isVoid() ) {
    602                                         throw SemanticError( "invalid type void in assertion of function ", node );
     601                                        throw SemanticError( "invalid type void in assertion of function ", func );
    603602                                } // if
    604603                        } // for
     
    608607
    609608        void ForallPointerDecay::previsit( ObjectDecl *object ) {
    610                 forallFixer( object->type->forall, object );
    611                 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->type ) ) {
    612                         forallFixer( pointer->base->forall, object );
     609                forallFixer( object->get_type() );
     610                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     611                        forallFixer( pointer->get_base() );
    613612                } // if
    614613                object->fixUniqueId();
     
    616615
    617616        void ForallPointerDecay::previsit( FunctionDecl *func ) {
    618                 forallFixer( func->type->forall, func );
     617                forallFixer( func->get_type() );
    619618                func->fixUniqueId();
    620619        }
  • src/SynTree/Visitor.h

    ra2d4d1c r4dfa562  
    2525  public:
    2626        // visit: Default implementation of all functions visits the children
    27         // of the given syntax node, but performs no other action.
     27    // of the given syntax node, but performs no other action.
    2828
    2929        virtual void visit( ObjectDecl *objectDecl );
  • src/SynTree/module.mk

    ra2d4d1c r4dfa562  
    4848       SynTree/Visitor.cc \
    4949       SynTree/Mutator.cc \
     50       SynTree/AddStmtVisitor.cc \
    5051       SynTree/TypeSubstitution.cc \
    5152       SynTree/Attribute.cc \
  • src/Tuples/TupleExpansion.cc

    ra2d4d1c r4dfa562  
    2121#include "Common/ScopedMap.h"     // for ScopedMap
    2222#include "Common/utility.h"       // for CodeLocation
     23#include "GenPoly/DeclMutator.h"  // for DeclMutator
    2324#include "InitTweak/InitTweak.h"  // for getFunction
    2425#include "Parser/LinkageSpec.h"   // for Spec, C, Intrinsic
  • src/main.cc

    ra2d4d1c r4dfa562  
    239239                } // if
    240240
     241                // OPTPRINT( "Concurrency" )
     242                // Concurrency::applyKeywords( translationUnit );
     243
    241244                // add the assignment statement after the initialization of a type parameter
    242245                OPTPRINT( "validate" )
  • src/tests/.expect/64/sched-ext-parse.txt

    ra2d4d1c r4dfa562  
    10551055static inline struct condition ___operator_assign__F10scondition_R10scondition10scondition_autogen___1(struct condition *___dst__R10scondition_1, struct condition ___src__10scondition_1){
    10561056    struct condition ___ret__10scondition_1;
    1057     struct __condition_blocked_queue_t _tmp_cp4;
     1057    struct __condition_blocked_queue_t _tmp_cp56;
    10581058    struct __condition_blocked_queue_t _tmp_cp_ret29;
    1059     ((void)(((void)(_tmp_cp_ret29=___operator_assign__F28s__condition_blocked_queue_t_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&(*___dst__R10scondition_1).__blocked__28s__condition_blocked_queue_t_1), (((void)___constructor__F_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&_tmp_cp4), ___src__10scondition_1.__blocked__28s__condition_blocked_queue_t_1)) , _tmp_cp4)))) , _tmp_cp_ret29));
     1059    ((void)(((void)(_tmp_cp_ret29=___operator_assign__F28s__condition_blocked_queue_t_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&(*___dst__R10scondition_1).__blocked__28s__condition_blocked_queue_t_1), (((void)___constructor__F_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&_tmp_cp56), ___src__10scondition_1.__blocked__28s__condition_blocked_queue_t_1)) , _tmp_cp56)))) , _tmp_cp_ret29));
    10601060    ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp_ret29)));
    1061     ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp4)));
     1061    ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp56)));
    10621062    ((void)((*___dst__R10scondition_1).__monitors__PP13smonitor_desc_1=___src__10scondition_1.__monitors__PP13smonitor_desc_1));
    10631063    ((void)((*___dst__R10scondition_1).__monitor_count__Us_1=___src__10scondition_1.__monitor_count__Us_1));
     
    11551155static inline struct M ___operator_assign__F2sM_R2sM2sM_autogen___1(struct M *___dst__R2sM_1, struct M ___src__2sM_1){
    11561156    struct M ___ret__2sM_1;
    1157     struct monitor_desc _tmp_cp5;
     1157    struct monitor_desc _tmp_cp60;
    11581158    struct monitor_desc _tmp_cp_ret31;
    1159     ((void)(((void)(_tmp_cp_ret31=___operator_assign__F13smonitor_desc_R13smonitor_desc13smonitor_desc_autogen___1((&(*___dst__R2sM_1).____mon__13smonitor_desc_1), (((void)___constructor__F_R13smonitor_desc13smonitor_desc_autogen___1((&_tmp_cp5), ___src__2sM_1.____mon__13smonitor_desc_1)) , _tmp_cp5)))) , _tmp_cp_ret31));
     1159    ((void)(((void)(_tmp_cp_ret31=___operator_assign__F13smonitor_desc_R13smonitor_desc13smonitor_desc_autogen___1((&(*___dst__R2sM_1).____mon__13smonitor_desc_1), (((void)___constructor__F_R13smonitor_desc13smonitor_desc_autogen___1((&_tmp_cp60), ___src__2sM_1.____mon__13smonitor_desc_1)) , _tmp_cp60)))) , _tmp_cp_ret31));
    11601160    ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp_ret31)));
    1161     ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp5)));
     1161    ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp60)));
    11621162    ((void)___constructor__F_R2sM2sM_autogen___1((&___ret__2sM_1), ___src__2sM_1));
    11631163    return ((struct M )___ret__2sM_1);
Note: See TracChangeset for help on using the changeset viewer.