Changes in / [f8b69da7:546b51e]


Ignore:
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • libcfa/prelude/builtins.c

    rf8b69da7 r546b51e  
    111111static inline unsigned int ?\=?( unsigned int & x, unsigned long int y ) { x = x \ y; return x; }
    112112
    113 // type that wraps a pointer and a destructor-like function - used in generating implicit destructor calls for struct members in user-defined functions
    114 forall(dtype T)
    115 struct __Destructor {
    116   T * object;
    117   void (*dtor)(T *);
    118 };
    119 
    120 // defined destructor in the case that non-generated code wants to use __Destructor
    121 forall(dtype T)
    122 static inline void ^?{}(__Destructor(T) & x) {
    123         if (x.object && x.dtor) {
    124           x.dtor(x.object);
    125         }
    126 }
    127 
    128 // easy interface into __Destructor's destructor for easy codegen purposes
    129 extern "C" {
    130   forall(dtype T)
    131   static inline void __destroy_Destructor(__Destructor(T) * dtor) {
    132     ^(*dtor){};
    133   }
    134 }
    135 
    136113// Local Variables: //
    137114// mode: c //
  • src/ControlStruct/ExceptTranslate.cc

    rf8b69da7 r546b51e  
    319319                        }
    320320
    321                         block->push_back( handler->body );
    322                         handler->body = nullptr;
     321                        block->push_back( handler->get_body() );
     322                        handler->set_body( nullptr );
    323323
    324324                        std::list<Statement *> caseBody
  • src/InitTweak/FixInit.cc

    rf8b69da7 r546b51e  
    5454#include "SynTree/Type.h"              // for Type, Type::StorageClasses
    5555#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution, operator<<
    56 #include "SynTree/DeclReplacer.h"      // for DeclReplacer
    5756#include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
    5857
     
    163162                        using Parent::previsit;
    164163
     164                        void previsit( ObjectDecl * objDecl );
    165165                        void previsit( FunctionDecl * funcDecl );
    166166
     167                        void previsit( CompoundStmt * compoundStmt );
     168                        void postvisit( CompoundStmt * compoundStmt );
     169                        void previsit( ReturnStmt * returnStmt );
    167170                        void previsit( BranchStmt * stmt );
    168171                private:
     
    204207                        static void generate( std::list< Declaration * > & translationUnit );
    205208
    206                         void premutate( StructDecl * structDecl );
    207 
    208209                        void premutate( FunctionDecl * funcDecl );
    209210                        DeclarationWithType * postmutate( FunctionDecl * funcDecl );
     
    227228                        bool isCtor = false; // true if current function is a constructor
    228229                        StructDecl * structDecl = nullptr;
    229 
    230                         // special built-in functions necessary for this to work
    231                         StructDecl * dtorStruct = nullptr;
    232                         FunctionDecl * dtorStructDestroy = nullptr;
    233230                };
    234231
     
    735732                }
    736733
    737                 DeclarationWithType * getDtorFunc( ObjectDecl * objDecl, Statement * input, std::list< Statement * > & stmtsToAdd ) {
    738                         // unwrap implicit statement wrapper
    739                         Statement * dtor = input;
    740                         if ( ImplicitCtorDtorStmt * implicit = dynamic_cast< ImplicitCtorDtorStmt * >( input ) ) {
    741                                 // dtor = implicit->callStmt;
    742                                 // implicit->callStmt = nullptr;
    743                         }
    744                         assert( dtor );
    745                         std::list< Expression * > matches;
    746                         collectCtorDtorCalls( dtor, matches );
    747 
    748                         if ( dynamic_cast< ExprStmt * >( dtor ) ) {
    749                                 // only one destructor call in the expression
    750                                 if ( matches.size() == 1 ) {
    751                                         DeclarationWithType * func = getFunction( matches.front() );
    752                                         assertf( func, "getFunction failed to find function in %s", toString( matches.front() ).c_str() );
    753 
    754                                         // cleanup argument must be a function, not an object (including function pointer)
    755                                         if ( FunctionDecl * dtorFunc = dynamic_cast< FunctionDecl * > ( func ) ) {
    756                                                 if ( dtorFunc->type->forall.empty() ) {
    757                                                         // simple case where the destructor is a monomorphic function call - can simply
    758                                                         // use that function as the cleanup function.
    759                                                         delete dtor;
    760                                                         return func;
    761                                                 }
    762                                         }
    763                                 }
    764                         }
    765 
    766                         // otherwise the cleanup is more complicated - need to build a single argument cleanup function that
    767                         // wraps the more complicated code.
    768                         static UniqueName dtorNamer( "__cleanup_dtor" );
    769                         FunctionDecl * dtorFunc = FunctionDecl::newFunction( dtorNamer.newName(), SymTab::genDefaultType( objDecl->type->stripReferences(), false ), new CompoundStmt() );
    770                         stmtsToAdd.push_back( new DeclStmt( dtorFunc ) );
    771 
    772                         // the original code contains uses of objDecl - replace them with the newly generated 'this' parameter.
    773                         ObjectDecl * thisParam = getParamThis( dtorFunc->type );
    774                         Expression * replacement = new VariableExpr( thisParam );
    775 
    776                         Type * base = replacement->result->stripReferences();
    777                         if ( dynamic_cast< ArrayType * >( base ) || dynamic_cast< TupleType * > ( base ) ) {
    778                                 // need to cast away reference for array types, since the destructor is generated without the reference type,
    779                                 // and for tuple types since tuple indexing does not work directly on a reference
    780                                 replacement = new CastExpr( replacement, base->clone() );
    781                         }
    782                         DeclReplacer::replace( dtor, { std::make_pair( objDecl, replacement ) } );
    783                         dtorFunc->statements->push_back( strict_dynamic_cast<Statement *>( dtor ) );
    784 
    785                         return dtorFunc;
    786                 }
    787 
    788734                DeclarationWithType * FixInit::postmutate( ObjectDecl *objDecl ) {
    789735                        // since this removes the init field from objDecl, it must occur after children are mutated (i.e. postmutate)
     
    898844                                                        ctorInit->ctor = nullptr;
    899845                                                }
    900 
    901                                                 Statement * dtor = ctorInit->dtor;
    902                                                 if ( dtor ) {
    903                                                         ImplicitCtorDtorStmt * implicit = strict_dynamic_cast< ImplicitCtorDtorStmt * >( dtor );
    904                                                         Statement * dtorStmt = implicit->callStmt;
    905 
    906                                                         // don't need to call intrinsic dtor, because it does nothing, but
    907                                                         // non-intrinsic dtors must be called
    908                                                         if ( ! isIntrinsicSingleArgCallStmt( dtorStmt ) ) {
    909                                                                 // set dtor location to the object's location for error messages
    910                                                                 DeclarationWithType * dtorFunc = getDtorFunc( objDecl, dtorStmt, stmtsToAddBefore );
    911                                                                 objDecl->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( dtorFunc ) } ) );
    912                                                                 ctorInit->dtor = nullptr;
    913                                                         } // if
    914                                                 }
    915846                                        } // if
    916847                                } else if ( Initializer * init = ctorInit->init ) {
     
    955886
    956887
     888                template<typename Iterator, typename OutputIterator>
     889                void insertDtors( Iterator begin, Iterator end, OutputIterator out ) {
     890                        for ( Iterator it = begin ; it != end ; ++it ) {
     891                                // extract destructor statement from the object decl and insert it into the output. Note that this is
     892                                // only called on lists of non-static objects with implicit non-intrinsic dtors, so if the user manually
     893                                // calls an intrinsic dtor then the call must (and will) still be generated since the argument may
     894                                // contain side effects.
     895                                ObjectDecl * objDecl = *it;
     896                                ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() );
     897                                assert( ctorInit && ctorInit->get_dtor() );
     898                                *out++ = ctorInit->get_dtor()->clone();
     899                        } // for
     900                }
     901
     902                void InsertDtors::previsit( ObjectDecl * objDecl ) {
     903                        // remember non-static destructed objects so that their destructors can be inserted later
     904                        if ( ! objDecl->get_storageClasses().is_static ) {
     905                                if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
     906                                        // a decision should have been made by the resolver, so ctor and init are not both non-NULL
     907                                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
     908                                        Statement * dtor = ctorInit->get_dtor();
     909                                        // don't need to call intrinsic dtor, because it does nothing, but
     910                                        // non-intrinsic dtors must be called
     911                                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
     912                                                // set dtor location to the object's location for error messages
     913                                                ctorInit->dtor->location = objDecl->location;
     914                                                reverseDeclOrder.front().push_front( objDecl );
     915                                        } // if
     916                                } // if
     917                        } // if
     918                }
     919
    957920                void InsertDtors::previsit( FunctionDecl * funcDecl ) {
    958921                        // each function needs to have its own set of labels
     
    967930                }
    968931
     932                void InsertDtors::previsit( CompoundStmt * compoundStmt ) {
     933                        // visit statements - this will also populate reverseDeclOrder list.  don't want to dump all destructors
     934                        // when block is left, just the destructors associated with variables defined in this block, so push a new
     935                        // list to the top of the stack so that we can differentiate scopes
     936                        reverseDeclOrder.push_front( OrderedDecls() );
     937                        Parent::previsit( compoundStmt );
     938                }
     939
     940                void InsertDtors::postvisit( CompoundStmt * compoundStmt ) {
     941                        // add destructors for the current scope that we're exiting, unless the last statement is a return, which
     942                        // causes unreachable code warnings
     943                        std::list< Statement * > & statements = compoundStmt->get_kids();
     944                        if ( ! statements.empty() && ! dynamic_cast< ReturnStmt * >( statements.back() ) ) {
     945                                insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) );
     946                        }
     947                        reverseDeclOrder.pop_front();
     948                }
     949
     950                void InsertDtors::previsit( ReturnStmt * ) {
     951                        // return exits all scopes, so dump destructors for all scopes
     952                        for ( OrderedDecls & od : reverseDeclOrder ) {
     953                                insertDtors( od.begin(), od.end(), back_inserter( stmtsToAddBefore ) );
     954                        } // for
     955                }
     956
    969957                // Handle break/continue/goto in the same manner as C++.  Basic idea: any objects that are in scope at the
    970958                // BranchStmt but not at the labelled (target) statement must be destructed.  If there are any objects in scope
     
    994982                        if ( ! diff.empty() ) {
    995983                                SemanticError( stmt, std::string("jump to label '") + stmt->get_target().get_name() + "' crosses initialization of " + (*diff.begin())->get_name() + " " );
     984                        } // if
     985                        // S_G-S_L results in set of objects that must be destructed
     986                        diff.clear();
     987                        std::set_difference( curVars.begin(), curVars.end(), lvars.begin(), lvars.end(), std::inserter( diff, diff.end() ) );
     988                        DTOR_PRINT(
     989                                std::cerr << "S_G-S_L = " << printSet( diff ) << std::endl;
     990                        )
     991                        if ( ! diff.empty() ) {
     992                                // create an auxilliary set for fast lookup -- can't make diff a set, because diff ordering should be consistent for error messages.
     993                                std::unordered_set<ObjectDecl *> needsDestructor( diff.begin(), diff.end() );
     994
     995                                // go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor
     996                                OrderedDecls ordered;
     997                                for ( OrderedDecls & rdo : reverseDeclOrder ) {
     998                                        // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order.
     999                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
     1000                                } // for
     1001                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAddBefore ) );
    9961002                        } // if
    9971003                }
     
    10191025                }
    10201026
    1021                 void GenStructMemberCalls::premutate( StructDecl * structDecl ) {
    1022                         if ( ! dtorStruct && structDecl->name == "__Destructor" ) {
    1023                                 dtorStruct = structDecl;
    1024                         }
    1025                 }
    1026 
    10271027                void GenStructMemberCalls::premutate( FunctionDecl * funcDecl ) {
    10281028                        GuardValue( function );
     
    10371037                        unhandled.clear();
    10381038                        usedUninit.clear();
    1039 
    1040                         if ( ! dtorStructDestroy && funcDecl->name == "__destroy_Destructor" ) {
    1041                                 dtorStructDestroy = funcDecl;
    1042                                 return;
    1043                         }
    10441039
    10451040                        function = funcDecl;
     
    10531048                                if ( structType ) {
    10541049                                        structDecl = structType->get_baseStruct();
    1055                                         if ( structDecl == dtorStruct ) return;
    10561050                                        for ( Declaration * member : structDecl->get_members() ) {
    10571051                                                if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
     
    11221116                                                        callStmt->acceptMutator( *visitor );
    11231117                                                        if ( isCtor ) {
    1124                                                                 function->statements->push_front( callStmt );
    1125                                                         } else { // TODO: don't generate destructor function/object for intrinsic calls
     1118                                                                function->get_statements()->push_front( callStmt );
     1119                                                        } else {
    11261120                                                                // destructor statements should be added at the end
    1127                                                                 // function->get_statements()->push_back( callStmt );
    1128 
    1129                                                                 // __Destructor _dtor0 = { (void *)&b.a1, (void (*)(void *)_destroy_A };
    1130                                                                 std::list< Statement * > stmtsToAdd;
    1131 
    1132                                                                 static UniqueName memberDtorNamer = { "__memberDtor" };
    1133                                                                 assertf( dtorStruct, "builtin __Destructor not found." );
    1134                                                                 assertf( dtorStructDestroy, "builtin __destroy_Destructor not found." );
    1135 
    1136                                                                 Expression * thisExpr = new CastExpr( new AddressExpr( new VariableExpr( thisParam ) ), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) );
    1137                                                                 Expression * dtorExpr = new VariableExpr( getDtorFunc( thisParam, callStmt, stmtsToAdd ) );
    1138 
    1139                                                                 // cast destructor pointer to void (*)(void *), to silence GCC incompatible pointer warnings
    1140                                                                 FunctionType * dtorFtype = new FunctionType( Type::Qualifiers(), false );
    1141                                                                 dtorFtype->parameters.push_back( ObjectDecl::newObject( "", new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), nullptr ) );
    1142                                                                 Type * dtorType = new PointerType( Type::Qualifiers(), dtorFtype );
    1143 
    1144                                                                 ObjectDecl * destructor = ObjectDecl::newObject( memberDtorNamer.newName(), new StructInstType( Type::Qualifiers(), dtorStruct ), new ListInit( { new SingleInit( thisExpr ), new SingleInit( new CastExpr( dtorExpr, dtorType ) ) } ) );
    1145                                                                 function->statements->push_front( new DeclStmt( destructor ) );
    1146                                                                 destructor->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( dtorStructDestroy ) } ) );
    1147 
    1148                                                                 function->statements->kids.splice( function->statements->kids.begin(), stmtsToAdd );
     1121                                                                function->get_statements()->push_back( callStmt );
    11491122                                                        }
    11501123                                                } catch ( SemanticErrorException & error ) {
  • src/InitTweak/InitTweak.cc

    rf8b69da7 r546b51e  
    339339                std::list< Expression * > matches;
    340340                collectCtorDtorCalls( stmt, matches );
    341                 assertf( matches.size() <= 1, "%zd constructor/destructors found in %s", matches.size(), toString( stmt ).c_str() );
     341                assert( matches.size() <= 1 );
    342342                return matches.size() == 1 ? matches.front() : nullptr;
    343343        }
  • src/Makefile.am

    rf8b69da7 r546b51e  
    9494  CodeGen/CodeGenerator.cc \
    9595  CodeGen/FixMain.cc \
    96   CodeGen/Generate.cc \
    9796  CodeGen/GenType.cc \
    9897  CodeGen/OperatorTable.cc \
  • src/Makefile.in

    rf8b69da7 r546b51e  
    182182        SynTree/DeclReplacer.$(OBJEXT) CompilationState.$(OBJEXT) \
    183183        CodeGen/CodeGenerator.$(OBJEXT) CodeGen/FixMain.$(OBJEXT) \
    184         CodeGen/Generate.$(OBJEXT) CodeGen/GenType.$(OBJEXT) \
    185         CodeGen/OperatorTable.$(OBJEXT) Common/Assert.$(OBJEXT) \
    186         Common/Eval.$(OBJEXT) Common/SemanticError.$(OBJEXT) \
    187         Common/UniqueName.$(OBJEXT) Concurrency/Keywords.$(OBJEXT) \
     184        CodeGen/GenType.$(OBJEXT) CodeGen/OperatorTable.$(OBJEXT) \
     185        Common/Assert.$(OBJEXT) Common/Eval.$(OBJEXT) \
     186        Common/SemanticError.$(OBJEXT) Common/UniqueName.$(OBJEXT) \
     187        Concurrency/Keywords.$(OBJEXT) \
    188188        ControlStruct/ForExprMutator.$(OBJEXT) \
    189189        ControlStruct/LabelFixer.$(OBJEXT) \
     
    621621  CodeGen/CodeGenerator.cc \
    622622  CodeGen/FixMain.cc \
    623   CodeGen/Generate.cc \
    624623  CodeGen/GenType.cc \
    625624  CodeGen/OperatorTable.cc \
     
    798797        CodeGen/$(DEPDIR)/$(am__dirstamp)
    799798CodeGen/FixMain.$(OBJEXT): CodeGen/$(am__dirstamp) \
    800         CodeGen/$(DEPDIR)/$(am__dirstamp)
    801 CodeGen/Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \
    802799        CodeGen/$(DEPDIR)/$(am__dirstamp)
    803800CodeGen/GenType.$(OBJEXT): CodeGen/$(am__dirstamp) \
     
    990987clean-cfa_cpplibPROGRAMS:
    991988        -test -z "$(cfa_cpplib_PROGRAMS)" || rm -f $(cfa_cpplib_PROGRAMS)
     989CodeGen/Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \
     990        CodeGen/$(DEPDIR)/$(am__dirstamp)
    992991CodeGen/FixNames.$(OBJEXT): CodeGen/$(am__dirstamp) \
    993992        CodeGen/$(DEPDIR)/$(am__dirstamp)
  • src/SymTab/Autogen.cc

    rf8b69da7 r546b51e  
    4545        /// Data used to generate functions generically. Specifically, the name of the generated function and a function which generates the routine protoype
    4646        struct FuncData {
    47                 typedef FunctionType * (*TypeGen)( Type *, bool );
     47                typedef FunctionType * (*TypeGen)( Type * );
    4848                FuncData( const std::string & fname, const TypeGen & genType ) : fname( fname ), genType( genType ) {}
    4949                std::string fname;
     
    231231
    232232        /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *)
    233         FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic ) {
     233        FunctionType * genDefaultType( Type * paramType ) {
     234                const auto & typeParams = getGenericParams( paramType );
    234235                FunctionType *ftype = new FunctionType( Type::Qualifiers(), false );
    235                 if ( maybePolymorphic ) {
    236                         // only copy in
    237                         const auto & typeParams = getGenericParams( paramType );
    238                         cloneAll( typeParams, ftype->forall );
    239                 }
     236                cloneAll( typeParams, ftype->forall );
    240237                ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
    241238                ftype->parameters.push_back( dstParam );
     
    244241
    245242        /// given type T, generate type of copy ctor, i.e. function type void (*) (T *, T)
    246         FunctionType * genCopyType( Type * paramType, bool maybePolymorphic ) {
    247                 FunctionType *ftype = genDefaultType( paramType, maybePolymorphic );
     243        FunctionType * genCopyType( Type * paramType ) {
     244                FunctionType *ftype = genDefaultType( paramType );
    248245                ObjectDecl *srcParam = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr );
    249246                ftype->parameters.push_back( srcParam );
     
    252249
    253250        /// given type T, generate type of assignment, i.e. function type T (*) (T *, T)
    254         FunctionType * genAssignType( Type * paramType, bool maybePolymorphic ) {
    255                 FunctionType *ftype = genCopyType( paramType, maybePolymorphic );
     251        FunctionType * genAssignType( Type * paramType ) {
     252                FunctionType *ftype = genCopyType( paramType );
    256253                ObjectDecl *returnVal = new ObjectDecl( "_ret", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr );
    257254                ftype->returnVals.push_back( returnVal );
     
    311308                for ( const FuncData & d : data ) {
    312309                        // generate a function (?{}, ?=?, ^?{}) based on the current FuncData.
    313                         FunctionType * ftype = d.genType( type, true );
     310                        FunctionType * ftype = d.genType( type );
    314311
    315312                        // destructor for concurrent type must be mutex
  • src/SymTab/Autogen.h

    rf8b69da7 r546b51e  
    4545        extern FunctionDecl * dereferenceOperator;
    4646
    47         /// generate the type of an assignment function for paramType.
    48         /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic
    49         FunctionType * genAssignType( Type * paramType, bool maybePolymorphic = true );
    50 
    51         /// generate the type of a default constructor or destructor for paramType.
    52         /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic
    53         FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic = true );
    54 
    55         /// generate the type of a copy constructor for paramType.
    56         /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic
    57         FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true );
     47        // generate the type of an assignment function for paramType
     48        FunctionType * genAssignType( Type * paramType );
     49
     50        // generate the type of a default constructor or destructor for paramType
     51        FunctionType * genDefaultType( Type * paramType );
     52
     53        // generate the type of a copy constructor for paramType
     54        FunctionType * genCopyType( Type * paramType );
    5855
    5956        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
  • src/SymTab/Validate.cc

    rf8b69da7 r546b51e  
    13331333        void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) {
    13341334                if ( ! dereferenceOperator ) {
    1335                         // find and remember the intrinsic dereference operator for object pointers
    1336                         if ( funcDecl->name == "*?" && funcDecl->linkage == LinkageSpec::Intrinsic ) {
    1337                                 FunctionType * ftype = funcDecl->type;
    1338                                 if ( ftype->parameters.size() == 1 ) {
    1339                                         PointerType * ptrType = strict_dynamic_cast<PointerType *>( ftype->parameters.front()->get_type() );
    1340                                         if ( ptrType->base->get_qualifiers() == Type::Qualifiers() ) {
    1341                                                 TypeInstType * inst = dynamic_cast<TypeInstType *>( ptrType->base );
    1342                                                 if ( inst && ! inst->get_isFtype() ) {
    1343                                                         dereferenceOperator = funcDecl;
    1344                                                 }
    1345                                         }
     1335                        if ( funcDecl->get_name() == "*?" && funcDecl->get_linkage() == LinkageSpec::Intrinsic ) {
     1336                                FunctionType * ftype = funcDecl->get_functionType();
     1337                                if ( ftype->get_parameters().size() == 1 && ftype->get_parameters().front()->get_type()->get_qualifiers() == Type::Qualifiers() ) {
     1338                                        dereferenceOperator = funcDecl;
    13461339                                }
    13471340                        }
  • src/SynTree/DeclReplacer.cc

    rf8b69da7 r546b51e  
    3838                        void previsit( TypeInstType * inst );
    3939                };
    40 
    41                 /// Mutator that replaces uses of declarations with arbitrary expressions, according to the supplied mapping
    42                 struct ExprDeclReplacer {
    43                 private:
    44                         const ExprMap & exprMap;
    45                         bool debug;
    46                 public:
    47                         ExprDeclReplacer( const ExprMap & exprMap, bool debug = false );
    48 
    49                         // replace variable with new node from expr map
    50                         Expression * postmutate( VariableExpr * varExpr );
    51                 };
    5240        }
    5341
     
    6553                DeclMap declMap;
    6654                replace( node, declMap, typeMap, debug );
    67         }
    68 
    69         void replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug ) {
    70                 PassVisitor<ExprDeclReplacer> replacer( exprMap, debug );
    71                 node = maybeMutate( node, replacer );
    7255        }
    7356
     
    9679                        }
    9780                }
    98 
    99                 ExprDeclReplacer::ExprDeclReplacer( const ExprMap & exprMap, bool debug ) : exprMap( exprMap ), debug( debug ) {}
    100 
    101                 Expression * ExprDeclReplacer::postmutate( VariableExpr * varExpr ) {
    102                         if ( exprMap.count( varExpr->var ) ) {
    103                                 Expression * replacement = exprMap.at( varExpr->var )->clone();
    104                                 if ( debug ) {
    105                                         std::cerr << "replacing variable reference: " << (void*)varExpr->var << " " << varExpr->var << " with " << (void*)replacement << " " << replacement << std::endl;
    106                                 }
    107                                 std::swap( varExpr->env, replacement->env );
    108                                 delete varExpr;
    109                                 return replacement;
    110                         }
    111                         return varExpr;
    112                 }
    11381        }
    11482} // namespace VarExprReplacer
  • src/SynTree/DeclReplacer.h

    rf8b69da7 r546b51e  
    2626        typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;
    2727        typedef std::map< TypeDecl *, TypeDecl * > TypeMap;
    28         typedef std::map< DeclarationWithType *, Expression * > ExprMap;
    2928
    3029        void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false );
    3130        void replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false );
    3231        void replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
    33 
    34         void replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug = false);
    35         template<typename T>
    36                 void replace( T *& node, const ExprMap & exprMap, bool debug = false ) {
    37                 if ( ! node ) return;
    38                 BaseSyntaxNode * arg = node;
    39                 replace( arg, exprMap, debug );
    40                 node = dynamic_cast<T *>( arg );
    41                 assertf( node, "DeclReplacer fundamentally changed the type of its argument." );
    42         }
    4332}
    4433
  • tests/raii/.expect/memberCtors-ERR1.txt

    rf8b69da7 r546b51e  
    1 raii/memberCtors.c:92:1 error: in void ?{}(B &b), field a2 used before being constructed
     1raii/memberCtors.c:71:1 error: in void ?{}(B &b), field a2 used before being constructed
  • tests/raii/.expect/memberCtors.txt

    rf8b69da7 r546b51e  
    11Before declaration of b1
    2 constructing int id: 0
    3 constructing int id: 1
    4 constructing int id: 2
    5 default construct A 0
    6 constructing int id: 3
    7 constructing int id: 4
    8 constructing int id: 5
    9 default construct A 1
    10 begin construct B id: 0
     2constructing int
     3constructing int
     4constructing int
     5constructing int
     6constructing int
     7constructing int
     8begin construct B
    119assign b.a2
    12 constructing int id: 6
    13 constructing int id: 7
    14 begin construct A id: 2
    15 construct a.x
    16 constructing int: 1001 id: 8
    17 assign a.y
    18 assigning int: 0 0 id: 6
    19 end construct A
    20 copy constructing int: 0 id: 9
    21 copy constructing int: 0 id: 10
    22 begin copy construct A id: 3
    23 copy construct this.x
    24 copy constructing int: 1001 id: 11
    25 assign this.y
    26 copy constructing int: 0 id: 12
    27 destructing int: 0 id: 12
    28 destructing int: 0 id: 12
    29 end copy construct A
    30 begin ?=? A id: 0
    31 copy constructing int: 1001 id: 13
    32 destructing int: 1001 id: 13
    33 destructing int: 1001 id: 13
    34 copy constructing int: 0 id: 14
    35 destructing int: 0 id: 14
    36 destructing int: 0 id: 14
    37 copy constructing int: 0 id: 15
    38 destructing int: 0 id: 15
    39 destructing int: 0 id: 15
     10constructing int
     11constructing int
     12begin construct A
     13construct a.x
     14constructing int: 1001
     15assign a.y
     16assigning int: 0 0
     17end construct A
     18copy constructing int: 0
     19copy constructing int: 0
     20begin copy construct A
     21copy construct this.x
     22copy constructing int: 1001
     23assign this.y
     24copy constructing int: 0
     25destructing int: 0
     26destructing int: 0
     27end copy construct A
     28begin ?=? A
     29copy constructing int: 1001
     30destructing int: 1001
     31destructing int: 1001
     32copy constructing int: 0
     33destructing int: 0
     34destructing int: 0
     35copy constructing int: 0
     36destructing int: 0
     37destructing int: 0
    4038end ?=? A
    41 copy constructing int: 0 id: 16
    42 copy constructing int: 0 id: 17
    43 begin copy construct A id: 4
    44 copy construct this.x
    45 copy constructing int: 1001 id: 18
    46 assign this.y
    47 copy constructing int: 0 id: 19
    48 destructing int: 0 id: 19
    49 destructing int: 0 id: 19
    50 end copy construct A
    51 destructing int: 0 id: 17
    52 destructing int: 0 id: 19
    53 destructing int: 1001 id: 18
    54 destructing int: 0 id: 10
    55 destructing int: 0 id: 12
    56 destructing int: 1001 id: 11
     39copy constructing int: 0
     40copy constructing int: 0
     41begin copy construct A
     42copy construct this.x
     43copy constructing int: 1001
     44assign this.y
     45copy constructing int: 0
     46destructing int: 0
     47destructing int: 0
     48end copy construct A
     49destructing int: 0
     50destructing int: 0
     51destructing int: 1001
     52destructing int: 0
     53destructing int: 0
     54destructing int: 1001
    5755construct b.a1
    58 constructing int id: 20
    59 constructing int id: 21
    60 begin construct A id: 5
    61 construct a.x
    62 constructing int: 1000 id: 22
    63 assign a.y
    64 assigning int: 0 0 id: 20
     56constructing int
     57constructing int
     58begin construct A
     59construct a.x
     60constructing int: 1000
     61assign a.y
     62assigning int: 0 0
    6563end construct A
    6664end construct B
    67 destructing int: 0 id: 7
    68 destructing int: 0 id: 6
    69 destructing int: 1001 id: 8
     65destructing int: 0
     66destructing int: 0
     67destructing int: 1001
    7068Before declaration of b2
    71 copy constructing int: 0 id: 23
    72 copy constructing int: 0 id: 24
    73 begin copy construct A id: 6
    74 copy construct this.x
    75 copy constructing int: 1000 id: 25
    76 assign this.y
    77 copy constructing int: 0 id: 26
    78 destructing int: 0 id: 26
    79 destructing int: 0 id: 26
    80 end copy construct A
    81 copy constructing int: 0 id: 27
    82 copy constructing int: 0 id: 28
    83 begin copy construct A id: 7
    84 copy construct this.x
    85 copy constructing int: 1001 id: 29
    86 assign this.y
    87 copy constructing int: 0 id: 30
    88 destructing int: 0 id: 30
    89 destructing int: 0 id: 30
    90 end copy construct A
    91 copy constructing int: 0 id: 31
    92 copy constructing int: 0 id: 32
    93 begin copy construct A id: 8
    94 copy construct this.x
    95 copy constructing int: 0 id: 33
    96 assign this.y
    97 copy constructing int: 0 id: 34
    98 destructing int: 0 id: 34
    99 destructing int: 0 id: 34
     69copy constructing int: 0
     70copy constructing int: 0
     71begin copy construct A
     72copy construct this.x
     73copy constructing int: 1000
     74assign this.y
     75copy constructing int: 0
     76destructing int: 0
     77destructing int: 0
     78end copy construct A
     79copy constructing int: 0
     80copy constructing int: 0
     81begin copy construct A
     82copy construct this.x
     83copy constructing int: 1001
     84assign this.y
     85copy constructing int: 0
     86destructing int: 0
     87destructing int: 0
     88end copy construct A
     89copy constructing int: 0
     90copy constructing int: 0
     91begin copy construct A
     92copy construct this.x
     93copy constructing int: 0
     94assign this.y
     95copy constructing int: 0
     96destructing int: 0
     97destructing int: 0
    10098end copy construct A
    10199End of main
    102 begin destruct B id: 1
    103 constructing int id: 35
    104 constructing int id: 36
    105 begin construct A id: 9
    106 construct a.x
    107 constructing int: 999 id: 37
    108 assign a.y
    109 assigning int: 0 0 id: 35
    110 end construct A
    111 copy constructing int: 0 id: 38
    112 copy constructing int: 0 id: 39
    113 begin copy construct A id: 10
    114 copy construct this.x
    115 copy constructing int: 999 id: 40
    116 assign this.y
    117 copy constructing int: 0 id: 41
    118 destructing int: 0 id: 41
    119 destructing int: 0 id: 41
    120 end copy construct A
    121 begin ?=? A id: 7
    122 copy constructing int: 999 id: 42
    123 destructing int: 999 id: 42
    124 destructing int: 999 id: 42
    125 copy constructing int: 0 id: 43
    126 destructing int: 0 id: 43
    127 destructing int: 0 id: 43
    128 copy constructing int: 0 id: 44
    129 destructing int: 0 id: 44
    130 destructing int: 0 id: 44
     100constructing int
     101constructing int
     102begin construct A
     103construct a.x
     104constructing int: 999
     105assign a.y
     106assigning int: 0 0
     107end construct A
     108copy constructing int: 0
     109copy constructing int: 0
     110begin copy construct A
     111copy construct this.x
     112copy constructing int: 999
     113assign this.y
     114copy constructing int: 0
     115destructing int: 0
     116destructing int: 0
     117end copy construct A
     118begin ?=? A
     119copy constructing int: 999
     120destructing int: 999
     121destructing int: 999
     122copy constructing int: 0
     123destructing int: 0
     124destructing int: 0
     125copy constructing int: 0
     126destructing int: 0
     127destructing int: 0
    131128end ?=? A
    132 copy constructing int: 0 id: 45
    133 copy constructing int: 0 id: 46
    134 begin copy construct A id: 11
    135 copy construct this.x
    136 copy constructing int: 999 id: 47
    137 assign this.y
    138 copy constructing int: 0 id: 48
    139 destructing int: 0 id: 48
    140 destructing int: 0 id: 48
    141 end copy construct A
    142 destructing int: 0 id: 46
    143 destructing int: 0 id: 48
    144 destructing int: 999 id: 47
    145 destructing int: 0 id: 39
    146 destructing int: 0 id: 41
    147 destructing int: 999 id: 40
    148 destructing int: 0 id: 24
    149 destructing int: 0 id: 26
    150 destructing int: 1000 id: 25
    151 end destruct B
    152 destructing int: 0 id: 36
    153 destructing int: 0 id: 35
    154 destructing int: 999 id: 37
    155 destructing int: 0 id: 32
    156 destructing int: 0 id: 34
    157 destructing int: 0 id: 33
    158 destructing int: 0 id: 44
    159 destructing int: 0 id: 43
    160 destructing int: 999 id: 42
    161 begin destruct B id: 2
    162 constructing int id: 49
    163 constructing int id: 50
    164 begin construct A id: 12
    165 construct a.x
    166 constructing int: 999 id: 51
    167 assign a.y
    168 assigning int: 0 0 id: 49
    169 end construct A
    170 copy constructing int: 0 id: 52
    171 copy constructing int: 0 id: 53
    172 begin copy construct A id: 13
    173 copy construct this.x
    174 copy constructing int: 999 id: 54
    175 assign this.y
    176 copy constructing int: 0 id: 55
    177 destructing int: 0 id: 55
    178 destructing int: 0 id: 55
    179 end copy construct A
    180 begin ?=? A id: 0
    181 copy constructing int: 999 id: 56
    182 destructing int: 999 id: 56
    183 destructing int: 999 id: 56
    184 copy constructing int: 0 id: 57
    185 destructing int: 0 id: 57
    186 destructing int: 0 id: 57
    187 copy constructing int: 0 id: 58
    188 destructing int: 0 id: 58
    189 destructing int: 0 id: 58
     129copy constructing int: 0
     130copy constructing int: 0
     131begin copy construct A
     132copy construct this.x
     133copy constructing int: 999
     134assign this.y
     135copy constructing int: 0
     136destructing int: 0
     137destructing int: 0
     138end copy construct A
     139destructing int: 0
     140destructing int: 0
     141destructing int: 999
     142destructing int: 0
     143destructing int: 0
     144destructing int: 999
     145destructing int: 0
     146destructing int: 0
     147destructing int: 1000
     148destructing int: 0
     149destructing int: 0
     150destructing int: 999
     151destructing int: 0
     152destructing int: 0
     153destructing int: 0
     154destructing int: 0
     155destructing int: 0
     156destructing int: 999
     157constructing int
     158constructing int
     159begin construct A
     160construct a.x
     161constructing int: 999
     162assign a.y
     163assigning int: 0 0
     164end construct A
     165copy constructing int: 0
     166copy constructing int: 0
     167begin copy construct A
     168copy construct this.x
     169copy constructing int: 999
     170assign this.y
     171copy constructing int: 0
     172destructing int: 0
     173destructing int: 0
     174end copy construct A
     175begin ?=? A
     176copy constructing int: 999
     177destructing int: 999
     178destructing int: 999
     179copy constructing int: 0
     180destructing int: 0
     181destructing int: 0
     182copy constructing int: 0
     183destructing int: 0
     184destructing int: 0
    190185end ?=? A
    191 copy constructing int: 0 id: 59
    192 copy constructing int: 0 id: 60
    193 begin copy construct A id: 14
    194 copy construct this.x
    195 copy constructing int: 999 id: 61
    196 assign this.y
    197 copy constructing int: 0 id: 62
    198 destructing int: 0 id: 62
    199 destructing int: 0 id: 62
    200 end copy construct A
    201 destructing int: 0 id: 60
    202 destructing int: 0 id: 62
    203 destructing int: 999 id: 61
    204 destructing int: 0 id: 53
    205 destructing int: 0 id: 55
    206 destructing int: 999 id: 54
    207 destructing int: 0 id: 21
    208 destructing int: 0 id: 20
    209 destructing int: 1000 id: 22
    210 end destruct B
    211 destructing int: 0 id: 50
    212 destructing int: 0 id: 49
    213 destructing int: 999 id: 51
    214 destructing int: 0 id: 5
    215 destructing int: 0 id: 4
    216 destructing int: 0 id: 3
    217 destructing int: 0 id: 58
    218 destructing int: 0 id: 57
    219 destructing int: 999 id: 56
     186copy constructing int: 0
     187copy constructing int: 0
     188begin copy construct A
     189copy construct this.x
     190copy constructing int: 999
     191assign this.y
     192copy constructing int: 0
     193destructing int: 0
     194destructing int: 0
     195end copy construct A
     196destructing int: 0
     197destructing int: 0
     198destructing int: 999
     199destructing int: 0
     200destructing int: 0
     201destructing int: 999
     202destructing int: 0
     203destructing int: 0
     204destructing int: 1000
     205destructing int: 0
     206destructing int: 0
     207destructing int: 999
     208destructing int: 0
     209destructing int: 0
     210destructing int: 0
     211destructing int: 0
     212destructing int: 0
     213destructing int: 999
  • tests/raii/memberCtors.c

    rf8b69da7 r546b51e  
    11struct WrappedInt {
    22  int x;
    3   int id;
    43};
    5 int intID = 0;
    64
    75void ?{}(WrappedInt & this) {
    8   this.id = intID++;
    9   printf("constructing int id: %d\n", this.id);
     6  printf("constructing int\n");
    107  this.x = 0;
    118}
    129
    1310void ?{}(WrappedInt & this, WrappedInt other) {
    14   this.id = intID++;
    15   printf("copy constructing int: %d id: %d\n", other.x, this.id);
     11  printf("copy constructing int: %d\n", other.x);
    1612  this.x = other.x;
    1713}
    1814
    1915void ?{}(WrappedInt & this, int x) {
    20   this.id = intID++;
    21   printf("constructing int: %d id: %d\n", x, this.id);
     16  printf("constructing int: %d\n", x);
    2217  this.x = x;
    2318}
    2419
    2520void ^?{}(WrappedInt & this) {
    26   printf("destructing int: %d id: %d\n", this.x, this.id);
     21  printf("destructing int: %d\n", this.x);
    2722}
    2823
    29 /* WrappedInt */ void ?=?(WrappedInt & this, int x) {
    30   printf("assigning int: %d %d id: %d\n", this.x, x, this.id);
     24void ?=?(WrappedInt & this, int x) {
     25  printf("assigning int: %d %d\n", this.x, x);
    3126  this.x = x;
    32   // return this;
    3327}
    34 
    35 // WrappedInt ?=?(WrappedInt & this, WrappedInt other) {
    36 //   printf("assigning int: %d %d\n", this.x, other.x);
    37 //   this.x = other.x;
    38 //   return this;
    39 // }
    4028
    4129struct A {
    4230  WrappedInt x, y, z;
    43   int id;
    4431};
    45 int AID = 0;
    4632
    4733void ?{}(A & a) {
    4834  // currently must define default ctor, since there's no "= default" syntax
    49   a.id = AID++;
    50   printf("default construct A %d\n", a.id);
    5135}
    5236
    5337void ?{}(A & a, int x) {
    54   a.id = AID++;
    55   printf("begin construct A id: %d\n", a.id);
     38  printf("begin construct A\n");
    5639  printf("construct a.x\n");
    5740  (a.x){ x+999 };
     
    6245
    6346void ?{}(A & this, A other) {
    64   this.id = AID++;
    65   printf("begin copy construct A id: %d\n", this.id);
     47  printf("begin copy construct A\n");
    6648  printf("copy construct this.x\n");
    6749  (this.x){ other.x };
     
    7254
    7355A ?=?(A & this, A other) {
    74   printf("begin ?=? A id: %d\n", this.id);
     56  printf("begin ?=? A\n");
    7557  this.x = other.x;
    7658  this.y = other.y;
     
    8264struct B {
    8365  A a1, a2, a3;
    84   int id;
    8566};
    86 int BID = 0;
    8767
    8868void ?{}(B & b) {
    89   b.id = BID++;
    90   printf("begin construct B id: %d\n", b.id);
     69  printf("begin construct B\n");
    9170  printf("assign b.a2\n");
    9271  b.a2 = (A) { 2 };
     
    10079
    10180void ^?{}(B & b) {
    102   b.id = BID++;
    103   printf("begin destruct B id: %d\n", b.id);
    10481  b.a2 = (A) { 0 };
    10582  ^(b.a1){};
    106   printf("end destruct B\n");
    10783} // a2, a3 never destructed - will be automatically destructed
    10884
    10985int main() {
    11086  printf("Before declaration of b1\n");
    111   B b1;  // b1 = { { 1000, 0, 0 }, { 1001, 0, 0 }, { 0, 0, 0 } }
     87  B b1;
    11288  printf("Before declaration of b2\n");
    11389  B b2 = b1;
Note: See TracChangeset for help on using the changeset viewer.