Changes in / [06088f9a:fb57626]


Ignore:
Location:
src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • src/CodeTools/TrackLoc.cc

    r06088f9a rfb57626  
    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

    r06088f9a rfb57626  
    382382                        } // if
    383383                        delete stmt;
     384                        if ( TupleAssignExpr * assign = dynamic_cast< TupleAssignExpr * >( resolved ) ) {
     385                                // fix newly generated StmtExpr
     386                                postvisit( assign->stmtExpr );
     387                        }
    384388                        return resolved;
    385389                }
     
    479483                                env->apply( result );
    480484                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    481                                 ret->get_type()->set_const( false );
    482                                 stmtExpr->get_returnDecls().push_front( ret );
     485                                ret->type->set_const( false );
     486                                stmtExpr->returnDecls.push_front( ret );
    483487
    484488                                // must have a non-empty body, otherwise it wouldn't have a result
    485                                 CompoundStmt * body = stmtExpr->get_statements();
     489                                CompoundStmt * body = stmtExpr->statements;
    486490                                assert( ! body->get_kids().empty() );
    487491                                // must be an ExprStmt, otherwise it wouldn't have a result
    488492                                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 ) );
     493                                last->expr = makeCtorDtor( "?{}", ret, last->get_expr() );
     494
     495                                stmtExpr->dtors.push_front( makeCtorDtor( "^?{}", ret ) );
    492496                        } // if
    493497                }
     
    606610                                // must have a non-empty body, otherwise it wouldn't have a result
    607611                                assert( ! stmts.empty() );
    608                                 assert( ! stmtExpr->get_returnDecls().empty() );
     612                                assertf( ! stmtExpr->get_returnDecls().empty(), "StmtExpr returns non-void, but no return decls: %s", toString( stmtExpr ).c_str() );
    609613                                stmts.push_back( new ExprStmt( new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
    610614                                stmtExpr->get_returnDecls().clear();
  • src/Parser/DeclarationNode.cc

    r06088f9a rfb57626  
    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

    r06088f9a rfb57626  
    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;
  • src/ResolvExpr/ConversionCost.cc

    r06088f9a rfb57626  
    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 );
     
    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/SymTab/Indexer.cc

    r06088f9a rfb57626  
    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

    r06088f9a rfb57626  
    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

    r06088f9a rfb57626  
    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/Tuples/TupleAssignment.cc

    r06088f9a rfb57626  
    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

    r06088f9a rfb57626  
    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 ) {
Note: See TracChangeset for help on using the changeset viewer.