Changeset 5b51f5e for src/ResolvExpr


Ignore:
Timestamp:
Jan 5, 2018, 3:21:42 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
65deb18, cae28da
Parents:
5c4f2c2 (diff), b834e98 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/ResolvExpr
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CommonType.cc

    r5c4f2c2 r5b51f5e  
    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

    r5c4f2c2 r5b51f5e  
    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

    r5c4f2c2 r5b51f5e  
    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 ) {
     
    141125                        base = at->get_base();
    142126                        memberIter = createMemberIterator( base );
     127                        if ( at->isVarLen ) throw SemanticError( "VLA initialization does not support @=", at );
    143128                        setSize( at->get_dimension() );
    144129                }
     
    151136                void setSize( Expression * expr ) {
    152137                        if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
    153                                 size = getConstValue( constExpr );
    154                                 PRINT( std::cerr << "array type with size: " << size << std::endl; )
     138                                try {
     139                                        size = constExpr->intValue();
     140                                        PRINT( std::cerr << "array type with size: " << size << std::endl; )
     141                                } catch ( SemanticError & ) {
     142                                        throw SemanticError( "Constant expression of non-integral type in array dimension: ", expr );
     143                                }
    155144                        }       else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    156145                                setSize( castExpr->get_arg() ); // xxx - need to perform the conversion specified by the cast
     146                        } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
     147                                if ( EnumInstType * inst = dynamic_cast< EnumInstType * > ( varExpr->result ) ) {
     148                                        long long int value;
     149                                        if ( inst->baseEnum->valueOf( varExpr->var, value ) ) {
     150                                                size = value;
     151                                        }
     152                                }
    157153                        } else {
    158154                                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
     
    164160                        // need to permit integer-constant-expressions, including: integer constants, enumeration constants, character constants, sizeof expressions, _Alignof expressions, cast expressions
    165161                        if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
    166                                 index = getConstValue( constExpr );
     162                                try {
     163                                        index = constExpr->intValue();
     164                                } catch( SemanticError & ) {
     165                                        throw SemanticError( "Constant expression of non-integral type in array designator: ", expr );
     166                                }
    167167                        } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    168168                                setPosition( castExpr->get_arg() );
    169169                        } 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
     170                                EnumInstType * inst = dynamic_cast<EnumInstType *>( varExpr->get_result() );
     171                                assertf( inst, "ArrayIterator given variable that isn't an enum constant : %s", toString( expr ).c_str() );
     172                                long long int value;
     173                                if ( inst->baseEnum->valueOf( varExpr->var, value ) ) {
     174                                        index = value;
     175                                }
    172176                        } else if ( dynamic_cast< SizeofExpr * >( expr ) || dynamic_cast< AlignofExpr * >( expr ) ) {
    173177                                index = 0; // xxx - get actual sizeof/alignof value?
  • src/ResolvExpr/FindOpenVars.cc

    r5c4f2c2 r5b51f5e  
    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

    r5c4f2c2 r5b51f5e  
    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

    r5c4f2c2 r5b51f5e  
    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

    r5c4f2c2 r5b51f5e  
    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

    r5c4f2c2 r5b51f5e  
    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 );
Note: See TracChangeset for help on using the changeset viewer.