Changeset c653b37 for src


Ignore:
Timestamp:
Jun 28, 2018, 4:04:11 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
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, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
Children:
e3b2474
Parents:
a12c81f3 (diff), 944ce47 (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:/u/cforall/software/cfa/cfa-cc

Location:
src
Files:
2 added
24 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/TypedefTable.cc

    ra12c81f3 rc653b37  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  7 13:17:56 2018
    13 // Update Count     : 192
     12// Last Modified On : Fri Jun 22 06:14:39 2018
     13// Update Count     : 206
    1414//
    1515
     
    7878        debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
    7979        auto ret = kindTable.insertAt( scope, identifier, kind );
    80         if ( ! ret.second ) ret.first->second = kind;           // exists => update
     80        //if ( ! ret.second ) ret.first->second = kind;         // exists => update
     81        assert( ret.first->second == kind );                            // exists
    8182} // TypedefTable::addToScope
    8283
    8384void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
    84         assert( kindTable.currentScope() >= 1 );
    85         auto scope = kindTable.currentScope() - 1;
    86         debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
     85        assert( kindTable.currentScope() >= 1 + level );
     86        auto scope = kindTable.currentScope() - 1 - level;
     87        debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << endl );
    8788        auto ret = kindTable.insertAt( scope, identifier, kind );
    8889        if ( ! ret.second ) ret.first->second = kind;           // exists => update
     
    9192void TypedefTable::enterScope() {
    9293        kindTable.beginScope();
    93         debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl );
    94         debugPrint( print() );
     94        debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl; print() );
    9595} // TypedefTable::enterScope
    9696
    9797void TypedefTable::leaveScope() {
    98         debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl );
    99         debugPrint( print() );
     98        debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl; print() );
    10099        kindTable.endScope();
    101100} // TypedefTable::leaveScope
     
    114113                --scope;
    115114                debugPrint( cerr << endl << "[" << scope << "]" );
    116         }
     115        } // while
    117116        debugPrint( cerr << endl );
    118 }
     117} // TypedefTable::print
    119118
    120119// Local Variables: //
  • src/Parser/TypedefTable.h

    ra12c81f3 rc653b37  
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  7 12:10:17 2018
    13 // Update Count     : 85
     12// Last Modified On : Fri Jun 22 05:29:58 2018
     13// Update Count     : 86
    1414//
    1515
     
    2525        typedef ScopedMap< std::string, int > KindTable;
    2626        KindTable kindTable;   
     27        unsigned int level = 0;
    2728  public:
    2829        ~TypedefTable();
     
    3738        void leaveScope();
    3839
     40        void up() { level += 1; }
     41        void down() { level -= 1; }
     42
    3943        void print( void ) const;
    4044}; // TypedefTable
  • src/Parser/lex.ll

    ra12c81f3 rc653b37  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Jun  7 08:27:40 2018
    13  * Update Count     : 679
     12 * Last Modified On : Wed Jun 20 09:08:28 2018
     13 * Update Count     : 682
    1414 */
    1515
     
    2525//**************************** Includes and Defines ****************************
    2626
     27// trigger before each matching rule's action
     28#define YY_USER_ACTION \
     29        yylloc.first_line = yylineno; \
     30        yylloc.first_column = column; \
     31        column += yyleng; \
     32        yylloc.last_column = column; \
     33        yylloc.last_line = yylineno; \
     34        yylloc.filename = yyfilename ? yyfilename : "";
    2735unsigned int column = 0;                                                                // position of the end of the last token parsed
    28 #define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : "";                          // trigger before each matching rule's action
    2936
    3037#include <string>
     
    4956#define NUMERIC_RETURN(x)       rm_underscore(); RETURN_VAL( x ) // numeric constant
    5057#define KEYWORD_RETURN(x)       RETURN_CHAR( x )                        // keyword
    51 #define QKEYWORD_RETURN(x)      typedefTable.isKind( yytext ); RETURN_VAL(x); // quasi-keyword
     58#define QKEYWORD_RETURN(x)      RETURN_VAL(x);                          // quasi-keyword
    5259#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    5360#define ATTRIBUTE_RETURN()      RETURN_VAL( ATTR_IDENTIFIER )
  • src/Parser/parser.yy

    ra12c81f3 rc653b37  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  7 10:07:12 2018
    13 // Update Count     : 3527
     12// Last Modified On : Sun Jun 24 10:41:10 2018
     13// Update Count     : 3587
    1414//
    1515
     
    136136} // build_postfix_name
    137137
    138 bool forall = false, xxx = false;                                               // aggregate have one or more forall qualifiers ?
     138bool forall = false, xxx = false, yyy = false;                  // aggregate have one or more forall qualifiers ?
    139139
    140140// https://www.gnu.org/software/bison/manual/bison.html#Location-Type
     
    304304%type<en> enumerator_value_opt
    305305
    306 %type<decl> exception_declaration external_definition external_definition_list external_definition_list_no_pop_push external_definition_list_opt
     306%type<decl> external_definition external_definition_list external_definition_list_opt
     307
     308%type<decl> exception_declaration
    307309
    308310%type<decl> field_declaration field_declaration_list_opt field_declarator_opt field_declaring_list
     
    503505                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); }
    504506        | type_name '.' no_attr_identifier                                      // CFA, nested type
    505                 // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    506                 { $$ = nullptr; }
     507                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    507508        | type_name '.' '[' field_list ']'                                      // CFA, nested type / tuple field selector
    508                 // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    509                 { $$ = nullptr; }
     509                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    510510        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    511511                {
     
    18211821        ;
    18221822
     1823fred:
     1824        // empty
     1825                { yyy = false; }
     1826        ;
     1827
    18231828aggregate_type:                                                                                 // struct, union
    18241829        aggregate_key attribute_list_opt '{' field_declaration_list_opt '}'
    18251830                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
    1826         | aggregate_key attribute_list_opt no_attr_identifier
     1831        | aggregate_key attribute_list_opt no_attr_identifier fred
    18271832                {
    18281833                        typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); // create typedef
    1829                         //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update
    18301834                        forall = false;                                                         // reset
    18311835                }
    18321836          '{' field_declaration_list_opt '}'
    1833                 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); }
    1834         | aggregate_key attribute_list_opt type_name
     1837                { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $7, true )->addQualifiers( $2 ); }
     1838        | aggregate_key attribute_list_opt type_name fred
    18351839                {
    18361840                        typedefTable.makeTypedef( *$3->type->symbolic.name, forall ? TYPEGENname : TYPEDEFname ); // create typedef
    1837                         //if ( forall ) typedefTable.changeKind( *$3->type->symbolic.name, TYPEGENname ); // possibly update
    18381841                        forall = false;                                                         // reset
    18391842                }
    18401843          '{' field_declaration_list_opt '}'
    1841                 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $6, true )->addQualifiers( $2 ); }
     1844                { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $7, true )->addQualifiers( $2 ); }
    18421845        | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA
    18431846                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
     
    18461849
    18471850aggregate_type_nobody:                                                                  // struct, union - {...}
    1848         aggregate_key attribute_list_opt no_attr_identifier
     1851        aggregate_key attribute_list_opt no_attr_identifier fred
    18491852                {
    18501853                        typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname );
    1851                         //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update
    18521854                        forall = false;                                                         // reset
    18531855                        $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 );
    18541856                }
    1855         | aggregate_key attribute_list_opt type_name
     1857        | aggregate_key attribute_list_opt type_name fred
    18561858                {
    18571859                        // Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is
     
    18671869aggregate_key:
    18681870        STRUCT
    1869                 { $$ = DeclarationNode::Struct; }
     1871                { yyy = true; $$ = DeclarationNode::Struct; }
    18701872        | UNION
    1871                 { $$ = DeclarationNode::Union; }
     1873                { yyy = true; $$ = DeclarationNode::Union; }
    18721874        | EXCEPTION
    1873                 { $$ = DeclarationNode::Exception; }
     1875                { yyy = true; $$ = DeclarationNode::Exception; }
    18741876        | COROUTINE
    1875                 { $$ = DeclarationNode::Coroutine; }
     1877                { yyy = true; $$ = DeclarationNode::Coroutine; }
    18761878        | MONITOR
    1877                 { $$ = DeclarationNode::Monitor; }
     1879                { yyy = true; $$ = DeclarationNode::Monitor; }
    18781880        | THREAD
    1879                 { $$ = DeclarationNode::Thread; }
     1881                { yyy = true; $$ = DeclarationNode::Thread; }
    18801882        ;
    18811883
     
    23202322
    23212323translation_unit:
    2322         // empty
    2323                 {}                                                                                              // empty input file
     2324        // empty, input file
    23242325        | external_definition_list
    23252326                { parseTree = parseTree ? parseTree->appendList( $1 ) : $1;     }
     
    23352336        ;
    23362337
    2337         // SKULLDUGGERY: Declarations in extern "X" and distribution need to be added to the current lexical scope.
    2338         // However, external_definition_list creates a new scope around each external_definition, but the pop loses all the
    2339         // types in the extern "X" and distribution at the end of the block. This version of external_definition_list does
    2340 
    2341         // not do push/pop for declarations at the level of the extern "X" and distribution block. Any recursive uses of
    2342         // external_definition_list within the extern "X" and distribution block correctly pushes/pops for that scope level.
    2343 external_definition_list_no_pop_push:
    2344         external_definition
    2345         | external_definition_list_no_pop_push
    2346                 { forall = xxx; }
    2347           external_definition
    2348                 { $$ = $1 ? $1->appendList( $3 ) : $3; }
    2349         ;
    2350 
    23512338external_definition_list_opt:
    23522339        // empty
    23532340                { $$ = nullptr; }
    2354         | external_definition_list_no_pop_push
     2341        | external_definition_list
     2342        ;
     2343
     2344up:
     2345                { typedefTable.up(); }
     2346        ;
     2347
     2348down:
     2349                { typedefTable.down(); }
    23552350        ;
    23562351
     
    23722367                        linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 );
    23732368                }
    2374           '{' external_definition_list_opt '}'
     2369          '{' up external_definition_list_opt down '}'
    23752370                {
    23762371                        linkage = linkageStack.top();
    23772372                        linkageStack.pop();
    2378                         $$ = $5;
     2373                        $$ = $6;
    23792374                }
    23802375        | type_qualifier_list
    2381                 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
    2382           '{' external_definition_list_opt '}'                          // CFA, namespace
    2383                 {
    2384                         for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2376                {
     2377                        if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2378                        if ( $1->type->forall ) xxx = forall = true; // remember generic type
     2379                }
     2380          '{' up external_definition_list_opt down '}'          // CFA, namespace
     2381                {
     2382                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    23852383                                if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    23862384                                        iter->addQualifiers( $1->clone() );
     
    23892387                        xxx = false;
    23902388                        delete $1;
    2391                         $$ = $4;
     2389                        $$ = $5;
    23922390                }
    23932391        | declaration_qualifier_list
    2394                 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
    2395           '{' external_definition_list_opt '}'                          // CFA, namespace
    2396                 {
    2397                         for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2392                {
     2393                        if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2394                        if ( $1->type->forall ) xxx = forall = true; // remember generic type
     2395                }
     2396          '{' up external_definition_list_opt down '}'          // CFA, namespace
     2397                {
     2398                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    23982399                                if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    23992400                                        iter->addQualifiers( $1->clone() );
     
    24022403                        xxx = false;
    24032404                        delete $1;
    2404                         $$ = $4;
     2405                        $$ = $5;
    24052406                }
    24062407        | declaration_qualifier_list type_qualifier_list
    24072408                {
    2408                         // forall must be in the type_qualifier_list
    2409                         if ( $2->type->forall ) xxx = forall = true; // remember generic type
    2410                 }
    2411           '{' external_definition_list_opt '}'                          // CFA, namespace
    2412                 {
    2413                         for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2409                        if ( ($1->type && $1->type->qualifiers.val) || $2->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2410                        if ( ($1->type && $1->type->forall) || $2->type->forall ) xxx = forall = true; // remember generic type
     2411                }
     2412          '{' up external_definition_list_opt down '}'          // CFA, namespace
     2413                {
     2414                        for ( DeclarationNode * iter = $6; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    24142415                                if ( isMangled( iter->linkage ) && isMangled( $2->linkage ) ) { // ignore extern "C"
    24152416                                        iter->addQualifiers( $1->clone() );
     
    24202421                        delete $1;
    24212422                        delete $2;
    2422                         $$ = $5;
     2423                        $$ = $6;
    24232424                }
    24242425        ;
  • src/ResolvExpr/AlternativeFinder.cc

    ra12c81f3 rc653b37  
    10991099                        argExpansions.emplace_back();
    11001100                        auto& argE = argExpansions.back();
    1101                         argE.reserve( arg.alternatives.size() );
     1101                        // argE.reserve( arg.alternatives.size() );
    11021102
    11031103                        for ( const Alternative& actual : arg ) {
  • src/ResolvExpr/CommonType.cc

    ra12c81f3 rc653b37  
    2424#include "SynTree/Type.h"                // for BasicType, BasicType::Kind::...
    2525#include "SynTree/Visitor.h"             // for Visitor
    26 #include "Unify.h"                       // for unifyExact, bindVar, WidenMode
     26#include "Unify.h"                       // for unifyExact, WidenMode
    2727#include "typeops.h"                     // for isFtype
    2828
     
    238238                                AssertionSet need, have;
    239239                                WidenMode widen( widenFirst, widenSecond );
    240                                 if ( entry != openVars.end() && ! bindVar(var, voidPointer->get_base(), entry->second, env, need, have, openVars, widen, indexer ) ) return;
     240                                if ( entry != openVars.end() && ! env.bindVar(var, voidPointer->get_base(), entry->second, need, have, openVars, widen, indexer ) ) return;
    241241                        }
    242242                }
  • src/ResolvExpr/ExplodedActual.h

    ra12c81f3 rc653b37  
    3232
    3333                ExplodedActual() : env(), cost(Cost::zero), exprs() {}
    34 
    3534                ExplodedActual( const Alternative& actual, const SymTab::Indexer& indexer );
     35                ExplodedActual(ExplodedActual&&) = default;
     36                ExplodedActual& operator= (ExplodedActual&&) = default;
    3637        };
    3738}
  • src/ResolvExpr/Resolver.cc

    ra12c81f3 rc653b37  
    582582
    583583                                                        // Make sure we don't widen any existing bindings
    584                                                         for ( auto & i : resultEnv ) {
    585                                                                 i.allowWidening = false;
    586                                                         }
    587 
     584                                                        resultEnv.forbidWidening();
     585                                                       
    588586                                                        // Find any unbound type variables
    589587                                                        resultEnv.extractOpenVars( openVars );
  • src/ResolvExpr/TypeEnvironment.cc

    ra12c81f3 rc653b37  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:19:47 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 12:23:36 2015
    13 // Update Count     : 3
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    1717#include <algorithm>                   // for copy, set_intersection
    1818#include <iterator>                    // for ostream_iterator, insert_iterator
     19#include <memory>                      // for unique_ptr
    1920#include <utility>                     // for pair, move
    2021
     
    2223#include "SynTree/Type.h"              // for Type, FunctionType, Type::Fora...
    2324#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
     25#include "Tuples/Tuples.h"             // for isTtype
    2426#include "TypeEnvironment.h"
     27#include "typeops.h"                   // for occurs
     28#include "Unify.h"                     // for unifyInexact
    2529
    2630namespace ResolvExpr {
     
    6569        }
    6670
     71        EqvClass::EqvClass( EqvClass &&other )
     72        : vars{std::move(other.vars)}, type{other.type},
     73          allowWidening{std::move(other.allowWidening)}, data{std::move(other.data)} {
     74                  other.type = nullptr;
     75        }
     76
    6777        EqvClass &EqvClass::operator=( const EqvClass &other ) {
    6878                if ( this == &other ) return *this;
     
    7282        }
    7383
     84        EqvClass &EqvClass::operator=( EqvClass &&other ) {
     85                if ( this == &other ) return *this;
     86                delete type;
     87               
     88                vars = std::move(other.vars);
     89                type = other.type;
     90                other.type = nullptr;
     91                allowWidening = std::move(other.allowWidening);
     92                data = std::move(other.data);
     93
     94                return *this;
     95        }
     96
    7497        EqvClass::~EqvClass() {
    7598                delete type;
     99        }
     100
     101        void EqvClass::set_type( Type* ty ) {
     102                if ( ty == type ) return;
     103                delete type;
     104                type = ty;
    76105        }
    77106
     
    92121        const EqvClass* TypeEnvironment::lookup( const std::string &var ) const {
    93122                for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
    94                         if ( i->vars.find( var ) != i->vars.end() ) {
    95 ///       std::cout << var << " is in class ";
    96 ///       i->print( std::cout );
    97                                 return &*i;
    98                         }
    99 ///     std::cout << var << " is not in class ";
    100 ///     i->print( std::cout );
     123                        if ( i->vars.find( var ) != i->vars.end() ) return &*i;
    101124                } // for
    102125                return nullptr;
     
    116139        }
    117140
    118         void TypeEnvironment::add( const EqvClass &eqvClass ) {
    119                 filterOverlappingClasses( env, eqvClass );
    120                 env.push_back( eqvClass );
    121         }
    122 
    123141        void TypeEnvironment::add( EqvClass &&eqvClass ) {
    124142                filterOverlappingClasses( env, eqvClass );
     
    131149                        newClass.vars.insert( (*i)->get_name() );
    132150                        newClass.data = TypeDecl::Data{ (*i) };
    133                         env.push_back( newClass );
     151                        env.push_back( std::move(newClass) );
    134152                } // for
    135153        }
     
    145163                        // transition to TypeSubstitution
    146164                        newClass.data = TypeDecl::Data{ TypeDecl::Dtype, false };
    147                         add( newClass );
     165                        add( std::move(newClass) );
    148166                }
    149167        }
     
    152170                for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    153171                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    154 ///       std::cerr << "adding " << *theVar;
    155172                                if ( theClass->type ) {
    156 ///         std::cerr << " bound to ";
    157 ///         theClass->type->print( std::cerr );
    158 ///         std::cerr << std::endl;
    159173                                        sub.add( *theVar, theClass->type );
    160174                                } else if ( theVar != theClass->vars.begin() ) {
    161175                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    162 ///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
    163176                                        sub.add( *theVar, newTypeInst );
    164177                                        delete newTypeInst;
     
    166179                        } // for
    167180                } // for
    168 ///   std::cerr << "input env is:" << std::endl;
    169 ///   print( std::cerr, 8 );
    170 ///   std::cerr << "sub is:" << std::endl;
    171 ///   sub.print( std::cerr, 8 );
    172181                sub.normalize();
    173182        }
     
    181190        std::list< EqvClass >::iterator TypeEnvironment::internal_lookup( const std::string &var ) {
    182191                for ( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) {
    183                         if ( i->vars.find( var ) == i->vars.end() ) {
    184                                 return i;
    185                         } // if
     192                        if ( i->vars.count( var ) ) return i;
    186193                } // for
    187194                return env.end();
     
    190197        void TypeEnvironment::simpleCombine( const TypeEnvironment &second ) {
    191198                env.insert( env.end(), second.env.begin(), second.env.end() );
    192         }
    193 
    194         void TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ) {
    195                 TypeEnvironment secondCopy( second );
    196                 for ( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) {
    197                         EqvClass &newClass = *firstClass;
    198                         std::set< std::string > newVars;
    199                         for ( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) {
    200                                 std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var );
    201                                 if ( secondClass != secondCopy.env.end() ) {
    202                                         newVars.insert( secondClass->vars.begin(), secondClass->vars.end() );
    203                                         if ( secondClass->type ) {
    204                                                 if ( newClass.type ) {
    205                                                         Type *newType = combineFunc( newClass.type, secondClass->type );
    206                                                         delete newClass.type;
    207                                                         newClass.type = newType;
    208                                                         newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening;
    209                                                 } else {
    210                                                         newClass.type = secondClass->type->clone();
    211                                                         newClass.allowWidening = secondClass->allowWidening;
    212                                                 } // if
    213                                         } // if
    214                                         secondCopy.env.erase( secondClass );
    215                                 } // if
    216                         } // for
    217                         newClass.vars.insert( newVars.begin(), newVars.end() );
    218                 } // for
    219                 for ( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) {
    220                         env.push_back( *secondClass );
    221                 } // for
    222199        }
    223200
     
    241218        }
    242219
     220        bool isFtype( Type *type ) {
     221                if ( dynamic_cast< FunctionType* >( type ) ) {
     222                        return true;
     223                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
     224                        return typeInst->get_isFtype();
     225                } // if
     226                return false;
     227        }
     228
     229        bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
     230                switch ( data.kind ) {
     231                  case TypeDecl::Dtype:
     232                        // to bind to an object type variable, the type must not be a function type.
     233                        // if the type variable is specified to be a complete type then the incoming
     234                        // type must also be complete
     235                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
     236                        return ! isFtype( type ) && (! data.isComplete || type->isComplete() );
     237                  case TypeDecl::Ftype:
     238                        return isFtype( type );
     239                  case TypeDecl::Ttype:
     240                        // ttype unifies with any tuple type
     241                        return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
     242                } // switch
     243                return false;
     244        }
     245
     246        bool TypeEnvironment::bindVar( TypeInstType *typeInst, Type *bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     247               
     248                // remove references from other, so that type variables can only bind to value types
     249                bindTo = bindTo->stripReferences();
     250                OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
     251                assert( tyvar != openVars.end() );
     252                if ( ! tyVarCompatible( tyvar->second, bindTo ) ) {
     253                        return false;
     254                } // if
     255                if ( occurs( bindTo, typeInst->get_name(), *this ) ) {
     256                        return false;
     257                } // if
     258                auto curClass = internal_lookup( typeInst->get_name() );
     259                if ( curClass != env.end() ) {
     260                        if ( curClass->type ) {
     261                                Type *common = 0;
     262                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
     263                                std::unique_ptr< Type > newType( curClass->type->clone() );
     264                                newType->get_qualifiers() = typeInst->get_qualifiers();
     265                                if ( unifyInexact( newType.get(), bindTo, *this, need, have, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
     266                                        if ( common ) {
     267                                                common->get_qualifiers() = Type::Qualifiers{};
     268                                                curClass->set_type( common );
     269                                        } // if
     270                                } else return false;
     271                        } else {
     272                                Type* newType = bindTo->clone();
     273                                newType->get_qualifiers() = Type::Qualifiers{};
     274                                curClass->set_type( newType );
     275                                curClass->allowWidening = widenMode.widenFirst && widenMode.widenSecond;
     276                        } // if
     277                } else {
     278                        EqvClass newClass;
     279                        newClass.vars.insert( typeInst->get_name() );
     280                        newClass.type = bindTo->clone();
     281                        newClass.type->get_qualifiers() = Type::Qualifiers();
     282                        newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
     283                        newClass.data = data;
     284                        env.push_back( std::move(newClass) );
     285                } // if
     286                return true;
     287        }
     288
     289        bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     290
     291                auto class1 = internal_lookup( var1->get_name() );
     292                auto class2 = internal_lookup( var2->get_name() );
     293               
     294                // exit early if variables already bound together
     295                if ( class1 != env.end() && class1 == class2 ) {
     296                        class1->allowWidening &= widenMode;
     297                        return true;
     298                }
     299
     300                bool widen1 = false, widen2 = false;
     301                const Type *type1 = nullptr, *type2 = nullptr;
     302
     303                // check for existing bindings, perform occurs check
     304                if ( class1 != env.end() ) {
     305                        if ( class1->type ) {
     306                                if ( occurs( class1->type, var2->get_name(), *this ) ) return false;
     307                                type1 = class1->type;
     308                        } // if
     309                        widen1 = widenMode.widenFirst && class1->allowWidening;
     310                } // if
     311                if ( class2 != env.end() ) {
     312                        if ( class2->type ) {
     313                                if ( occurs( class2->type, var1->get_name(), *this ) ) return false;
     314                                type2 = class2->type;
     315                        } // if
     316                        widen2 = widenMode.widenSecond && class2->allowWidening;
     317                } // if
     318
     319                if ( type1 && type2 ) {
     320                        // both classes bound, merge if bound types can be unified
     321                        std::unique_ptr<Type> newType1{ type1->clone() }, newType2{ type2->clone() };
     322                        WidenMode newWidenMode{ widen1, widen2 };
     323                        Type *common = 0;
     324                        if ( unifyInexact( newType1.get(), newType2.get(), *this, need, have, openVars, newWidenMode, indexer, common ) ) {
     325                                class1->vars.insert( class2->vars.begin(), class2->vars.end() );
     326                                class1->allowWidening = widen1 && widen2;
     327                                if ( common ) {
     328                                        common->get_qualifiers() = Type::Qualifiers{};
     329                                        class1->set_type( common );
     330                                }
     331                                env.erase( class2 );
     332                        } else return false;
     333                } else if ( class1 != env.end() && class2 != env.end() ) {
     334                        // both classes exist, at least one unbound, merge unconditionally
     335                        if ( type1 ) {
     336                                class1->vars.insert( class2->vars.begin(), class2->vars.end() );
     337                                class1->allowWidening = widen1;
     338                                env.erase( class2 );
     339                        } else {
     340                                class2->vars.insert( class1->vars.begin(), class1->vars.end() );
     341                                class2->allowWidening = widen2;
     342                                env.erase( class1 );
     343                        } // if
     344                } else if ( class1 != env.end() ) {
     345                        // var2 unbound, add to class1
     346                        class1->vars.insert( var2->get_name() );
     347                        class1->allowWidening = widen1;
     348                } else if ( class2 != env.end() ) {
     349                        // var1 unbound, add to class2
     350                        class2->vars.insert( var1->get_name() );
     351                        class2->allowWidening = widen2;
     352                } else {
     353                        // neither var bound, create new class
     354                        EqvClass newClass;
     355                        newClass.vars.insert( var1->get_name() );
     356                        newClass.vars.insert( var2->get_name() );
     357                        newClass.allowWidening = widen1 && widen2;
     358                        newClass.data = data;
     359                        env.push_back( std::move(newClass) );
     360                } // if
     361                return true;
     362        }
     363
     364        void TypeEnvironment::forbidWidening() {
     365                for ( EqvClass& c : env ) c.allowWidening = false;
     366        }
     367
    243368        std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ) {
    244369                env.print( out );
  • src/ResolvExpr/TypeEnvironment.h

    ra12c81f3 rc653b37  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:24:58 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:35:45 2017
    13 // Update Count     : 3
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    2121#include <set>                         // for set
    2222#include <string>                      // for string
     23#include <utility>                     // for move, swap
     24
     25#include "WidenMode.h"                 // for WidenMode
    2326
    2427#include "SynTree/Declaration.h"       // for TypeDecl::Data, DeclarationWit...
     
    7780                EqvClass( const EqvClass &other );
    7881                EqvClass( const EqvClass &other, const Type *ty );
     82                EqvClass( EqvClass &&other );
    7983                EqvClass &operator=( const EqvClass &other );
     84                EqvClass &operator=( EqvClass &&other );
    8085                ~EqvClass();
    8186                void print( std::ostream &os, Indenter indent = {} ) const;
     87
     88                /// Takes ownership of `ty`, freeing old `type`
     89                void set_type(Type* ty);
    8290        };
    8391
     
    8593          public:
    8694                const EqvClass* lookup( const std::string &var ) const;
    87                 void add( const EqvClass &eqvClass );
     95          private:
    8896                void add( EqvClass &&eqvClass  );
     97          public:
    8998                void add( const Type::ForallList &tyDecls );
    9099                void add( const TypeSubstitution & sub );
     
    94103                bool isEmpty() const { return env.empty(); }
    95104                void print( std::ostream &os, Indenter indent = {} ) const;
    96                 void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
     105                // void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
    97106                void simpleCombine( const TypeEnvironment &second );
    98107                void extractOpenVars( OpenVarSet &openVars ) const;
     
    103112                void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars );
    104113
    105                 typedef std::list< EqvClass >::iterator iterator;
    106                 iterator begin() { return env.begin(); }
    107                 iterator end() { return env.end(); }
    108                 typedef std::list< EqvClass >::const_iterator const_iterator;
    109                 const_iterator begin() const { return env.begin(); }
    110                 const_iterator end() const { return env.end(); }
     114                /// Binds the type class represented by `typeInst` to the type `bindTo`; will add
     115                /// the class if needed. Returns false on failure.
     116                bool bindVar( TypeInstType *typeInst, Type *bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     117               
     118                /// Binds the type classes represented by `var1` and `var2` together; will add
     119                /// one or both classes if needed. Returns false on failure.
     120                bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     121
     122                /// Disallows widening for all bindings in the environment
     123                void forbidWidening();
     124
     125                using iterator = std::list< EqvClass >::const_iterator;
     126                iterator begin() const { return env.begin(); }
     127                iterator end() const { return env.end(); }
     128
    111129          private:
    112130                std::list< EqvClass > env;
     131               
    113132                std::list< EqvClass >::iterator internal_lookup( const std::string &var );
    114133        };
  • src/ResolvExpr/Unify.cc

    ra12c81f3 rc653b37  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:27:10 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 16:22:54 2017
    13 // Update Count     : 42
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 43
    1414//
    1515
     
    129129        }
    130130
    131         bool isFtype( Type *type ) {
    132                 if ( dynamic_cast< FunctionType* >( type ) ) {
    133                         return true;
    134                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    135                         return typeInst->get_isFtype();
    136                 } // if
    137                 return false;
    138         }
    139 
    140         bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
    141                 switch ( data.kind ) {
    142                   case TypeDecl::Dtype:
    143                         // to bind to an object type variable, the type must not be a function type.
    144                         // if the type variable is specified to be a complete type then the incoming
    145                         // type must also be complete
    146                         // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    147                         return ! isFtype( type ) && (! data.isComplete || type->isComplete() );
    148                   case TypeDecl::Ftype:
    149                         return isFtype( type );
    150                   case TypeDecl::Ttype:
    151                         // ttype unifies with any tuple type
    152                         return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
    153                 } // switch
    154                 return false;
    155         }
    156 
    157         bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    158                 // remove references from other, so that type variables can only bind to value types
    159                 other = other->stripReferences();
    160                 OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
    161                 assert( tyvar != openVars.end() );
    162                 if ( ! tyVarCompatible( tyvar->second, other ) ) {
    163                         return false;
    164                 } // if
    165                 if ( occurs( other, typeInst->get_name(), env ) ) {
    166                         return false;
    167                 } // if
    168                 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
    169                         if ( curClass->type ) {
    170                                 Type *common = 0;
    171                                 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    172                                 std::unique_ptr< Type > newType( curClass->type->clone() );
    173                                 newType->get_qualifiers() = typeInst->get_qualifiers();
    174                                 if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
    175                                         if ( common ) {
    176                                                 common->get_qualifiers() = Type::Qualifiers();
    177                                                 env.add( EqvClass{ *curClass, common } );
    178                                         } // if
    179                                         return true;
    180                                 } else {
    181                                         return false;
    182                                 } // if
    183                         } else {
    184                                 EqvClass newClass { *curClass, other };
    185                                 newClass.type->get_qualifiers() = Type::Qualifiers();
    186                                 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    187                                 env.add( std::move(newClass) );
    188                         } // if
    189                 } else {
    190                         EqvClass newClass;
    191                         newClass.vars.insert( typeInst->get_name() );
    192                         newClass.type = other->clone();
    193                         newClass.type->get_qualifiers() = Type::Qualifiers();
    194                         newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    195                         newClass.data = data;
    196                         env.add( newClass );
    197                 } // if
    198                 return true;
    199         }
    200 
    201         bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    202                 bool result = true;
    203                 const EqvClass *class1 = env.lookup( var1->get_name() );
    204                 const EqvClass *class2 = env.lookup( var2->get_name() );
    205                 bool widen1 = false, widen2 = false;
    206                 Type *type1 = nullptr, *type2 = nullptr;
    207 
    208                 if ( class1 ) {
    209                         if ( class1->type ) {
    210                                 if ( occurs( class1->type, var2->get_name(), env ) ) {
    211                                         return false;
    212                                 } // if
    213                                 type1 = class1->type->clone();
    214                         } // if
    215                         widen1 = widenMode.widenFirst && class1->allowWidening;
    216                 } // if
    217                 if ( class2 ) {
    218                         if ( class2->type ) {
    219                                 if ( occurs( class2->type, var1->get_name(), env ) ) {
    220                                         return false;
    221                                 } // if
    222                                 type2 = class2->type->clone();
    223                         } // if
    224                         widen2 = widenMode.widenSecond && class2->allowWidening;
    225                 } // if
    226 
    227                 if ( type1 && type2 ) {
    228 //    std::cerr << "has type1 && type2" << std::endl;
    229                         WidenMode newWidenMode ( widen1, widen2 );
    230                         Type *common = 0;
    231                         if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
    232                                 EqvClass newClass1 = *class1;
    233                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    234                                 newClass1.allowWidening = widen1 && widen2;
    235                                 if ( common ) {
    236                                         common->get_qualifiers() = Type::Qualifiers();
    237                                         delete newClass1.type;
    238                                         newClass1.type = common;
    239                                 } // if
    240                                 env.add( std::move(newClass1) );
    241                         } else {
    242                                 result = false;
    243                         } // if
    244                 } else if ( class1 && class2 ) {
    245                         if ( type1 ) {
    246                                 EqvClass newClass1 = *class1;
    247                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    248                                 newClass1.allowWidening = widen1;
    249                                 env.add( std::move(newClass1) );
    250                         } else {
    251                                 EqvClass newClass2 = *class2;
    252                                 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );
    253                                 newClass2.allowWidening = widen2;
    254                                 env.add( std::move(newClass2) );
    255                         } // if
    256                 } else if ( class1 ) {
    257                         EqvClass newClass1 = *class1;
    258                         newClass1.vars.insert( var2->get_name() );
    259                         newClass1.allowWidening = widen1;
    260                         env.add( std::move(newClass1) );
    261                 } else if ( class2 ) {
    262                         EqvClass newClass2 = *class2;
    263                         newClass2.vars.insert( var1->get_name() );
    264                         newClass2.allowWidening = widen2;
    265                         env.add( std::move(newClass2) );
    266                 } else {
    267                         EqvClass newClass;
    268                         newClass.vars.insert( var1->get_name() );
    269                         newClass.vars.insert( var2->get_name() );
    270                         newClass.allowWidening = widen1 && widen2;
    271                         newClass.data = data;
    272                         env.add( newClass );
    273                 } // if
    274                 delete type1;
    275                 delete type2;
    276                 return result;
    277         }
    278 
    279131        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    280132                OpenVarSet closedVars;
     
    321173
    322174                if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
    323                         result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     175                        result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
    324176                } else if ( isopen1 ) {
    325                         result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     177                        result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
    326178                } else if ( isopen2 ) { // TODO: swap widenMode values in call, since type positions are flipped?
    327                         result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     179                        result = env.bindVar( var2, type1, entry2->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
    328180                } else {
    329181                        PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
  • src/ResolvExpr/Unify.h

    ra12c81f3 rc653b37  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 13:09:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 23:09:34 2017
    13 // Update Count     : 3
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    2121#include "SynTree/Declaration.h"  // for TypeDecl, TypeDecl::Data
    2222#include "TypeEnvironment.h"      // for AssertionSet, OpenVarSet
     23#include "WidenMode.h"            // for WidenMode
    2324
    2425class Type;
     
    2930
    3031namespace ResolvExpr {
    31         struct WidenMode {
    32                 WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}
    33                 WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }
    34                 WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }
    35                 WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }
    36                 WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
    37                 operator bool() { return widenFirst && widenSecond; }
    38 
    39                 bool widenFirst : 1, widenSecond : 1;
    40         };
    41 
    42         bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    4332        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    4433        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
    4534        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     35        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
    4636
    4737        template< typename Iterator1, typename Iterator2 >
  • src/SynTree/Type.cc

    ra12c81f3 rc653b37  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:16:32 2017
    13 // Update Count     : 38
     12// Last Modified On : Fri Jun 22 10:17:19 2018
     13// Update Count     : 39
    1414//
    1515#include "Type.h"
     
    6969
    7070// These must remain in the same order as the corresponding bit fields.
    71 const char * Type::FuncSpecifiersNames[] = { "inline", "fortran", "_Noreturn" };
     71const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" };
    7272const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_Thread_local" };
    7373const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
  • src/tests/.gitignore

    ra12c81f3 rc653b37  
    11.out/
    22.err/
     3.type
  • src/tests/concurrent/coroutineYield.c

    ra12c81f3 rc653b37  
    55#include <time>
    66
     7#define __kick_rate 150000ul
    78#include "long_tests.h"
    89
     
    2526void main(Coroutine& this) {
    2627        while(true) {
    27                 sout | "Coroutine 1" | endl;
     28                #if !defined(TEST_FOREVER)
     29                        sout | "Coroutine 1" | endl;
     30                #endif
    2831                yield();
    29                 sout | "Coroutine 2" | endl;
     32                #if !defined(TEST_FOREVER)
     33                        sout | "Coroutine 2" | endl;
     34                #endif
    3035                suspend();
    3136        }
     
    3641        Coroutine c;
    3742        for(int i = 0; TEST(i < N); i++) {
    38                 sout | "Thread 1" | endl;
     43                #if !defined(TEST_FOREVER)
     44                        sout | "Thread 1" | endl;
     45                #endif
    3946                resume(c);
    40                 sout | "Thread 2" | endl;
     47                #if !defined(TEST_FOREVER)
     48                        sout | "Thread 2" | endl;
     49                #endif
    4150                yield();
    4251                KICK_WATCHDOG;
  • src/tests/concurrent/signal/disjoint.c

    ra12c81f3 rc653b37  
    6969        }
    7070
    71         d.counter++;
    72 
    73         if( (d.counter % 1000) == 0 ) sout | d.counter | endl;
     71        #if !defined(TEST_FOREVER)
     72                d.counter++;
     73                if( (d.counter % 1000) == 0 ) sout | d.counter | endl;
     74        #endif
    7475
    7576        return TEST(d.counter < N);
  • src/tests/concurrent/signal/wait.c

    ra12c81f3 rc653b37  
    1212#include <time>
    1313
     14#define __kick_rate 12000ul
    1415#include "long_tests.h"
    1516
  • src/tests/long_tests.h

    ra12c81f3 rc653b37  
    44
    55#if   defined(TEST_FOREVER)
     6
     7static unsigned long long __kick_count = 0;
     8#if !defined(__kick_rate)
     9#define __kick_rate 5000ul
     10#endif
     11
    612#define TEST(x) 1
    7 #define KICK_WATCHDOG write(STDOUT_FILENO, ".", 1)
    8 #elif defined(TEST_LONG)
     13#define KICK_WATCHDOG do { __kick_count++; if(__kick_count > __kick_rate) { write(STDOUT_FILENO, ".", 1); __kick_count = 0; } } while(0)
     14
     15
     16#else
     17
    918#define TEST(x) x
    1019#define KICK_WATCHDOG
    11 #else
    12 #define TEST(x) x
    13 #define KICK_WATCHDOG
     20
    1421#endif
  • src/tests/preempt_longrun/Makefile.am

    ra12c81f3 rc653b37  
    2525TIME = /usr/bin/time -f "%E"
    2626
    27 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -I.. -I. -DTEST_$(shell echo $(type) | tr a-z A-Z)
     27# $(shell ./update-type $(type))
     28# ./update-type $(type)
     29
     30UPDATED_TYPE = $(shell ./update-type $(type))
     31
     32BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -I.. -I. -DTEST_$(shell cat .type | tr a-z A-Z)
    2833CFLAGS = ${BUILD_FLAGS}
    2934CC = @CFA_BINDIR@/@CFA_NAME@
     
    4550
    4651clean-local:
    47         rm -f ${TESTS} core* out.log
     52        rm -f ${TESTS} core* out.log .type
    4853
    49 % : %.c ${CC}
     54% : %.c ${CC} ${UPDATED_TYPE}
    5055        ${AM_V_GEN}${CC} ${CFLAGS} ${<} $(debug) -o ${@}
    5156
  • src/tests/preempt_longrun/Makefile.in

    ra12c81f3 rc653b37  
    456456WATCHDOG = ${abs_top_srcdir}/tools/watchdog
    457457TIME = /usr/bin/time -f "%E"
    458 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -I.. -I. -DTEST_$(shell echo $(type) | tr a-z A-Z)
     458
     459# $(shell ./update-type $(type))
     460# ./update-type $(type)
     461UPDATED_TYPE = $(shell ./update-type $(type))
     462BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -I.. -I. -DTEST_$(shell cat .type | tr a-z A-Z)
    459463TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
    460464all: all-am
     
    889893
    890894clean-local:
    891         rm -f ${TESTS} core* out.log
    892 
    893 % : %.c ${CC}
     895        rm -f ${TESTS} core* out.log .type
     896
     897% : %.c ${CC} ${UPDATED_TYPE}
    894898        ${AM_V_GEN}${CC} ${CFLAGS} ${<} $(debug) -o ${@}
    895899
  • src/tests/preempt_longrun/enter.c

    ra12c81f3 rc653b37  
    44#include <time>
    55
     6#define __kick_rate 75000ul
    67#include "long_tests.h"
    78
  • src/tests/preempt_longrun/enter3.c

    ra12c81f3 rc653b37  
    44#include <time>
    55
     6#define __kick_rate 75000ul
    67#include "long_tests.h"
    78
  • src/tests/preempt_longrun/stack.c

    ra12c81f3 rc653b37  
    44#include <time>
    55
     6#define __kick_rate 5000000ul
    67#include "long_tests.h"
    78
     
    1718
    1819void main(worker_t & this) {
    19         volatile long long p = 5_021_609ul;
    20         volatile long long a = 326_417ul;
    21         volatile long long n = 1l;
    22         for (volatile long long i = 0; TEST(i < p); i++) {
    23                 n *= a;
    24                 n %= p;
    25                 KICK_WATCHDOG;
    26         }
     20        while(TEST(0)) {
     21                volatile long long p = 5_021_609ul;
     22                volatile long long a = 326_417ul;
     23                volatile long long n = 1l;
     24                for (volatile long long i = 0; i < p; i++) {
     25                        n *= a;
     26                        n %= p;
     27                        KICK_WATCHDOG;
     28                }
    2729
    28         if( !TEST(n == a) ) {
    29                 abort();
     30                if( !TEST(n == a) ) {
     31                        abort();
     32                }
    3033        }
    3134}
  • src/tests/preempt_longrun/yield.c

    ra12c81f3 rc653b37  
    33#include <time>
    44
     5#define __kick_rate 550000ul
    56#include "long_tests.h"
    67
Note: See TracChangeset for help on using the changeset viewer.