Changes in / [93cdd5c:f3458a8]


Ignore:
Location:
src
Files:
13 added
13 deleted
23 edited

Legend:

Unmodified
Added
Removed
  • src/CodeTools/TrackLoc.cc

    r93cdd5c rf3458a8  
    6464                                }
    6565                                else {
    66                                         assertf( false, "Top level node has no CodeLocation %s", name.c_str() );
     66                                        assertf( false, "Top level node has no CodeLocation %s", toString( node ).c_str() );
    6767                                }
    6868                        }
  • src/InitTweak/FixInit.cc

    r93cdd5c rf3458a8  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixInit.h --
     7// FixInit.cc --
    88//
    99// Author           : Rob Schluntz
     
    365365                        // arrays are not copy constructed, so this should always be an ExprStmt
    366366                        ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg );
    367                         ExprStmt * exprStmt = strict_dynamic_cast< ExprStmt * >( stmt->get_callStmt() );
     367                        assertf( stmt, "ResolveCopyCtors: genCtorDtor returned nullptr: %s / %s / %s", fname.c_str(), toString( var ).c_str(), toString( cpArg ).c_str() );
     368                        ExprStmt * exprStmt = strict_dynamic_cast< ExprStmt * >( stmt->callStmt );
    368369                        Expression * resolved = exprStmt->expr;
    369370                        exprStmt->expr = nullptr; // take ownership of expr
     
    382383                        } // if
    383384                        delete stmt;
     385                        if ( TupleAssignExpr * assign = dynamic_cast< TupleAssignExpr * >( resolved ) ) {
     386                                // fix newly generated StmtExpr
     387                                postvisit( assign->stmtExpr );
     388                        }
    384389                        return resolved;
    385390                }
     
    475480                                static UniqueName retNamer("_tmp_stmtexpr_ret");
    476481
    477                                 // create variable that will hold the result of the stmt expr
    478482                                result = result->clone();
    479483                                env->apply( result );
     484                                if ( ! InitTweak::isConstructable( result ) ) {
     485                                        delete result;
     486                                        return;
     487                                }
     488
     489                                // create variable that will hold the result of the stmt expr
    480490                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    481                                 ret->get_type()->set_const( false );
    482                                 stmtExpr->get_returnDecls().push_front( ret );
     491                                ret->type->set_const( false );
     492                                stmtExpr->returnDecls.push_front( ret );
    483493
    484494                                // must have a non-empty body, otherwise it wouldn't have a result
    485                                 CompoundStmt * body = stmtExpr->get_statements();
     495                                CompoundStmt * body = stmtExpr->statements;
    486496                                assert( ! body->get_kids().empty() );
    487497                                // must be an ExprStmt, otherwise it wouldn't have a result
    488498                                ExprStmt * last = strict_dynamic_cast< ExprStmt * >( body->get_kids().back() );
    489                                 last->set_expr( makeCtorDtor( "?{}", ret, last->get_expr() ) );
    490 
    491                                 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
     499                                last->expr = makeCtorDtor( "?{}", ret, last->get_expr() );
     500
     501                                stmtExpr->dtors.push_front( makeCtorDtor( "^?{}", ret ) );
    492502                        } // if
    493503                }
     
    590600                        // to the outer context, rather than inside of the statement expression.
    591601                        visit_children = false;
    592                         std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
     602                        std::list< Statement * > & stmts = stmtExpr->statements->get_kids();
    593603                        for ( Statement *& stmt : stmts ) {
    594604                                stmt = stmt->acceptMutator( *visitor );
    595605                        } // for
    596                         assert( stmtExpr->get_result() );
    597                         Type * result = stmtExpr->get_result();
     606                        assert( stmtExpr->result );
     607                        Type * result = stmtExpr->result;
    598608                        if ( ! result->isVoid() ) {
    599                                 for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
     609                                for ( ObjectDecl * obj : stmtExpr->returnDecls ) {
    600610                                        stmtsToAddBefore.push_back( new DeclStmt( obj ) );
    601611                                } // for
    602612                                // add destructors after current statement
    603                                 for ( Expression * dtor : stmtExpr->get_dtors() ) {
     613                                for ( Expression * dtor : stmtExpr->dtors ) {
    604614                                        stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
    605615                                } // for
    606616                                // must have a non-empty body, otherwise it wouldn't have a result
    607617                                assert( ! stmts.empty() );
    608                                 assert( ! stmtExpr->get_returnDecls().empty() );
    609                                 stmts.push_back( new ExprStmt( new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
    610                                 stmtExpr->get_returnDecls().clear();
    611                                 stmtExpr->get_dtors().clear();
    612                         }
    613                         assert( stmtExpr->get_returnDecls().empty() );
    614                         assert( stmtExpr->get_dtors().empty() );
     618                                assertf( ! stmtExpr->returnDecls.empty() || stmtExpr->dtors.empty(), "StmtExpr returns non-void, but no return decls: %s", toString( stmtExpr ).c_str() );
     619                                // if there is a return decl, add a use as the last statement; will not have return decl on non-constructable returns
     620                                if ( ! stmtExpr->returnDecls.empty() ) {
     621                                        stmts.push_back( new ExprStmt( new VariableExpr( stmtExpr->returnDecls.front() ) ) );
     622                                }
     623                                stmtExpr->returnDecls.clear();
     624                                stmtExpr->dtors.clear();
     625                        }
     626                        assert( stmtExpr->returnDecls.empty() );
     627                        assert( stmtExpr->dtors.empty() );
    615628                }
    616629
  • src/InitTweak/GenInit.cc

    r93cdd5c rf3458a8  
    3030#include "InitTweak.h"             // for isConstExpr, InitExpander, checkIn...
    3131#include "Parser/LinkageSpec.h"    // for isOverridable, C
     32#include "ResolvExpr/Resolver.h"
    3233#include "SymTab/Autogen.h"        // for genImplicitCall, SizeType
    3334#include "SymTab/Mangler.h"        // for Mangler
     
    8990        };
    9091
    91         struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
     92        struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards, public WithIndexer {
    9293                /// hoist dimension from array types in object declaration so that it uses a single
    9394                /// const variable of type size_t, so that side effecting array dimensions are only
     
    104105                void premutate( FunctionType * ) { visit_children = false; }
    105106
     107                // need this so that enumerators are added to the indexer, due to premutate(AggregateDecl *)
     108                void premutate( EnumDecl * ) {}
     109
    106110                void hoist( Type * type );
    107111
     
    135139                                if ( varExpr->var == retVal ) return;
    136140                        }
    137                         stmtsToAddBefore.push_back( genCtorDtor( "?{}", retVal, returnStmt->get_expr() ) );
     141                        Statement * stmt = genCtorDtor( "?{}", retVal, returnStmt->expr );
     142                        assertf( stmt, "ReturnFixer: genCtorDtor returned nullptr: %s / %s", toString( retVal ).c_str(), toString( returnStmt->expr ).c_str() );
     143                        stmtsToAddBefore.push_back( stmt );
    138144
    139145                        // return the retVal object
     
    178184                        if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?
    179185
     186                        // need to resolve array dimensions in order to accurately determine if constexpr
     187                        ResolvExpr::findSingleExpression( arrayType->dimension, SymTab::SizeType->clone(), indexer );
    180188                        // don't need to hoist dimension if it's a constexpr - only need to if there's potential for side effects.
    181189                        if ( isConstExpr( arrayType->get_dimension() ) ) return;
     
    194202        void HoistArrayDimension::premutate( FunctionDecl * ) {
    195203                GuardValue( inFunction );
     204                inFunction = true;
    196205        }
    197206
  • src/InitTweak/InitTweak.cc

    r93cdd5c rf3458a8  
    564564                void previsit( ConstantExpr * ) {}
    565565
     566                void previsit( VariableExpr * varExpr ) {
     567                        visit_children = false;
     568
     569                        if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( varExpr->result ) ) {
     570                                long long int value;
     571                                if ( inst->baseEnum->valueOf( varExpr->var, value ) ) {
     572                                        // enumerators are const expr
     573                                        return;
     574                                }
     575                        }
     576                        isConstExpr = false;
     577                }
     578
    566579                bool isConstExpr = true;
    567580        };
  • src/Parser/DeclarationNode.cc

    r93cdd5c rf3458a8  
    343343        DeclarationNode * newnode = new DeclarationNode;
    344344        newnode->type = new TypeData( kind == OperKinds::PointTo ? TypeData::Pointer : TypeData::Reference );
     345        if ( kind == OperKinds::And ) {
     346                // T && is parsed as 'And' operator rather than two references => add a second reference type
     347                TypeData * td = new TypeData( TypeData::Reference );
     348                td->base = newnode->type;
     349                newnode->type = td;
     350        }
    345351        if ( qualifiers ) {
    346352                return newnode->addQualifiers( qualifiers );
  • src/ResolvExpr/CommonType.cc

    r93cdd5c rf3458a8  
    9191                        // special case where one type has a reference depth of 1 larger than the other
    9292                        if ( diff > 0 || diff < 0 ) {
     93                                // std::cerr << "reference depth diff: " << diff << std::endl;
    9394                                Type * result = nullptr;
    94                                 if ( ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 ) ) {
     95                                ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 );
     96                                ReferenceType * ref2 = dynamic_cast< ReferenceType * >( type2 );
     97                                if ( diff > 0 ) {
     98                                        // deeper on the left
     99                                        assert( ref1 );
     100                                        result = handleReference( ref1->base, type2, widenFirst, widenSecond, indexer, env, openVars );
     101                                } else {
     102                                        // deeper on the right
     103                                        assert( ref2 );
     104                                        result = handleReference( type1, ref2->base, widenFirst, widenSecond, indexer, env, openVars );
     105                                }
     106                                if ( result && ref1 ) {
    95107                                        // formal is reference, so result should be reference
    96                                         result = handleReference( ref1->base, type2, widenFirst, widenSecond, indexer, env, openVars );
    97                                         if ( result ) result = new ReferenceType( ref1->get_qualifiers(), result );
    98                                 } else {
    99                                         // formal is value, so result should be value
    100                                         ReferenceType * ref2 = strict_dynamic_cast< ReferenceType * > ( type2 );
    101                                         result = handleReference( type1, ref2->base, widenFirst, widenSecond, indexer, env, openVars );
     108                                        // std::cerr << "formal is reference; result should be reference" << std::endl;
     109                                        result = new ReferenceType( ref1->get_qualifiers(), result );
    102110                                }
    103111                                // std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl;
     
    180188        }
    181189
    182         void CommonType::visit( __attribute((unused)) VoidType *voidType ) {}
     190        void CommonType::visit( VoidType * ) {}
    183191
    184192        void CommonType::visit( BasicType *basicType ) {
     
    246254        }
    247255
    248         void CommonType::visit( __attribute((unused)) ArrayType *arrayType ) {}
     256        void CommonType::visit( ArrayType * ) {}
    249257
    250258        void CommonType::visit( ReferenceType *refType ) {
     
    283291        }
    284292
    285         void CommonType::visit( __attribute((unused)) FunctionType *functionType ) {}
    286         void CommonType::visit( __attribute((unused)) StructInstType *aggregateUseType ) {}
    287         void CommonType::visit( __attribute((unused)) UnionInstType *aggregateUseType ) {}
     293        void CommonType::visit( FunctionType * ) {}
     294        void CommonType::visit( StructInstType * ) {}
     295        void CommonType::visit( UnionInstType * ) {}
    288296
    289297        void CommonType::visit( EnumInstType *enumInstType ) {
     
    296304        }
    297305
    298         void CommonType::visit( __attribute((unused)) TraitInstType *aggregateUseType ) {
     306        void CommonType::visit( TraitInstType * ) {
    299307        }
    300308
     
    321329        }
    322330
    323         void CommonType::visit( __attribute((unused)) TupleType *tupleType ) {}
    324         void CommonType::visit( __attribute((unused)) VarArgsType *varArgsType ) {}
     331        void CommonType::visit( TupleType * ) {}
     332        void CommonType::visit( VarArgsType * ) {}
    325333
    326334        void CommonType::visit( ZeroType *zeroType ) {
  • src/ResolvExpr/ConversionCost.cc

    r93cdd5c rf3458a8  
    9292
    9393        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    94                 PRINT( std::cerr << "convert to reference cost... diff " << diff << std::endl; )
     94                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    9595                if ( diff > 0 ) {
    9696                        // TODO: document this
     
    108108                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    109109                                PRINT( std::cerr << "converting between references" << std::endl; )
    110                                 if ( srcAsRef->get_base()->get_qualifiers() <= destAsRef->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) {
    111                                         return Cost::safe;
     110                                Type::Qualifiers tq1 = srcAsRef->get_base()->get_qualifiers();
     111                                Type::Qualifiers tq2 = destAsRef->get_base()->get_qualifiers();
     112                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) {
     113                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     114                                        if ( tq1 == tq2 ) {
     115                                                // types are the same
     116                                                return Cost::zero;
     117                                        } else {
     118                                                // types are the same, except otherPointer has more qualifiers
     119                                                return Cost::safe;
     120                                        }
    112121                                } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    113122                                        int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
     
    248257        };
    249258
    250         void ConversionCost::visit( __attribute((unused)) VoidType *voidType ) {
     259        void ConversionCost::visit( VoidType * ) {
    251260                cost = Cost::infinity;
    252261        }
     
    271280        void ConversionCost::visit( PointerType * pointerType ) {
    272281                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    273                         PRINT( std::cerr << pointerType << " ===> " << destAsPtr; )
     282                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
    274283                        Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers();
    275284                        Type::Qualifiers tq2 = destAsPtr->get_base()->get_qualifiers();
    276285                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
     286                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    277287                                if ( tq1 == tq2 ) {
    278288                                        // types are the same
     
    280290                                } else {
    281291                                        // types are the same, except otherPointer has more qualifiers
    282                                         PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    283292                                        cost = Cost::safe;
    284293                                }
    285                         } else {  // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
     294                        } else {
    286295                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
    287296                                PRINT( std::cerr << " :: " << assignResult << std::endl; )
    288                                 if ( assignResult > 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
    289                                         cost = Cost::safe;
     297                                if ( assignResult > 0 && tq1 <= tq2 ) {
     298                                        // xxx - want the case where qualifiers are added to be more expensive than the case where qualifiers are the same. Is 1 safe vs. 2 safe correct?
     299                                        if ( tq1 == tq2 ) {
     300                                                cost = Cost::safe;
     301                                        } else if ( tq1 < tq2 ) {
     302                                                cost = Cost::safe+Cost::safe;
     303                                        }
    290304                                } else if ( assignResult < 0 ) {
    291305                                        cost = Cost::unsafe;
  • src/ResolvExpr/CurrentObject.cc

    r93cdd5c rf3458a8  
    3838
    3939namespace ResolvExpr {
    40         long long int getConstValue( ConstantExpr * constExpr ) {
    41                 if ( BasicType * basicType = dynamic_cast< BasicType * >( constExpr->get_result() ) ) {
    42                         if ( basicType->isInteger() ) {
    43                                 return constExpr->get_constant()->get_ival();
    44                         } else {
    45                                 assertf( false, "Non-integer constant expression in getConstValue %s", toString( constExpr ).c_str() ); // xxx - might be semantic error
    46                         }
    47                 } else if ( dynamic_cast< OneType * >( constExpr->get_result() ) ) {
    48                         return 1;
    49                 } else if ( dynamic_cast< ZeroType * >( constExpr->get_result() ) ) {
    50                         return 0;
    51                 } else {
    52                         assertf( false, "unhandled type on getConstValue %s", toString( constExpr->get_result() ).c_str() ); // xxx - might be semantic error
    53                 }
    54         }
    55 
    5640        template< typename AggrInst >
    5741        TypeSubstitution makeGenericSubstitution( AggrInst * inst ) {
     
    151135                void setSize( Expression * expr ) {
    152136                        if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
    153                                 size = getConstValue( constExpr );
     137                                size = constExpr->intValue();
     138                                isVLA = false;
    154139                                PRINT( std::cerr << "array type with size: " << size << std::endl; )
    155140                        }       else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    156141                                setSize( castExpr->get_arg() ); // xxx - need to perform the conversion specified by the cast
     142                        } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
     143                                if ( EnumInstType * inst = dynamic_cast< EnumInstType * > ( varExpr->result ) ) {
     144                                        long long int value;
     145                                        if ( inst->baseEnum->valueOf( varExpr->var, value ) ) {
     146                                                size = value;
     147                                                isVLA = false;
     148                                        }
     149                                }
    157150                        } else {
    158151                                assertf( false, "unhandled expression in setSize: %s", toString( expr ).c_str() ); // xxx - if not a constant expression, it's not simple to determine how long the array actually is, which is necessary for initialization to be done correctly -- fix this
     
    164157                        // need to permit integer-constant-expressions, including: integer constants, enumeration constants, character constants, sizeof expressions, _Alignof expressions, cast expressions
    165158                        if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
    166                                 index = getConstValue( constExpr );
     159                                index = constExpr->intValue();
    167160                        } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    168161                                setPosition( castExpr->get_arg() );
    169162                        } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
    170                                 assertf( dynamic_cast<EnumInstType *> ( varExpr->get_result() ), "ArrayIterator given variable that isn't an enum constant : %s", toString( expr ).c_str() );
    171                                 index = 0; // xxx - get actual value of enum constant
     163                                EnumInstType * inst = dynamic_cast<EnumInstType *>( varExpr->get_result() );
     164                                assertf( inst, "ArrayIterator given variable that isn't an enum constant : %s", toString( expr ).c_str() );
     165                                long long int value;
     166                                if ( inst->baseEnum->valueOf( varExpr->var, value ) ) {
     167                                        index = value;
     168                                }
    172169                        } else if ( dynamic_cast< SizeofExpr * >( expr ) || dynamic_cast< AlignofExpr * >( expr ) ) {
    173170                                index = 0; // xxx - get actual sizeof/alignof value?
     
    189186                }
    190187
    191                 virtual operator bool() const { return index < size; }
     188                virtual operator bool() const { return ! isVLA && index < size; }
    192189
    193190                virtual MemberIterator & bigStep() {
     
    195192                        ++index;
    196193                        delete memberIter;
    197                         if ( index < size ) memberIter = createMemberIterator( base );
     194                        if ( ! isVLA && index < size ) memberIter = createMemberIterator( base );
    198195                        else memberIter = nullptr;
    199196                        return *this;
     
    242239                size_t index = 0;
    243240                size_t size = 0;
     241                bool isVLA = true;
    244242                MemberIterator * memberIter = nullptr;
    245243        };
  • src/ResolvExpr/FindOpenVars.cc

    r93cdd5c rf3458a8  
    1919#include <map>                    // for map<>::mapped_type
    2020
     21#include "Common/PassVisitor.h"
    2122#include "SynTree/Declaration.h"  // for TypeDecl, DeclarationWithType (ptr ...
    2223#include "SynTree/Type.h"         // for Type, Type::ForallList, ArrayType
    23 #include "SynTree/Visitor.h"      // for Visitor
    2424
    2525namespace ResolvExpr {
    26         class FindOpenVars : public Visitor {
    27           public:
     26        struct FindOpenVars : public WithGuards {
    2827                FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
    2928
    30           private:
    31                 virtual void visit(PointerType *pointerType);
    32                 virtual void visit(ArrayType *arrayType);
    33                 virtual void visit(FunctionType *functionType);
    34                 virtual void visit(TupleType *tupleType);
     29                void previsit( PointerType * pointerType );
     30                void previsit( ArrayType * arrayType );
     31                void previsit( FunctionType * functionType );
     32                void previsit( TupleType * tupleType );
    3533
    3634                void common_action( Type *type );
     
    4240
    4341        void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {
    44                 FindOpenVars finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
     42                PassVisitor<FindOpenVars> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
    4543                type->accept( finder );
    4644        }
     
    7068                        } // for
    7169                } // if
    72 ///   std::cout << "type is ";
    73 ///   type->print( std::cout );
    74 ///   std::cout << std::endl << "need is" << std::endl;
    75 ///   printAssertionSet( needAssertions, std::cout );
    76 ///   std::cout << std::endl << "have is" << std::endl;
    77 ///   printAssertionSet( haveAssertions, std::cout );
     70///   std::cerr << "type is ";
     71///   type->print( std::cerr );
     72///   std::cerr << std::endl << "need is" << std::endl;
     73///   printAssertionSet( needAssertions, std::cerr );
     74///   std::cerr << std::endl << "have is" << std::endl;
     75///   printAssertionSet( haveAssertions, std::cerr );
    7876        }
    7977
    80         void FindOpenVars::visit(PointerType *pointerType) {
     78        void FindOpenVars::previsit(PointerType *pointerType) {
    8179                common_action( pointerType );
    82                 Visitor::visit( pointerType );
    8380        }
    8481
    85         void FindOpenVars::visit(ArrayType *arrayType) {
     82        void FindOpenVars::previsit(ArrayType *arrayType) {
    8683                common_action( arrayType );
    87                 Visitor::visit( arrayType );
    8884        }
    8985
    90         void FindOpenVars::visit(FunctionType *functionType) {
     86        void FindOpenVars::previsit(FunctionType *functionType) {
    9187                common_action( functionType );
    9288                nextIsOpen = ! nextIsOpen;
    93                 Visitor::visit( functionType );
    94                 nextIsOpen = ! nextIsOpen;
     89                GuardAction( [this](){ nextIsOpen = ! nextIsOpen; } );
    9590        }
    9691
    97         void FindOpenVars::visit(TupleType *tupleType) {
     92        void FindOpenVars::previsit(TupleType *tupleType) {
    9893                common_action( tupleType );
    99                 Visitor::visit( tupleType );
    10094        }
    10195} // namespace ResolvExpr
  • src/ResolvExpr/Occurs.cc

    r93cdd5c rf3458a8  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Occurs.cc -- 
     7// Occurs.cc --
    88//
    99// Author           : Richard C. Bilson
     
    1717#include <string>             // for string
    1818
     19#include "Common/PassVisitor.h"
    1920#include "SynTree/Type.h"     // for TypeInstType, Type
    20 #include "SynTree/Visitor.h"  // for Visitor
    2121#include "TypeEnvironment.h"  // for EqvClass, TypeEnvironment
    2222
    2323namespace ResolvExpr {
    24         class Occurs : public Visitor {
    25           public:
     24        struct Occurs : public WithVisitorRef<Occurs> {
    2625                Occurs( std::string varName, const TypeEnvironment &env );
    27                 bool get_result() const { return result; }
    28                 virtual void visit( TypeInstType *typeInst );
    29           private:
     26                void previsit( TypeInstType * typeInst );
     27
    3028                bool result;
    3129                std::set< std::string > eqvVars;
    32                 const TypeEnvironment &env;
     30                const TypeEnvironment &tenv;
    3331        };
    3432
    3533        bool occurs( Type *type, std::string varName, const TypeEnvironment &env ) {
    36                 Occurs occur( varName, env );
     34                PassVisitor<Occurs> occur( varName, env );
    3735                type->accept( occur );
    38                 return occur.get_result();
     36                return occur.pass.result;
    3937        }
    4038
    41         Occurs::Occurs( std::string varName, const TypeEnvironment &env ) : result( false ), env( env ) {
     39        Occurs::Occurs( std::string varName, const TypeEnvironment & env ) : result( false ), tenv( env ) {
    4240                EqvClass eqvClass;
    43                 if ( env.lookup( varName, eqvClass ) ) {
     41                if ( tenv.lookup( varName, eqvClass ) ) {
    4442                        eqvVars = eqvClass.vars;
    4543                } else {
     
    4846        }
    4947
    50         void Occurs::visit( TypeInstType *typeInst ) {
     48        void Occurs::previsit( TypeInstType * typeInst ) {
    5149                EqvClass eqvClass;
    52 ///   std::cout << "searching for vars: ";
    53 ///   std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cout, " " ) );
    54 ///   std::cout << std::endl;
     50///   std::cerr << "searching for vars: ";
     51///   std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cerr, " " ) );
     52///   std::cerr << std::endl;
    5553                if ( eqvVars.find( typeInst->get_name() ) != eqvVars.end() ) {
    5654                        result = true;
    57                 } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     55                } else if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
    5856                        if ( eqvClass.type ) {
    59 ///       std::cout << typeInst->get_name() << " is bound to";
    60 ///       eqvClass.type->print( std::cout );
    61 ///       std::cout << std::endl;
    62                                 eqvClass.type->accept( *this );
     57///       std::cerr << typeInst->get_name() << " is bound to";
     58///       eqvClass.type->print( std::cerr );
     59///       std::cerr << std::endl;
     60                                eqvClass.type->accept( *visitor );
    6361                        } // if
    6462                } // if
  • src/ResolvExpr/PolyCost.cc

    r93cdd5c rf3458a8  
    1414//
    1515
     16#include "Common/PassVisitor.h"
    1617#include "SymTab/Indexer.h"   // for Indexer
    1718#include "SynTree/Type.h"     // for TypeInstType, Type
    18 #include "SynTree/Visitor.h"  // for Visitor
    1919#include "TypeEnvironment.h"  // for EqvClass, TypeEnvironment
    2020
    2121namespace ResolvExpr {
    22         class PolyCost : public Visitor {
    23           public:
     22        struct PolyCost {
    2423                PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer );
    25                 int get_result() const { return result; }
    26           private:
    27                 virtual void visit(TypeInstType *aggregateUseType);
     24
     25                void previsit( TypeInstType * aggregateUseType );
    2826                int result;
    29                 const TypeEnvironment &env;
     27                const TypeEnvironment &tenv;
    3028                const SymTab::Indexer &indexer;
    3129        };
    3230
    3331        int polyCost( Type *type, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {
    34                 PolyCost coster( env, indexer );
     32                PassVisitor<PolyCost> coster( env, indexer );
    3533                type->accept( coster );
    36                 return coster.get_result();
     34                return coster.pass.result;
    3735        }
    3836
    39         PolyCost::PolyCost( const TypeEnvironment & env, const SymTab::Indexer & indexer ) : result( 0 ), env( env ), indexer( indexer ) {
     37        PolyCost::PolyCost( const TypeEnvironment & env, const SymTab::Indexer & indexer ) : result( 0 ), tenv( env ), indexer( indexer ) {
    4038        }
    4139
    42         void PolyCost::visit(TypeInstType * typeInst) {
     40        void PolyCost::previsit(TypeInstType * typeInst) {
    4341                EqvClass eqvClass;
    44                 if ( env.lookup( typeInst->name, eqvClass ) ) {
     42                if ( tenv.lookup( typeInst->name, eqvClass ) ) {
    4543                        if ( eqvClass.type ) {
    4644                                if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
  • src/ResolvExpr/PtrsAssignable.cc

    r93cdd5c rf3458a8  
    6767        PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
    6868
    69         void PtrsAssignable::visit( __attribute((unused)) VoidType *voidType ) {
     69        void PtrsAssignable::visit( VoidType * ) {
    7070                // T * = void * is disallowed - this is a change from C, where any
    7171                // void * can be assigned or passed to a non-void pointer without a cast.
  • src/ResolvExpr/Resolver.h

    r93cdd5c rf3458a8  
    3333        void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer );
    3434        void findSingleExpression( Expression *& untyped, const SymTab::Indexer &indexer );
     35        void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer &indexer );
    3536        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3637        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
  • src/SymTab/Indexer.cc

    r93cdd5c rf3458a8  
    572572        }
    573573
     574        void Indexer::addMembers( AggregateDecl * aggr, Expression * expr ) {
     575                for ( Declaration * decl : aggr->members ) {
     576                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     577                                addId( dwt, expr );
     578                                if ( dwt->name == "" ) {
     579                                        Type * t = dwt->get_type()->stripReferences();
     580                                        if ( dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ) ) {
     581                                                Expression * base = expr->clone();
     582                                                ResolvExpr::referenceToRvalueConversion( base );
     583                                                addMembers( t->getAggr(), new MemberExpr( dwt, base ) );
     584                                        }
     585                                }
     586                        }
     587                }
     588        }
     589
    574590        void Indexer::addWith( WithStmt * stmt ) {
    575591                for ( Expression * expr : stmt->exprs ) {
     
    578594                                assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
    579595
    580                                 for ( Declaration * decl : aggr->members ) {
    581                                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    582                                                 addId( dwt, expr );
    583                                         }
    584                                 }
     596                                addMembers( aggr, expr );
    585597                        }
    586598                }
  • src/SymTab/Indexer.h

    r93cdd5c rf3458a8  
    8686                void addWith( WithStmt * );
    8787
     88                /// adds all of the members of the Aggregate (addWith helper)
     89                void addMembers( AggregateDecl * aggr, Expression * expr );
     90
    8891                /// convenience function for adding a list of Ids to the indexer
    8992                void addIds( const std::list< DeclarationWithType * > & decls );
  • src/SymTab/Validate.cc

    r93cdd5c rf3458a8  
    9494                template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
    9595
    96                 bool inStruct = false;
     96                AggregateDecl * parentAggr = nullptr;
    9797        };
    9898
     
    303303        template< typename AggDecl >
    304304        void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
    305                 if ( inStruct ) {
     305                if ( parentAggr ) {
    306306                        // Add elements in stack order corresponding to nesting structure.
    307307                        declsToAddBefore.push_front( aggregateDecl );
    308308                } else {
    309                         GuardValue( inStruct );
    310                         inStruct = true;
     309                        GuardValue( parentAggr );
     310                        parentAggr = aggregateDecl;
    311311                } // if
    312312                // Always remove the hoisted aggregate from the inner structure.
  • src/SynTree/AggregateDecl.cc

    r93cdd5c rf3458a8  
    8686std::string TraitDecl::typeString() const { return "trait"; }
    8787
     88namespace {
     89        long long int getConstValue( Expression * expr ) {
     90                if ( CastExpr * castExpr = dynamic_cast< CastExpr * > ( expr ) ) {
     91                        return getConstValue( castExpr->arg );
     92                } else if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
     93                        return constExpr->intValue();
     94                } else {
     95                        assertf( false, "Unhandled expression type in getConstValue for enumerators: %s", toString( expr ).c_str() );
     96                }
     97        }
     98}
     99
     100bool EnumDecl::valueOf( Declaration * enumerator, long long int & value ) {
     101        if ( enumValues.empty() ) {
     102                long long int currentValue = 0;
     103                for ( Declaration * member : members ) {
     104                        ObjectDecl * field = strict_dynamic_cast< ObjectDecl * >( member );
     105                        if ( field->init ) {
     106                                SingleInit * init = strict_dynamic_cast< SingleInit * >( field->init );
     107                                currentValue = getConstValue( init->value );
     108                        }
     109                        assertf( enumValues.count( field->name ) == 0, "Enum %s has multiple members with the name %s", name.c_str(), field->name.c_str() );
     110                        enumValues[ field->name ] = currentValue;
     111                        ++currentValue;
     112                }
     113        }
     114        if ( enumValues.count( enumerator->name ) ) {
     115                value = enumValues[ enumerator->name ];
     116                return true;
     117        }
     118        return false;
     119}
     120
    88121// Local Variables: //
    89122// tab-width: 4 //
  • src/SynTree/Declaration.h

    r93cdd5c rf3458a8  
    319319        EnumDecl( const EnumDecl &other ) : Parent( other ) {}
    320320
     321        bool valueOf( Declaration * enumerator, long long int & value );
     322
    321323        virtual EnumDecl *clone() const override { return new EnumDecl( *this ); }
    322324        virtual void accept( Visitor &v ) override { v.visit( this ); }
    323325        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    324326  private:
     327        std::map< std::string, long long int > enumValues;
    325328        virtual std::string typeString() const override;
    326329};
  • src/SynTree/Expression.cc

    r93cdd5c rf3458a8  
    8383}
    8484
     85long long int ConstantExpr::intValue() const {
     86        if ( BasicType * basicType = dynamic_cast< BasicType * >( result ) ) {
     87                if ( basicType->isInteger() ) {
     88                        return get_constant()->get_ival();
     89                }
     90        } else if ( dynamic_cast< OneType * >( result ) ) {
     91                return 1;
     92        } else if ( dynamic_cast< ZeroType * >( result ) ) {
     93                return 0;
     94        }
     95        throw SemanticError( "Constant expression of non-integral type ", this );
     96}
     97
    8598VariableExpr::VariableExpr( DeclarationWithType *_var ) : Expression(), var( _var ) {
    8699        assert( var );
     
    589602        if ( ! body.empty() ) {
    590603                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) {
    591                         set_result( maybeClone( exprStmt->get_expr()->get_result() ) );
     604                        result = maybeClone( exprStmt->expr->result );
    592605                }
    593606        }
    594607        // ensure that StmtExpr has a result type
    595608        if ( ! result ) {
    596                 set_result( new VoidType( Type::Qualifiers() ) );
     609                result = new VoidType( Type::Qualifiers() );
    597610        }
    598611}
  • src/SynTree/Expression.h

    r93cdd5c rf3458a8  
    295295
    296296        Constant * get_constant() { return & constant; }
     297        const Constant * get_constant() const { return & constant; }
    297298        void set_constant( const Constant & newValue ) { constant = newValue; }
     299
     300        long long int intValue() const;
    298301
    299302        virtual ConstantExpr * clone() const { return new ConstantExpr( * this ); }
  • src/Tuples/TupleAssignment.cc

    r93cdd5c rf3458a8  
    272272                // args.push_back( new AddressExpr( new VariableExpr( left ) ) );
    273273                if ( right ) args.push_back( new VariableExpr( right ) );
    274                 return new UntypedExpr( new NameExpr( fname ), args );
     274                if ( left->type->referenceDepth() > 1 && CodeGen::isConstructor( fname ) ) {
     275                        args.front() = new AddressExpr( args.front() );
     276                        if ( right ) args.back() = new AddressExpr( args.back() );
     277                        return new UntypedExpr( new NameExpr( "?=?" ), args );
     278                } else {
     279                        return new UntypedExpr( new NameExpr( fname ), args );
     280                }
    275281        }
    276282
     
    291297                if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
    292298                        ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
    293                         ret->set_init( ctorInit );
     299                        ret->init = ctorInit;
    294300                        ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
    295301                        PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs
  • src/Tuples/TupleExpansion.cc

    r93cdd5c rf3458a8  
    202202                        // generate struct type to replace tuple type based on the number of components in the tuple
    203203                        StructDecl * decl = new StructDecl( toString( "_tuple", tupleSize, "_" ) );
     204                        decl->location = tupleType->location;
    204205                        decl->set_body( true );
    205206                        for ( size_t i = 0; i < tupleSize; ++i ) {
  • src/libcfa/concurrency/monitor.c

    r93cdd5c rf3458a8  
    534534        __lock_size_t actual_count = aggregate( mon_storage, mask );
    535535
    536         __cfaabi_dbg_print_buffer_decl( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max);
     536        __cfaabi_dbg_print_buffer_decl( "Kernel : waitfor %"PRIdFAST16" (s: %"PRIdFAST16", m: %"PRIdFAST16")\n", actual_count, mask.size, (__lock_size_t)max);
    537537
    538538        if(actual_count == 0) return;
     
    575575                                monitor_save;
    576576
    577                                 __cfaabi_dbg_print_buffer_local( "Kernel :  baton of %d monitors : ", count );
     577                                __cfaabi_dbg_print_buffer_local( "Kernel :  baton of %"PRIdFAST16" monitors : ", count );
    578578                                #ifdef __CFA_DEBUG_PRINT__
    579579                                        for( int i = 0; i < count; i++) {
Note: See TracChangeset for help on using the changeset viewer.