Changeset e6cee92


Ignore:
Timestamp:
Jul 17, 2017, 3:25:58 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
795d450
Parents:
7ebaa56
Message:

Fix TupleAssignment? code for references

Location:
src
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r7ebaa56 re6cee92  
    182182                        genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
    183183                        output << ")" << endl;
     184                        output << indent;
    184185                }
    185186
     
    321322        void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){
    322323                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
    323                 // xxx - generate something reasonable for constructor/destructor pairs
    324                 output << "<ctorinit>";
     324                // pseudo-output for constructor/destructor pairs
     325                output << "<ctorinit>{" << std::endl << ++indent << "ctor: ";
     326                maybeAccept( init->get_ctor(), *this );
     327                output << ", " << std::endl << indent << "dtor: ";
     328                maybeAccept( init->get_dtor(), *this );
     329                output << std::endl << --indent << "}";
    325330        }
    326331
  • src/CodeGen/CodeGenerator.h

    r7ebaa56 re6cee92  
    2020#include <ostream>                // for ostream, operator<<
    2121#include <string>                 // for string
     22
     23#include "Common/Indenter.h"      // for Indenter
    2224
    2325#include "SynTree/Declaration.h"  // for DeclarationWithType (ptr only), Fun...
  • src/Parser/DeclarationNode.cc

    r7ebaa56 re6cee92  
    770770DeclarationNode * DeclarationNode::addNewPointer( DeclarationNode * p ) {
    771771        if ( p ) {
    772                 assert( p->type->kind == TypeData::Pointer );
     772                assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
    773773                if ( type ) {
    774774                        switch ( type->kind ) {
  • src/ResolvExpr/AlternativeFinder.cc

    r7ebaa56 re6cee92  
    815815
    816816        Expression * restructureCast( Expression * argExpr, Type * toType ) {
    817                 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
    818                         // Argument expression is a tuple and the target type is not void. Cast each member of the tuple
    819                         // to its corresponding target type, producing the tuple of those cast expressions. If there are
    820                         // more components of the tuple than components in the target type, then excess components do not
    821                         // come out in the result expression (but UniqueExprs ensure that side effects will still be done).
     817                if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() && ! dynamic_cast<ReferenceType *>( toType ) ) {
     818                        // Argument expression is a tuple and the target type is not void and not a reference type.
     819                        // Cast each member of the tuple to its corresponding target type, producing the tuple of those
     820                        // cast expressions. If there are more components of the tuple than components in the target type,
     821                        // then excess components do not come out in the result expression (but UniqueExprs ensure that
     822                        // side effects will still be done).
    822823                        if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
    823824                                // expressions which may contain side effects require a single unique instance of the expression.
  • src/ResolvExpr/CommonType.cc

    r7ebaa56 re6cee92  
    8181                CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
    8282
    83                 ReferenceType * refType1 = dynamic_cast< ReferenceType * >( type1 );
    84                 ReferenceType * refType2 = dynamic_cast< ReferenceType * >( type2 );
    85                 if ( (refType1 || refType2) && (! refType1 || ! refType2) ) {
    86                         // handle the case where exactly one of the types is a reference type specially
    87                         if ( refType1 ) {
    88                                 return handleReference( refType1, type2, widenFirst, widenSecond, indexer, env, openVars );
    89                         } else if ( refType2 ) {
    90                                 return handleReference( refType2, type1, widenSecond, widenFirst, indexer, env, openVars );
    91                         }
     83                int depth1 = type1->referenceDepth();
     84                int depth2 = type2->referenceDepth();
     85                if ( depth1 > 0 || depth2 > 0 ) {
     86                        int diff = depth1-depth2;
     87                        // TODO: should it be possible for commonType to generate complicated conversions? I would argue no, only conversions that involve types of the same reference level or a difference of 1 should be allowed.
     88                        if ( diff > 1 || diff < -1 ) return nullptr;
     89
     90                        // special case where one type has a reference depth of 1 larger than the other
     91                        if ( diff > 0 ) {
     92                                return handleReference( safe_dynamic_cast<ReferenceType *>( type1 ), type2, widenFirst, widenSecond, indexer, env, openVars );
     93                        } else if ( diff < 0 ) {
     94                                return handleReference( safe_dynamic_cast<ReferenceType *>( type2 ), type1, widenSecond, widenFirst, indexer, env, openVars );
     95                        }
     96                        // otherwise, both are reference types of the same depth and this is handled by the CommonType visitor.
    9297                }
    9398
  • src/ResolvExpr/Unify.cc

    r7ebaa56 re6cee92  
    377377                                } // if
    378378                        } else {
     379                                common = type1->clone();
     380                                common->get_qualifiers() = tq1 | tq2;
    379381                                result = true;
    380382                        } // if
  • src/SynTree/Expression.cc

    r7ebaa56 re6cee92  
    502502}
    503503
    504 AsmExpr::AsmExpr( const AsmExpr & other ) : inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
     504AsmExpr::AsmExpr( const AsmExpr & other ) : Expression( other ), inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
    505505
    506506
  • src/SynTree/ReferenceType.cc

    r7ebaa56 re6cee92  
    1919
    2020ReferenceType::ReferenceType( const Type::Qualifiers &tq, Type *base, const std::list< Attribute * > & attributes )
    21   : Type( tq, attributes ), base( base ) {
     21        : Type( tq, attributes ), base( base ) {
     22        assertf( base, "Reference Type with a null base created." );
    2223}
    2324
    2425ReferenceType::ReferenceType( const ReferenceType &other )
    25   : Type( other ), base( maybeClone( other.base ) ) {
     26        : Type( other ), base( maybeClone( other.base ) ) {
    2627}
    2728
    2829ReferenceType::~ReferenceType() {
    29   delete base;
     30        delete base;
     31}
     32
     33int ReferenceType::referenceDepth() const {
     34        return base->referenceDepth()+1;
    3035}
    3136
    3237void ReferenceType::print( std::ostream &os, int indent ) const {
    33   Type::print( os, indent );
    34   os << "reference to ";
    35   if ( base ) {
    36     base->print( os, indent );
    37   } // if
     38        Type::print( os, indent );
     39        os << "reference to ";
     40        if ( base ) {
     41                base->print( os, indent );
     42        } // if
    3843}
    3944
  • src/SynTree/Type.cc

    r7ebaa56 re6cee92  
    8181}
    8282
     83int Type::referenceDepth() const { return 0; }
     84
    8385void Type::print( std::ostream &os, int indent ) const {
    8486        if ( ! forall.empty() ) {
  • src/SynTree/Type.h

    r7ebaa56 re6cee92  
    163163        Type * stripReferences();
    164164
     165        /// return the number of references occuring consecutively on the outermost layer of this type (i.e. do not count references nested within other types)
     166        virtual int referenceDepth() const;
     167
    165168        virtual bool isComplete() const { return true; }
    166169
     
    304307        void set_base( Type *newValue ) { base = newValue; }
    305308
     309        virtual int referenceDepth() const;
     310
    306311        virtual ReferenceType *clone() const { return new ReferenceType( *this ); }
    307312        virtual void accept( Visitor & v ) { v.visit( this ); }
  • src/SynTree/TypeExpr.cc

    r7ebaa56 re6cee92  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeExpr.cc -- 
     7// TypeExpr.cc --
    88//
    99// Author           : Richard C. Bilson
     
    2121}
    2222
    23 TypeExpr::TypeExpr( const TypeExpr &other ) : type( maybeClone( other.type ) ) {
     23TypeExpr::TypeExpr( const TypeExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {
    2424}
    2525
  • src/Tuples/Explode.h

    r7ebaa56 re6cee92  
    2727
    2828namespace Tuples {
    29         /// helper function used by explode to properly distribute
    30         /// '&' across a tuple expression
    31         Expression * distributeAddr( Expression * expr );
    32 
    3329        /// helper function used by explode
    3430        template< typename OutputIterator >
    3531        void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
    36                 if ( isTupleAssign ) {
    37                         // tuple assignment needs AddressExprs to be recursively exploded to easily get at all of the components
    38                         if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
    39                                 ResolvExpr::AltList alts;
    40                                 explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
    41                                 for ( ResolvExpr::Alternative & alt : alts ) {
    42                                         // distribute '&' over all components
    43                                         alt.expr = distributeAddr( alt.expr );
    44                                         *out++ = alt;
    45                                 }
    46                                 // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
    47                                 return;
    48                         }
    49                 }
    5032                Type * res = expr->get_result();
    5133                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
  • src/Tuples/TupleAssignment.cc

    r7ebaa56 re6cee92  
    7777                if ( ! expr ) return false;
    7878                assert( expr->has_result() );
    79                 return dynamic_cast< TupleType * >( expr->get_result() );
     79                return dynamic_cast< TupleType * >( expr->get_result()->stripReferences() );
    8080        }
    8181
     
    8989        }
    9090
    91         bool pointsToTuple( Expression *expr ) {
     91        bool refToTuple( Expression *expr ) {
     92                assert( expr->get_result() );
    9293                // also check for function returning tuple of reference types
    9394                if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    94                         return pointsToTuple( castExpr->get_arg() );
    95                 } else if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) {
    96                         return isTuple( addr->get_arg() );
     95                        return refToTuple( castExpr->get_arg() );
     96                } else {
     97                        return isTuple( expr );
    9798                }
    9899                return false;
     
    122123                                        const ResolvExpr::Alternative & alt1 = ali->front();
    123124                                        auto begin = std::next(ali->begin(), 1), end = ali->end();
    124                                         if ( pointsToTuple(alt1.expr) ) {
     125                                        if ( refToTuple(alt1.expr) ) {
    125126                                                if ( isMultAssign( begin, end ) ) {
    126127                                                        matcher.reset( new MultipleAssignMatcher( *this, *ali ) );
     
    196197                        for ( ResolvExpr::Alternative & alt : lhs ) {
    197198                                Expression *& expr = alt.expr;
    198                                 Type * castType = expr->get_result()->clone();
    199                                 Type * type = InitTweak::getPointerBase( castType );
    200                                 assert( type );
     199                                Type * type = expr->get_result()->clone();
    201200                                type->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    202                                 type->set_lvalue( true ); // xxx - might not need this
    203                                 expr = new CastExpr( expr, castType );
     201                                expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), type ) );
    204202                        }
    205203                }
     
    221219                assert( left );
    222220                std::list< Expression * > args;
    223                 args.push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( left ) ) ) );
     221                args.push_back( new VariableExpr( left ) );
    224222                // args.push_back( new AddressExpr( new VariableExpr( left ) ) );
    225223                if ( right ) args.push_back( new VariableExpr( right ) );
     
    241239                assert( expr->has_result() && ! expr->get_result()->isVoid() );
    242240                ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
    243                 ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
    244                 ret->set_init( ctorInit );
    245                 ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
    246                 EnvRemover rm; // remove environments from subexpressions of StmtExprs
    247                 ctorInit->accept( rm );
     241                // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient.
     242                if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
     243                        ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
     244                        ret->set_init( ctorInit );
     245                        ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
     246                        EnvRemover rm; // remove environments from subexpressions of StmtExprs
     247                        ctorInit->accept( rm );
     248                }
    248249                return ret;
    249250        }
Note: See TracChangeset for help on using the changeset viewer.