Ignore:
Timestamp:
May 17, 2015, 1:19:35 PM (11 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
0dd3a2f
Parents:
b87a5ed
Message:

licencing: second groups of files

Location:
translator/ResolvExpr
Files:
29 edited

Legend:

Unmodified
Added
Removed
  • translator/ResolvExpr/AdjustExprType.cc

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// AdjustExprType.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sat May 16 23:41:42 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 23:54:02 2015
     13// Update Count     : 3
     14//
     15
    116#include "typeops.h"
    217#include "SynTree/Type.h"
     
    520
    621namespace ResolvExpr {
    7     class AdjustExprType : public Mutator {
    8         typedef Mutator Parent;
    9       public:
    10         AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
    11       private:
    12         virtual Type* mutate(VoidType *voidType);
    13         virtual Type* mutate(BasicType *basicType);
    14         virtual Type* mutate(PointerType *pointerType);
    15         virtual Type* mutate(ArrayType *arrayType);
    16         virtual Type* mutate(FunctionType *functionType);
    17         virtual Type* mutate(StructInstType *aggregateUseType);
    18         virtual Type* mutate(UnionInstType *aggregateUseType);
    19         virtual Type* mutate(EnumInstType *aggregateUseType);
    20         virtual Type* mutate(ContextInstType *aggregateUseType);
    21         virtual Type* mutate(TypeInstType *aggregateUseType);
    22         virtual Type* mutate(TupleType *tupleType);
    23  
    24         const TypeEnvironment &env;
    25         const SymTab::Indexer &indexer;
    26     };
     22        class AdjustExprType : public Mutator {
     23                typedef Mutator Parent;
     24          public:
     25                AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
     26          private:
     27                virtual Type* mutate( VoidType *voidType );
     28                virtual Type* mutate( BasicType *basicType );
     29                virtual Type* mutate( PointerType *pointerType );
     30                virtual Type* mutate( ArrayType *arrayType );
     31                virtual Type* mutate( FunctionType *functionType );
     32                virtual Type* mutate( StructInstType *aggregateUseType );
     33                virtual Type* mutate( UnionInstType *aggregateUseType );
     34                virtual Type* mutate( EnumInstType *aggregateUseType );
     35                virtual Type* mutate( ContextInstType *aggregateUseType );
     36                virtual Type* mutate( TypeInstType *aggregateUseType );
     37                virtual Type* mutate( TupleType *tupleType );
    2738
    28     void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    29         AdjustExprType adjuster( env, indexer );
    30         Type *newType = type->acceptMutator( adjuster );
    31         type = newType;
    32     }
     39                const TypeEnvironment &env;
     40                const SymTab::Indexer &indexer;
     41        };
    3342
    34     AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
    35         : env( env ), indexer( indexer ) {
    36     }
     43        void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     44                AdjustExprType adjuster( env, indexer );
     45                Type *newType = type->acceptMutator( adjuster );
     46                type = newType;
     47        }
    3748
    38     Type *AdjustExprType::mutate(VoidType *voidType) {
    39         return voidType;
    40     }
     49        AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
     50                : env( env ), indexer( indexer ) {
     51        }
    4152
    42     Type *AdjustExprType::mutate(BasicType *basicType) {
    43         return basicType;
    44     }
     53        Type *AdjustExprType::mutate( VoidType *voidType ) {
     54                return voidType;
     55        }
    4556
    46     Type *AdjustExprType::mutate(PointerType *pointerType) {
    47         return pointerType;
    48     }
     57        Type *AdjustExprType::mutate( BasicType *basicType ) {
     58                return basicType;
     59        }
    4960
    50     Type *AdjustExprType::mutate(ArrayType *arrayType) {
    51         PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone() );
    52         delete arrayType;
    53         return pointerType;
    54     }
     61        Type *AdjustExprType::mutate( PointerType *pointerType ) {
     62                return pointerType;
     63        }
    5564
    56     Type *AdjustExprType::mutate(FunctionType *functionType) {
    57         PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
    58         return pointerType;
    59     }
     65        Type *AdjustExprType::mutate( ArrayType *arrayType ) {
     66                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone() );
     67                delete arrayType;
     68                return pointerType;
     69        }
    6070
    61     Type *AdjustExprType::mutate(StructInstType *aggregateUseType) {
    62         return aggregateUseType;
    63     }
     71        Type *AdjustExprType::mutate( FunctionType *functionType ) {
     72                PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
     73                return pointerType;
     74        }
    6475
    65     Type *AdjustExprType::mutate(UnionInstType *aggregateUseType) {
    66         return aggregateUseType;
    67     }
     76        Type *AdjustExprType::mutate( StructInstType *aggregateUseType ) {
     77                return aggregateUseType;
     78        }
    6879
    69     Type *AdjustExprType::mutate(EnumInstType *aggregateUseType) {
    70         return aggregateUseType;
    71     }
     80        Type *AdjustExprType::mutate( UnionInstType *aggregateUseType ) {
     81                return aggregateUseType;
     82        }
    7283
    73     Type *AdjustExprType::mutate(ContextInstType *aggregateUseType) {
    74         return aggregateUseType;
    75     }
     84        Type *AdjustExprType::mutate( EnumInstType *aggregateUseType ) {
     85                return aggregateUseType;
     86        }
    7687
    77     Type *AdjustExprType::mutate(TypeInstType *typeInst) {
    78         EqvClass eqvClass;
    79         if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
    80             if ( eqvClass.kind == TypeDecl::Ftype ) {
    81                 PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
    82                 return pointerType;
    83             }
    84         } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    85             if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    86                 if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
    87                     PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
    88                     return pointerType;
    89                 }
    90             }
     88        Type *AdjustExprType::mutate( ContextInstType *aggregateUseType ) {
     89                return aggregateUseType;
    9190        }
    92         return typeInst;
    93     }
    9491
    95     Type *AdjustExprType::mutate(TupleType *tupleType) {
    96         return tupleType;
    97     }
     92        Type *AdjustExprType::mutate( TypeInstType *typeInst ) {
     93                EqvClass eqvClass;
     94                if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     95                        if ( eqvClass.kind == TypeDecl::Ftype ) {
     96                                PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
     97                                return pointerType;
     98                        }
     99                } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     100                        if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
     101                                if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     102                                        PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
     103                                        return pointerType;
     104                                } // if
     105                        } // if
     106                } // if
     107                return typeInst;
     108        }
     109
     110        Type *AdjustExprType::mutate( TupleType *tupleType ) {
     111                return tupleType;
     112        }
    98113} // namespace ResolvExpr
     114
     115// Local Variables: //
     116// tab-width: 4 //
     117// mode: c++ //
     118// compile-command: "make install" //
     119// End: //
  • translator/ResolvExpr/Alternative.cc

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Alternative.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sat May 16 23:44:23 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 23:54:23 2015
     13// Update Count     : 2
     14//
     15
    116#include "Alternative.h"
    217#include "SynTree/Type.h"
     
    520
    621namespace ResolvExpr {
    7     Alternative::Alternative() : expr( 0 ) {}
     22        Alternative::Alternative() : expr( 0 ) {}
    823
    9     Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
    10         : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ) {}
     24        Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
     25                : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ) {}
    1126
    12     Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost )
    13         : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ) {}
     27        Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost )
     28                : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ) {}
    1429
    15     Alternative::Alternative( const Alternative &other ) {
    16         initialize( other, *this );
    17     }
     30        Alternative::Alternative( const Alternative &other ) {
     31                initialize( other, *this );
     32        }
    1833
    19     Alternative &Alternative::operator=( const Alternative &other ) {
    20         if ( &other == this ) return *this;
    21         initialize( other, *this );
    22         return *this;
    23     }
     34        Alternative &Alternative::operator=( const Alternative &other ) {
     35                if ( &other == this ) return *this;
     36                initialize( other, *this );
     37                return *this;
     38        }
    2439
    25     void Alternative::initialize( const Alternative &src, Alternative &dest ) {
    26         dest.cost = src.cost;
    27         dest.cvtCost = src.cvtCost;
    28         dest.expr = maybeClone( src.expr );
    29         dest.env = src.env;
    30     }
     40        void Alternative::initialize( const Alternative &src, Alternative &dest ) {
     41                dest.cost = src.cost;
     42                dest.cvtCost = src.cvtCost;
     43                dest.expr = maybeClone( src.expr );
     44                dest.env = src.env;
     45        }
    3146
    32     Alternative::~Alternative() {
    33         delete expr;
    34     }
     47        Alternative::~Alternative() {
     48                delete expr;
     49        }
    3550
    36     void Alternative::print( std::ostream &os, int indent ) const {
    37         os << std::string( indent, ' ' ) << "Cost " << cost << ": ";
    38         if ( expr ) {
    39             expr->print( os, indent );
    40             os << "(types:" << std::endl;
    41             printAll( expr->get_results(), os, indent + 4 );
    42             os << ")" << std::endl;
    43         } else {
    44             os << "Null expression!" << std::endl;
     51        void Alternative::print( std::ostream &os, int indent ) const {
     52                os << std::string( indent, ' ' ) << "Cost " << cost << ": ";
     53                if ( expr ) {
     54                        expr->print( os, indent );
     55                        os << "(types:" << std::endl;
     56                        printAll( expr->get_results(), os, indent + 4 );
     57                        os << ")" << std::endl;
     58                } else {
     59                        os << "Null expression!" << std::endl;
     60                } // if
     61                os << std::string( indent, ' ' ) << "Environment: ";
     62                env.print( os, indent+2 );
     63                os << std::endl;
    4564        }
    46         os << std::string( indent, ' ' ) << "Environment: ";
    47         env.print( os, indent+2 );
    48         os << std::endl;
    49     }
    5065} // namespace ResolvExpr
     66
     67// Local Variables: //
     68// tab-width: 4 //
     69// mode: c++ //
     70// compile-command: "make install" //
     71// End: //
  • translator/ResolvExpr/Alternative.h

    rb87a5ed ra32b204  
    1 #ifndef RESOLVEXPR_ALTERNATIVE_H
    2 #define RESOLVEXPR_ALTERNATIVE_H
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Alternative.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sat May 16 23:45:43 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 23:54:39 2015
     13// Update Count     : 2
     14//
     15
     16#ifndef ALTERNATIVE_H
     17#define ALTERNATIVE_H
    318
    419#include <list>
     
    823
    924namespace ResolvExpr {
    10     struct Alternative;
    11     typedef std::list< Alternative > AltList;
     25        struct Alternative;
     26        typedef std::list< Alternative > AltList;
    1227
    13     struct Alternative {
    14         Alternative();
    15         Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost );
    16         Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost );
    17         Alternative( const Alternative &other );
    18         Alternative &operator=( const Alternative &other );
    19         ~Alternative();
     28        struct Alternative {
     29                Alternative();
     30                Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost );
     31                Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost, const Cost &cvtCost );
     32                Alternative( const Alternative &other );
     33                Alternative &operator=( const Alternative &other );
     34                ~Alternative();
    2035 
    21         void initialize( const Alternative &src, Alternative &dest );
     36                void initialize( const Alternative &src, Alternative &dest );
    2237 
    23         void print( std::ostream &os, int indent = 0 ) const;
     38                void print( std::ostream &os, int indent = 0 ) const;
    2439 
    25         Cost cost;
    26         Cost cvtCost;
    27         Expression *expr;
    28         TypeEnvironment env;
    29     };
     40                Cost cost;
     41                Cost cvtCost;
     42                Expression *expr;
     43                TypeEnvironment env;
     44        };
    3045} // namespace ResolvExpr
    3146
    32 #endif // RESOLVEXPR_ALTERNATIVE_H
     47#endif // ALTERNATIVE_H
     48
     49// Local Variables: //
     50// tab-width: 4 //
     51// mode: c++ //
     52// compile-command: "make install" //
     53// End: //
  • translator/ResolvExpr/AlternativeFinder.cc

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// AlternativeFinder.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sat May 16 23:52:08 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 23:55:30 2015
     13// Update Count     : 3
     14//
     15
    116#include <list>
    217#include <iterator>
     
    3045
    3146namespace ResolvExpr {
    32     Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) {
    33         CastExpr *castToVoid = new CastExpr( expr );
    34 
    35         AlternativeFinder finder( indexer, env );
    36         finder.findWithAdjustment( castToVoid );
    37 
    38         // it's a property of the language that a cast expression has either 1 or 0 interpretations; if it has 0
    39         // interpretations, an exception has already been thrown.
    40         assert( finder.get_alternatives().size() == 1 );
    41         CastExpr *newExpr = dynamic_cast< CastExpr* >( finder.get_alternatives().front().expr );
    42         assert( newExpr );
    43         env = finder.get_alternatives().front().env;
    44         return newExpr->get_arg()->clone();
    45     }
    46 
    47     namespace {
    48         void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
    49             for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    50                 i->print( os, indent );
    51                 os << std::endl;
    52             }
    53         }
    54 
    55         void makeExprList( const AltList &in, std::list< Expression* > &out ) {
    56             for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    57                 out.push_back( i->expr->clone() );
    58             }
    59         }
    60 
    61         Cost sumCost( const AltList &in ) {
    62             Cost total;
    63             for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    64                 total += i->cost;
    65             }
    66             return total;
    67         }
    68 
    69         struct PruneStruct {
    70             bool isAmbiguous;
    71             AltList::iterator candidate;
    72             PruneStruct() {}
    73             PruneStruct( AltList::iterator candidate ): isAmbiguous( false ), candidate( candidate ) {}
    74         };
     47        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) {
     48                CastExpr *castToVoid = new CastExpr( expr );
     49
     50                AlternativeFinder finder( indexer, env );
     51                finder.findWithAdjustment( castToVoid );
     52
     53                // it's a property of the language that a cast expression has either 1 or 0 interpretations; if it has 0
     54                // interpretations, an exception has already been thrown.
     55                assert( finder.get_alternatives().size() == 1 );
     56                CastExpr *newExpr = dynamic_cast< CastExpr* >( finder.get_alternatives().front().expr );
     57                assert( newExpr );
     58                env = finder.get_alternatives().front().env;
     59                return newExpr->get_arg()->clone();
     60        }
     61
     62        namespace {
     63                void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     64                        for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
     65                                i->print( os, indent );
     66                                os << std::endl;
     67                        }
     68                }
     69
     70                void makeExprList( const AltList &in, std::list< Expression* > &out ) {
     71                        for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
     72                                out.push_back( i->expr->clone() );
     73                        }
     74                }
     75
     76                Cost sumCost( const AltList &in ) {
     77                        Cost total;
     78                        for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
     79                                total += i->cost;
     80                        }
     81                        return total;
     82                }
     83
     84                struct PruneStruct {
     85                        bool isAmbiguous;
     86                        AltList::iterator candidate;
     87                        PruneStruct() {}
     88                        PruneStruct( AltList::iterator candidate ): isAmbiguous( false ), candidate( candidate ) {}
     89                };
     90
     91                template< typename InputIterator, typename OutputIterator >
     92                void pruneAlternatives( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer ) {
     93                        // select the alternatives that have the minimum conversion cost for a particular set of result types
     94                        std::map< std::string, PruneStruct > selected;
     95                        for ( AltList::iterator candidate = begin; candidate != end; ++candidate ) {
     96                                PruneStruct current( candidate );
     97                                std::string mangleName;
     98                                for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
     99                                        Type *newType = (*retType)->clone();
     100                                        candidate->env.apply( newType );
     101                                        mangleName += SymTab::Mangler::mangle( newType );
     102                                        delete newType;
     103                                }
     104                                std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
     105                                if ( mapPlace != selected.end() ) {
     106                                        if ( candidate->cost < mapPlace->second.candidate->cost ) {
     107                                                PRINT(
     108                                                        std::cout << "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl;
     109                                                        )
     110                                                        selected[ mangleName ] = current;
     111                                        } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
     112                                                PRINT(
     113                                                        std::cout << "marking ambiguous" << std::endl;
     114                                                        )
     115                                                        mapPlace->second.isAmbiguous = true;
     116                                        }
     117                                } else {
     118                                        selected[ mangleName ] = current;
     119                                }
     120                        }
     121
     122                        PRINT(
     123                                std::cout << "there are " << selected.size() << " alternatives before elimination" << std::endl;
     124                                )
     125
     126                                // accept the alternatives that were unambiguous
     127                                for ( std::map< std::string, PruneStruct >::iterator target = selected.begin(); target != selected.end(); ++target ) {
     128                                        if ( ! target->second.isAmbiguous ) {
     129                                                Alternative &alt = *target->second.candidate;
     130                                                for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
     131                                                        alt.env.applyFree( *result );
     132                                                }
     133                                                *out++ = alt;
     134                                        }
     135                                }
     136
     137                }
     138
     139                template< typename InputIterator, typename OutputIterator >
     140                void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
     141                        AltList alternatives;
     142
     143                        // select the alternatives that have the minimum parameter cost
     144                        Cost minCost = Cost::infinity;
     145                        for ( AltList::iterator i = begin; i != end; ++i ) {
     146                                if ( i->cost < minCost ) {
     147                                        minCost = i->cost;
     148                                        i->cost = i->cvtCost;
     149                                        alternatives.clear();
     150                                        alternatives.push_back( *i );
     151                                } else if ( i->cost == minCost ) {
     152                                        i->cost = i->cvtCost;
     153                                        alternatives.push_back( *i );
     154                                }
     155                        }
     156                        std::copy( alternatives.begin(), alternatives.end(), out );
     157                }
     158
     159                template< typename InputIterator >
     160                void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) {
     161                        while ( begin != end ) {
     162                                result.simpleCombine( (*begin++).env );
     163                        }
     164                }
     165
     166                void renameTypes( Expression *expr ) {
     167                        for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
     168                                (*i)->accept( global_renamer );
     169                        }
     170                }
     171        }
    75172
    76173        template< typename InputIterator, typename OutputIterator >
    77         void pruneAlternatives( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer ) {
    78             // select the alternatives that have the minimum conversion cost for a particular set of result types
    79             std::map< std::string, PruneStruct > selected;
    80             for ( AltList::iterator candidate = begin; candidate != end; ++candidate ) {
    81                 PruneStruct current( candidate );
    82                 std::string mangleName;
    83                 for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
    84                     Type *newType = (*retType)->clone();
    85                     candidate->env.apply( newType );
    86                     mangleName += SymTab::Mangler::mangle( newType );
    87                     delete newType;
    88                 }
    89                 std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
    90                 if ( mapPlace != selected.end() ) {
    91                     if ( candidate->cost < mapPlace->second.candidate->cost ) {
     174        void AlternativeFinder::findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ) {
     175                while ( begin != end ) {
     176                        AlternativeFinder finder( indexer, env );
     177                        finder.findWithAdjustment( *begin );
     178                        // XXX  either this
     179                        //Designators::fixDesignations( finder, (*begin++)->get_argName() );
     180                        // or XXX this
     181                        begin++;
    92182                        PRINT(
    93                             std::cout << "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl;
    94                             )
    95                         selected[ mangleName ] = current;
    96                     } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
     183                                std::cout << "findSubExprs" << std::endl;
     184                                printAlts( finder.alternatives, std::cout );
     185                                )
     186                                *out++ = finder;
     187                }
     188        }
     189
     190        AlternativeFinder::AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env )
     191                : indexer( indexer ), env( env ) {
     192        }
     193
     194        void AlternativeFinder::find( Expression *expr, bool adjust ) {
     195                expr->accept( *this );
     196                if ( alternatives.empty() ) {
     197                        throw SemanticError( "No reasonable alternatives for expression ", expr );
     198                }
     199                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
     200                        if ( adjust ) {
     201                                adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
     202                        }
     203                }
     204                PRINT(
     205                        std::cout << "alternatives before prune:" << std::endl;
     206                        printAlts( alternatives, std::cout );
     207                        )
     208                        AltList::iterator oldBegin = alternatives.begin();
     209                pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
     210                if ( alternatives.begin() == oldBegin ) {
     211                        std::ostrstream stream;
     212                        stream << "Can't choose between alternatives for expression ";
     213                        expr->print( stream );
     214                        stream << "Alternatives are:";
     215                        AltList winners;
     216                        findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
     217                        printAlts( winners, stream, 8 );
     218                        throw SemanticError( std::string( stream.str(), stream.pcount() ) );
     219                }
     220                alternatives.erase( oldBegin, alternatives.end() );
     221                PRINT(
     222                        std::cout << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
     223                        )
     224                        }
     225
     226        void AlternativeFinder::findWithAdjustment( Expression *expr ) {
     227                find( expr, true );
     228        }
     229
     230        template< typename StructOrUnionType >
     231        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name ) {
     232                std::list< Declaration* > members;
     233                aggInst->lookup( name, members );
     234                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
     235                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
     236                                alternatives.push_back( Alternative( new MemberExpr( dwt->clone(), expr->clone() ), env, newCost ) );
     237                                renameTypes( alternatives.back().expr );
     238                        } else {
     239                                assert( false );
     240                        }
     241                }
     242        }
     243
     244        void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) {
     245                alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
     246        }
     247
     248        Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
     249                ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
     250                assert( appExpr );
     251                PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     252                assert( pointer );
     253                FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     254                assert( function );
     255
     256                Cost convCost( 0, 0, 0 );
     257                std::list< DeclarationWithType* >& formals = function->get_parameters();
     258                std::list< DeclarationWithType* >::iterator formal = formals.begin();
     259                std::list< Expression* >& actuals = appExpr->get_args();
     260                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    97261                        PRINT(
    98                             std::cout << "marking ambiguous" << std::endl;
    99                             )
    100                         mapPlace->second.isAmbiguous = true;
    101                     }
    102                 } else {
    103                     selected[ mangleName ] = current;
    104                 }
    105             }
    106 
    107             PRINT(
    108                 std::cout << "there are " << selected.size() << " alternatives before elimination" << std::endl;
    109                 )
    110 
    111             // accept the alternatives that were unambiguous
    112             for ( std::map< std::string, PruneStruct >::iterator target = selected.begin(); target != selected.end(); ++target ) {
    113                 if ( !target->second.isAmbiguous ) {
    114                     Alternative &alt = *target->second.candidate;
    115                     for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
    116                         alt.env.applyFree( *result );
    117                     }
    118                     *out++ = alt;
    119                 }
    120             }
    121 
    122         }
    123 
    124         template< typename InputIterator, typename OutputIterator >
    125         void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
    126             AltList alternatives;
    127 
    128             // select the alternatives that have the minimum parameter cost
    129             Cost minCost = Cost::infinity;
    130             for ( AltList::iterator i = begin; i != end; ++i ) {
    131                 if ( i->cost < minCost ) {
    132                     minCost = i->cost;
    133                     i->cost = i->cvtCost;
    134                     alternatives.clear();
    135                     alternatives.push_back( *i );
    136                 } else if ( i->cost == minCost ) {
    137                     i->cost = i->cvtCost;
    138                     alternatives.push_back( *i );
    139                 }
    140             }
    141             std::copy( alternatives.begin(), alternatives.end(), out );
    142         }
    143 
    144         template< typename InputIterator >
    145         void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) {
    146             while ( begin != end ) {
    147                 result.simpleCombine( (*begin++).env );
    148             }
    149         }
    150 
    151         void renameTypes( Expression *expr ) {
    152             for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
    153                 (*i)->accept( global_renamer );
    154             }
    155         }
    156     }
    157 
    158     template< typename InputIterator, typename OutputIterator >
    159     void AlternativeFinder::findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ) {
    160         while ( begin != end ) {
    161             AlternativeFinder finder( indexer, env );
    162             finder.findWithAdjustment( *begin );
    163             // XXX  either this
    164             //Designators::fixDesignations( finder, (*begin++)->get_argName() );
    165             // or XXX this
    166             begin++;
    167             PRINT(
    168                 std::cout << "findSubExprs" << std::endl;
    169                 printAlts( finder.alternatives, std::cout );
    170                 )
    171             *out++ = finder;
    172         }
    173     }
    174 
    175     AlternativeFinder::AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env )
    176         : indexer( indexer ), env( env ) {
    177     }
    178 
    179     void AlternativeFinder::find( Expression *expr, bool adjust ) {
    180         expr->accept( *this );
    181         if ( alternatives.empty() ) {
    182             throw SemanticError( "No reasonable alternatives for expression ", expr );
    183         }
    184         for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    185             if ( adjust ) {
    186                 adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
    187             }
    188         }
    189         PRINT(
    190             std::cout << "alternatives before prune:" << std::endl;
    191             printAlts( alternatives, std::cout );
    192             )
    193         AltList::iterator oldBegin = alternatives.begin();
    194         pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
    195         if ( alternatives.begin() == oldBegin ) {
    196             std::ostrstream stream;
    197             stream << "Can't choose between alternatives for expression ";
    198             expr->print( stream );
    199             stream << "Alternatives are:";
    200             AltList winners;
    201             findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
    202             printAlts( winners, stream, 8 );
    203             throw SemanticError( std::string( stream.str(), stream.pcount() ) );
    204         }
    205         alternatives.erase( oldBegin, alternatives.end() );
    206         PRINT(
    207             std::cout << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
    208             )
    209     }
    210 
    211     void AlternativeFinder::findWithAdjustment( Expression *expr ) {
    212         find( expr, true );
    213     }
    214 
    215     template< typename StructOrUnionType >
    216     void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name ) {
    217         std::list< Declaration* > members;
    218         aggInst->lookup( name, members );
    219         for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    220             if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    221                 alternatives.push_back( Alternative( new MemberExpr( dwt->clone(), expr->clone() ), env, newCost ) );
    222                 renameTypes( alternatives.back().expr );
    223             } else {
    224                 assert( false );
    225             }
    226         }
    227     }
    228 
    229     void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) {
    230         alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
    231     }
    232 
    233     Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    234         ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
    235         assert( appExpr );
    236         PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    237         assert( pointer );
    238         FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    239         assert( function );
    240 
    241         Cost convCost( 0, 0, 0 );
    242         std::list< DeclarationWithType* >& formals = function->get_parameters();
    243         std::list< DeclarationWithType* >::iterator formal = formals.begin();
    244         std::list< Expression* >& actuals = appExpr->get_args();
    245         for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    246             PRINT(
    247                 std::cout << "actual expression:" << std::endl;
    248                 (*actualExpr)->print( std::cout, 8 );
    249                 std::cout << "--- results are" << std::endl;
    250                 printAll( (*actualExpr)->get_results(), std::cout, 8 );
    251                 )
    252             std::list< DeclarationWithType* >::iterator startFormal = formal;
    253             Cost actualCost;
    254             for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
    255                 if ( formal == formals.end() ) {
    256                     if ( function->get_isVarArgs() ) {
    257                         convCost += Cost( 1, 0, 0 );
    258                         break;
    259                     } else {
     262                                std::cout << "actual expression:" << std::endl;
     263                                (*actualExpr)->print( std::cout, 8 );
     264                                std::cout << "--- results are" << std::endl;
     265                                printAll( (*actualExpr)->get_results(), std::cout, 8 );
     266                                )
     267                                std::list< DeclarationWithType* >::iterator startFormal = formal;
     268                        Cost actualCost;
     269                        for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
     270                                if ( formal == formals.end() ) {
     271                                        if ( function->get_isVarArgs() ) {
     272                                                convCost += Cost( 1, 0, 0 );
     273                                                break;
     274                                        } else {
     275                                                return Cost::infinity;
     276                                        }
     277                                }
     278                                PRINT(
     279                                        std::cout << std::endl << "converting ";
     280                                        (*actual)->print( std::cout, 8 );
     281                                        std::cout << std::endl << " to ";
     282                                        (*formal)->get_type()->print( std::cout, 8 );
     283                                        )
     284                                        Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
     285                                PRINT(
     286                                        std::cout << std::endl << "cost is" << newCost << std::endl;
     287                                        )
     288
     289                                        if ( newCost == Cost::infinity ) {
     290                                                return newCost;
     291                                        }
     292                                convCost += newCost;
     293                                actualCost += newCost;
     294
     295                                convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
     296
     297                                formal++;
     298                        }
     299                        if ( actualCost != Cost( 0, 0, 0 ) ) {
     300                                std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal;
     301                                startFormalPlusOne++;
     302                                if ( formal == startFormalPlusOne ) {
     303                                        // not a tuple type
     304                                        Type *newType = (*startFormal)->get_type()->clone();
     305                                        alt.env.apply( newType );
     306                                        *actualExpr = new CastExpr( *actualExpr, newType );
     307                                } else {
     308                                        TupleType *newType = new TupleType( Type::Qualifiers() );
     309                                        for ( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) {
     310                                                newType->get_types().push_back( (*i)->get_type()->clone() );
     311                                        }
     312                                        alt.env.apply( newType );
     313                                        *actualExpr = new CastExpr( *actualExpr, newType );
     314                                }
     315                        }
     316
     317                }
     318                if ( formal != formals.end() ) {
    260319                        return Cost::infinity;
    261                     }
    262                 }
     320                }
     321
     322                for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
     323                        PRINT(
     324                                std::cout << std::endl << "converting ";
     325                                assert->second.actualType->print( std::cout, 8 );
     326                                std::cout << std::endl << " to ";
     327                                assert->second.formalType->print( std::cout, 8 );
     328                                )
     329                                Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
     330                        PRINT(
     331                                std::cout << std::endl << "cost of conversion is " << newCost << std::endl;
     332                                )
     333                                if ( newCost == Cost::infinity ) {
     334                                        return newCost;
     335                                }
     336                        convCost += newCost;
     337
     338                        convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
     339                }
     340
     341                return convCost;
     342        }
     343
     344        void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) {
     345                for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
     346                        unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
     347                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     348                                needAssertions[ *assert ] = true;
     349                        }
     350///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
     351                }
     352        }
     353
     354        bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
     355                std::list< TypeEnvironment > toBeDone;
     356                simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
     357                // make sure we don't widen any existing bindings
     358                for ( TypeEnvironment::iterator i = resultEnv.begin(); i != resultEnv.end(); ++i ) {
     359                        i->allowWidening = false;
     360                }
     361                resultEnv.extractOpenVars( openVars );
     362
     363                /*
     364                  Tuples::NameMatcher matcher( formals );
     365                  try {
     366                  matcher.match( actuals );
     367                  } catch ( Tuples::NoMatch &e ) {
     368                  std::cerr << "Alternative doesn't match: " << e.message << std::endl;
     369                  }
     370                */
     371                std::list< DeclarationWithType* >::iterator formal = formals.begin();
     372                for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
     373                        for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
     374                                if ( formal == formals.end() ) {
     375                                        return isVarArgs;
     376                                }
     377                                PRINT(
     378                                        std::cerr << "formal type is ";
     379                                        (*formal)->get_type()->print( std::cerr );
     380                                        std::cerr << std::endl << "actual type is ";
     381                                        (*actual)->print( std::cerr );
     382                                        std::cerr << std::endl;
     383                                        )
     384                                        if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     385                                                return false;
     386                                        }
     387                                formal++;
     388                        }
     389                }
     390                // Handling of default values
     391                while ( formal != formals.end() ) {
     392                        if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) )
     393                                if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() ))
     394                                        // so far, only constant expressions are accepted as default values
     395                                        if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) )
     396                                                if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) )
     397                                                        if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     398                                                                // XXX Don't know if this is right
     399                                                                actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) );
     400                                                                formal++;
     401                                                                if ( formal == formals.end()) break;
     402                                                        }
     403                        return false;
     404                }
     405                return true;
     406        }
     407
     408        static const int recursionLimit = 10;
     409
     410        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
     411                for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
     412                        if ( i->second == true ) {
     413                                i->first->accept( indexer );
     414                        }
     415                }
     416        }
     417
     418        template< typename ForwardIterator, typename OutputIterator >
     419        void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
     420                if ( begin == end ) {
     421                        if ( newNeed.empty() ) {
     422                                *out++ = newAlt;
     423                                return;
     424                        } else if ( level >= recursionLimit ) {
     425                                throw SemanticError( "Too many recursive assertions" );
     426                        } else {
     427                                AssertionSet newerNeed;
     428                                PRINT(
     429                                        std::cerr << "recursing with new set:" << std::endl;
     430                                        printAssertionSet( newNeed, std::cerr, 8 );
     431                                        )
     432                                        inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
     433                                return;
     434                        }
     435                }
     436
     437                ForwardIterator cur = begin++;
     438                if ( ! cur->second ) {
     439                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
     440                }
     441                DeclarationWithType *curDecl = cur->first;
    263442                PRINT(
    264                     std::cout << std::endl << "converting ";
    265                     (*actual)->print( std::cout, 8 );
    266                     std::cout << std::endl << " to ";
    267                     (*formal)->get_type()->print( std::cout, 8 );
    268                     )
    269                 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
    270                 PRINT(
    271                     std::cout << std::endl << "cost is" << newCost << std::endl;
    272                     )
    273 
    274                 if ( newCost == Cost::infinity ) {
    275                     return newCost;
    276                 }
    277                 convCost += newCost;
    278                 actualCost += newCost;
    279 
    280                 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
    281 
    282                 formal++;
    283             }
    284             if ( actualCost != Cost( 0, 0, 0 ) ) {
    285                 std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal;
    286                 startFormalPlusOne++;
    287                 if ( formal == startFormalPlusOne ) {
    288                     // not a tuple type
    289                     Type *newType = (*startFormal)->get_type()->clone();
    290                     alt.env.apply( newType );
    291                     *actualExpr = new CastExpr( *actualExpr, newType );
    292                 } else {
    293                     TupleType *newType = new TupleType( Type::Qualifiers() );
    294                     for ( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) {
    295                         newType->get_types().push_back( (*i)->get_type()->clone() );
    296                     }
    297                     alt.env.apply( newType );
    298                     *actualExpr = new CastExpr( *actualExpr, newType );
    299                 }
    300             }
    301 
    302         }
    303         if ( formal != formals.end() ) {
    304             return Cost::infinity;
    305         }
    306 
    307         for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    308             PRINT(
    309                 std::cout << std::endl << "converting ";
    310                 assert->second.actualType->print( std::cout, 8 );
    311                 std::cout << std::endl << " to ";
    312                 assert->second.formalType->print( std::cout, 8 );
    313                 )
    314             Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    315             PRINT(
    316                 std::cout << std::endl << "cost of conversion is " << newCost << std::endl;
    317                 )
    318             if ( newCost == Cost::infinity ) {
    319                 return newCost;
    320             }
    321             convCost += newCost;
    322 
    323             convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
    324         }
    325 
    326         return convCost;
    327     }
    328 
    329     void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) {
    330         for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    331             unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
    332             for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
    333                 needAssertions[ *assert ] = true;
    334             }
    335 ///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
    336         }
    337     }
    338 
    339     bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
    340         std::list< TypeEnvironment > toBeDone;
    341         simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    342         // make sure we don't widen any existing bindings
    343         for ( TypeEnvironment::iterator i = resultEnv.begin(); i != resultEnv.end(); ++i ) {
    344             i->allowWidening  = false;
    345         }
    346         resultEnv.extractOpenVars( openVars );
    347 
    348         /*
    349           Tuples::NameMatcher matcher( formals );
    350           try {
    351           matcher.match( actuals );
    352           } catch ( Tuples::NoMatch &e ) {
    353           std::cerr << "Alternative doesn't match: " << e.message << std::endl;
    354           }
    355         */
    356         std::list< DeclarationWithType* >::iterator formal = formals.begin();
    357         for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    358             for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
    359                 if ( formal == formals.end() ) {
    360                     return isVarArgs;
    361                 }
    362                 PRINT(
    363                     std::cerr << "formal type is ";
    364                     (*formal)->get_type()->print( std::cerr );
    365                     std::cerr << std::endl << "actual type is ";
    366                     (*actual)->print( std::cerr );
    367                     std::cerr << std::endl;
    368                     )
    369                 if ( !unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    370                     return false;
    371                 }
    372                 formal++;
    373             }
    374         }
    375         // Handling of default values
    376         while ( formal != formals.end() ) {
    377             if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) )
    378                 if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() ))
    379                     // so far, only constant expressions are accepted as default values
    380                     if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) )
    381                         if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) )
    382                             if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    383                                 // XXX Don't know if this is right
    384                                 actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) );
    385                                 formal++;
    386                                 if ( formal == formals.end()) break;
    387                             }
    388             return false;
    389         }
    390         return true;
    391     }
    392 
    393     static const int recursionLimit = 10;
    394 
    395     void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    396         for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    397             if ( i->second == true ) {
    398                 i->first->accept( indexer );
    399             }
    400         }
    401     }
    402 
    403     template< typename ForwardIterator, typename OutputIterator >
    404     void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
    405         if ( begin == end ) {
    406             if ( newNeed.empty() ) {
    407                 *out++ = newAlt;
    408                 return;
    409             } else if ( level >= recursionLimit ) {
    410                 throw SemanticError( "Too many recursive assertions" );
    411             } else {
    412                 AssertionSet newerNeed;
    413                 PRINT(
    414                     std::cerr << "recursing with new set:" << std::endl;
    415                     printAssertionSet( newNeed, std::cerr, 8 );
    416                     )
    417                 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
    418                 return;
    419             }
    420         }
    421 
    422         ForwardIterator cur = begin++;
    423         if ( !cur->second ) {
    424             inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
    425         }
    426         DeclarationWithType *curDecl = cur->first;
    427         PRINT(
    428             std::cerr << "inferRecursive: assertion is ";
    429             curDecl->print( std::cerr );
    430             std::cerr << std::endl;
    431             )
    432         std::list< DeclarationWithType* > candidates;
    433         decls.lookupId( curDecl->get_name(), candidates );
     443                        std::cerr << "inferRecursive: assertion is ";
     444                        curDecl->print( std::cerr );
     445                        std::cerr << std::endl;
     446                        )
     447                        std::list< DeclarationWithType* > candidates;
     448                decls.lookupId( curDecl->get_name(), candidates );
    434449///   if ( candidates.empty() ) { std::cout << "no candidates!" << std::endl; }
    435         for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
    436             PRINT(
    437                 std::cout << "inferRecursive: candidate is ";
    438                 (*candidate)->print( std::cout );
    439                 std::cout << std::endl;
    440                 )
    441             AssertionSet newHave, newerNeed( newNeed );
    442             TypeEnvironment newEnv( newAlt.env );
    443             OpenVarSet newOpenVars( openVars );
    444             Type *adjType = (*candidate)->get_type()->clone();
    445             adjustExprType( adjType, newEnv, indexer );
    446             adjType->accept( global_renamer );
    447             PRINT(
    448                 std::cerr << "unifying ";
    449                 curDecl->get_type()->print( std::cerr );
    450                 std::cerr << " with ";
    451                 adjType->print( std::cerr );
    452                 std::cerr << std::endl;
    453                 )
    454             if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
    455                 PRINT(
    456                     std::cerr << "success!" << std::endl;
    457                     )
    458                 SymTab::Indexer newDecls( decls );
    459                 addToIndexer( newHave, newDecls );
    460                 Alternative newerAlt( newAlt );
    461                 newerAlt.env = newEnv;
    462                 assert( (*candidate)->get_uniqueId() );
    463                 Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) );
    464                 deleteAll( varExpr->get_results() );
    465                 varExpr->get_results().clear();
    466                 varExpr->get_results().push_front( adjType->clone() );
    467                 PRINT(
    468                     std::cout << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    469                     curDecl->print( std::cout );
    470                     std::cout << " with declaration " << (*candidate)->get_uniqueId() << " ";
    471                     (*candidate)->print( std::cout );
    472                     std::cout << std::endl;
    473                     )
    474                 ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
    475                 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    476                 appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    477                 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
    478             } else {
    479                 delete adjType;
    480             }
    481         }
    482     }
    483 
    484     template< typename OutputIterator >
    485     void AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {
     450                for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
     451                        PRINT(
     452                                std::cout << "inferRecursive: candidate is ";
     453                                (*candidate)->print( std::cout );
     454                                std::cout << std::endl;
     455                                )
     456                                AssertionSet newHave, newerNeed( newNeed );
     457                        TypeEnvironment newEnv( newAlt.env );
     458                        OpenVarSet newOpenVars( openVars );
     459                        Type *adjType = (*candidate)->get_type()->clone();
     460                        adjustExprType( adjType, newEnv, indexer );
     461                        adjType->accept( global_renamer );
     462                        PRINT(
     463                                std::cerr << "unifying ";
     464                                curDecl->get_type()->print( std::cerr );
     465                                std::cerr << " with ";
     466                                adjType->print( std::cerr );
     467                                std::cerr << std::endl;
     468                                )
     469                                if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
     470                                        PRINT(
     471                                                std::cerr << "success!" << std::endl;
     472                                                )
     473                                                SymTab::Indexer newDecls( decls );
     474                                        addToIndexer( newHave, newDecls );
     475                                        Alternative newerAlt( newAlt );
     476                                        newerAlt.env = newEnv;
     477                                        assert( (*candidate)->get_uniqueId() );
     478                                        Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) );
     479                                        deleteAll( varExpr->get_results() );
     480                                        varExpr->get_results().clear();
     481                                        varExpr->get_results().push_front( adjType->clone() );
     482                                        PRINT(
     483                                                std::cout << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     484                                                curDecl->print( std::cout );
     485                                                std::cout << " with declaration " << (*candidate)->get_uniqueId() << " ";
     486                                                (*candidate)->print( std::cout );
     487                                                std::cout << std::endl;
     488                                                )
     489                                                ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
     490                                        // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
     491                                        appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     492                                        inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
     493                                } else {
     494                                        delete adjType;
     495                                }
     496                }
     497        }
     498
     499        template< typename OutputIterator >
     500        void AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {
    486501//      PRINT(
    487502//          std::cout << "inferParameters: assertions needed are" << std::endl;
    488503//          printAll( need, std::cout, 8 );
    489504//          )
    490         SymTab::Indexer decls( indexer );
    491         PRINT(
    492             std::cout << "============= original indexer" << std::endl;
    493             indexer.print( std::cout );
    494             std::cout << "============= new indexer" << std::endl;
    495             decls.print( std::cout );
    496             )
    497         addToIndexer( have, decls );
    498         AssertionSet newNeed;
    499         inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
     505                SymTab::Indexer decls( indexer );
     506                PRINT(
     507                        std::cout << "============= original indexer" << std::endl;
     508                        indexer.print( std::cout );
     509                        std::cout << "============= new indexer" << std::endl;
     510                        decls.print( std::cout );
     511                        )
     512                        addToIndexer( have, decls );
     513                AssertionSet newNeed;
     514                inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
    500515//      PRINT(
    501516//          std::cout << "declaration 14 is ";
     
    503518//          *out++ = newAlt;
    504519//          )
    505     }
    506 
    507     template< typename OutputIterator >
    508     void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {
    509         OpenVarSet openVars;
    510         AssertionSet resultNeed, resultHave;
    511         TypeEnvironment resultEnv;
    512         makeUnifiableVars( funcType, openVars, resultNeed );
    513         if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
    514             ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    515             Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
    516             makeExprList( actualAlt, appExpr->get_args() );
    517             PRINT(
    518                 std::cout << "need assertions:" << std::endl;
    519                 printAssertionSet( resultNeed, std::cout, 8 );
    520                 )
    521             inferParameters( resultNeed, resultHave, newAlt, openVars, out );
    522         }
    523     }
    524 
    525     void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
    526         bool doneInit = false;
    527         AlternativeFinder funcOpFinder( indexer, env );
    528 
    529         AlternativeFinder funcFinder( indexer, env ); {
    530             NameExpr *fname;
    531             if ( ( fname = dynamic_cast<NameExpr *>( untypedExpr->get_function()))
    532                  && ( fname->get_name() == std::string("LabAddress")) ) {
    533                 alternatives.push_back( Alternative( untypedExpr, env, Cost()) );
    534                 return;
    535             }
    536         }
    537 
    538         funcFinder.findWithAdjustment( untypedExpr->get_function() );
    539         std::list< AlternativeFinder > argAlternatives;
    540         findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) );
    541 
    542         std::list< AltList > possibilities;
    543         combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
    544 
    545         Tuples::TupleAssignSpotter tassign( this );
    546         if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) {
    547             // take care of possible tuple assignments, or discard expression
    548             return;
    549         } // else ...
    550 
    551         AltList candidates;
    552 
    553         for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
    554             PRINT(
    555                 std::cout << "working on alternative: " << std::endl;
    556                 func->print( std::cout, 8 );
    557                 )
    558             // check if the type is pointer to function
    559             PointerType *pointer;
    560             if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
    561                 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    562                     for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    563                         // XXX
    564                         //Designators::check_alternative( function, *actualAlt );
    565                         makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    566                     }
    567                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
    568                     EqvClass eqvClass;
    569                     if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    570                         if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    571                             for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    572                                 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    573                             }
    574                         }
    575                     }
    576                 }
    577             } else {
    578                 // seek a function operator that's compatible
    579                 if ( !doneInit ) {
    580                     doneInit = true;
    581                     NameExpr *opExpr = new NameExpr( "?()" );
    582                     try {
    583                         funcOpFinder.findWithAdjustment( opExpr );
    584                     } catch( SemanticError &e ) {
    585                         // it's ok if there aren't any defined function ops
    586                     }
    587                     PRINT(
    588                         std::cout << "known function ops:" << std::endl;
    589                         printAlts( funcOpFinder.alternatives, std::cout, 8 );
     520        }
     521
     522        template< typename OutputIterator >
     523        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {
     524                OpenVarSet openVars;
     525                AssertionSet resultNeed, resultHave;
     526                TypeEnvironment resultEnv;
     527                makeUnifiableVars( funcType, openVars, resultNeed );
     528                if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
     529                        ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
     530                        Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
     531                        makeExprList( actualAlt, appExpr->get_args() );
     532                        PRINT(
     533                                std::cout << "need assertions:" << std::endl;
     534                                printAssertionSet( resultNeed, std::cout, 8 );
     535                                )
     536                                inferParameters( resultNeed, resultHave, newAlt, openVars, out );
     537                }
     538        }
     539
     540        void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
     541                bool doneInit = false;
     542                AlternativeFinder funcOpFinder( indexer, env );
     543
     544                AlternativeFinder funcFinder( indexer, env ); {
     545                        NameExpr *fname;
     546                        if ( ( fname = dynamic_cast<NameExpr *>( untypedExpr->get_function()))
     547                                 && ( fname->get_name() == std::string("LabAddress")) ) {
     548                                alternatives.push_back( Alternative( untypedExpr, env, Cost()) );
     549                                return;
     550                        }
     551                }
     552
     553                funcFinder.findWithAdjustment( untypedExpr->get_function() );
     554                std::list< AlternativeFinder > argAlternatives;
     555                findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) );
     556
     557                std::list< AltList > possibilities;
     558                combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
     559
     560                Tuples::TupleAssignSpotter tassign( this );
     561                if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) {
     562                        // take care of possible tuple assignments, or discard expression
     563                        return;
     564                } // else ...
     565
     566                AltList candidates;
     567
     568                for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
     569                        PRINT(
     570                                std::cout << "working on alternative: " << std::endl;
     571                                func->print( std::cout, 8 );
     572                                )
     573                                // check if the type is pointer to function
     574                                PointerType *pointer;
     575                        if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
     576                                if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     577                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     578                                                // XXX
     579                                                //Designators::check_alternative( function, *actualAlt );
     580                                                makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     581                                        }
     582                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
     583                                        EqvClass eqvClass;
     584                                        if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
     585                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
     586                                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     587                                                                makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     588                                                        } // for
     589                                                } // if
     590                                        } // if
     591                                } // if
     592                        } else {
     593                                // seek a function operator that's compatible
     594                                if ( ! doneInit ) {
     595                                        doneInit = true;
     596                                        NameExpr *opExpr = new NameExpr( "?()" );
     597                                        try {
     598                                                funcOpFinder.findWithAdjustment( opExpr );
     599                                        } catch( SemanticError &e ) {
     600                                                // it's ok if there aren't any defined function ops
     601                                        }
     602                                        PRINT(
     603                                                std::cout << "known function ops:" << std::endl;
     604                                                printAlts( funcOpFinder.alternatives, std::cout, 8 );
     605                                                )
     606                                                }
     607
     608                                for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     609                                        // check if the type is pointer to function
     610                                        PointerType *pointer;
     611                                        if ( funcOp->expr->get_results().size() == 1
     612                                                 && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
     613                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     614                                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     615                                                                AltList currentAlt;
     616                                                                currentAlt.push_back( *func );
     617                                                                currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
     618                                                                makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
     619                                                        } // for
     620                                                } // if
     621                                        } // if
     622                                } // for
     623                        } // if
     624                } // for
     625
     626                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
     627                        Cost cvtCost = computeConversionCost( *withFunc, indexer );
     628
     629                        PRINT(
     630                                ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
     631                                assert( appExpr );
     632                                PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     633                                assert( pointer );
     634                                FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     635                                assert( function );
     636                                std::cout << "Case +++++++++++++" << std::endl;
     637                                std::cout << "formals are:" << std::endl;
     638                                printAll( function->get_parameters(), std::cout, 8 );
     639                                std::cout << "actuals are:" << std::endl;
     640                                printAll( appExpr->get_args(), std::cout, 8 );
     641                                std::cout << "bindings are:" << std::endl;
     642                                withFunc->env.print( std::cout, 8 );
     643                                std::cout << "cost of conversion is:" << cvtCost << std::endl;
     644                                )
     645                                if ( cvtCost != Cost::infinity ) {
     646                                        withFunc->cvtCost = cvtCost;
     647                                        alternatives.push_back( *withFunc );
     648                                } // if
     649                } // for
     650                candidates.clear();
     651                candidates.splice( candidates.end(), alternatives );
     652
     653                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
     654        }
     655
     656        bool isLvalue( Expression *expr ) {
     657                for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
     658                        if ( !(*i)->get_isLvalue() ) return false;
     659                } // for
     660                return true;
     661        }
     662
     663        void AlternativeFinder::visit( AddressExpr *addressExpr ) {
     664                AlternativeFinder finder( indexer, env );
     665                finder.find( addressExpr->get_arg() );
     666                for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
     667                        if ( isLvalue( i->expr ) ) {
     668                                alternatives.push_back( Alternative( new AddressExpr( i->expr->clone() ), i->env, i->cost ) );
     669                        } // if
     670                } // for
     671        }
     672
     673        void AlternativeFinder::visit( CastExpr *castExpr ) {
     674                for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
     675                        SymTab::validateType( *i, &indexer );
     676                        adjustExprType( *i, env, indexer );
     677                } // for
     678
     679                AlternativeFinder finder( indexer, env );
     680                finder.findWithAdjustment( castExpr->get_arg() );
     681
     682                AltList candidates;
     683                for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
     684                        AssertionSet needAssertions, haveAssertions;
     685                        OpenVarSet openVars;
     686
     687                        // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
     688                        // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
     689                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
     690                        // to.
     691                        int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
     692                        if ( discardedValues < 0 ) continue;
     693                        std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
     694                        std::advance( candidate_end, castExpr->get_results().size() );
     695                        if ( ! unifyList( (*i).expr->get_results().begin(), candidate_end,
     696                                                         castExpr->get_results().begin(), castExpr->get_results().end(), i->env, needAssertions, haveAssertions, openVars, indexer ) ) continue;
     697                        Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
     698                                                                                  castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env );
     699                        if ( thisCost != Cost::infinity ) {
     700                                // count one safe conversion for each value that is thrown away
     701                                thisCost += Cost( 0, 0, discardedValues );
     702                                CastExpr *newExpr = castExpr->clone();
     703                                newExpr->set_arg( i->expr->clone() );
     704                                candidates.push_back( Alternative( newExpr, i->env, i->cost, thisCost ) );
     705                        } // if
     706                } // for
     707
     708                // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the
     709                // cvtCost member to the cost member (since the old cost is now irrelevant).  Thus, calling findMinCost twice
     710                // selects first based on argument cost, then on conversion cost.
     711                AltList minArgCost;
     712                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
     713                findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
     714        }
     715
     716        void AlternativeFinder::visit( UntypedMemberExpr *memberExpr ) {
     717                AlternativeFinder funcFinder( indexer, env );
     718                funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
     719
     720                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
     721                        if ( agg->expr->get_results().size() == 1 ) {
     722                                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
     723                                        addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() );
     724                                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
     725                                        addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() );
     726                                } // if
     727                        } // if
     728                } // for
     729        }
     730
     731        void AlternativeFinder::visit( MemberExpr *memberExpr ) {
     732                alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
     733        }
     734
     735        void AlternativeFinder::visit( NameExpr *nameExpr ) {
     736                std::list< DeclarationWithType* > declList;
     737                indexer.lookupId( nameExpr->get_name(), declList );
     738                PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; )
     739                        for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
     740                                VariableExpr newExpr( *i, nameExpr->get_argName() );
     741                                alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
     742                                PRINT(
     743                                        std::cerr << "decl is ";
     744                                        (*i)->print( std::cerr );
     745                                        std::cerr << std::endl;
     746                                        std::cerr << "newExpr is ";
     747                                        newExpr.print( std::cerr );
     748                                        std::cerr << std::endl;
     749                                        )
     750                                        renameTypes( alternatives.back().expr );
     751                                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
     752                                        addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), "" );
     753                                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
     754                                        addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), "" );
     755                                } // if
     756                        } // for
     757        }
     758
     759        void AlternativeFinder::visit( VariableExpr *variableExpr ) {
     760                alternatives.push_back( Alternative( variableExpr->clone(), env, Cost::zero ) );
     761        }
     762
     763        void AlternativeFinder::visit( ConstantExpr *constantExpr ) {
     764                alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
     765        }
     766
     767        void AlternativeFinder::visit( SizeofExpr *sizeofExpr ) {
     768                if ( sizeofExpr->get_isType() ) {
     769                        alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) );
     770                } else {
     771                        // find all alternatives for the argument to sizeof
     772                        AlternativeFinder finder( indexer, env );
     773                        finder.find( sizeofExpr->get_expr() );
     774                        // find the lowest cost alternative among the alternatives, otherwise ambiguous
     775                        AltList winners;
     776                        findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
     777                        if ( winners.size() != 1 ) {
     778                                throw SemanticError( "Ambiguous expression in sizeof operand: ", sizeofExpr->get_expr() );
     779                        } // if
     780                        // return the lowest cost alternative for the argument
     781                        Alternative &choice = winners.front();
     782                        alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     783                } // if
     784        }
     785
     786        void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
     787                // assume no polymorphism
     788                // assume no implicit conversions
     789                assert( function->get_parameters().size() == 1 );
     790                PRINT(
     791                        std::cout << "resolvAttr: funcDecl is ";
     792                        funcDecl->print( std::cout );
     793                        std::cout << " argType is ";
     794                        argType->print( std::cout );
     795                        std::cout << std::endl;
    590796                        )
    591                 }
    592 
    593                 for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    594                     // check if the type is pointer to function
    595                     PointerType *pointer;
    596                     if ( funcOp->expr->get_results().size() == 1
    597                         && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
    598                         if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    599                             for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    600                                 AltList currentAlt;
    601                                 currentAlt.push_back( *func );
    602                                 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
    603                                 makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
    604                             }
    605                         }
    606                     }
    607                 }
    608             }
    609         }
    610 
    611         for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    612             Cost cvtCost = computeConversionCost( *withFunc, indexer );
    613 
    614             PRINT(
    615                 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
    616                 assert( appExpr );
    617                 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    618                 assert( pointer );
    619                 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    620                 assert( function );
    621                 std::cout << "Case +++++++++++++" << std::endl;
    622                 std::cout << "formals are:" << std::endl;
    623                 printAll( function->get_parameters(), std::cout, 8 );
    624                 std::cout << "actuals are:" << std::endl;
    625                 printAll( appExpr->get_args(), std::cout, 8 );
    626                 std::cout << "bindings are:" << std::endl;
    627                 withFunc->env.print( std::cout, 8 );
    628                 std::cout << "cost of conversion is:" << cvtCost << std::endl;
    629                 )
    630             if ( cvtCost != Cost::infinity ) {
    631                 withFunc->cvtCost = cvtCost;
    632                 alternatives.push_back( *withFunc );
    633             }
    634         }
    635         candidates.clear();
    636         candidates.splice( candidates.end(), alternatives );
    637 
    638         findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
    639     }
    640 
    641     bool isLvalue( Expression *expr ) {
    642         for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
    643             if ( !(*i)->get_isLvalue() ) return false;
    644         }
    645         return true;
    646     }
    647 
    648     void AlternativeFinder::visit( AddressExpr *addressExpr ) {
    649         AlternativeFinder finder( indexer, env );
    650         finder.find( addressExpr->get_arg() );
    651         for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
    652             if ( isLvalue( i->expr ) ) {
    653                 alternatives.push_back( Alternative( new AddressExpr( i->expr->clone() ), i->env, i->cost ) );
    654             }
    655         }
    656     }
    657 
    658     void AlternativeFinder::visit( CastExpr *castExpr ) {
    659         for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
    660             SymTab::validateType( *i, &indexer );
    661             adjustExprType( *i, env, indexer );
    662         }
    663 
    664         AlternativeFinder finder( indexer, env );
    665         finder.findWithAdjustment( castExpr->get_arg() );
    666 
    667         AltList candidates;
    668         for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
    669             AssertionSet needAssertions, haveAssertions;
    670             OpenVarSet openVars;
    671 
    672             // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
    673             // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
    674             // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    675             // to.
    676             int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
    677             if ( discardedValues < 0 ) continue;
    678             std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
    679             std::advance( candidate_end, castExpr->get_results().size() );
    680             if ( !unifyList( (*i).expr->get_results().begin(), candidate_end,
    681                             castExpr->get_results().begin(), castExpr->get_results().end(), i->env, needAssertions, haveAssertions, openVars, indexer ) ) continue;
    682             Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
    683                                           castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env );
    684             if ( thisCost != Cost::infinity ) {
    685                 // count one safe conversion for each value that is thrown away
    686                 thisCost += Cost( 0, 0, discardedValues );
    687                 CastExpr *newExpr = castExpr->clone();
    688                 newExpr->set_arg( i->expr->clone() );
    689                 candidates.push_back( Alternative( newExpr, i->env, i->cost, thisCost ) );
    690             }
    691         }
    692 
    693         // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the
    694         // cvtCost member to the cost member (since the old cost is now irrelevant).  Thus, calling findMinCost twice
    695         // selects first based on argument cost, then on conversion cost.
    696         AltList minArgCost;
    697         findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
    698         findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
    699     }
    700 
    701     void AlternativeFinder::visit( UntypedMemberExpr *memberExpr ) {
    702         AlternativeFinder funcFinder( indexer, env );
    703         funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
    704 
    705         for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    706             if ( agg->expr->get_results().size() == 1 ) {
    707                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
    708                     addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() );
    709                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
    710                     addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() );
    711                 }
    712             }
    713         }
    714     }
    715 
    716     void AlternativeFinder::visit( MemberExpr *memberExpr ) {
    717         alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
    718     }
    719 
    720     void AlternativeFinder::visit( NameExpr *nameExpr ) {
    721         std::list< DeclarationWithType* > declList;
    722         indexer.lookupId( nameExpr->get_name(), declList );
    723         PRINT(
    724             std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl;
    725             )
    726         for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    727             VariableExpr newExpr( *i, nameExpr->get_argName() );
    728             alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    729             PRINT(
    730                 std::cerr << "decl is ";
    731                 (*i)->print( std::cerr );
    732                 std::cerr << std::endl;
    733                 std::cerr << "newExpr is ";
    734                 newExpr.print( std::cerr );
    735                 std::cerr << std::endl;
    736                 )
    737             renameTypes( alternatives.back().expr );
    738             if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    739                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), "" );
    740             } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    741                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), "" );
    742             }
    743         }
    744     }
    745 
    746     void AlternativeFinder::visit( VariableExpr *variableExpr ) {
    747         alternatives.push_back( Alternative( variableExpr->clone(), env, Cost::zero ) );
    748     }
    749 
    750     void AlternativeFinder::visit( ConstantExpr *constantExpr ) {
    751         alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
    752     }
    753 
    754     void AlternativeFinder::visit( SizeofExpr *sizeofExpr ) {
    755         if ( sizeofExpr->get_isType() ) {
    756             alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) );
    757         } else {
    758             // find all alternatives for the argument to sizeof
    759             AlternativeFinder finder( indexer, env );
    760             finder.find( sizeofExpr->get_expr() );
    761             // find the lowest cost alternative among the alternatives, otherwise ambiguous
    762             AltList winners;
    763             findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
    764             if ( winners.size() != 1 ) {
    765                 throw SemanticError( "Ambiguous expression in sizeof operand: ", sizeofExpr->get_expr() );
    766             }
    767             // return the lowest cost alternative for the argument
    768             Alternative &choice = winners.front();
    769             alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
    770         }
    771     }
    772 
    773     void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
    774         // assume no polymorphism
    775         // assume no implicit conversions
    776         assert( function->get_parameters().size() == 1 );
    777         PRINT(
    778             std::cout << "resolvAttr: funcDecl is ";
    779             funcDecl->print( std::cout );
    780             std::cout << " argType is ";
    781             argType->print( std::cout );
    782             std::cout << std::endl;
    783             )
    784         if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
    785             alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    786             for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
    787                 alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
    788             }
    789         }
    790     }
    791 
    792     void AlternativeFinder::visit( AttrExpr *attrExpr ) {
    793         // assume no 'pointer-to-attribute'
    794         NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    795         assert( nameExpr );
    796         std::list< DeclarationWithType* > attrList;
    797         indexer.lookupId( nameExpr->get_name(), attrList );
    798         if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
    799             for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    800                 // check if the type is function
    801                 if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {
    802                     // assume exactly one parameter
    803                     if ( function->get_parameters().size() == 1 ) {
    804                         if ( attrExpr->get_isType() ) {
    805                             resolveAttr( *i, function, attrExpr->get_type(), env );
    806                         } else {
    807                             AlternativeFinder finder( indexer, env );
    808                             finder.find( attrExpr->get_expr() );
    809                             for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    810                                 if ( choice->expr->get_results().size() == 1 ) {
    811                                     resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
    812                                 }
    813                             }
    814                         }
    815                     }
    816                 }
    817             }
    818         } else {
    819             for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    820                 VariableExpr newExpr( *i );
    821                 alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    822                 renameTypes( alternatives.back().expr );
    823             }
    824         }
    825     }
    826 
    827     void AlternativeFinder::visit( LogicalExpr *logicalExpr ) {
    828         AlternativeFinder firstFinder( indexer, env );
    829         firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
    830         for ( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
    831             AlternativeFinder secondFinder( indexer, first->env );
    832             secondFinder.findWithAdjustment( logicalExpr->get_arg2() );
    833             for ( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
    834                 LogicalExpr *newExpr = new LogicalExpr( first->expr->clone(), second->expr->clone(), logicalExpr->get_isAnd() );
    835                 alternatives.push_back( Alternative( newExpr, second->env, first->cost + second->cost ) );
    836             }
    837         }
    838     }
    839 
    840     void AlternativeFinder::visit( ConditionalExpr *conditionalExpr ) {
    841         AlternativeFinder firstFinder( indexer, env );
    842         firstFinder.findWithAdjustment( conditionalExpr->get_arg1() );
    843         for ( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
    844             AlternativeFinder secondFinder( indexer, first->env );
    845             secondFinder.findWithAdjustment( conditionalExpr->get_arg2() );
    846             for ( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
    847                 AlternativeFinder thirdFinder( indexer, second->env );
    848                 thirdFinder.findWithAdjustment( conditionalExpr->get_arg3() );
    849                 for ( AltList::const_iterator third = thirdFinder.alternatives.begin(); third != thirdFinder.alternatives.end(); ++third ) {
    850                     OpenVarSet openVars;
    851                     AssertionSet needAssertions, haveAssertions;
    852                     Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
    853                     std::list< Type* > commonTypes;
    854                     if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
    855                         ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    856                         std::list< Type* >::const_iterator original = second->expr->get_results().begin();
    857                         std::list< Type* >::const_iterator commonType = commonTypes.begin();
    858                         for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
    859                             if ( *commonType ) {
    860                                 newExpr->get_results().push_back( *commonType );
    861                             } else {
    862                                 newExpr->get_results().push_back( (*original)->clone() );
    863                             }
    864                         }
    865                         newAlt.expr = newExpr;
    866                         inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
    867                     }
    868                 }
    869             }
    870         }
    871     }
    872 
    873     void AlternativeFinder::visit( CommaExpr *commaExpr ) {
    874         TypeEnvironment newEnv( env );
    875         Expression *newFirstArg = resolveInVoidContext( commaExpr->get_arg1(), indexer, newEnv );
    876         AlternativeFinder secondFinder( indexer, newEnv );
    877         secondFinder.findWithAdjustment( commaExpr->get_arg2() );
    878         for ( AltList::const_iterator alt = secondFinder.alternatives.begin(); alt != secondFinder.alternatives.end(); ++alt ) {
    879             alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt->expr->clone() ), alt->env, alt->cost ) );
    880         }
    881         delete newFirstArg;
    882     }
    883 
    884     void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
    885         std::list< AlternativeFinder > subExprAlternatives;
    886         findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
    887         std::list< AltList > possibilities;
    888         combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
    889         for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
    890             TupleExpr *newExpr = new TupleExpr;
    891             makeExprList( *i, newExpr->get_exprs() );
    892             for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
    893                 for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
    894                     newExpr->get_results().push_back( (*resultType)->clone() );
    895                 }
    896             }
    897 
    898             TypeEnvironment compositeEnv;
    899             simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
    900             alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
    901         }
    902     }
     797                        if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
     798                                alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
     799                                for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
     800                                        alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
     801                                } // for
     802                        } // if
     803        }
     804
     805        void AlternativeFinder::visit( AttrExpr *attrExpr ) {
     806                // assume no 'pointer-to-attribute'
     807                NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
     808                assert( nameExpr );
     809                std::list< DeclarationWithType* > attrList;
     810                indexer.lookupId( nameExpr->get_name(), attrList );
     811                if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
     812                        for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
     813                                // check if the type is function
     814                                if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {
     815                                        // assume exactly one parameter
     816                                        if ( function->get_parameters().size() == 1 ) {
     817                                                if ( attrExpr->get_isType() ) {
     818                                                        resolveAttr( *i, function, attrExpr->get_type(), env );
     819                                                } else {
     820                                                        AlternativeFinder finder( indexer, env );
     821                                                        finder.find( attrExpr->get_expr() );
     822                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
     823                                                                if ( choice->expr->get_results().size() == 1 ) {
     824                                                                        resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
     825                                                                } // fi
     826                                                        } // for
     827                                                } // if
     828                                        } // if
     829                                } // if
     830                        } // for
     831                } else {
     832                        for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
     833                                VariableExpr newExpr( *i );
     834                                alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
     835                                renameTypes( alternatives.back().expr );
     836                        } // for
     837                } // if
     838        }
     839
     840        void AlternativeFinder::visit( LogicalExpr *logicalExpr ) {
     841                AlternativeFinder firstFinder( indexer, env );
     842                firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
     843                for ( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
     844                        AlternativeFinder secondFinder( indexer, first->env );
     845                        secondFinder.findWithAdjustment( logicalExpr->get_arg2() );
     846                        for ( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
     847                                LogicalExpr *newExpr = new LogicalExpr( first->expr->clone(), second->expr->clone(), logicalExpr->get_isAnd() );
     848                                alternatives.push_back( Alternative( newExpr, second->env, first->cost + second->cost ) );
     849                        }
     850                }
     851        }
     852
     853        void AlternativeFinder::visit( ConditionalExpr *conditionalExpr ) {
     854                AlternativeFinder firstFinder( indexer, env );
     855                firstFinder.findWithAdjustment( conditionalExpr->get_arg1() );
     856                for ( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
     857                        AlternativeFinder secondFinder( indexer, first->env );
     858                        secondFinder.findWithAdjustment( conditionalExpr->get_arg2() );
     859                        for ( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
     860                                AlternativeFinder thirdFinder( indexer, second->env );
     861                                thirdFinder.findWithAdjustment( conditionalExpr->get_arg3() );
     862                                for ( AltList::const_iterator third = thirdFinder.alternatives.begin(); third != thirdFinder.alternatives.end(); ++third ) {
     863                                        OpenVarSet openVars;
     864                                        AssertionSet needAssertions, haveAssertions;
     865                                        Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
     866                                        std::list< Type* > commonTypes;
     867                                        if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
     868                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
     869                                                std::list< Type* >::const_iterator original = second->expr->get_results().begin();
     870                                                std::list< Type* >::const_iterator commonType = commonTypes.begin();
     871                                                for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
     872                                                        if ( *commonType ) {
     873                                                                newExpr->get_results().push_back( *commonType );
     874                                                        } else {
     875                                                                newExpr->get_results().push_back( (*original)->clone() );
     876                                                        } // if
     877                                                } // for
     878                                                newAlt.expr = newExpr;
     879                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     880                                        } // if
     881                                } // for
     882                        } // for
     883                } // for
     884        }
     885
     886        void AlternativeFinder::visit( CommaExpr *commaExpr ) {
     887                TypeEnvironment newEnv( env );
     888                Expression *newFirstArg = resolveInVoidContext( commaExpr->get_arg1(), indexer, newEnv );
     889                AlternativeFinder secondFinder( indexer, newEnv );
     890                secondFinder.findWithAdjustment( commaExpr->get_arg2() );
     891                for ( AltList::const_iterator alt = secondFinder.alternatives.begin(); alt != secondFinder.alternatives.end(); ++alt ) {
     892                        alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt->expr->clone() ), alt->env, alt->cost ) );
     893                } // for
     894                delete newFirstArg;
     895        }
     896
     897        void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
     898                std::list< AlternativeFinder > subExprAlternatives;
     899                findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
     900                std::list< AltList > possibilities;
     901                combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
     902                for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
     903                        TupleExpr *newExpr = new TupleExpr;
     904                        makeExprList( *i, newExpr->get_exprs() );
     905                        for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
     906                                for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
     907                                        newExpr->get_results().push_back( (*resultType)->clone() );
     908                                } // for
     909                        } // for
     910
     911                        TypeEnvironment compositeEnv;
     912                        simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
     913                        alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
     914                } // for
     915        }
    903916} // namespace ResolvExpr
     917
     918// Local Variables: //
     919// tab-width: 4 //
     920// mode: c++ //
     921// compile-command: "make install" //
     922// End: //
  • translator/ResolvExpr/AlternativeFinder.h

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// AlternativeFinder.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sat May 16 23:56:12 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 23:58:43 2015
     13// Update Count     : 2
     14//
     15
    116#ifndef ALTERNATIVEFINDER_H
    217#define ALTERNATIVEFINDER_H
     
    1126
    1227namespace ResolvExpr {
    13     class AlternativeFinder : public Visitor {
    14       public:
    15         AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env );
    16         void find( Expression *expr, bool adjust = false );
    17         void findWithAdjustment( Expression *expr );
    18         AltList &get_alternatives() { return alternatives; }
    19  
    20         // make this look like an STL container so that we can apply generic algorithms
    21         typedef Alternative value_type;
    22         typedef AltList::iterator iterator;
    23         typedef AltList::const_iterator const_iterator;
    24         AltList::iterator begin() { return alternatives.begin(); }
    25         AltList::iterator end() { return alternatives.end(); }
    26         AltList::const_iterator begin() const { return alternatives.begin(); }
    27         AltList::const_iterator end() const { return alternatives.end(); }
    28  
    29         const SymTab::Indexer &get_indexer() const { return indexer; }
    30         const TypeEnvironment &get_environ() const { return env; }
    31       private:
    32         virtual void visit( ApplicationExpr *applicationExpr );
    33         virtual void visit( UntypedExpr *untypedExpr );
    34         virtual void visit( AddressExpr *addressExpr );
    35         virtual void visit( CastExpr *castExpr );
    36         virtual void visit( UntypedMemberExpr *memberExpr );
    37         virtual void visit( MemberExpr *memberExpr );
    38         virtual void visit( NameExpr *variableExpr );
    39         virtual void visit( VariableExpr *variableExpr );
    40         virtual void visit( ConstantExpr *constantExpr );
    41         virtual void visit( SizeofExpr *sizeofExpr );
    42         virtual void visit( AttrExpr *attrExpr );
    43         virtual void visit( LogicalExpr *logicalExpr );
    44         virtual void visit( ConditionalExpr *conditionalExpr );
    45         virtual void visit( CommaExpr *commaExpr );
    46         virtual void visit( TupleExpr *tupleExpr );
    47       public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
    48         template< typename InputIterator, typename OutputIterator >
    49             void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
     28        class AlternativeFinder : public Visitor {
     29          public:
     30                AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env );
     31                void find( Expression *expr, bool adjust = false );
     32                void findWithAdjustment( Expression *expr );
     33                AltList &get_alternatives() { return alternatives; }
    5034
    51       private:
    52         template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name );
    53         bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave );
    54         template< typename OutputIterator >
    55             void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out );
    56         template< typename OutputIterator >
    57             void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
    58         void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );
     35                // make this look like an STL container so that we can apply generic algorithms
     36                typedef Alternative value_type;
     37                typedef AltList::iterator iterator;
     38                typedef AltList::const_iterator const_iterator;
     39                AltList::iterator begin() { return alternatives.begin(); }
     40                AltList::iterator end() { return alternatives.end(); }
     41                AltList::const_iterator begin() const { return alternatives.begin(); }
     42                AltList::const_iterator end() const { return alternatives.end(); }
    5943
    60         const SymTab::Indexer &indexer;
    61         AltList alternatives;
    62         const TypeEnvironment &env;
    63     }; // AlternativeFinder
     44                const SymTab::Indexer &get_indexer() const { return indexer; }
     45                const TypeEnvironment &get_environ() const { return env; }
     46          private:
     47                virtual void visit( ApplicationExpr *applicationExpr );
     48                virtual void visit( UntypedExpr *untypedExpr );
     49                virtual void visit( AddressExpr *addressExpr );
     50                virtual void visit( CastExpr *castExpr );
     51                virtual void visit( UntypedMemberExpr *memberExpr );
     52                virtual void visit( MemberExpr *memberExpr );
     53                virtual void visit( NameExpr *variableExpr );
     54                virtual void visit( VariableExpr *variableExpr );
     55                virtual void visit( ConstantExpr *constantExpr );
     56                virtual void visit( SizeofExpr *sizeofExpr );
     57                virtual void visit( AttrExpr *attrExpr );
     58                virtual void visit( LogicalExpr *logicalExpr );
     59                virtual void visit( ConditionalExpr *conditionalExpr );
     60                virtual void visit( CommaExpr *commaExpr );
     61                virtual void visit( TupleExpr *tupleExpr );
     62          public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
     63                template< typename InputIterator, typename OutputIterator >
     64                void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    6465
    65     Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
     66          private:
     67                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name );
     68                bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave );
     69                template< typename OutputIterator >
     70                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out );
     71                template< typename OutputIterator >
     72                void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
     73                void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );
     74
     75                const SymTab::Indexer &indexer;
     76                AltList alternatives;
     77                const TypeEnvironment &env;
     78        }; // AlternativeFinder
     79
     80        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
    6681} // namespace ResolvExpr
    6782
    6883#endif // ALTERNATIVEFINDER_H
     84
     85// Local Variables: //
     86// tab-width: 4 //
     87// mode: c++ //
     88// compile-command: "make install" //
     89// End: //
  • translator/ResolvExpr/AlternativePrinter.cc

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// AlternativePrinter.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 06:53:19 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 06:55:05 2015
     13// Update Count     : 2
     14//
     15
    116#include "AlternativePrinter.h"
    217#include "AlternativeFinder.h"
     
    823
    924namespace ResolvExpr {
    10     AlternativePrinter::AlternativePrinter( std::ostream &os ) : SymTab::Indexer( false ), os( os ) {}
     25        AlternativePrinter::AlternativePrinter( std::ostream &os ) : SymTab::Indexer( false ), os( os ) {}
    1126
    12     void AlternativePrinter::visit( ExprStmt *exprStmt ) {
    13         TypeEnvironment env;
    14         AlternativeFinder finder( *this, env );
    15         finder.findWithAdjustment( exprStmt->get_expr() );
    16         int count = 1;
    17         os << "There are " << finder.get_alternatives().size() << " alternatives" << std::endl;
    18         for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    19             os << "Alternative " << count++ << " ==============" << std::endl;
    20             printAll( i->expr->get_results(), os );
    21             //    i->print( os );
    22             os << std::endl;
    23         } // for
    24     } // AlternativePrinter::visit
     27        void AlternativePrinter::visit( ExprStmt *exprStmt ) {
     28                TypeEnvironment env;
     29                AlternativeFinder finder( *this, env );
     30                finder.findWithAdjustment( exprStmt->get_expr() );
     31                int count = 1;
     32                os << "There are " << finder.get_alternatives().size() << " alternatives" << std::endl;
     33                for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     34                        os << "Alternative " << count++ << " ==============" << std::endl;
     35                        printAll( i->expr->get_results(), os );
     36                        //    i->print( os );
     37                        os << std::endl;
     38                } // for
     39        } // AlternativePrinter::visit
    2540} // namespace ResolvExpr
     41
     42// Local Variables: //
     43// tab-width: 4 //
     44// mode: c++ //
     45// compile-command: "make install" //
     46// End: //
  • translator/ResolvExpr/AlternativePrinter.h

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// AlternativePrinter.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 06:55:43 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 06:57:12 2015
     13// Update Count     : 3
     14//
     15
    116#ifndef ALTERNATIVEPRINTER_H
    217#define ALTERNATIVEPRINTER_H
     
    823
    924namespace ResolvExpr {
    10     class AlternativePrinter : public SymTab::Indexer {
    11       public:
    12         AlternativePrinter( std::ostream &os );
    13         virtual void visit(ExprStmt *exprStmt);
    14       private:
    15         std::ostream &os;
    16     };
     25        class AlternativePrinter : public SymTab::Indexer {
     26          public:
     27                AlternativePrinter( std::ostream &os );
     28                virtual void visit( ExprStmt *exprStmt );
     29          private:
     30                std::ostream &os;
     31        };
    1732} // namespace ResolvExpr
    1833
    1934#endif // ALTERNATIVEPRINTER_H
     35
     36// Local Variables: //
     37// tab-width: 4 //
     38// mode: c++ //
     39// compile-command: "make install" //
     40// End: //
  • translator/ResolvExpr/CastCost.cc

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// CastCost.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 06:57:43 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 06:59:10 2015
     13// Update Count     : 2
     14//
     15
    116#include "typeops.h"
    217#include "Cost.h"
     
    823
    924namespace ResolvExpr {
    10     class CastCost : public ConversionCost {
    11       public:
    12         CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     25        class CastCost : public ConversionCost {
     26          public:
     27                CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    1328 
    14         virtual void visit( BasicType *basicType );
    15         virtual void visit( PointerType *pointerType );
    16     };
     29                virtual void visit( BasicType *basicType );
     30                virtual void visit( PointerType *pointerType );
     31        };
    1732
    18     Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    19         if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    20             EqvClass eqvClass;
    21             NamedTypeDecl *namedType;
    22             if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
    23                 return castCost( src, eqvClass.type, indexer, env );
    24             } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
    25                 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    26                 // all typedefs should be gone by this point
    27                 assert( type );
    28                 if ( type->get_base() ) {
    29                     return castCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 );
     33        Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     34                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     35                        EqvClass eqvClass;
     36                        NamedTypeDecl *namedType;
     37                        if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
     38                                return castCost( src, eqvClass.type, indexer, env );
     39                        } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
     40                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     41                                // all typedefs should be gone by this point
     42                                assert( type );
     43                                if ( type->get_base() ) {
     44                                        return castCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 );
     45                                } // if
     46                        } // if
    3047                } // if
    31             } // if
    32         } // if
    33         if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
    34             return Cost( 0, 0, 0 );
    35         } else if ( dynamic_cast< VoidType* >( dest ) ) {
    36             return Cost( 0, 0, 1 );
    37         } else {
    38             CastCost converter( dest, indexer, env );
    39             src->accept( converter );
    40             if ( converter.get_cost() == Cost::infinity ) {
    41                 return Cost::infinity;
    42             } else {
    43                 return converter.get_cost() + Cost( 0, 0, 0 );
    44             } // if
    45         } // if
    46     }
     48                if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
     49                        return Cost( 0, 0, 0 );
     50                } else if ( dynamic_cast< VoidType* >( dest ) ) {
     51                        return Cost( 0, 0, 1 );
     52                } else {
     53                        CastCost converter( dest, indexer, env );
     54                        src->accept( converter );
     55                        if ( converter.get_cost() == Cost::infinity ) {
     56                                return Cost::infinity;
     57                        } else {
     58                                return converter.get_cost() + Cost( 0, 0, 0 );
     59                        } // if
     60                } // if
     61        }
    4762
    48     CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    49         : ConversionCost( dest, indexer, env ) {
    50     }
     63        CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
     64                : ConversionCost( dest, indexer, env ) {
     65        }
    5166
    52     void CastCost::visit( BasicType *basicType ) {
    53         if ( dynamic_cast< PointerType* >( dest ) ) {
    54             cost = Cost( 1, 0, 0 );
    55         } else {
    56             ConversionCost::visit( basicType );
    57         } // if
    58     }
     67        void CastCost::visit( BasicType *basicType ) {
     68                if ( dynamic_cast< PointerType* >( dest ) ) {
     69                        cost = Cost( 1, 0, 0 );
     70                } else {
     71                        ConversionCost::visit( basicType );
     72                } // if
     73        }
    5974
    60     void CastCost::visit( PointerType *pointerType ) {
    61         if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    62             if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
    63                 cost = Cost( 0, 0, 1 );
    64             } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    65                 if ( destAsBasic->isInteger() ) {
    66                     cost = Cost( 1, 0, 0 );
    67                 }
    68             } else {
    69                 TypeEnvironment newEnv( env );
    70                 newEnv.add( pointerType->get_forall() );
    71                 newEnv.add( pointerType->get_base()->get_forall() );
    72                 int assignResult = ptrsCastable( pointerType->get_base(), destAsPtr->get_base(), newEnv, indexer );
    73                 if ( assignResult > 0 ) {
    74                     cost = Cost( 0, 0, 1 );
    75                 } else if ( assignResult < 0 ) {
    76                     cost = Cost( 1, 0, 0 );
     75        void CastCost::visit( PointerType *pointerType ) {
     76                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
     77                        if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
     78                                cost = Cost( 0, 0, 1 );
     79                        } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     80                                if ( destAsBasic->isInteger() ) {
     81                                        cost = Cost( 1, 0, 0 );
     82                                } // if
     83                        } else {
     84                                TypeEnvironment newEnv( env );
     85                                newEnv.add( pointerType->get_forall() );
     86                                newEnv.add( pointerType->get_base()->get_forall() );
     87                                int assignResult = ptrsCastable( pointerType->get_base(), destAsPtr->get_base(), newEnv, indexer );
     88                                if ( assignResult > 0 ) {
     89                                        cost = Cost( 0, 0, 1 );
     90                                } else if ( assignResult < 0 ) {
     91                                        cost = Cost( 1, 0, 0 );
     92                                } // if
     93                        } // if
    7794                } // if
    78             } // if
    79         } // if
    80     }
     95        }
    8196} // namespace ResolvExpr
     97
     98// Local Variables: //
     99// tab-width: 4 //
     100// mode: c++ //
     101// compile-command: "make install" //
     102// End: //
  • translator/ResolvExpr/CommonType.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: CommonType.cc,v 1.6 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// CommonType.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 06:59:27 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 07:04:50 2015
     13// Update Count     : 2
     14//
    715
    816#include "typeops.h"
     
    1422
    1523namespace ResolvExpr {
    16 
    17 class CommonType : public Visitor
    18 {
    19 public:
    20   CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    21  
    22   Type *get_result() const { return result; }
    23 
    24 private:
    25   virtual void visit( VoidType *voidType );
    26   virtual void visit( BasicType *basicType );
    27   virtual void visit( PointerType *pointerType );
    28   virtual void visit( ArrayType *arrayType );
    29   virtual void visit( FunctionType *functionType );
    30   virtual void visit( StructInstType *aggregateUseType );
    31   virtual void visit( UnionInstType *aggregateUseType );
    32   virtual void visit( EnumInstType *aggregateUseType );
    33   virtual void visit( ContextInstType *aggregateUseType );
    34   virtual void visit( TypeInstType *aggregateUseType );
    35   virtual void visit( TupleType *tupleType );
    36 
    37   template< typename RefType > void handleRefType( RefType *inst, Type *other );
    38 
    39   Type *result;
    40   Type *type2;                          // inherited
    41   bool widenFirst, widenSecond;
    42   const SymTab::Indexer &indexer;
    43   TypeEnvironment &env;
    44   const OpenVarSet &openVars;
    45 };
    46 
    47 Type *
    48 commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
    49 {
    50   CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
    51   type1->accept( visitor );
    52   Type *result = visitor.get_result();
    53   if( !result ) {
    54     if( widenSecond ) {
    55       TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 );
    56       if( inst ) {
    57         NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
    58         if( nt ) {
    59           TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
    60           assert( type );
    61           if( type->get_base() ) {
    62             Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
    63             AssertionSet have, need;
    64             OpenVarSet newOpen( openVars );
    65             type1->get_qualifiers() = Type::Qualifiers();
    66             type->get_base()->get_qualifiers() = tq1;
    67             if( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
    68               result = type1->clone();
    69               result->get_qualifiers() = tq1 + tq2;
    70             }
    71             type1->get_qualifiers() = tq1;
    72             type->get_base()->get_qualifiers() = Type::Qualifiers();
    73           }
    74         }
    75       }
    76     }
    77   }
     24        class CommonType : public Visitor {
     25          public:
     26                CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     27                Type *get_result() const { return result; }
     28          private:
     29                virtual void visit( VoidType *voidType );
     30                virtual void visit( BasicType *basicType );
     31                virtual void visit( PointerType *pointerType );
     32                virtual void visit( ArrayType *arrayType );
     33                virtual void visit( FunctionType *functionType );
     34                virtual void visit( StructInstType *aggregateUseType );
     35                virtual void visit( UnionInstType *aggregateUseType );
     36                virtual void visit( EnumInstType *aggregateUseType );
     37                virtual void visit( ContextInstType *aggregateUseType );
     38                virtual void visit( TypeInstType *aggregateUseType );
     39                virtual void visit( TupleType *tupleType );
     40
     41                template< typename RefType > void handleRefType( RefType *inst, Type *other );
     42
     43                Type *result;
     44                Type *type2;                            // inherited
     45                bool widenFirst, widenSecond;
     46                const SymTab::Indexer &indexer;
     47                TypeEnvironment &env;
     48                const OpenVarSet &openVars;
     49        };
     50
     51        Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
     52                CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
     53                type1->accept( visitor );
     54                Type *result = visitor.get_result();
     55                if ( ! result ) {
     56                        if ( widenSecond ) {
     57                                TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 );
     58                                if ( inst ) {
     59                                        NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
     60                                        if ( nt ) {
     61                                                TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
     62                                                assert( type );
     63                                                if ( type->get_base() ) {
     64                                                        Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
     65                                                        AssertionSet have, need;
     66                                                        OpenVarSet newOpen( openVars );
     67                                                        type1->get_qualifiers() = Type::Qualifiers();
     68                                                        type->get_base()->get_qualifiers() = tq1;
     69                                                        if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
     70                                                                result = type1->clone();
     71                                                                result->get_qualifiers() = tq1 + tq2;
     72                                                        } // if
     73                                                        type1->get_qualifiers() = tq1;
     74                                                        type->get_base()->get_qualifiers() = Type::Qualifiers();
     75                                                } // if
     76                                        } // if
     77                                } // if
     78                        } // if
     79                } // if
    7880#ifdef DEBUG
    79   std::cout << "============= commonType" << std::endl << "type1 is ";
    80   type1->print( std::cout );
    81   std::cout << " type2 is ";
    82   type2->print( std::cout );
    83   if( result ) {
    84     std::cout << " common type is ";
    85     result->print( std::cout );
    86   } else {
    87     std::cout << " no common type";
    88   }
    89   std::cout << std::endl;
     81                std::cout << "============= commonType" << std::endl << "type1 is ";
     82                type1->print( std::cout );
     83                std::cout << " type2 is ";
     84                type2->print( std::cout );
     85                if ( result ) {
     86                        std::cout << " common type is ";
     87                        result->print( std::cout );
     88                } else {
     89                        std::cout << " no common type";
     90                } // if
     91                std::cout << std::endl;
    9092#endif
    91   return result;
    92 }
    93 
    94 static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
    95 {
     93                return result;
     94        }
     95
     96        static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
     97        {
    9698/*              Bool            Char    SignedChar      UnsignedChar    ShortSignedInt  ShortUnsignedInt        SignedInt       UnsignedInt     LongSignedInt   LongUnsignedInt LongLongSignedInt       LongLongUnsignedInt     Float   Double  LongDouble      FloatComplex    DoubleComplex   LongDoubleComplex       FloatImaginary  DoubleImaginary LongDoubleImaginary */
    97 /* Bool */      { BasicType::Bool,              BasicType::Char,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    98 /* Char */      { BasicType::Char,              BasicType::Char,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    99 /* SignedChar */        { BasicType::SignedChar,        BasicType::UnsignedChar,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    100 /* UnsignedChar */      { BasicType::UnsignedChar,      BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    101 /* ShortSignedInt */    { BasicType::ShortSignedInt,    BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    102 /* ShortUnsignedInt */  { BasicType::ShortUnsignedInt,  BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    103 /* SignedInt */         { BasicType::SignedInt,         BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    104 /* UnsignedInt */       { BasicType::UnsignedInt,               BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    105 /* LongSignedInt */     { BasicType::LongSignedInt,             BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    106 /* LongUnsignedInt */   { BasicType::LongUnsignedInt,   BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    107 /* LongLongSignedInt */         { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    108 /* LongLongUnsignedInt */       { BasicType::LongLongUnsignedInt,       BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    109 /* Float */     { BasicType::Float,     BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    110 /* Double */    { BasicType::Double,    BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::LongDouble,  BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    111 /* LongDouble */        { BasicType::LongDouble,                BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex },
    112 /* FloatComplex */      { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    113 /* DoubleComplex */     { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    114 /* LongDoubleComplex */         { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex },
    115 /* FloatImaginary */    { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatImaginary,      BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary },
    116 /* DoubleImaginary */   { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleImaginary,     BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary },
    117 /* LongDoubleImaginary */       { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary }
    118 };
    119 
    120 CommonType::CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
    121   : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars )
    122 {
    123 }
    124 
    125 void
    126 CommonType::visit( VoidType *voidType )
    127 {
    128 }
    129 
    130 void
    131 CommonType::visit( BasicType *basicType )
    132 {
    133   if( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    134     BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ];
    135     if( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
    136       result = new BasicType( basicType->get_qualifiers() + otherBasic->get_qualifiers(), newType );
    137     }
    138   }
    139 }
    140 
    141 void
    142 CommonType::visit( PointerType *pointerType )
    143 {
    144   if( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    145     if( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) ) {
    146       result = otherPointer->clone();
    147       result->get_qualifiers() += pointerType->get_qualifiers();
    148     } else if( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) ) {
    149       result = pointerType->clone();
    150       result->get_qualifiers() += otherPointer->get_qualifiers();
    151     } else if( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
    152                && ( pointerType->get_base()->get_qualifiers() <= otherPointer->get_base()->get_qualifiers() || widenSecond ) ) {
    153       Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();
    154       pointerType->get_base()->get_qualifiers() = Type::Qualifiers();
    155       otherPointer->get_base()->get_qualifiers() = Type::Qualifiers();
    156       AssertionSet have, need;
    157       OpenVarSet newOpen( openVars );
    158       if( unifyExact( pointerType->get_base(), otherPointer->get_base(), env, have, need, newOpen, indexer ) ) {
    159         if( tq1 < tq2 ) {
    160           result = pointerType->clone();
    161         } else {
    162           result = otherPointer->clone();
    163         }
    164         result->get_qualifiers() = tq1 + tq2;
    165       } else {
    166         /// std::cout << "place for ptr-to-type" << std::endl;
    167       }
    168       pointerType->get_base()->get_qualifiers() = tq1;
    169       otherPointer->get_base()->get_qualifiers() = tq2;
    170     }
    171   }
    172 }
    173 
    174 void
    175 CommonType::visit( ArrayType *arrayType )
    176 {
    177 }
    178 
    179 void
    180 CommonType::visit( FunctionType *functionType )
    181 {
    182 }
    183 
    184 template< typename RefType > void
    185 CommonType::handleRefType( RefType *inst, Type *other )
    186 {
    187 }
    188 
    189 void
    190 CommonType::visit( StructInstType *aggregateUseType )
    191 {
    192 }
    193 
    194 void
    195 CommonType::visit( UnionInstType *aggregateUseType )
    196 {
    197 }
    198 
    199 void
    200 CommonType::visit( EnumInstType *aggregateUseType )
    201 {
    202 }
    203 
    204 void
    205 CommonType::visit( ContextInstType *aggregateUseType )
    206 {
    207 }
    208 
    209 void
    210 CommonType::visit( TypeInstType *inst )
    211 {
    212   if( widenFirst ) {
    213     NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
    214     if( nt ) {
    215       TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
    216       assert( type );
    217       if( type->get_base() ) {
    218         Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers();
    219         AssertionSet have, need;
    220         OpenVarSet newOpen( openVars );
    221         type2->get_qualifiers() = Type::Qualifiers();
    222         type->get_base()->get_qualifiers() = tq1;
    223         if( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
    224           result = type2->clone();
    225           result->get_qualifiers() = tq1 + tq2;
    226         }
    227         type2->get_qualifiers() = tq2;
    228         type->get_base()->get_qualifiers() = Type::Qualifiers();
    229       }
    230     }
    231   }
    232 }
    233 
    234 void
    235 CommonType::visit( TupleType *tupleType )
    236 {
    237 }
    238 
     99                /* Bool */      { BasicType::Bool,              BasicType::Char,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     100                /* Char */      { BasicType::Char,              BasicType::Char,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     101                /* SignedChar */        { BasicType::SignedChar,        BasicType::UnsignedChar,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     102                /* UnsignedChar */      { BasicType::UnsignedChar,      BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     103                /* ShortSignedInt */    { BasicType::ShortSignedInt,    BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     104                /* ShortUnsignedInt */  { BasicType::ShortUnsignedInt,  BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     105                /* SignedInt */         { BasicType::SignedInt,         BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     106                /* UnsignedInt */       { BasicType::UnsignedInt,               BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     107                /* LongSignedInt */     { BasicType::LongSignedInt,             BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     108                /* LongUnsignedInt */   { BasicType::LongUnsignedInt,   BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     109                /* LongLongSignedInt */         { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     110                /* LongLongUnsignedInt */       { BasicType::LongLongUnsignedInt,       BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     111                /* Float */     { BasicType::Float,     BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     112                /* Double */    { BasicType::Double,    BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::LongDouble,  BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     113                /* LongDouble */        { BasicType::LongDouble,                BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex },
     114                /* FloatComplex */      { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     115                /* DoubleComplex */     { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
     116                /* LongDoubleComplex */         { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex },
     117                /* FloatImaginary */    { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatImaginary,      BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary },
     118                /* DoubleImaginary */   { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleImaginary,     BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary },
     119                /* LongDoubleImaginary */       { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary }
     120        };
     121
     122        CommonType::CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
     123                : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) {
     124        }
     125
     126        void CommonType::visit( VoidType *voidType ) {
     127        }
     128
     129        void CommonType::visit( BasicType *basicType ) {
     130                if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
     131                        BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ];
     132                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
     133                                result = new BasicType( basicType->get_qualifiers() + otherBasic->get_qualifiers(), newType );
     134                        } // if
     135                } // if
     136        }
     137
     138        void CommonType::visit( PointerType *pointerType ) {
     139                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
     140                        if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) ) {
     141                                result = otherPointer->clone();
     142                                result->get_qualifiers() += pointerType->get_qualifiers();
     143                        } else if ( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) ) {
     144                                result = pointerType->clone();
     145                                result->get_qualifiers() += otherPointer->get_qualifiers();
     146                        } else if ( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
     147                                           && ( pointerType->get_base()->get_qualifiers() <= otherPointer->get_base()->get_qualifiers() || widenSecond ) ) {
     148                                Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();
     149                                pointerType->get_base()->get_qualifiers() = Type::Qualifiers();
     150                                otherPointer->get_base()->get_qualifiers() = Type::Qualifiers();
     151                                AssertionSet have, need;
     152                                OpenVarSet newOpen( openVars );
     153                                if ( unifyExact( pointerType->get_base(), otherPointer->get_base(), env, have, need, newOpen, indexer ) ) {
     154                                        if ( tq1 < tq2 ) {
     155                                                result = pointerType->clone();
     156                                        } else {
     157                                                result = otherPointer->clone();
     158                                        } // if
     159                                        result->get_qualifiers() = tq1 + tq2;
     160                                } else {
     161                                        /// std::cout << "place for ptr-to-type" << std::endl;
     162                                } // if
     163                                pointerType->get_base()->get_qualifiers() = tq1;
     164                                otherPointer->get_base()->get_qualifiers() = tq2;
     165                        } // if
     166                } // if
     167        }
     168
     169        void CommonType::visit( ArrayType *arrayType ) {
     170        }
     171
     172        void CommonType::visit( FunctionType *functionType ) {
     173        }
     174
     175        template< typename RefType > void CommonType::handleRefType( RefType *inst, Type *other ) {
     176        }
     177
     178        void CommonType::visit( StructInstType *aggregateUseType ) {
     179        }
     180
     181        void CommonType::visit( UnionInstType *aggregateUseType ) {
     182        }
     183
     184        void CommonType::visit( EnumInstType *aggregateUseType ) {
     185        }
     186
     187        void CommonType::visit( ContextInstType *aggregateUseType ) {
     188        }
     189
     190        void CommonType::visit( TypeInstType *inst ) {
     191                if ( widenFirst ) {
     192                        NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
     193                        if ( nt ) {
     194                                TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
     195                                assert( type );
     196                                if ( type->get_base() ) {
     197                                        Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers();
     198                                        AssertionSet have, need;
     199                                        OpenVarSet newOpen( openVars );
     200                                        type2->get_qualifiers() = Type::Qualifiers();
     201                                        type->get_base()->get_qualifiers() = tq1;
     202                                        if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
     203                                                result = type2->clone();
     204                                                result->get_qualifiers() = tq1 + tq2;
     205                                        } // if
     206                                        type2->get_qualifiers() = tq2;
     207                                        type->get_base()->get_qualifiers() = Type::Qualifiers();
     208                                } // if
     209                        } // if
     210                } // if
     211        }
     212
     213        void CommonType::visit( TupleType *tupleType ) {
     214        }
    239215} // namespace ResolvExpr
     216
     217// Local Variables: //
     218// tab-width: 4 //
     219// mode: c++ //
     220// compile-command: "make install" //
     221// End: //
  • translator/ResolvExpr/ConversionCost.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: ConversionCost.cc,v 1.11 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// ConversionCost.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 07:06:19 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 07:22:19 2015
     13// Update Count     : 4
     14//
    715
    816#include "ConversionCost.h"
     
    1220#include "SymTab/Indexer.h"
    1321
    14 
    1522namespace ResolvExpr {
    16 
    17 const Cost Cost::zero = Cost( 0, 0, 0 );
    18 const Cost Cost::infinity = Cost( -1, -1, -1 );
    19 
    20 Cost
    21 conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    22 {
    23   if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    24     EqvClass eqvClass;
    25     NamedTypeDecl *namedType;
     23        const Cost Cost::zero = Cost( 0, 0, 0 );
     24        const Cost Cost::infinity = Cost( -1, -1, -1 );
     25
     26        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     27                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     28                        EqvClass eqvClass;
     29                        NamedTypeDecl *namedType;
    2630///     std::cout << "type inst " << destAsTypeInst->get_name();
    27     if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
    28       return conversionCost( src, eqvClass.type, indexer, env );
    29     } else if( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
     31                        if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
     32                                return conversionCost( src, eqvClass.type, indexer, env );
     33                        } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
    3034///       std::cout << " found" << std::endl;
    31       TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    32       // all typedefs should be gone by this point
    33       assert( type );
    34       if( type->get_base() ) {
    35         return conversionCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 );
    36       }
    37     }
     35                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     36                                // all typedefs should be gone by this point
     37                                assert( type );
     38                                if ( type->get_base() ) {
     39                                        return conversionCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 );
     40                                } // if
     41                        } // if
    3842///     std::cout << " not found" << std::endl;
    39   }
     43                } // if
    4044///   std::cout << "src is ";
    4145///   src->print( std::cout );
     
    4448///   std::cout << std::endl << "env is" << std::endl;
    4549///   env.print( std::cout, 8 );
    46   if( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
     50                if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
    4751///     std::cout << "compatible!" << std::endl;
    48     return Cost( 0, 0, 0 );
    49   } else if( dynamic_cast< VoidType* >( dest ) ) {
    50     return Cost( 0, 0, 1 );
    51   } else {
    52     ConversionCost converter( dest, indexer, env );
    53     src->accept( converter );
    54     if( converter.get_cost() == Cost::infinity ) {
    55       return Cost::infinity;
    56     } else {
    57       return converter.get_cost() + Cost( 0, 0, 0 );
    58     }
    59   }
    60 }
    61 
    62 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    63   : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env )
    64 {
    65 }
     52                        return Cost( 0, 0, 0 );
     53                } else if ( dynamic_cast< VoidType* >( dest ) ) {
     54                        return Cost( 0, 0, 1 );
     55                } else {
     56                        ConversionCost converter( dest, indexer, env );
     57                        src->accept( converter );
     58                        if ( converter.get_cost() == Cost::infinity ) {
     59                                return Cost::infinity;
     60                        } else {
     61                                return converter.get_cost() + Cost( 0, 0, 0 );
     62                        } // if
     63                } // if
     64        }
     65
     66        ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
     67                : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ) {
     68        }
    6669
    6770/*
    68 Old
    69 ===
    70                      Double
    71                        |
    72                      Float
    73                        |
    74                      ULong
    75                      /   \
    76                   UInt    Long
    77                      \   /
    78                       Int
    79                        |
    80                      Ushort
    81                        |
    82                      Short
    83                        |
    84                      Uchar
    85                      /   \
    86                  Schar   Char
    87 
    88 New
    89 ===
    90                                +-----LongDoubleComplex--+
    91                    LongDouble--+          |             +-LongDoubleImag
    92                        |         +---DoubleComplex---+         |
    93                      Double------+        |          +----DoubleImag
    94                        |           +-FloatComplex-+            |
    95                      Float---------+              +-------FloatImag
    96                        |
    97                    ULongLong
    98                        |
    99                    LongLong
    100                        |
    101                      ULong
    102                      /   \
    103                   UInt    Long
    104                      \   /
    105                       Int
    106                        |
    107                      Ushort
    108                        |
    109                      Short
    110                        |
    111                      Uchar
    112                      /   \
    113                  Schar   Char
    114                      \   /
    115                       Bool
     71            Old
     72            ===
     73           Double
     74             |
     75           Float
     76             |
     77           ULong
     78           /   \
     79        UInt    Long
     80           \   /
     81            Int
     82             |
     83           Ushort
     84             |
     85           Short
     86             |
     87           Uchar
     88           /   \
     89        Schar   Char
     90
     91                                New
     92                                ===
     93                       +-----LongDoubleComplex--+
     94           LongDouble--+          |             +-LongDoubleImag
     95             |         +---DoubleComplex---+         |
     96           Double------+        |          +----DoubleImag
     97             |           +-FloatComplex-+            |
     98           Float---------+              +-------FloatImag
     99             |
     100          ULongLong
     101             |
     102          LongLong
     103             |
     104           ULong
     105           /   \
     106        UInt    Long
     107           \   /
     108            Int
     109             |
     110           Ushort
     111             |
     112           Short
     113             |
     114           Uchar
     115           /   \
     116        Schar   Char
     117           \   /
     118            Bool
    116119*/
    117120
    118 static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
    119 {
    120 /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag */
    121 /* Bool */      { 0,    1,      1,      2,      3,      4,      5,      6,      6,      7,      8,      9,      10,     11,     12,     11,     12,     13,     -1,     -1,     -1 },
    122 /* Char */      { -1,   0,      -1,     1,      2,      3,      4,      5,      5,      6,      7,      8,      9,      10,     11,     10,     11,     12,     -1,     -1,     -1 },
    123 /* SChar */     { -1,   -1,     0,      1,      2,      3,      4,      5,      5,      6,      7,      8,      9,      10,     11,     10,     11,     12,     -1,     -1,     -1 },
    124 /* UChar */     { -1,   -1,     -1,     0,      1,      2,      3,      4,      4,      5,      6,      7,      8,      9,      10,     9,      10,     11,     -1,     -1,     -1 },
    125 /* Short */     { -1,   -1,     -1,     -1,     0,      1,      2,      3,      3,      4,      5,      6,      7,      8,      9,      8,      9,      10,     -1,     -1,     -1 },
    126 /* UShort */    { -1,   -1,     -1,     -1,     -1,     0,      1,      2,      2,      3,      4,      5,      6,      7,      8,      7,      8,      9,      -1,     -1,     -1 },
    127 /* Int */       { -1,   -1,     -1,     -1,     -1,     -1,     0,      1,      1,      2,      3,      4,      5,      6,      7,      6,      7,      8,      -1,     -1,     -1 },
    128 /* UInt */      { -1,   -1,     -1,     -1,     -1,     -1,     -1,     0,      -1,     1,      2,      3,      4,      5,      6,      5,      6,      7,      -1,     -1,     -1 },
    129 /* Long */      { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      3,      4,      5,      6,      5,      6,      7,      -1,     -1,     -1 },
    130 /* ULong */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      3,      4,      5,      4,      5,      6,      -1,     -1,     -1 },
    131 /* LLong */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      3,      4,      3,      4,      5,      -1,     -1,     -1 },
    132 /* ULLong */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      3,      2,      3,      4,      -1,     -1,     -1 },
    133 /* Float */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      1,      2,      3,      -1,     -1,     -1 },
    134 /* Double */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      -1,     1,      2,      -1,     -1,     -1 },
    135 /* LDbl */      { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      -1,     -1,     1,      -1,     -1,     -1 },
    136 /* FCplex */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      -1,     -1,     -1 },
    137 /* DCplex */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      -1,     -1,     -1 },
    138 /* LDCplex */   { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      -1,     -1,     -1 },
    139 /* FImag */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     1,      2,      3,      0,      1,      2 },
    140 /* DImag */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     1,      2,      -1,     0,      1 },
    141 /* LDImag */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     1,      -1,     -1,     0 }
    142 };
    143 
    144 void
    145 ConversionCost::visit(VoidType *voidType)
    146 {
    147   cost = Cost::infinity;
    148 }
    149 
    150 void
    151 ConversionCost::visit(BasicType *basicType)
    152 {
    153   if( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    154     int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
    155     if( tableResult == -1 ) {
    156       cost = Cost( 1, 0, 0 );
    157     } else {
    158       cost = Cost( 0, 0, tableResult );
    159     }
    160   }
    161 }
    162 
    163 void
    164 ConversionCost::visit(PointerType *pointerType)
    165 {
    166   if( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    167     if( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
    168       cost = Cost( 0, 0, 1 );
    169     } else {
    170       int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
    171       if( assignResult < 0 ) {
    172         cost = Cost( 0, 0, 1 );
    173       } else if( assignResult > 0 ) {
    174         cost = Cost( 1, 0, 0 );
    175       }
    176     }
    177   }
    178 }
    179 
    180 void
    181 ConversionCost::visit(ArrayType *arrayType)
    182 {
    183 }
    184 
    185 void
    186 ConversionCost::visit(FunctionType *functionType)
    187 {
    188 }
    189 
    190 void
    191 ConversionCost::visit(StructInstType *inst)
    192 {
    193   if( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    194     if( inst->get_name() == destAsInst->get_name() ) {
    195       cost = Cost::zero;
    196     }
    197   }
    198 }
    199 
    200 void
    201 ConversionCost::visit(UnionInstType *inst)
    202 {
    203   if( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    204     if( inst->get_name() == destAsInst->get_name() ) {
    205       cost = Cost::zero;
    206     }
    207   }
    208 }
    209 
    210 void
    211 ConversionCost::visit(EnumInstType *inst)
    212 {
    213   static Type::Qualifiers q;
    214   static BasicType integer( q, BasicType::SignedInt );
    215   integer.accept( *this );
    216   if( cost < Cost( 1, 0, 0 ) ) {
    217     cost.incSafe();
    218   }
    219 }
    220 
    221 void
    222 ConversionCost::visit(ContextInstType *inst)
    223 {
    224 }
    225 
    226 void
    227 ConversionCost::visit(TypeInstType *inst)
    228 {
    229   EqvClass eqvClass;
    230   NamedTypeDecl *namedType;
    231   if( env.lookup( inst->get_name(), eqvClass ) ) {
    232     cost = conversionCost( eqvClass.type, dest, indexer, env );
    233   } else if( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
    234     if( inst->get_name() == destAsInst->get_name() ) {
    235       cost = Cost::zero;
    236     }
    237   } else if( ( namedType = indexer.lookupType( inst->get_name() ) ) ) {
    238     TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    239     // all typedefs should be gone by this point
    240     assert( type );
    241     if( type->get_base() ) {
    242       cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost( 0, 0, 1 );
    243     }
    244   }
    245 }
    246 
    247 void
    248 ConversionCost::visit(TupleType *tupleType)
    249 {
    250   Cost c;
    251   if( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
    252     std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
    253     std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
    254     while( srcIt != tupleType->get_types().end() ) {
    255       Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
    256       if( newCost == Cost::infinity ) {
    257         return;
    258       }
    259       c += newCost;
    260     }
    261     if( destIt != destAsTuple->get_types().end() ) {
    262       cost = Cost::infinity;
    263     } else {
    264       cost = c;
    265     }
    266   }
    267 }
    268 
     121        static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
     122        {
     123        /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag */
     124                /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              10,             11,             12,             11,             12,             13,             -1,             -1,             -1 },
     125                /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              9,              10,             11,             10,             11,             12,             -1,             -1,             -1 },
     126                /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              9,              10,             11,             10,             11,             12,             -1,             -1,             -1 },
     127                /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              8,              9,              10,             9,              10,             11,             -1,             -1,             -1 },
     128                /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              7,              8,              9,              8,              9,              10,             -1,             -1,             -1 },
     129                /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              6,              7,              8,              7,              8,              9,              -1,             -1,             -1 },
     130                /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              5,              6,              7,              6,              7,              8,              -1,             -1,             -1 },
     131                /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              4,              5,              6,              5,              6,              7,              -1,             -1,             -1 },
     132                /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              5,              6,              5,              6,              7,              -1,             -1,             -1 },
     133                /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              5,              4,              5,              6,              -1,             -1,             -1 },
     134                /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              3,              4,              5,              -1,             -1,             -1 },
     135                /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              2,              3,              4,              -1,             -1,             -1 },
     136                /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1 },
     137                /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1 },
     138                /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1 },
     139                /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1 },
     140                /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1 },
     141                /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1 },
     142                /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2 },
     143                /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1 },
     144                /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0 }
     145        };
     146
     147        void ConversionCost::visit(VoidType *voidType) {
     148                cost = Cost::infinity;
     149        }
     150
     151        void ConversionCost::visit(BasicType *basicType) {
     152                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     153                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
     154                        if ( tableResult == -1 ) {
     155                                cost = Cost( 1, 0, 0 );
     156                        } else {
     157                                cost = Cost( 0, 0, tableResult );
     158                        } // if
     159                } // if
     160        }
     161
     162        void ConversionCost::visit(PointerType *pointerType) {
     163                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
     164                        if ( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
     165                                cost = Cost( 0, 0, 1 );
     166                        } else {
     167                                int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
     168                                if ( assignResult < 0 ) {
     169                                        cost = Cost( 0, 0, 1 );
     170                                } else if ( assignResult > 0 ) {
     171                                        cost = Cost( 1, 0, 0 );
     172                                } // if
     173                        } // if
     174                } // if
     175        }
     176
     177        void ConversionCost::visit(ArrayType *arrayType) {
     178        }
     179
     180        void ConversionCost::visit(FunctionType *functionType) {
     181        }
     182
     183        void ConversionCost::visit(StructInstType *inst) {
     184                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
     185                        if ( inst->get_name() == destAsInst->get_name() ) {
     186                                cost = Cost::zero;
     187                        } // if
     188                } // if
     189        }
     190
     191        void ConversionCost::visit(UnionInstType *inst) {
     192                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
     193                        if ( inst->get_name() == destAsInst->get_name() ) {
     194                                cost = Cost::zero;
     195                        } // if
     196                } // if
     197        }
     198
     199        void ConversionCost::visit(EnumInstType *inst) {
     200                static Type::Qualifiers q;
     201                static BasicType integer( q, BasicType::SignedInt );
     202                integer.accept( *this );
     203                if ( cost < Cost( 1, 0, 0 ) ) {
     204                        cost.incSafe();
     205                } // if
     206        }
     207
     208        void ConversionCost::visit(ContextInstType *inst) {
     209        }
     210
     211        void ConversionCost::visit(TypeInstType *inst) {
     212                EqvClass eqvClass;
     213                NamedTypeDecl *namedType;
     214                if ( env.lookup( inst->get_name(), eqvClass ) ) {
     215                        cost = conversionCost( eqvClass.type, dest, indexer, env );
     216                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
     217                        if ( inst->get_name() == destAsInst->get_name() ) {
     218                                cost = Cost::zero;
     219                        }
     220                } else if ( ( namedType = indexer.lookupType( inst->get_name() ) ) ) {
     221                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     222                        // all typedefs should be gone by this point
     223                        assert( type );
     224                        if ( type->get_base() ) {
     225                                cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost( 0, 0, 1 );
     226                        } // if
     227                } // if
     228        }
     229
     230        void ConversionCost::visit(TupleType *tupleType) {
     231                Cost c;
     232                if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
     233                        std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
     234                        std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
     235                        while ( srcIt != tupleType->get_types().end() ) {
     236                                Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
     237                                if ( newCost == Cost::infinity ) {
     238                                        return;
     239                                } // if
     240                                c += newCost;
     241                        } // while
     242                        if ( destIt != destAsTuple->get_types().end() ) {
     243                                cost = Cost::infinity;
     244                        } else {
     245                                cost = c;
     246                        } // if
     247                } // if
     248        }
    269249} // namespace ResolvExpr
     250
     251// Local Variables: //
     252// tab-width: 4 //
     253// mode: c++ //
     254// compile-command: "make install" //
     255// End: //
  • translator/ResolvExpr/ConversionCost.h

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: ConversionCost.h,v 1.6 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// ConversionCost.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 09:37:28 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 09:39:23 2015
     13// Update Count     : 2
     14//
    715
    8 #ifndef RESOLVEXPR_CONVERSIONCOST_PROTECTED_H
    9 #define RESOLVEXPR_CONVERSIONCOST_PROTECTED_H
     16#ifndef CONVERSIONCOST_H
     17#define CONVERSIONCOST_H
    1018
    1119#include "SynTree/Visitor.h"
     
    1523
    1624namespace ResolvExpr {
     25        class ConversionCost : public Visitor {
     26          public:
     27                ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     28 
     29                Cost get_cost() const { return cost; }
    1730
    18 class ConversionCost : public Visitor
    19 {
    20 public:
    21   ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    22  
    23   Cost get_cost() const { return cost; }
    24 
    25   virtual void visit(VoidType *voidType);
    26   virtual void visit(BasicType *basicType);
    27   virtual void visit(PointerType *pointerType);
    28   virtual void visit(ArrayType *arrayType);
    29   virtual void visit(FunctionType *functionType);
    30   virtual void visit(StructInstType *aggregateUseType);
    31   virtual void visit(UnionInstType *aggregateUseType);
    32   virtual void visit(EnumInstType *aggregateUseType);
    33   virtual void visit(ContextInstType *aggregateUseType);
    34   virtual void visit(TypeInstType *aggregateUseType);
    35   virtual void visit(TupleType *tupleType);
    36 
    37 protected:
    38   Type *dest;
    39   const SymTab::Indexer &indexer;
    40   Cost cost;
    41   const TypeEnvironment &env;
    42 };
    43 
     31                virtual void visit(VoidType *voidType);
     32                virtual void visit(BasicType *basicType);
     33                virtual void visit(PointerType *pointerType);
     34                virtual void visit(ArrayType *arrayType);
     35                virtual void visit(FunctionType *functionType);
     36                virtual void visit(StructInstType *aggregateUseType);
     37                virtual void visit(UnionInstType *aggregateUseType);
     38                virtual void visit(EnumInstType *aggregateUseType);
     39                virtual void visit(ContextInstType *aggregateUseType);
     40                virtual void visit(TypeInstType *aggregateUseType);
     41                virtual void visit(TupleType *tupleType);
     42          protected:
     43                Type *dest;
     44                const SymTab::Indexer &indexer;
     45                Cost cost;
     46                const TypeEnvironment &env;
     47        };
    4448} // namespace ResolvExpr
    4549
    46 #endif /* #ifndef RESOLVEXPR_CONVERSIONCOST_PROTECTED_H */
     50#endif // CONVERSIONCOST_H */
     51
     52// Local Variables: //
     53// tab-width: 4 //
     54// mode: c++ //
     55// compile-command: "make install" //
     56// End: //
  • translator/ResolvExpr/Cost.h

    rb87a5ed ra32b204  
    1 #ifndef RESOLVEXPR_COST_H
    2 #define RESOLVEXPR_COST_H
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Cost.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 09:39:50 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 09:42:04 2015
     13// Update Count     : 3
     14//
     15
     16#ifndef COST_H
     17#define COST_H
    318
    419#include <iostream>
    520
    621namespace ResolvExpr {
    7     class Cost {
    8       public:
    9         Cost();
    10         Cost( int unsafe, int poly, int safe );
     22        class Cost {
     23          public:
     24                Cost();
     25                Cost( int unsafe, int poly, int safe );
    1126 
    12         void incUnsafe( int inc = 1 );
    13         void incPoly( int inc = 1 );
    14         void incSafe( int inc = 1 );
     27                void incUnsafe( int inc = 1 );
     28                void incPoly( int inc = 1 );
     29                void incSafe( int inc = 1 );
    1530 
    16         Cost operator+( const Cost &other ) const;
    17         Cost operator-( const Cost &other ) const;
    18         Cost &operator+=( const Cost &other );
    19         bool operator<( const Cost &other ) const;
    20         bool operator==( const Cost &other ) const;
    21         bool operator!=( const Cost &other ) const;
    22         friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
     31                Cost operator+( const Cost &other ) const;
     32                Cost operator-( const Cost &other ) const;
     33                Cost &operator+=( const Cost &other );
     34                bool operator<( const Cost &other ) const;
     35                bool operator==( const Cost &other ) const;
     36                bool operator!=( const Cost &other ) const;
     37                friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
    2338 
    24         static const Cost zero;
    25         static const Cost infinity;
    26       private:
    27         int compare( const Cost &other ) const;
     39                static const Cost zero;
     40                static const Cost infinity;
     41          private:
     42                int compare( const Cost &other ) const;
    2843
    29         int unsafe;
    30         int poly;
    31         int safe;
    32     };
     44                int unsafe;
     45                int poly;
     46                int safe;
     47        };
    3348
    34     inline Cost::Cost() : unsafe( 0 ), poly( 0 ), safe( 0 ) {}
     49        inline Cost::Cost() : unsafe( 0 ), poly( 0 ), safe( 0 ) {}
    3550
    36     inline Cost::Cost( int unsafe, int poly, int safe ) : unsafe( unsafe ), poly( poly ), safe( safe ) {}
     51        inline Cost::Cost( int unsafe, int poly, int safe ) : unsafe( unsafe ), poly( poly ), safe( safe ) {}
    3752
    38     inline void
    39         Cost::incUnsafe( int inc ) {
    40         unsafe += inc;
    41     }
     53        inline void Cost::incUnsafe( int inc ) {
     54                unsafe += inc;
     55        }
    4256
    43     inline void
    44         Cost::incPoly( int inc ) {
    45         unsafe += inc;
    46     }
     57        inline void Cost::incPoly( int inc ) {
     58                unsafe += inc;
     59        }
    4760
    48     inline void
    49         Cost::incSafe( int inc ) {
    50         unsafe += inc;
    51     }
     61        inline void Cost::incSafe( int inc ) {
     62                unsafe += inc;
     63        }
    5264
    53     inline Cost Cost::operator+( const Cost &other ) const {
    54         return Cost( unsafe + other.unsafe, poly + other.poly, safe + other.safe );
    55     }
     65        inline Cost Cost::operator+( const Cost &other ) const {
     66                return Cost( unsafe + other.unsafe, poly + other.poly, safe + other.safe );
     67        }
    5668
    57     inline Cost Cost::operator-( const Cost &other ) const {
    58         return Cost( unsafe - other.unsafe, poly - other.poly, safe - other.safe );
    59     }
     69        inline Cost Cost::operator-( const Cost &other ) const {
     70                return Cost( unsafe - other.unsafe, poly - other.poly, safe - other.safe );
     71        }
    6072
    61     inline Cost &Cost::operator+=( const Cost &other ) {
    62         unsafe += other.unsafe;
    63         poly += other.poly;
    64         safe += other.safe;
    65         return *this;
    66     }
     73        inline Cost &Cost::operator+=( const Cost &other ) {
     74                unsafe += other.unsafe;
     75                poly += other.poly;
     76                safe += other.safe;
     77                return *this;
     78        }
    6779
    68     inline bool Cost::operator<( const Cost &other ) const {
     80        inline bool Cost::operator<( const Cost &other ) const {
    6981            if ( *this == infinity ) return false;
    7082            if ( other == infinity ) return true;
    7183            if ( unsafe > other.unsafe ) {
    72                 return false;
     84                        return false;
    7385            } else if ( unsafe < other.unsafe ) {
    74                 return true;
     86                        return true;
    7587            } else if ( poly > other.poly ) {
    76                 return false;
     88                        return false;
    7789            } else if ( poly < other.poly ) {
    78                 return true;
     90                        return true;
    7991            } else if ( safe > other.safe ) {
    80                 return false;
     92                        return false;
    8193            } else if ( safe < other.safe ) {
    82                 return true;
     94                        return true;
    8395            } else {
    84                 return false;
    85             }
     96                        return false;
     97            } // if
    8698        }
    8799
    88     inline bool Cost::operator==( const Cost &other ) const {
    89         return unsafe == other.unsafe
    90         && poly == other.poly
    91         && safe == other.safe;
    92     }
     100        inline bool Cost::operator==( const Cost &other ) const {
     101                return unsafe == other.unsafe
     102                        && poly == other.poly
     103                        && safe == other.safe;
     104        }
    93105
    94     inline bool Cost::operator!=( const Cost &other ) const {
    95         return !( *this == other );
    96     }
     106        inline bool Cost::operator!=( const Cost &other ) const {
     107                return !( *this == other );
     108        }
    97109
    98     inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
    99         os << "( " << cost.unsafe << ", " << cost.poly << ", " << cost.safe << " )";
    100         return os;
    101     }
     110        inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
     111                os << "( " << cost.unsafe << ", " << cost.poly << ", " << cost.safe << " )";
     112                return os;
     113        }
    102114} // namespace ResolvExpr
    103115
    104 #endif // RESOLVEXPR_COST_H
     116#endif // COST_H
     117
     118// Local Variables: //
     119// tab-width: 4 //
     120// mode: c++ //
     121// compile-command: "make install" //
     122// End: //
  • translator/ResolvExpr/FindOpenVars.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: FindOpenVars.cc,v 1.4 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// FindOpenVars.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 09:42:48 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 09:45:25 2015
     13// Update Count     : 3
     14//
    715
    816#include "FindOpenVars.h"
     
    1018#include "SynTree/Visitor.h"
    1119
     20namespace ResolvExpr {
     21        class FindOpenVars : public Visitor {
     22          public:
     23                FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
    1224
    13 namespace ResolvExpr {
     25          private:
     26                virtual void visit(PointerType *pointerType);
     27                virtual void visit(ArrayType *arrayType);
     28                virtual void visit(FunctionType *functionType);
     29                virtual void visit(TupleType *tupleType);
    1430
    15 class FindOpenVars : public Visitor
    16 {
    17 public:
    18   FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
    19  
    20 private:
    21   virtual void visit(PointerType *pointerType);
    22   virtual void visit(ArrayType *arrayType);
    23   virtual void visit(FunctionType *functionType);
    24   virtual void visit(TupleType *tupleType);
    25  
    26   void common_action( Type *type );
    27  
    28   OpenVarSet &openVars, &closedVars;
    29   AssertionSet &needAssertions, &haveAssertions;
    30   bool nextIsOpen;
    31 };
     31                void common_action( Type *type );
    3232
    33 void
    34 findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
    35 {
    36   FindOpenVars finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
    37   type->accept( finder );
    38 }
     33                OpenVarSet &openVars, &closedVars;
     34                AssertionSet &needAssertions, &haveAssertions;
     35                bool nextIsOpen;
     36        };
    3937
    40 FindOpenVars::FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
    41   : openVars( openVars ), closedVars( closedVars ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), nextIsOpen( firstIsOpen )
    42 {
    43 }
     38        void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {
     39                FindOpenVars finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
     40                type->accept( finder );
     41        }
    4442
    45 void
    46 FindOpenVars::common_action( Type *type )
    47 {
    48   if( nextIsOpen ) {
    49     for( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    50       openVars[ (*i)->get_name() ] = (*i)->get_kind();
    51       for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    52         needAssertions[ *assert ] = false;
    53       }
     43        FindOpenVars::FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
     44                : openVars( openVars ), closedVars( closedVars ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), nextIsOpen( firstIsOpen ) {
     45        }
     46
     47        void FindOpenVars::common_action( Type *type ) {
     48                if ( nextIsOpen ) {
     49                        for ( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     50                                openVars[ (*i)->get_name() ] = (*i)->get_kind();
     51                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
     52                                        needAssertions[ *assert ] = false;
     53                                }
    5454///       cloneAll( (*i)->get_assertions(), needAssertions );
    5555///       needAssertions.insert( needAssertions.end(), (*i)->get_assertions().begin(), (*i)->get_assertions().end() );
    56     }
    57   } else {
    58     for( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    59       closedVars[ (*i)->get_name() ] = (*i)->get_kind();
    60       for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    61         haveAssertions[ *assert ] = false;
    62       }
     56                        }
     57                } else {
     58                        for ( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     59                                closedVars[ (*i)->get_name() ] = (*i)->get_kind();
     60                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
     61                                        haveAssertions[ *assert ] = false;
     62                                }
    6363///       cloneAll( (*i)->get_assertions(), haveAssertions );
    6464///       haveAssertions.insert( haveAssertions.end(), (*i)->get_assertions().begin(), (*i)->get_assertions().end() );
    65     }
    66   }
     65                        } // for
     66                } // if
    6767///   std::cout << "type is ";
    6868///   type->print( std::cout );
     
    7171///   std::cout << std::endl << "have is" << std::endl;
    7272///   printAssertionSet( haveAssertions, std::cout );
    73 }
     73        }
    7474
    75 void
    76 FindOpenVars::visit(PointerType *pointerType)
    77 {
    78   common_action( pointerType );
    79   Visitor::visit( pointerType );
    80 }
     75        void FindOpenVars::visit(PointerType *pointerType) {
     76                common_action( pointerType );
     77                Visitor::visit( pointerType );
     78        }
    8179
    82 void
    83 FindOpenVars::visit(ArrayType *arrayType)
    84 {
    85   common_action( arrayType );
    86   Visitor::visit( arrayType );
    87 }
     80        void FindOpenVars::visit(ArrayType *arrayType) {
     81                common_action( arrayType );
     82                Visitor::visit( arrayType );
     83        }
    8884
    89 void
    90 FindOpenVars::visit(FunctionType *functionType)
    91 {
    92   common_action( functionType );
    93   nextIsOpen = !nextIsOpen;
    94   Visitor::visit( functionType );
    95   nextIsOpen = !nextIsOpen;
    96 }
     85        void FindOpenVars::visit(FunctionType *functionType) {
     86                common_action( functionType );
     87                nextIsOpen = ! nextIsOpen;
     88                Visitor::visit( functionType );
     89                nextIsOpen = ! nextIsOpen;
     90        }
    9791
    98 void
    99 FindOpenVars::visit(TupleType *tupleType)
    100 {
    101   common_action( tupleType );
    102   Visitor::visit( tupleType );
    103 }
     92        void FindOpenVars::visit(TupleType *tupleType) {
     93                common_action( tupleType );
     94                Visitor::visit( tupleType );
     95        }
     96} // namespace ResolvExpr
    10497
    105 } // namespace ResolvExpr
     98// Local Variables: //
     99// tab-width: 4 //
     100// mode: c++ //
     101// compile-command: "make install" //
     102// End: //
  • translator/ResolvExpr/FindOpenVars.h

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: FindOpenVars.h,v 1.3 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// FindOpenVars.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 09:46:04 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 09:47:20 2015
     13// Update Count     : 2
     14//
    715
    8 #ifndef RESOLVEXPR_FINDOPENVARS_H
    9 #define RESOLVEXPR_FINDOPENVARS_H
     16#ifndef FINDOPENVARS_H
     17#define FINDOPENVARS_H
    1018
    1119#include "Unify.h"
     
    1321
    1422namespace ResolvExpr {
    15 
    16 void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
    17 
     23        void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
    1824} // namespace ResolvExpr
    1925
    20 #endif // #ifndef RESOLVEXPR_FINDOPENVARS_H
     26#endif // FINDOPENVARS_H
     27
     28// Local Variables: //
     29// tab-width: 4 //
     30// mode: c++ //
     31// compile-command: "make install" //
     32// End: //
  • translator/ResolvExpr/Occurs.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Occurs.cc,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Occurs.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 09:47:41 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 09:49:26 2015
     13// Update Count     : 2
     14//
    715
    816#include <set>
     
    1321#include "TypeEnvironment.h"
    1422
     23namespace ResolvExpr {
     24        class Occurs : public Visitor {
     25          public:
     26                Occurs( std::string varName, const TypeEnvironment &env );
     27                bool get_result() const { return result; }
     28                virtual void visit( TypeInstType *typeInst );
     29          private:
     30                bool result;
     31                std::set< std::string > eqvVars;
     32                const TypeEnvironment &env;
     33        };
    1534
    16 namespace ResolvExpr {
     35        bool occurs( Type *type, std::string varName, const TypeEnvironment &env ) {
     36                Occurs occur( varName, env );
     37                type->accept( occur );
     38                return occur.get_result();
     39        }
    1740
    18 class Occurs : public Visitor
    19 {
    20 public:
    21   Occurs( std::string varName, const TypeEnvironment &env );
    22  
    23   bool get_result() const { return result; }
     41        Occurs::Occurs( std::string varName, const TypeEnvironment &env ) : result( false ), env( env ) {
     42                EqvClass eqvClass;
     43                if ( env.lookup( varName, eqvClass ) ) {
     44                        eqvVars = eqvClass.vars;
     45                } else {
     46                        eqvVars.insert( varName );
     47                } // if
     48        }
    2449
    25   virtual void visit( TypeInstType *typeInst );
    26 
    27 private:
    28   bool result;
    29   std::set< std::string > eqvVars;
    30   const TypeEnvironment &env;
    31 };
    32 
    33 bool
    34 occurs( Type *type, std::string varName, const TypeEnvironment &env )
    35 {
    36   Occurs occur( varName, env );
    37   type->accept( occur );
    38   return occur.get_result();
    39 }
    40 
    41 Occurs::Occurs( std::string varName, const TypeEnvironment &env )
    42   : result( false ), env( env )
    43 {
    44   EqvClass eqvClass;
    45   if( env.lookup( varName, eqvClass ) ) {
    46     eqvVars = eqvClass.vars;
    47   } else {
    48     eqvVars.insert( varName );
    49   }
    50 }
    51 
    52 void
    53 Occurs::visit( TypeInstType *typeInst )
    54 {
    55   EqvClass eqvClass;
     50        void Occurs::visit( TypeInstType *typeInst ) {
     51                EqvClass eqvClass;
    5652///   std::cout << "searching for vars: ";
    5753///   std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cout, " " ) );
    5854///   std::cout << std::endl;
    59   if( eqvVars.find( typeInst->get_name() ) != eqvVars.end() ) {
    60     result = true;
    61   } else if( env.lookup( typeInst->get_name(), eqvClass ) ) {
    62     if( eqvClass.type ) {
     55                if ( eqvVars.find( typeInst->get_name() ) != eqvVars.end() ) {
     56                        result = true;
     57                } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     58                        if ( eqvClass.type ) {
    6359///       std::cout << typeInst->get_name() << " is bound to";
    6460///       eqvClass.type->print( std::cout );
    6561///       std::cout << std::endl;
    66       eqvClass.type->accept( *this );
    67     }
    68   }
    69 }
     62                                eqvClass.type->accept( *this );
     63                        } // if
     64                } // if
     65        }
     66} // namespace ResolvExpr
    7067
    71 } // namespace ResolvExpr
     68// Local Variables: //
     69// tab-width: 4 //
     70// mode: c++ //
     71// compile-command: "make install" //
     72// End: //
  • translator/ResolvExpr/PolyCost.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: PolyCost.cc,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// PolyCost.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 09:50:12 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 09:52:02 2015
     13// Update Count     : 3
     14//
    715
    816#include "typeops.h"
     
    1220#include "TypeEnvironment.h"
    1321
     22namespace ResolvExpr {
     23        class PolyCost : public Visitor {
     24          public:
     25                PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer );
     26                int get_result() const { return result; }
     27          private:
     28                virtual void visit(TypeInstType *aggregateUseType);
     29                int result;
     30                const TypeEnvironment &env;
     31                const SymTab::Indexer &indexer;
     32        };
    1433
    15 namespace ResolvExpr {
     34        int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     35                PolyCost coster( env, indexer );
     36                type->accept( coster );
     37                return coster.get_result();
     38        }
    1639
    17 class PolyCost : public Visitor
    18 {
    19 public:
    20   PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer );
     40        PolyCost::PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer ) : result( 0 ), env( env ), indexer( indexer ) {
     41        }
    2142
    22   int get_result() const { return result; }
    23 
    24 private:
    25   virtual void visit(TypeInstType *aggregateUseType);
    26  
    27   int result;
    28   const TypeEnvironment &env;
    29   const SymTab::Indexer &indexer;
    30 };
    31 
    32 int
    33 polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    34 {
    35   PolyCost coster( env, indexer );
    36   type->accept( coster );
    37   return coster.get_result();
    38 }
    39 
    40 PolyCost::PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer )
    41   : result( 0 ), env( env ), indexer( indexer )
    42 {
    43 }
    44 
    45 void
    46 PolyCost::visit(TypeInstType *typeInst)
    47 {
    48   EqvClass eqvClass;
    49   if( env.lookup( typeInst->get_name(), eqvClass ) ) {
    50     if( eqvClass.type ) {
    51       if( TypeInstType *otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
    52         if( indexer.lookupType( otherTypeInst->get_name() ) ) {
    53           result += 1;
    54         }
    55       } else {
    56         result += 1;
    57       }
    58     }
    59   }
    60 }
     43        void PolyCost::visit(TypeInstType *typeInst) {
     44                EqvClass eqvClass;
     45                if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     46                        if ( eqvClass.type ) {
     47                                if ( TypeInstType *otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
     48                                        if ( indexer.lookupType( otherTypeInst->get_name() ) ) {
     49                                                result += 1;
     50                                        } // if
     51                                } else {
     52                                        result += 1;
     53                                } // if
     54                        } // if
     55                } // if
     56        }
    6157
    6258} // namespace ResolvExpr
     59
     60// Local Variables: //
     61// tab-width: 4 //
     62// mode: c++ //
     63// compile-command: "make install" //
     64// End: //
  • translator/ResolvExpr/PtrsAssignable.cc

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// PtrsAssignable.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 11:44:11 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 11:47:36 2015
     13// Update Count     : 2
     14//
     15
    116#include "typeops.h"
    217#include "SynTree/Type.h"
     
    621
    722namespace ResolvExpr {
    8     class PtrsAssignable : public Visitor {
    9       public:
    10         PtrsAssignable( Type *dest, const TypeEnvironment &env );
    11  
    12         int get_result() const { return result; }
     23        class PtrsAssignable : public Visitor {
     24          public:
     25                PtrsAssignable( Type *dest, const TypeEnvironment &env );
    1326
    14         virtual void visit(VoidType *voidType);
    15         virtual void visit(BasicType *basicType);
    16         virtual void visit(PointerType *pointerType);
    17         virtual void visit(ArrayType *arrayType);
    18         virtual void visit(FunctionType *functionType);
    19         virtual void visit(StructInstType *inst);
    20         virtual void visit(UnionInstType *inst);
    21         virtual void visit(EnumInstType *inst);
    22         virtual void visit(ContextInstType *inst);
    23         virtual void visit(TypeInstType *inst);
    24         virtual void visit(TupleType *tupleType);
    25       private:
    26         Type *dest;
    27         int result;
    28         const TypeEnvironment &env;
    29     };
     27                int get_result() const { return result; }
    3028
    31     int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
    32         if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    33             EqvClass eqvClass;
    34             if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
    35                 return ptrsAssignable( src, eqvClass.type, env );
    36             }
     29                virtual void visit( VoidType *voidType );
     30                virtual void visit( BasicType *basicType );
     31                virtual void visit( PointerType *pointerType );
     32                virtual void visit( ArrayType *arrayType );
     33                virtual void visit( FunctionType *functionType );
     34                virtual void visit( StructInstType *inst );
     35                virtual void visit( UnionInstType *inst );
     36                virtual void visit( EnumInstType *inst );
     37                virtual void visit( ContextInstType *inst );
     38                virtual void visit( TypeInstType *inst );
     39                virtual void visit( TupleType *tupleType );
     40          private:
     41                Type *dest;
     42                int result;
     43                const TypeEnvironment &env;
     44        };
     45
     46        int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
     47                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     48                        EqvClass eqvClass;
     49                        if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
     50                                return ptrsAssignable( src, eqvClass.type, env );
     51                        } // if
     52                } // if
     53                if ( dynamic_cast< VoidType* >( dest ) ) {
     54                        return 1;
     55                } else {
     56                        PtrsAssignable ptrs( dest, env );
     57                        src->accept( ptrs );
     58                        return ptrs.get_result();
     59                } // if
    3760        }
    38         if ( dynamic_cast< VoidType* >( dest ) ) {
    39             return 1;
    40         } else {
    41             PtrsAssignable ptrs( dest, env );
    42             src->accept( ptrs );
    43             return ptrs.get_result();
     61
     62        PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {
    4463        }
    45     }
    4664
    47     PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {
    48     }
     65        void PtrsAssignable::visit( VoidType *voidType ) {
     66                if ( dynamic_cast< FunctionType* >( dest ) ) {
     67                        result = 0;
     68                } else {
     69                        result = -1;
     70                } // if
     71        }
    4972
    50     void PtrsAssignable::visit(VoidType *voidType) {
    51         if ( dynamic_cast< FunctionType* >( dest ) ) {
    52             result = 0;
    53         } else {
    54             result = -1;
     73        void PtrsAssignable::visit( BasicType *basicType ) {
    5574        }
    56     }
    5775
    58     void PtrsAssignable::visit( BasicType *basicType ) {
    59     }
     76        void PtrsAssignable::visit( PointerType *pointerType ) {
     77        }
    6078
    61     void PtrsAssignable::visit( PointerType *pointerType ) {
    62     }
     79        void PtrsAssignable::visit( ArrayType *arrayType ) {
     80        }
    6381
    64     void PtrsAssignable::visit( ArrayType *arrayType ) {
    65     }
     82        void PtrsAssignable::visit( FunctionType *functionType ) {
     83                result = -1;
     84        }
    6685
    67     void PtrsAssignable::visit( FunctionType *functionType ) {
    68         result = -1;
    69     }
     86        void PtrsAssignable::visit( StructInstType *inst ) {
     87                // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong
     88        }
    7089
    71     void PtrsAssignable::visit( StructInstType *inst ) {
    72         // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong
    73     }
     90        void PtrsAssignable::visit( UnionInstType *inst ) {
     91                // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong
     92        }
    7493
    75     void PtrsAssignable::visit( UnionInstType *inst ) {
    76         // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong
    77     }
     94        void PtrsAssignable::visit( EnumInstType *inst ) {
     95                if ( dynamic_cast< EnumInstType* >( inst ) ) {
     96                        result = 1;
     97                } else if ( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) {
     98                        result = bt->get_kind() == BasicType::SignedInt;
     99                }
     100        }
    78101
    79     void PtrsAssignable::visit( EnumInstType *inst ) {
    80         if ( dynamic_cast< EnumInstType* >( inst ) ) {
    81             result = 1;
    82         } else if ( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) {
    83             result = bt->get_kind() == BasicType::SignedInt;
     102        void PtrsAssignable::visit( ContextInstType *inst ) {
     103                // I definitely don't think we should be doing anything here
    84104        }
    85     }
    86105
    87     void PtrsAssignable::visit( ContextInstType *inst ) {
    88         // I definitely don't think we should be doing anything here
    89     }
     106        void PtrsAssignable::visit( TypeInstType *inst ) {
     107                EqvClass eqvClass;
     108                if ( env.lookup( inst->get_name(), eqvClass ) ) {
     109                        result = ptrsAssignable( eqvClass.type, dest, env );
     110                } else {
     111                        result = 0;
     112                } // if
     113        }
    90114
    91     void PtrsAssignable::visit( TypeInstType *inst ) {
    92         EqvClass eqvClass;
    93         if ( env.lookup( inst->get_name(), eqvClass ) ) {
    94             result = ptrsAssignable( eqvClass.type, dest, env );
    95         } else {
    96             result = 0;
    97         }
    98     }
    99 
    100     void PtrsAssignable::visit( TupleType *tupleType ) {
     115        void PtrsAssignable::visit( TupleType *tupleType ) {
    101116///  // This code doesn't belong here, but it might be useful somewhere else
    102117///   if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
     
    104119///     std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
    105120///     std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
    106 ///     while( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
     121///     while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
    107122///       int assignResult = ptrsAssignable( *srcIt++, *destIt++ );
    108123///       if ( assignResult == 0 ) {
     
    121136///     }
    122137///   }
    123     }
     138        }
    124139} // namespace ResolvExpr
     140
     141// Local Variables: //
     142// tab-width: 4 //
     143// mode: c++ //
     144// compile-command: "make install" //
     145// End: //
  • translator/ResolvExpr/PtrsCastable.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: PtrsCastable.cc,v 1.5 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// PtrsCastable.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 11:48:00 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 11:51:17 2015
     13// Update Count     : 2
     14//
    715
    816#include "typeops.h"
     
    1422
    1523namespace ResolvExpr {
     24        class PtrsCastable : public Visitor {
     25          public:
     26                PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     27 
     28                int get_result() const { return result; }
    1629
    17 class PtrsCastable : public Visitor
    18 {
    19 public:
    20   PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    21  
    22   int get_result() const { return result; }
     30                virtual void visit(VoidType *voidType);
     31                virtual void visit(BasicType *basicType);
     32                virtual void visit(PointerType *pointerType);
     33                virtual void visit(ArrayType *arrayType);
     34                virtual void visit(FunctionType *functionType);
     35                virtual void visit(StructInstType *inst);
     36                virtual void visit(UnionInstType *inst);
     37                virtual void visit(EnumInstType *inst);
     38                virtual void visit(ContextInstType *inst);
     39                virtual void visit(TypeInstType *inst);
     40                virtual void visit(TupleType *tupleType);
     41          private:
     42                Type *dest;
     43                int result;
     44                const TypeEnvironment &env;
     45                const SymTab::Indexer &indexer;
     46        };
    2347
    24   virtual void visit(VoidType *voidType);
    25   virtual void visit(BasicType *basicType);
    26   virtual void visit(PointerType *pointerType);
    27   virtual void visit(ArrayType *arrayType);
    28   virtual void visit(FunctionType *functionType);
    29   virtual void visit(StructInstType *inst);
    30   virtual void visit(UnionInstType *inst);
    31   virtual void visit(EnumInstType *inst);
    32   virtual void visit(ContextInstType *inst);
    33   virtual void visit(TypeInstType *inst);
    34   virtual void visit(TupleType *tupleType);
     48        int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     49                if ( dynamic_cast< FunctionType* >( src ) ) {
     50                        return -1;
     51                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
     52                        EqvClass eqvClass;
     53                        if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     54                                if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
     55                                        if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     56                                                return -1;
     57                                        } // if
     58                                } //if
     59                        } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     60                                if ( eqvClass.kind == TypeDecl::Ftype ) {
     61                                        return -1;
     62                                } // if
     63                        } // if
     64                } //if
     65                return 1;
     66        }
    3567
    36 private:
    37   Type *dest;
    38   int result;
    39   const TypeEnvironment &env;
    40   const SymTab::Indexer &indexer;
    41 };
     68        int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     69                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     70                        EqvClass eqvClass;
     71                        if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
     72                                return ptrsAssignable( src, eqvClass.type, env );
     73                        } // if
     74                } // if
     75                if ( dynamic_cast< VoidType* >( dest ) ) {
     76                        return objectCast( src, env, indexer );
     77                } else {
     78                        PtrsCastable ptrs( dest, env, indexer );
     79                        src->accept( ptrs );
     80                        return ptrs.get_result();
     81                } // if
     82        }
    4283
    43 int
    44 objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    45 {
    46   if( dynamic_cast< FunctionType* >( src ) ) {
    47     return -1;
    48   } else if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
    49     EqvClass eqvClass;
    50     if( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    51       if( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    52         if( tyDecl->get_kind() == TypeDecl::Ftype ) {
    53           return -1;
    54         }
    55       }
    56     } else if( env.lookup( typeInst->get_name(), eqvClass ) ) {
    57       if( eqvClass.kind == TypeDecl::Ftype ) {
    58         return -1;
    59       }
    60     }
    61   }
    62   return 1;
    63 }
     84        PtrsCastable::PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
     85                : dest( dest ), result( 0 ), env( env ), indexer( indexer )     {
     86        }
    6487
    65 int
    66 ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    67 {
    68   if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    69     EqvClass eqvClass;
    70     if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
    71       return ptrsAssignable( src, eqvClass.type, env );
    72     }
    73   }
    74   if( dynamic_cast< VoidType* >( dest ) ) {
    75     return objectCast( src, env, indexer );
    76   } else {
    77     PtrsCastable ptrs( dest, env, indexer );
    78     src->accept( ptrs );
    79     return ptrs.get_result();
    80   }
    81 }
     88        void PtrsCastable::visit(VoidType *voidType) {
     89                result = objectCast( dest, env, indexer );
     90        }
    8291
    83 PtrsCastable::PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    84   : dest( dest ), result( 0 ), env( env ), indexer( indexer )
    85 {
    86 }
     92        void PtrsCastable::visit(BasicType *basicType) {
     93                result = objectCast( dest, env, indexer );
     94        }
    8795
    88 void
    89 PtrsCastable::visit(VoidType *voidType)
    90 {
    91   result = objectCast( dest, env, indexer );
    92 }
     96        void PtrsCastable::visit(PointerType *pointerType) {
     97                result = objectCast( dest, env, indexer );
     98        }
    9399
    94 void
    95 PtrsCastable::visit(BasicType *basicType)
    96 {
    97   result = objectCast( dest, env, indexer );
    98 }
     100        void PtrsCastable::visit(ArrayType *arrayType) {
     101                result = objectCast( dest, env, indexer );
     102        }
    99103
    100 void
    101 PtrsCastable::visit(PointerType *pointerType)
    102 {
    103   result = objectCast( dest, env, indexer );
    104 }
     104        void PtrsCastable::visit(FunctionType *functionType) {
     105                result = -1;
     106        }
    105107
    106 void
    107 PtrsCastable::visit(ArrayType *arrayType)
    108 {
    109   result = objectCast( dest, env, indexer );
    110 }
     108        void PtrsCastable::visit(StructInstType *inst) {
     109                result = objectCast( dest, env, indexer );
     110        }
    111111
    112 void
    113 PtrsCastable::visit(FunctionType *functionType)
    114 {
    115   result = -1;
    116 }
     112        void PtrsCastable::visit(UnionInstType *inst) {
     113                result = objectCast( dest, env, indexer );
     114        }
    117115
    118 void
    119 PtrsCastable::visit(StructInstType *inst)
    120 {
    121   result = objectCast( dest, env, indexer );
    122 }
     116        void PtrsCastable::visit(EnumInstType *inst) {
     117                if ( dynamic_cast< EnumInstType* >( inst ) ) {
     118                        result = 1;
     119                } else if ( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) {
     120                        if ( bt->get_kind() == BasicType::SignedInt ) {
     121                                result = 0;
     122                        } else {
     123                                result = 1;
     124                        }
     125                } else {
     126                        result = objectCast( dest, env, indexer );
     127                }
     128        }
    123129
    124 void
    125 PtrsCastable::visit(UnionInstType *inst)
    126 {
    127   result = objectCast( dest, env, indexer );
    128 }
     130        void PtrsCastable::visit(ContextInstType *inst) {
     131                // I definitely don't think we should be doing anything here
     132        }
    129133
    130 void
    131 PtrsCastable::visit(EnumInstType *inst)
    132 {
    133   if( dynamic_cast< EnumInstType* >( inst ) ) {
    134     result = 1;
    135   } else if( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) {
    136     if( bt->get_kind() == BasicType::SignedInt ) {
    137       result = 0;
    138     } else {
    139       result = 1;
    140     }
    141   } else {
    142     result = objectCast( dest, env, indexer );
    143   }
    144 }
     134        void PtrsCastable::visit(TypeInstType *inst) {
     135                result = objectCast( inst, env, indexer ) && objectCast( dest, env, indexer ) ? 1 : -1;
     136        }
    145137
    146 void
    147 PtrsCastable::visit(ContextInstType *inst)
    148 {
    149   // I definitely don't think we should be doing anything here
    150 }
     138        void PtrsCastable::visit(TupleType *tupleType) {
     139                result = objectCast( dest, env, indexer );
     140        }
     141} // namespace ResolvExpr
    151142
    152 void
    153 PtrsCastable::visit(TypeInstType *inst)
    154 {
    155   result = objectCast( inst, env, indexer ) && objectCast( dest, env, indexer ) ? 1 : -1;
    156 }
    157 
    158 void
    159 PtrsCastable::visit(TupleType *tupleType)
    160 {
    161   result = objectCast( dest, env, indexer );
    162 }
    163 
    164 } // namespace ResolvExpr
     143// Local Variables: //
     144// tab-width: 4 //
     145// mode: c++ //
     146// compile-command: "make install" //
     147// End: //
  • translator/ResolvExpr/RenameVars.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: RenameVars.cc,v 1.4 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// RenameVars.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 12:05:18 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 12:07:59 2015
     13// Update Count     : 2
     14//
    715
    816#include <strstream>
     
    1523
    1624namespace ResolvExpr {
     25        RenameVars global_renamer;
    1726
    18 RenameVars global_renamer;
     27        RenameVars::RenameVars() : level( 0 ) {
     28                mapStack.push_front( std::map< std::string, std::string >() );
     29        }
    1930
    20 RenameVars::RenameVars()
    21   : level( 0 )
    22 {
    23   mapStack.push_front( std::map< std::string, std::string >() );
    24 }
     31        void RenameVars::reset() {
     32                level = 0;
     33        }
    2534
    26 void
    27 RenameVars::reset()
    28 {
    29   level = 0;
    30 }
     35        void RenameVars::visit( VoidType *voidType ) {
     36                typeBefore( voidType );
     37                typeAfter( voidType );
     38        }
    3139
    32 void
    33 RenameVars::visit( VoidType *voidType )
    34 {
    35   typeBefore( voidType );
    36   typeAfter( voidType );
    37 }
     40        void RenameVars::visit( BasicType *basicType ) {
     41                typeBefore( basicType );
     42                typeAfter( basicType );
     43        }
    3844
    39 void
    40 RenameVars::visit( BasicType *basicType )
    41 {
    42   typeBefore( basicType );
    43   typeAfter( basicType );
    44 }
     45        void RenameVars::visit( PointerType *pointerType ) {
     46                typeBefore( pointerType );
     47///   std::cout << "do pointer" << std::endl;
     48                maybeAccept( pointerType->get_base(), *this );
     49///   std::cout << "done pointer" << std::endl;
     50                typeAfter( pointerType );
     51        }
    4552
    46 void
    47 RenameVars::visit( PointerType *pointerType )
    48 {
    49   typeBefore( pointerType );
    50 ///   std::cout << "do pointer" << std::endl;
    51   maybeAccept( pointerType->get_base(), *this );
    52 ///   std::cout << "done pointer" << std::endl;
    53   typeAfter( pointerType );
    54 }
     53        void RenameVars::visit( ArrayType *arrayType ) {
     54                typeBefore( arrayType );
     55                maybeAccept( arrayType->get_dimension(), *this );
     56                maybeAccept( arrayType->get_base(), *this );
     57                typeAfter( arrayType );
     58        }
    5559
    56 void
    57 RenameVars::visit( ArrayType *arrayType )
    58 {
    59   typeBefore( arrayType );
    60   maybeAccept( arrayType->get_dimension(), *this );
    61   maybeAccept( arrayType->get_base(), *this );
    62   typeAfter( arrayType );
    63 }
     60        void RenameVars::visit( FunctionType *functionType ) {
     61                typeBefore( functionType );
     62///   std::cout << "return vals" << std::endl;
     63                acceptAll( functionType->get_returnVals(), *this );
     64///   std::cout << functionType->get_parameters().size() << " parameters" << std::endl;
     65                acceptAll( functionType->get_parameters(), *this );
     66///   std::cout << "done function" << std::endl;
     67                typeAfter( functionType );
     68        }
    6469
    65 void
    66 RenameVars::visit( FunctionType *functionType )
    67 {
    68   typeBefore( functionType );
    69 ///   std::cout << "return vals" << std::endl;
    70   acceptAll( functionType->get_returnVals(), *this );
    71 ///   std::cout << functionType->get_parameters().size() << " parameters" << std::endl;
    72   acceptAll( functionType->get_parameters(), *this );
    73 ///   std::cout << "done function" << std::endl;
    74   typeAfter( functionType );
    75 }
     70        void RenameVars::visit( StructInstType *aggregateUseType ) {
     71                typeBefore( aggregateUseType );
     72                acceptAll( aggregateUseType->get_parameters(), *this );
     73                typeAfter( aggregateUseType );
     74        }
    7675
    77 void
    78 RenameVars::visit( StructInstType *aggregateUseType )
    79 {
    80   typeBefore( aggregateUseType );
    81   acceptAll( aggregateUseType->get_parameters(), *this );
    82   typeAfter( aggregateUseType );
    83 }
     76        void RenameVars::visit( UnionInstType *aggregateUseType ) {
     77                typeBefore( aggregateUseType );
     78                acceptAll( aggregateUseType->get_parameters(), *this );
     79                typeAfter( aggregateUseType );
     80        }
    8481
    85 void
    86 RenameVars::visit( UnionInstType *aggregateUseType )
    87 {
    88   typeBefore( aggregateUseType );
    89   acceptAll( aggregateUseType->get_parameters(), *this );
    90   typeAfter( aggregateUseType );
    91 }
     82        void RenameVars::visit( EnumInstType *aggregateUseType ) {
     83                typeBefore( aggregateUseType );
     84                acceptAll( aggregateUseType->get_parameters(), *this );
     85                typeAfter( aggregateUseType );
     86        }
    9287
    93 void
    94 RenameVars::visit( EnumInstType *aggregateUseType )
    95 {
    96   typeBefore( aggregateUseType );
    97   acceptAll( aggregateUseType->get_parameters(), *this );
    98   typeAfter( aggregateUseType );
    99 }
     88        void RenameVars::visit( ContextInstType *aggregateUseType ) {
     89                typeBefore( aggregateUseType );
     90                acceptAll( aggregateUseType->get_parameters(), *this );
     91                acceptAll( aggregateUseType->get_members(), *this );
     92                typeAfter( aggregateUseType );
     93        }
    10094
    101 void
    102 RenameVars::visit( ContextInstType *aggregateUseType )
    103 {
    104   typeBefore( aggregateUseType );
    105   acceptAll( aggregateUseType->get_parameters(), *this );
    106   acceptAll( aggregateUseType->get_members(), *this );
    107   typeAfter( aggregateUseType );
    108 }
     95        void RenameVars::visit( TypeInstType *instType ) {
     96                typeBefore( instType );
     97///   std::cout << "instance of type " << instType->get_name() << std::endl;
     98                std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->get_name() );
     99                if ( i != mapStack.front().end() ) {
     100///     std::cout << "found name " << i->second << std::endl;
     101                        instType->set_name( i->second );
     102                } else {
     103///     std::cout << "no name found" << std::endl;
     104                } // if
     105                acceptAll( instType->get_parameters(), *this );
     106                typeAfter( instType );
     107        }
    109108
    110 void
    111 RenameVars::visit( TypeInstType *instType )
    112 {
    113   typeBefore( instType );
    114 ///   std::cout << "instance of type " << instType->get_name() << std::endl;
    115   std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->get_name() );
    116   if( i != mapStack.front().end() ) {
    117 ///     std::cout << "found name " << i->second << std::endl;
    118     instType->set_name( i->second );
    119   } else {
    120 ///     std::cout << "no name found" << std::endl;
    121   }
    122   acceptAll( instType->get_parameters(), *this );
    123   typeAfter( instType );
    124 }
     109        void RenameVars::visit( TupleType *tupleType ) {
     110                typeBefore( tupleType );
     111                acceptAll( tupleType->get_types(), *this );
     112                typeAfter( tupleType );
     113        }
    125114
    126 void
    127 RenameVars::visit( TupleType *tupleType )
    128 {
    129   typeBefore( tupleType );
    130   acceptAll( tupleType->get_types(), *this );
    131   typeAfter( tupleType );
    132 }
    133 
    134 void
    135 RenameVars::typeBefore( Type *type )
    136 {
    137   if( !type->get_forall().empty() ) {
     115        void RenameVars::typeBefore( Type *type ) {
     116                if ( ! type->get_forall().empty() ) {
    138117///     std::cout << "type with forall: ";
    139118///     type->print( std::cout );
    140119///     std::cout << std::endl;
    141     mapStack.push_front( mapStack.front() );
    142     for( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    143       std::ostrstream output;
    144       output << "_" << level << "_" << (*i)->get_name();
    145       std::string newname( output.str(), output.pcount() );
    146       mapStack.front()[ (*i)->get_name() ] = newname;
    147       (*i)->set_name( newname );
    148       level++;
    149       acceptAll( (*i)->get_assertions(), *this );
    150     }
    151   }
    152 }
     120                        mapStack.push_front( mapStack.front() );
     121                        for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     122                                std::ostrstream output;
     123                                output << "_" << level << "_" << (*i)->get_name();
     124                                std::string newname( output.str(), output.pcount() );
     125                                mapStack.front()[ (*i)->get_name() ] = newname;
     126                                (*i)->set_name( newname );
     127                                level++;
     128                                acceptAll( (*i)->get_assertions(), *this );
     129                        } // for
     130                } // if
     131        }
    153132
    154 void
    155 RenameVars::typeAfter( Type *type )
    156 {
    157   if( !type->get_forall().empty() ) {
    158     mapStack.pop_front();
    159   }
    160 }
     133        void RenameVars::typeAfter( Type *type ) {
     134                if ( ! type->get_forall().empty() ) {
     135                        mapStack.pop_front();
     136                } // if
     137        }
    161138
    162139} // namespace ResolvExpr
     140
     141// Local Variables: //
     142// tab-width: 4 //
     143// mode: c++ //
     144// compile-command: "make install" //
     145// End: //
  • translator/ResolvExpr/RenameVars.h

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: RenameVars.h,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// RenameVars.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 12:10:28 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 12:11:53 2015
     13// Update Count     : 2
     14//
    715
    816#ifndef RESOLVEXPR_RENAMEVARS_H
     
    1725
    1826namespace ResolvExpr {
     27        class RenameVars : public Visitor {
     28          public:
     29                RenameVars();
     30                void reset();
     31          private:
     32                virtual void visit( VoidType *basicType );
     33                virtual void visit( BasicType *basicType );
     34                virtual void visit( PointerType *pointerType );
     35                virtual void visit( ArrayType *arrayType );
     36                virtual void visit( FunctionType *functionType );
     37                virtual void visit( StructInstType *aggregateUseType );
     38                virtual void visit( UnionInstType *aggregateUseType );
     39                virtual void visit( EnumInstType *aggregateUseType );
     40                virtual void visit( ContextInstType *aggregateUseType );
     41                virtual void visit( TypeInstType *aggregateUseType );
     42                virtual void visit( TupleType *tupleType );
    1943
    20 class RenameVars : public Visitor
    21 {
    22 public:
    23   RenameVars();
    24   void reset();
    25  
    26 private:
    27   virtual void visit( VoidType *basicType );
    28   virtual void visit( BasicType *basicType );
    29   virtual void visit( PointerType *pointerType );
    30   virtual void visit( ArrayType *arrayType );
    31   virtual void visit( FunctionType *functionType );
    32   virtual void visit( StructInstType *aggregateUseType );
    33   virtual void visit( UnionInstType *aggregateUseType );
    34   virtual void visit( EnumInstType *aggregateUseType );
    35   virtual void visit( ContextInstType *aggregateUseType );
    36   virtual void visit( TypeInstType *aggregateUseType );
    37   virtual void visit( TupleType *tupleType );
    38  
    39   void typeBefore( Type *type );
    40   void typeAfter( Type *type );
    41   int level;
    42   std::list< std::map< std::string, std::string > > mapStack;
    43 };
     44                void typeBefore( Type *type );
     45                void typeAfter( Type *type );
     46                int level;
     47                std::list< std::map< std::string, std::string > > mapStack;
     48        };
    4449
    45 extern RenameVars global_renamer;
    46 
     50        extern RenameVars global_renamer;
    4751} // namespace ResolvExpr
    4852
    49 #endif /* #ifndef RESOLVEXPR_RENAMEVARS_H */
     53#endif // RENAMEVARS_H
     54
     55// Local Variables: //
     56// tab-width: 4 //
     57// mode: c++ //
     58// compile-command: "make install" //
     59// End: //
  • translator/ResolvExpr/ResolveTypeof.cc

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// ResolveTypeof.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 12:12:20 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 12:13:38 2015
     13// Update Count     : 2
     14//
     15
    116#include "ResolveTypeof.h"
    217#include "Alternative.h"
     
    1025    namespace {
    1126#if 0
    12         void
    13         printAlts( const AltList &list, std::ostream &os, int indent = 0 )
    14         {
    15             for( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    16                 i->print( os, indent );
    17                 os << std::endl;
    18             }
    19         }
     27                void
     28                printAlts( const AltList &list, std::ostream &os, int indent = 0 )
     29                {
     30                        for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
     31                                i->print( os, indent );
     32                                os << std::endl;
     33                        }
     34                }
    2035#endif
    2136    }
     
    2338    class ResolveTypeof : public Mutator {
    2439      public:
    25         ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
    26         Type *mutate( TypeofType *typeofType );
     40                ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
     41                Type *mutate( TypeofType *typeofType );
    2742
    2843      private:
    29         const SymTab::Indexer &indexer;
     44                const SymTab::Indexer &indexer;
    3045    };
    3146
    3247    Type *resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
    33         ResolveTypeof mutator( indexer );
    34         return type->acceptMutator( mutator );
     48                ResolveTypeof mutator( indexer );
     49                return type->acceptMutator( mutator );
    3550    }
    3651
    3752    Type *ResolveTypeof::mutate( TypeofType *typeofType ) {
    3853#if 0
    39         std::cout << "resolving typeof: ";
    40         typeofType->print( std::cout );
    41         std::cout << std::endl;
     54                std::cout << "resolving typeof: ";
     55                typeofType->print( std::cout );
     56                std::cout << std::endl;
    4257#endif
    43         if ( typeofType->get_expr() ) {
    44             Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
    45             assert( newExpr->get_results().size() > 0 );
    46             Type *newType;
    47             if ( newExpr->get_results().size() > 1 ) {
    48                 TupleType *tupleType = new TupleType( Type::Qualifiers() );
    49                 cloneAll( newExpr->get_results(), tupleType->get_types() );
    50                 newType = tupleType;
    51             } else {
    52                 newType = newExpr->get_results().front()->clone();
    53             }
    54             delete typeofType;
    55             return newType;
    56         }
    57         return typeofType;
     58                if ( typeofType->get_expr() ) {
     59                        Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
     60                        assert( newExpr->get_results().size() > 0 );
     61                        Type *newType;
     62                        if ( newExpr->get_results().size() > 1 ) {
     63                                TupleType *tupleType = new TupleType( Type::Qualifiers() );
     64                                cloneAll( newExpr->get_results(), tupleType->get_types() );
     65                                newType = tupleType;
     66                        } else {
     67                                newType = newExpr->get_results().front()->clone();
     68                        } // if
     69                        delete typeofType;
     70                        return newType;
     71                } // if
     72                return typeofType;
    5873    }
     74} // namespace ResolvExpr
    5975
    60 } // namespace ResolvExpr
     76// Local Variables: //
     77// tab-width: 4 //
     78// mode: c++ //
     79// compile-command: "make install" //
     80// End: //
  • translator/ResolvExpr/ResolveTypeof.h

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// ResolveTypeof.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 12:14:53 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 12:16:29 2015
     13// Update Count     : 2
     14//
     15
    116#ifndef RESOLVETYPEOF_H
    217#define RESOLVETYPEOF_H
     
    621
    722namespace ResolvExpr {
    8     Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
     23        Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
    924} // namespace ResolvExpr
    1025
    1126#endif // RESOLVETYPEOF_H
     27
     28// Local Variables: //
     29// tab-width: 4 //
     30// mode: c++ //
     31// compile-command: "make install" //
     32// End: //
  • translator/ResolvExpr/Resolver.cc

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Resolver.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 12:17:01 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 12:18:17 2015
     13// Update Count     : 2
     14//
     15
    116#include "Resolver.h"
    217#include "AlternativeFinder.h"
     
    1530
    1631namespace ResolvExpr {
    17     class Resolver : public SymTab::Indexer {
    18       public:
    19         Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
    20  
    21         virtual void visit( FunctionDecl *functionDecl );
    22         virtual void visit( ObjectDecl *functionDecl );
    23         virtual void visit( TypeDecl *typeDecl );
    24 
    25         virtual void visit( ExprStmt *exprStmt );
    26         virtual void visit( IfStmt *ifStmt );
    27         virtual void visit( WhileStmt *whileStmt );
    28         virtual void visit( ForStmt *forStmt );
    29         virtual void visit( SwitchStmt *switchStmt );
    30         virtual void visit( ChooseStmt *switchStmt );
    31         virtual void visit( CaseStmt *caseStmt );
    32         virtual void visit( ReturnStmt *returnStmt );
    33 
    34         virtual void visit( SingleInit *singleInit );
    35         virtual void visit( ListInit *listInit );
    36       private:
    37         std::list< Type * > functionReturn;
    38         Type *initContext;
    39         Type *switchType;
    40     };
    41 
    42     void resolve( std::list< Declaration * > translationUnit ) {
    43         Resolver resolver;
    44         acceptAll( translationUnit, resolver );
    45 #if 0
    46         resolver.print( cerr );
    47         for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
    48             (*i)->print( std::cerr );
    49             (*i)->accept( resolver );
    50         } // for
    51 #endif
    52     }
    53 
    54     Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
    55         TypeEnvironment env;
    56         return resolveInVoidContext( expr, indexer, env );
    57     }
    58 
    59     namespace {
    60         void finishExpr( Expression *expr, const TypeEnvironment &env ) {
    61             expr->set_env( new TypeSubstitution );
    62             env.makeSubstitution( *expr->get_env() );
    63         }
    64 
    65         Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    66             global_renamer.reset();
    67             TypeEnvironment env;
    68             Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    69             finishExpr( newExpr, env );
    70             return newExpr;
    71         }
    72  
    73         Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    74             TypeEnvironment env;
    75             AlternativeFinder finder( indexer, env );
    76             finder.find( untyped );
    77 #if 0
    78             if ( finder.get_alternatives().size() != 1 ) {
    79                 std::cout << "untyped expr is ";
    80                 untyped->print( std::cout );
    81                 std::cout << std::endl << "alternatives are:";
    82                 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    83                     i->print( std::cout );
     32        class Resolver : public SymTab::Indexer {
     33          public:
     34                Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
     35 
     36                virtual void visit( FunctionDecl *functionDecl );
     37                virtual void visit( ObjectDecl *functionDecl );
     38                virtual void visit( TypeDecl *typeDecl );
     39
     40                virtual void visit( ExprStmt *exprStmt );
     41                virtual void visit( IfStmt *ifStmt );
     42                virtual void visit( WhileStmt *whileStmt );
     43                virtual void visit( ForStmt *forStmt );
     44                virtual void visit( SwitchStmt *switchStmt );
     45                virtual void visit( ChooseStmt *switchStmt );
     46                virtual void visit( CaseStmt *caseStmt );
     47                virtual void visit( ReturnStmt *returnStmt );
     48
     49                virtual void visit( SingleInit *singleInit );
     50                virtual void visit( ListInit *listInit );
     51          private:
     52                std::list< Type * > functionReturn;
     53                Type *initContext;
     54                Type *switchType;
     55        };
     56
     57        void resolve( std::list< Declaration * > translationUnit ) {
     58                Resolver resolver;
     59                acceptAll( translationUnit, resolver );
     60#if 0
     61                resolver.print( cerr );
     62                for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     63                        (*i)->print( std::cerr );
     64                        (*i)->accept( resolver );
    8465                } // for
    85             } // if
    86 #endif
    87             assert( finder.get_alternatives().size() == 1 );
    88             Alternative &choice = finder.get_alternatives().front();
    89             Expression *newExpr = choice.expr->clone();
    90             finishExpr( newExpr, choice.env );
    91             return newExpr;
    92         }
    93 
    94         bool isIntegralType( Type *type ) {
    95             if ( dynamic_cast< EnumInstType * >( type ) ) {
    96                 return true;
    97             } else if ( BasicType *bt = dynamic_cast< BasicType * >( type ) ) {
    98                 return bt->isInteger();
    99             } else {
    100                 return false;
    101             } // if
    102         }
    103  
    104         Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    105             TypeEnvironment env;
    106             AlternativeFinder finder( indexer, env );
    107             finder.find( untyped );
    108 #if 0
    109             if ( finder.get_alternatives().size() != 1 ) {
    110                 std::cout << "untyped expr is ";
    111                 untyped->print( std::cout );
    112                 std::cout << std::endl << "alternatives are:";
    113                 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    114                     i->print( std::cout );
     66#endif
     67        }
     68
     69        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
     70                TypeEnvironment env;
     71                return resolveInVoidContext( expr, indexer, env );
     72        }
     73
     74        namespace {
     75                void finishExpr( Expression *expr, const TypeEnvironment &env ) {
     76                        expr->set_env( new TypeSubstitution );
     77                        env.makeSubstitution( *expr->get_env() );
     78                }
     79
     80                Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     81                        global_renamer.reset();
     82                        TypeEnvironment env;
     83                        Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
     84                        finishExpr( newExpr, env );
     85                        return newExpr;
     86                }
     87 
     88                Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     89                        TypeEnvironment env;
     90                        AlternativeFinder finder( indexer, env );
     91                        finder.find( untyped );
     92#if 0
     93                        if ( finder.get_alternatives().size() != 1 ) {
     94                                std::cout << "untyped expr is ";
     95                                untyped->print( std::cout );
     96                                std::cout << std::endl << "alternatives are:";
     97                                for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     98                                        i->print( std::cout );
     99                                } // for
     100                        } // if
     101#endif
     102                        assert( finder.get_alternatives().size() == 1 );
     103                        Alternative &choice = finder.get_alternatives().front();
     104                        Expression *newExpr = choice.expr->clone();
     105                        finishExpr( newExpr, choice.env );
     106                        return newExpr;
     107                }
     108
     109                bool isIntegralType( Type *type ) {
     110                        if ( dynamic_cast< EnumInstType * >( type ) ) {
     111                                return true;
     112                        } else if ( BasicType *bt = dynamic_cast< BasicType * >( type ) ) {
     113                                return bt->isInteger();
     114                        } else {
     115                                return false;
     116                        } // if
     117                }
     118 
     119                Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     120                        TypeEnvironment env;
     121                        AlternativeFinder finder( indexer, env );
     122                        finder.find( untyped );
     123#if 0
     124                        if ( finder.get_alternatives().size() != 1 ) {
     125                                std::cout << "untyped expr is ";
     126                                untyped->print( std::cout );
     127                                std::cout << std::endl << "alternatives are:";
     128                                for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     129                                        i->print( std::cout );
     130                                } // for
     131                        } // if
     132#endif
     133                        Expression *newExpr = 0;
     134                        const TypeEnvironment *newEnv = 0;
     135                        for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     136                                if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
     137                                        if ( newExpr ) {
     138                                                throw SemanticError( "Too many interpretations for case control expression", untyped );
     139                                        } else {
     140                                                newExpr = i->expr->clone();
     141                                                newEnv = &i->env;
     142                                        } // if
     143                                } // if
     144                        } // for
     145                        if ( ! newExpr ) {
     146                                throw SemanticError( "No interpretations for case control expression", untyped );
     147                        } // if
     148                        finishExpr( newExpr, *newEnv );
     149                        return newExpr;
     150                }
     151 
     152        }
     153 
     154        void Resolver::visit( ObjectDecl *objectDecl ) {
     155                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     156                objectDecl->set_type( new_type );
     157                initContext = new_type;
     158                SymTab::Indexer::visit( objectDecl );
     159        }
     160 
     161        void Resolver::visit( TypeDecl *typeDecl ) {
     162                if ( typeDecl->get_base() ) {
     163                        Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
     164                        typeDecl->set_base( new_type );
     165                } // if
     166                SymTab::Indexer::visit( typeDecl );
     167        }
     168 
     169        void Resolver::visit( FunctionDecl *functionDecl ) {
     170#if 0
     171                std::cout << "resolver visiting functiondecl ";
     172                functionDecl->print( std::cout );
     173                std::cout << std::endl;
     174#endif
     175                Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
     176                functionDecl->set_type( new_type );
     177                std::list< Type * > oldFunctionReturn = functionReturn;
     178                functionReturn.clear();
     179                for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
     180                        functionReturn.push_back( (*i)->get_type() );
    115181                } // for
    116             } // if
    117 #endif
    118             Expression *newExpr = 0;
    119             const TypeEnvironment *newEnv = 0;
    120             for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    121                 if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
    122                     if ( newExpr ) {
    123                         throw SemanticError( "Too many interpretations for case control expression", untyped );
    124                     } else {
    125                         newExpr = i->expr->clone();
    126                         newEnv = &i->env;
    127                     } // if
    128                 } // if
    129             } // for
    130             if ( ! newExpr ) {
    131                 throw SemanticError( "No interpretations for case control expression", untyped );
    132             } // if
    133             finishExpr( newExpr, *newEnv );
    134             return newExpr;
    135         }
    136  
    137     }
    138  
    139     void Resolver::visit( ObjectDecl *objectDecl ) {
    140         Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
    141         objectDecl->set_type( new_type );
    142         initContext = new_type;
    143         SymTab::Indexer::visit( objectDecl );
    144     }
    145  
    146     void Resolver::visit( TypeDecl *typeDecl ) {
    147         if ( typeDecl->get_base() ) {
    148             Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
    149             typeDecl->set_base( new_type );
    150         } // if
    151         SymTab::Indexer::visit( typeDecl );
    152     }
    153  
    154     void Resolver::visit( FunctionDecl *functionDecl ) {
    155 #if 0
    156         std::cout << "resolver visiting functiondecl ";
    157         functionDecl->print( std::cout );
    158         std::cout << std::endl;
    159 #endif
    160         Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
    161         functionDecl->set_type( new_type );
    162         std::list< Type * > oldFunctionReturn = functionReturn;
    163         functionReturn.clear();
    164         for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
    165             functionReturn.push_back( (*i)->get_type() );
    166         } // for
    167         SymTab::Indexer::visit( functionDecl );
    168         functionReturn = oldFunctionReturn;
    169     }
    170 
    171     void Resolver::visit( ExprStmt *exprStmt ) {
    172         if ( exprStmt->get_expr() ) {
    173             Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
    174             delete exprStmt->get_expr();
    175             exprStmt->set_expr( newExpr );
    176         } // if
    177     }
    178 
    179     void Resolver::visit( IfStmt *ifStmt ) {
    180         Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this );
    181         delete ifStmt->get_condition();
    182         ifStmt->set_condition( newExpr );
    183         Visitor::visit( ifStmt );
    184     }
    185 
    186     void Resolver::visit( WhileStmt *whileStmt ) {
    187         Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
    188         delete whileStmt->get_condition();
    189         whileStmt->set_condition( newExpr );
    190         Visitor::visit( whileStmt );
    191     }
    192 
    193     void Resolver::visit( ForStmt *forStmt ) {
    194         // SymTab::Indexer::visit( forStmt );
    195         Expression *newExpr;
    196         // for statements introduce a level of scope
    197         enterScope();
    198         maybeAccept( forStmt->get_initialization(), *this );
    199         if ( forStmt->get_condition() ) {
    200             newExpr = findSingleExpression( forStmt->get_condition(), *this );
    201             delete forStmt->get_condition();
    202             forStmt->set_condition( newExpr );
    203         } // if
    204  
    205         if ( forStmt->get_increment() ) {
    206             newExpr = findVoidExpression( forStmt->get_increment(), *this );
    207             delete forStmt->get_increment();
    208             forStmt->set_increment( newExpr );
    209         } // if
    210 
    211         maybeAccept( forStmt->get_condition(), *this );
    212         maybeAccept( forStmt->get_increment(), *this );
    213         maybeAccept( forStmt->get_body(), *this );
    214         leaveScope();
    215     }
    216 
    217     template< typename SwitchClass >
    218     void handleSwitchStmt( SwitchClass *switchStmt, SymTab::Indexer &visitor ) {
    219         Expression *newExpr;
    220         newExpr = findIntegralExpression( switchStmt->get_condition(), visitor );
    221         delete switchStmt->get_condition();
    222         switchStmt->set_condition( newExpr );
    223  
    224         visitor.Visitor::visit( switchStmt );
    225     }
    226 
    227     void Resolver::visit( SwitchStmt *switchStmt ) {
    228         handleSwitchStmt( switchStmt, *this );
    229     }
    230 
    231     void Resolver::visit( ChooseStmt *switchStmt ) {
    232         handleSwitchStmt( switchStmt, *this );
    233     }
    234 
    235     void Resolver::visit( CaseStmt *caseStmt ) {
    236         Visitor::visit( caseStmt );
    237     }
    238 
    239     void Resolver::visit( ReturnStmt *returnStmt ) {
    240         if ( returnStmt->get_expr() ) {
    241             CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
    242             cloneAll( functionReturn, castExpr->get_results() );
    243             Expression *newExpr = findSingleExpression( castExpr, *this );
    244             delete castExpr;
    245             returnStmt->set_expr( newExpr );
    246         } // if
    247     }
    248 
    249     void Resolver::visit( SingleInit *singleInit ) {
    250         if ( singleInit->get_value() ) {
    251 #if 0
    252             if (NameExpr * ne = dynamic_cast<NameExpr*>(singleInit->get_value())) {
    253                 string n = ne->get_name();
    254                 if (n == "0") {
    255                     initContext = new BasicType(Type::Qualifiers(),
    256                                                 BasicType::SignedInt);
    257                 } else {
    258                     DeclarationWithType * decl = lookupId(n);
    259                     initContext = decl->get_type();
    260                 }
    261             } else if (ConstantExpr * e =
    262                        dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
    263                 Constant *c = e->get_constant();
    264                 initContext = c->get_type();
    265             } else {
    266                 assert(0);
    267             }
    268 #endif
    269             CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
    270             Expression *newExpr = findSingleExpression( castExpr, *this );
    271             delete castExpr;
    272             singleInit->set_value( newExpr );
    273         } // if
     182                SymTab::Indexer::visit( functionDecl );
     183                functionReturn = oldFunctionReturn;
     184        }
     185
     186        void Resolver::visit( ExprStmt *exprStmt ) {
     187                if ( exprStmt->get_expr() ) {
     188                        Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
     189                        delete exprStmt->get_expr();
     190                        exprStmt->set_expr( newExpr );
     191                } // if
     192        }
     193
     194        void Resolver::visit( IfStmt *ifStmt ) {
     195                Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this );
     196                delete ifStmt->get_condition();
     197                ifStmt->set_condition( newExpr );
     198                Visitor::visit( ifStmt );
     199        }
     200
     201        void Resolver::visit( WhileStmt *whileStmt ) {
     202                Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
     203                delete whileStmt->get_condition();
     204                whileStmt->set_condition( newExpr );
     205                Visitor::visit( whileStmt );
     206        }
     207
     208        void Resolver::visit( ForStmt *forStmt ) {
     209            // SymTab::Indexer::visit( forStmt );
     210                Expression *newExpr;
     211            // for statements introduce a level of scope
     212            enterScope();
     213            maybeAccept( forStmt->get_initialization(), *this );
     214                if ( forStmt->get_condition() ) {
     215                        newExpr = findSingleExpression( forStmt->get_condition(), *this );
     216                        delete forStmt->get_condition();
     217                        forStmt->set_condition( newExpr );
     218                } // if
     219 
     220                if ( forStmt->get_increment() ) {
     221                        newExpr = findVoidExpression( forStmt->get_increment(), *this );
     222                        delete forStmt->get_increment();
     223                        forStmt->set_increment( newExpr );
     224                } // if
     225
     226            maybeAccept( forStmt->get_condition(), *this );
     227            maybeAccept( forStmt->get_increment(), *this );
     228            maybeAccept( forStmt->get_body(), *this );
     229            leaveScope();
     230        }
     231
     232        template< typename SwitchClass >
     233        void handleSwitchStmt( SwitchClass *switchStmt, SymTab::Indexer &visitor ) {
     234                Expression *newExpr;
     235                newExpr = findIntegralExpression( switchStmt->get_condition(), visitor );
     236                delete switchStmt->get_condition();
     237                switchStmt->set_condition( newExpr );
     238 
     239                visitor.Visitor::visit( switchStmt );
     240        }
     241
     242        void Resolver::visit( SwitchStmt *switchStmt ) {
     243                handleSwitchStmt( switchStmt, *this );
     244        }
     245
     246        void Resolver::visit( ChooseStmt *switchStmt ) {
     247                handleSwitchStmt( switchStmt, *this );
     248        }
     249
     250        void Resolver::visit( CaseStmt *caseStmt ) {
     251                Visitor::visit( caseStmt );
     252        }
     253
     254        void Resolver::visit( ReturnStmt *returnStmt ) {
     255                if ( returnStmt->get_expr() ) {
     256                        CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
     257                        cloneAll( functionReturn, castExpr->get_results() );
     258                        Expression *newExpr = findSingleExpression( castExpr, *this );
     259                        delete castExpr;
     260                        returnStmt->set_expr( newExpr );
     261                } // if
     262        }
     263
     264        void Resolver::visit( SingleInit *singleInit ) {
     265                if ( singleInit->get_value() ) {
     266#if 0
     267                        if (NameExpr * ne = dynamic_cast<NameExpr*>(singleInit->get_value())) {
     268                                string n = ne->get_name();
     269                                if (n == "0") {
     270                                        initContext = new BasicType(Type::Qualifiers(),
     271                                                                                                BasicType::SignedInt);
     272                                } else {
     273                                        DeclarationWithType * decl = lookupId(n);
     274                                        initContext = decl->get_type();
     275                                }
     276                        } else if (ConstantExpr * e =
     277                                           dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
     278                                Constant *c = e->get_constant();
     279                                initContext = c->get_type();
     280                        } else {
     281                                assert(0);
     282                        }
     283#endif
     284                        CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
     285                        Expression *newExpr = findSingleExpression( castExpr, *this );
     286                        delete castExpr;
     287                        singleInit->set_value( newExpr );
     288                } // if
    274289//      singleInit->get_value()->accept( *this );
    275     }
    276 
    277     void Resolver::visit( ListInit *listInit ) {
    278         Visitor::visit(listInit);
    279 #if 0
    280         if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) {
    281             std::list<Initializer *>::iterator iter( listInit->begin_initializers() );
    282             for ( ; iter != listInit->end_initializers(); ++iter ) {
    283                 initContext = at->get_base();
    284                 (*iter)->accept( *this );
    285             } // for
    286         } else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) {
    287             StructDecl *baseStruct = st->get_baseStruct();
    288             std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() );
    289             std::list<Initializer *>::iterator iter2( listInit->begin_initializers() );
    290             for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) {
    291                 if ( (*iter2)->get_designators().empty() ) {
    292                     DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 );
    293                     initContext = dt->get_type();
    294                     (*iter2)->accept( *this );
    295                     ++iter1;
    296                 } else {
    297                     StructDecl *st = baseStruct;
    298                     iter1 = st->get_members().begin();
    299                     std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() );
    300                     for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) {
    301                         NameExpr *key = dynamic_cast<NameExpr *>( *iter3 );
    302                         assert( key );
    303                         for ( ; iter1 != st->get_members().end(); ++iter1 ) {
    304                             if ( key->get_name() == (*iter1)->get_name() ) {
    305                                 (*iter1)->print( cout );
    306                                 cout << key->get_name() << endl;
    307                                 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
    308                                 assert( fred );
    309                                 StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() );
    310                                 assert( mary );
    311                                 st = mary->get_baseStruct();
    312                                 iter1 = st->get_members().begin();
    313                                 break;
    314                             } // if
    315                         }  // for
    316                     } // for
    317                     ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
    318                     assert( fred );
    319                     initContext = fred->get_type();
    320                     (*listInit->begin_initializers())->accept( *this );
    321                 } // if
    322             } // for
    323         } else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) {
    324             DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() );
    325             initContext = dt->get_type();
    326             (*listInit->begin_initializers())->accept( *this );
    327         } // if
    328 #endif
    329     }
     290        }
     291
     292        void Resolver::visit( ListInit *listInit ) {
     293                Visitor::visit(listInit);
     294#if 0
     295                if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) {
     296                        std::list<Initializer *>::iterator iter( listInit->begin_initializers() );
     297                        for ( ; iter != listInit->end_initializers(); ++iter ) {
     298                                initContext = at->get_base();
     299                                (*iter)->accept( *this );
     300                        } // for
     301                } else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) {
     302                        StructDecl *baseStruct = st->get_baseStruct();
     303                        std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() );
     304                        std::list<Initializer *>::iterator iter2( listInit->begin_initializers() );
     305                        for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) {
     306                                if ( (*iter2)->get_designators().empty() ) {
     307                                        DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 );
     308                                        initContext = dt->get_type();
     309                                        (*iter2)->accept( *this );
     310                                        ++iter1;
     311                                } else {
     312                                        StructDecl *st = baseStruct;
     313                                        iter1 = st->get_members().begin();
     314                                        std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() );
     315                                        for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) {
     316                                                NameExpr *key = dynamic_cast<NameExpr *>( *iter3 );
     317                                                assert( key );
     318                                                for ( ; iter1 != st->get_members().end(); ++iter1 ) {
     319                                                        if ( key->get_name() == (*iter1)->get_name() ) {
     320                                                                (*iter1)->print( cout );
     321                                                                cout << key->get_name() << endl;
     322                                                                ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
     323                                                                assert( fred );
     324                                                                StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() );
     325                                                                assert( mary );
     326                                                                st = mary->get_baseStruct();
     327                                                                iter1 = st->get_members().begin();
     328                                                                break;
     329                                                        } // if
     330                                                }  // for
     331                                        } // for
     332                                        ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
     333                                        assert( fred );
     334                                        initContext = fred->get_type();
     335                                        (*listInit->begin_initializers())->accept( *this );
     336                                } // if
     337                        } // for
     338                } else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) {
     339                        DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() );
     340                        initContext = dt->get_type();
     341                        (*listInit->begin_initializers())->accept( *this );
     342                } // if
     343#endif
     344        }
    330345} // namespace ResolvExpr
     346
     347// Local Variables: //
     348// tab-width: 4 //
     349// mode: c++ //
     350// compile-command: "make install" //
     351// End: //
  • translator/ResolvExpr/Resolver.h

    rb87a5ed ra32b204  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Resolver.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 12:18:34 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 12:19:32 2015
     13// Update Count     : 2
     14//
     15
    116#ifndef RESOLVER_H
    217#define RESOLVER_H
     
    621
    722namespace ResolvExpr {
    8     void resolve( std::list< Declaration * > translationUnit );
    9     Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
     23        void resolve( std::list< Declaration * > translationUnit );
     24        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
    1025} // namespace ResolvExpr
    1126
    1227#endif // RESOLVER_H
     28
     29// Local Variables: //
     30// tab-width: 4 //
     31// mode: c++ //
     32// compile-command: "make install" //
     33// End: //
  • translator/ResolvExpr/TypeEnvironment.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: TypeEnvironment.cc,v 1.7 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// TypeEnvironment.cc --
     8//
     9// Author           : Richard C. Bilson
     10// 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
     14//
    715
    816#include <algorithm>
     
    1523
    1624namespace ResolvExpr {
    17 
    18 void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent )
    19 {
    20   for( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
    21     i->first->print( os, indent );
    22     if( i->second ) {
    23       os << "(used)";
    24     } else {
    25       os << "(not used)";
    26     }
    27   }
    28 }
    29 
    30 void printOpenVarSet( const OpenVarSet &openVars, std::ostream &os, int indent )
    31 {
    32   os << std::string( indent, ' ' );
    33   for( OpenVarSet::const_iterator i = openVars.begin(); i != openVars.end(); ++i ) {
    34     os << i->first << "(" << i->second << ") ";
    35   }
    36 }
    37 
    38 void
    39 EqvClass::initialize( const EqvClass &src, EqvClass &dest )
    40 {
    41   dest.vars = src.vars;
    42   dest.type = maybeClone( src.type );
    43   dest.allowWidening = src.allowWidening;
    44   dest.kind = src.kind;
    45 }
    46 
    47 EqvClass::EqvClass() : type( 0 ), allowWidening( true )
    48 {
    49 }
    50 
    51 EqvClass::EqvClass( const EqvClass &other )
    52 {
    53   initialize( other, *this );
    54 }
    55 
    56 EqvClass &
    57 EqvClass::operator=( const EqvClass &other )
    58 {
    59   if( this == &other ) return *this;
    60   delete type;
    61   initialize( other, *this );
    62   return *this;
    63 }
    64 
    65 EqvClass::~EqvClass()
    66 {
    67   delete type;
    68 }
    69 
    70 void
    71 EqvClass::print( std::ostream &os, int indent ) const
    72 {
    73   os << std::string( indent, ' ' ) << "( ";
    74   std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) );
    75   os << ")";
    76   if( type ) {
    77     os << " -> ";
    78     type->print( os, indent );
    79   }
    80   if( !allowWidening ) {
    81     os << " (no widening)";
    82   }
    83   os << std::endl;
    84 }
    85 
    86 bool
    87 TypeEnvironment::lookup( const std::string &var, EqvClass &eqvClass ) const
    88 {
    89   for( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
    90     if( i->vars.find( var ) != i->vars.end() ) {
     25        void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) {
     26                for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
     27                        i->first->print( os, indent );
     28                        if ( i->second ) {
     29                                os << "(used)";
     30                        } else {
     31                                os << "(not used)";
     32                        } // if
     33                } // for
     34        }
     35
     36        void printOpenVarSet( const OpenVarSet &openVars, std::ostream &os, int indent ) {
     37                os << std::string( indent, ' ' );
     38                for ( OpenVarSet::const_iterator i = openVars.begin(); i != openVars.end(); ++i ) {
     39                        os << i->first << "(" << i->second << ") ";
     40                } // for
     41        }
     42
     43        void EqvClass::initialize( const EqvClass &src, EqvClass &dest ) {
     44                dest.vars = src.vars;
     45                dest.type = maybeClone( src.type );
     46                dest.allowWidening = src.allowWidening;
     47                dest.kind = src.kind;
     48        }
     49
     50        EqvClass::EqvClass() : type( 0 ), allowWidening( true ) {
     51        }
     52
     53        EqvClass::EqvClass( const EqvClass &other ) {
     54                initialize( other, *this );
     55        }
     56
     57        EqvClass &EqvClass::operator=( const EqvClass &other ) {
     58                if ( this == &other ) return *this;
     59                delete type;
     60                initialize( other, *this );
     61                return *this;
     62        }
     63
     64        EqvClass::~EqvClass() {
     65                delete type;
     66        }
     67
     68        void EqvClass::print( std::ostream &os, int indent ) const {
     69                os << std::string( indent, ' ' ) << "( ";
     70                std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) );
     71                os << ")";
     72                if ( type ) {
     73                        os << " -> ";
     74                        type->print( os, indent );
     75                } // if
     76                if ( ! allowWidening ) {
     77                        os << " (no widening)";
     78                } // if
     79                os << std::endl;
     80        }
     81
     82        bool TypeEnvironment::lookup( const std::string &var, EqvClass &eqvClass ) const {
     83                for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
     84                        if ( i->vars.find( var ) != i->vars.end() ) {
    9185///       std::cout << var << " is in class ";
    9286///       i->print( std::cout );
    93       eqvClass = *i;
    94       return true;
    95     }
     87                                eqvClass = *i;
     88                                return true;
     89                        }
    9690///     std::cout << var << " is not in class ";
    9791///     i->print( std::cout );
    98   }
    99   return false;
    100 }
    101 
    102 void
    103 TypeEnvironment::add( const EqvClass &eqvClass )
    104 {
    105   std::list< EqvClass >::iterator i = env.begin();
    106   while( i != env.end() ) {
    107     std::list< EqvClass >::iterator next = i;
    108     next++;
    109     std::set< std::string > intersection;
    110     std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), std::inserter( intersection, intersection.begin() ) );
    111     if( !intersection.empty() ) {
    112       env.erase( i );
    113     }
    114     i = next;
    115   }
    116   env.insert( env.end(), eqvClass );
    117 }
    118 
    119 void
    120 TypeEnvironment::add( const std::list< TypeDecl* > &tyDecls )
    121 {
    122   for( std::list< TypeDecl* >::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) {
    123     EqvClass newClass;
    124     newClass.vars.insert( (*i)->get_name() );
    125     newClass.kind = (*i)->get_kind();
    126     env.push_back( newClass );
    127   }
    128 }
    129 
    130 void
    131 TypeEnvironment::makeSubstitution( TypeSubstitution &sub ) const
    132 {
    133   for( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    134     for( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
     92                } // for
     93                return false;
     94        }
     95
     96        void TypeEnvironment::add( const EqvClass &eqvClass ) {
     97                std::list< EqvClass >::iterator i = env.begin();
     98                while ( i != env.end() ) {
     99                        std::list< EqvClass >::iterator next = i;
     100                        next++;
     101                        std::set< std::string > intersection;
     102                        std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), std::inserter( intersection, intersection.begin() ) );
     103                        if ( ! intersection.empty() ) {
     104                                env.erase( i );
     105                        } // if
     106                        i = next;
     107                } // while
     108                env.insert( env.end(), eqvClass );
     109        }
     110
     111        void TypeEnvironment::add( const std::list< TypeDecl* > &tyDecls ) {
     112                for ( std::list< TypeDecl* >::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) {
     113                        EqvClass newClass;
     114                        newClass.vars.insert( (*i)->get_name() );
     115                        newClass.kind = (*i)->get_kind();
     116                        env.push_back( newClass );
     117                } // for
     118        }
     119
     120        void TypeEnvironment::makeSubstitution( TypeSubstitution &sub ) const {
     121                for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
     122                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    135123///       std::cout << "adding " << *theVar;
    136       if( theClass->type ) {
     124                                if ( theClass->type ) {
    137125///         std::cout << " bound to ";
    138126///         theClass->type->print( std::cout );
    139127///         std::cout << std::endl;
    140         sub.add( *theVar, theClass->type );
    141       } else if( theVar != theClass->vars.begin() ) {
    142         TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->kind == TypeDecl::Ftype );
     128                                        sub.add( *theVar, theClass->type );
     129                                } else if ( theVar != theClass->vars.begin() ) {
     130                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->kind == TypeDecl::Ftype );
    143131///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
    144         sub.add( *theVar, newTypeInst );
    145         delete newTypeInst;
    146       }
    147     }
    148   }
     132                                        sub.add( *theVar, newTypeInst );
     133                                        delete newTypeInst;
     134                                } // if
     135                        } // for
     136                } // for
    149137///   std::cerr << "input env is:" << std::endl;
    150138///   print( std::cerr, 8 );
    151139///   std::cerr << "sub is:" << std::endl;
    152140///   sub.print( std::cerr, 8 );
    153   sub.normalize();
    154 }
    155 
    156 void
    157 TypeEnvironment::print( std::ostream &os, int indent ) const
    158 {
    159   for( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
    160     i->print( os, indent );
    161   }
    162 }
    163 
    164 std::list< EqvClass >::iterator
    165 TypeEnvironment::internal_lookup( const std::string &var )
    166 {
    167   for( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) {
    168     if( i->vars.find( var ) == i->vars.end() ) {
    169       return i;
    170     }
    171   }
    172   return env.end();
    173 }
    174 
    175 void
    176 TypeEnvironment::simpleCombine( const TypeEnvironment &second )
    177 {
    178   env.insert( env.end(), second.env.begin(), second.env.end() );
    179 }
    180 
    181 void
    182 TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) )
    183 {
    184   TypeEnvironment secondCopy( second );
    185   for( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) {
    186     EqvClass &newClass = *firstClass;
    187     std::set< std::string > newVars;
    188     for( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) {
    189       std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var );
    190       if( secondClass != secondCopy.env.end() ) {
    191         newVars.insert( secondClass->vars.begin(), secondClass->vars.end() );
    192         if( secondClass->type ) {
    193           if( newClass.type ) {
    194             Type *newType = combineFunc( newClass.type, secondClass->type );
    195             delete newClass.type;
    196             newClass.type = newType;
    197             newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening;
    198           } else {
    199             newClass.type = secondClass->type->clone();
    200             newClass.allowWidening = secondClass->allowWidening;
    201           }
    202         }
    203         secondCopy.env.erase( secondClass );
    204       }
    205     }
    206     newClass.vars.insert( newVars.begin(), newVars.end() );
    207   }
    208   for( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) {
    209     env.push_back( *secondClass );
    210   }
    211 }
    212 
    213 void
    214 TypeEnvironment::extractOpenVars( OpenVarSet &openVars ) const
    215 {
    216   for( std::list< EqvClass >::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {
    217     for( std::set< std::string >::const_iterator var = eqvClass->vars.begin(); var != eqvClass->vars.end(); ++var ) {
    218       openVars[ *var ] = eqvClass->kind;
    219     }
    220   }
    221 }
     141                sub.normalize();
     142        }
     143
     144        void TypeEnvironment::print( std::ostream &os, int indent ) const {
     145                for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
     146                        i->print( os, indent );
     147                } // for
     148        }
     149
     150        std::list< EqvClass >::iterator TypeEnvironment::internal_lookup( const std::string &var ) {
     151                for ( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) {
     152                        if ( i->vars.find( var ) == i->vars.end() ) {
     153                                return i;
     154                        } // if
     155                } // for
     156                return env.end();
     157        }
     158
     159        void TypeEnvironment::simpleCombine( const TypeEnvironment &second ) {
     160                env.insert( env.end(), second.env.begin(), second.env.end() );
     161        }
     162
     163        void TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ) {
     164                TypeEnvironment secondCopy( second );
     165                for ( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) {
     166                        EqvClass &newClass = *firstClass;
     167                        std::set< std::string > newVars;
     168                        for ( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) {
     169                                std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var );
     170                                if ( secondClass != secondCopy.env.end() ) {
     171                                        newVars.insert( secondClass->vars.begin(), secondClass->vars.end() );
     172                                        if ( secondClass->type ) {
     173                                                if ( newClass.type ) {
     174                                                        Type *newType = combineFunc( newClass.type, secondClass->type );
     175                                                        delete newClass.type;
     176                                                        newClass.type = newType;
     177                                                        newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening;
     178                                                } else {
     179                                                        newClass.type = secondClass->type->clone();
     180                                                        newClass.allowWidening = secondClass->allowWidening;
     181                                                } // if
     182                                        } // if
     183                                        secondCopy.env.erase( secondClass );
     184                                } // if
     185                        } // for
     186                        newClass.vars.insert( newVars.begin(), newVars.end() );
     187                } // for
     188                for ( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) {
     189                        env.push_back( *secondClass );
     190                } // for
     191        }
     192
     193        void TypeEnvironment::extractOpenVars( OpenVarSet &openVars ) const {
     194                for ( std::list< EqvClass >::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {
     195                        for ( std::set< std::string >::const_iterator var = eqvClass->vars.begin(); var != eqvClass->vars.end(); ++var ) {
     196                                openVars[ *var ] = eqvClass->kind;
     197                        } // for
     198                } // for
     199        }
    222200
    223201} // namespace ResolvExpr
     202
     203// Local Variables: //
     204// tab-width: 4 //
     205// mode: c++ //
     206// compile-command: "make install" //
     207// End: //
  • translator/ResolvExpr/TypeEnvironment.h

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: TypeEnvironment.h,v 1.8 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// TypeEnvironment.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 12:24:58 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 12:26:52 2015
     13// Update Count     : 2
     14//
    715
    8 #ifndef RESOLVEXPR_TYPEENVIRONMENT_H
    9 #define RESOLVEXPR_TYPEENVIRONMENT_H
     16#ifndef TYPEENVIRONMENT_H
     17#define TYPEENVIRONMENT_H
    1018
    1119#include <string>
     
    2028
    2129namespace ResolvExpr {
     30        typedef std::map< DeclarationWithType*, bool > AssertionSet;
     31        typedef std::map< std::string, TypeDecl::Kind > OpenVarSet;
    2232
    23 typedef std::map< DeclarationWithType*, bool > AssertionSet;
    24 typedef std::map< std::string, TypeDecl::Kind > OpenVarSet;
     33        void printAssertionSet( const AssertionSet &, std::ostream &, int indent = 0 );
     34        void printOpenVarSet( const OpenVarSet &, std::ostream &, int indent = 0 );
    2535
    26 void printAssertionSet( const AssertionSet &, std::ostream &, int indent = 0 );
    27 void printOpenVarSet( const OpenVarSet &, std::ostream &, int indent = 0 );
     36        struct EqvClass {
     37                std::set< std::string > vars;
     38                Type *type;
     39                bool allowWidening;
     40                TypeDecl::Kind kind;
     41 
     42                void initialize( const EqvClass &src, EqvClass &dest );
     43                EqvClass();
     44                EqvClass( const EqvClass &other );
     45                EqvClass &operator=( const EqvClass &other );
     46                ~EqvClass();
     47                void print( std::ostream &os, int indent = 0 ) const;
     48        };
    2849
    29 struct EqvClass
    30 {
    31   std::set< std::string > vars;
    32   Type *type;
    33   bool allowWidening;
    34   TypeDecl::Kind kind;
     50        class TypeEnvironment {
     51          public:
     52                bool lookup( const std::string &var, EqvClass &eqvClass ) const;
     53                void add( const EqvClass &eqvClass );
     54                void add( const std::list< TypeDecl* > &tyDecls );
     55                template< typename SynTreeClass > int apply( SynTreeClass *&type ) const;
     56                template< typename SynTreeClass > int applyFree( SynTreeClass *&type ) const;
     57                void makeSubstitution( TypeSubstitution &result ) const;
     58                bool isEmpty() const { return env.empty(); }
     59                void print( std::ostream &os, int indent = 0 ) const;
     60                void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
     61                void simpleCombine( const TypeEnvironment &second );
     62                void extractOpenVars( OpenVarSet &openVars ) const;
     63                TypeEnvironment *clone() const { return new TypeEnvironment( *this ); }
    3564 
    36   void initialize( const EqvClass &src, EqvClass &dest );
    37   EqvClass();
    38   EqvClass( const EqvClass &other );
    39   EqvClass &operator=( const EqvClass &other );
    40   ~EqvClass();
    41   void print( std::ostream &os, int indent = 0 ) const;
    42 };
     65                typedef std::list< EqvClass >::iterator iterator;
     66                iterator begin() { return env.begin(); }
     67                iterator end() { return env.end(); }
     68                typedef std::list< EqvClass >::const_iterator const_iterator;
     69                const_iterator begin() const { return env.begin(); }
     70                const_iterator end() const { return env.end(); }
     71          private:
     72                std::list< EqvClass > env;
     73                std::list< EqvClass >::iterator internal_lookup( const std::string &var );
     74        };
    4375
    44 class TypeEnvironment
    45 {
    46 public:
    47   bool lookup( const std::string &var, EqvClass &eqvClass ) const;
    48   void add( const EqvClass &eqvClass );
    49   void add( const std::list< TypeDecl* > &tyDecls );
    50   template< typename SynTreeClass > int apply( SynTreeClass *&type ) const;
    51   template< typename SynTreeClass > int applyFree( SynTreeClass *&type ) const;
    52   void makeSubstitution( TypeSubstitution &result ) const;
    53   bool isEmpty() const { return env.empty(); }
    54   void print( std::ostream &os, int indent = 0 ) const;
    55   void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
    56   void simpleCombine( const TypeEnvironment &second );
    57   void extractOpenVars( OpenVarSet &openVars ) const;
    58   TypeEnvironment *clone() const { return new TypeEnvironment( *this ); }
    59  
    60   typedef std::list< EqvClass >::iterator iterator;
    61   iterator begin() { return env.begin(); }
    62   iterator end() { return env.end(); }
    63   typedef std::list< EqvClass >::const_iterator const_iterator;
    64   const_iterator begin() const { return env.begin(); }
    65   const_iterator end() const { return env.end(); }
    66 private:
    67   std::list< EqvClass > env;
    68  
    69   std::list< EqvClass >::iterator internal_lookup( const std::string &var );
    70 };
     76        template< typename SynTreeClass >
     77        int TypeEnvironment::apply( SynTreeClass *&type ) const {
     78                TypeSubstitution sub;
     79                makeSubstitution( sub );
     80                return sub.apply( type );
     81        }
    7182
    72 template< typename SynTreeClass >
    73 int
    74 TypeEnvironment::apply( SynTreeClass *&type ) const
    75 {
    76   TypeSubstitution sub;
    77   makeSubstitution( sub );
    78   return sub.apply( type );
    79 }
    80 
    81 template< typename SynTreeClass >
    82 int
    83 TypeEnvironment::applyFree( SynTreeClass *&type ) const
    84 {
    85   TypeSubstitution sub;
    86   makeSubstitution( sub );
    87   return sub.applyFree( type );
    88 }
    89 
     83        template< typename SynTreeClass >
     84        int TypeEnvironment::applyFree( SynTreeClass *&type ) const {
     85                TypeSubstitution sub;
     86                makeSubstitution( sub );
     87                return sub.applyFree( type );
     88        }
    9089} // namespace ResolvExpr
    9190
    92 #endif /* #ifndef RESOLVEXPR_TYPEENVIRONMENT_H */
     91#endif // TYPEENVIRONMENT_H */
     92
     93// Local Variables: //
     94// tab-width: 4 //
     95// mode: c++ //
     96// compile-command: "make install" //
     97// End: //
  • translator/ResolvExpr/Unify.cc

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Unify.cc,v 1.14 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Unify.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 12:27:10 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 13:08:48 2015
     13// Update Count     : 6
     14//
    715
    816#include <set>
     
    2331
    2432namespace ResolvExpr {
    25 
    26 struct WidenMode
    27 {
    28   WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}
    29   WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }
    30   WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }
    31   WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }
    32   WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
    33   operator bool() { return widenFirst && widenSecond; }
    34  
    35   bool widenFirst : 1, widenSecond : 1;
    36 };
    37 
    38 class Unify : public Visitor
    39 {
    40 public:
    41   Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    42  
    43   bool get_result() const { return result; }
    44 
    45 private:
    46   virtual void visit(VoidType *voidType);
    47   virtual void visit(BasicType *basicType);
    48   virtual void visit(PointerType *pointerType);
    49   virtual void visit(ArrayType *arrayType);
    50   virtual void visit(FunctionType *functionType);
    51   virtual void visit(StructInstType *aggregateUseType);
    52   virtual void visit(UnionInstType *aggregateUseType);
    53   virtual void visit(EnumInstType *aggregateUseType);
    54   virtual void visit(ContextInstType *aggregateUseType);
    55   virtual void visit(TypeInstType *aggregateUseType);
    56   virtual void visit(TupleType *tupleType);
    57 
    58   template< typename RefType > void handleRefType( RefType *inst, Type *other );
    59 
    60   bool result;
    61   Type *type2;                          // inherited
    62   TypeEnvironment &env;
    63   AssertionSet &needAssertions;
    64   AssertionSet &haveAssertions;
    65   const OpenVarSet &openVars;
    66   WidenMode widenMode;
    67   Type *commonType;
    68   const SymTab::Indexer &indexer;
    69 };
    70 
    71 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
    72 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    73  
    74 bool
    75 typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    76 {
    77   TypeEnvironment newEnv;
    78   OpenVarSet openVars;
    79   AssertionSet needAssertions, haveAssertions;
    80   Type *newFirst = first->clone(), *newSecond = second->clone();
    81   env.apply( newFirst );
    82   env.apply( newSecond );
    83   bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    84   delete newFirst;
    85   delete newSecond;
    86   return result;
    87 }
    88 
    89 bool
    90 typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    91 {
    92   TypeEnvironment newEnv;
    93   OpenVarSet openVars;
    94   AssertionSet needAssertions, haveAssertions;
    95   Type *newFirst = first->clone(), *newSecond = second->clone();
    96   env.apply( newFirst );
    97   env.apply( newSecond );
    98   newFirst->get_qualifiers() = Type::Qualifiers();
    99   newSecond->get_qualifiers() = Type::Qualifiers();
     33        struct WidenMode {
     34                WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}
     35                WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }
     36                WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }
     37                WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }
     38                WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
     39                operator bool() { return widenFirst && widenSecond; }
     40 
     41                bool widenFirst : 1, widenSecond : 1;
     42        };
     43
     44        class Unify : public Visitor {
     45          public:
     46                Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     47 
     48                bool get_result() const { return result; }
     49          private:
     50                virtual void visit(VoidType *voidType);
     51                virtual void visit(BasicType *basicType);
     52                virtual void visit(PointerType *pointerType);
     53                virtual void visit(ArrayType *arrayType);
     54                virtual void visit(FunctionType *functionType);
     55                virtual void visit(StructInstType *aggregateUseType);
     56                virtual void visit(UnionInstType *aggregateUseType);
     57                virtual void visit(EnumInstType *aggregateUseType);
     58                virtual void visit(ContextInstType *aggregateUseType);
     59                virtual void visit(TypeInstType *aggregateUseType);
     60                virtual void visit(TupleType *tupleType);
     61
     62                template< typename RefType > void handleRefType( RefType *inst, Type *other );
     63
     64                bool result;
     65                Type *type2;                            // inherited
     66                TypeEnvironment &env;
     67                AssertionSet &needAssertions;
     68                AssertionSet &haveAssertions;
     69                const OpenVarSet &openVars;
     70                WidenMode widenMode;
     71                Type *commonType;
     72                const SymTab::Indexer &indexer;
     73        };
     74
     75        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
     76        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     77 
     78        bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     79                TypeEnvironment newEnv;
     80                OpenVarSet openVars;
     81                AssertionSet needAssertions, haveAssertions;
     82                Type *newFirst = first->clone(), *newSecond = second->clone();
     83                env.apply( newFirst );
     84                env.apply( newSecond );
     85                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     86                delete newFirst;
     87                delete newSecond;
     88                return result;
     89        }
     90
     91        bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     92                TypeEnvironment newEnv;
     93                OpenVarSet openVars;
     94                AssertionSet needAssertions, haveAssertions;
     95                Type *newFirst = first->clone(), *newSecond = second->clone();
     96                env.apply( newFirst );
     97                env.apply( newSecond );
     98                newFirst->get_qualifiers() = Type::Qualifiers();
     99                newSecond->get_qualifiers() = Type::Qualifiers();
    100100///   std::cout << "first is ";
    101101///   first->print( std::cout );
     
    107107///   newSecond->print( std::cout );
    108108///   std::cout << std::endl;
    109   bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    110   delete newFirst;
    111   delete newSecond;
    112   return result;
    113 }
    114 
    115 bool
    116 isFtype( Type *type, const SymTab::Indexer &indexer )
    117 {
    118   if( dynamic_cast< FunctionType* >( type ) ) {
    119     return true;
    120   } else if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    121     return typeInst->get_isFtype();
    122   }
    123   return false;
    124 }
    125 
    126 bool
    127 tyVarCompatible( TypeDecl::Kind kind, Type *type, const SymTab::Indexer &indexer )
    128 {
    129   switch( kind ) {
    130   case TypeDecl::Any:
    131   case TypeDecl::Dtype:
    132     return !isFtype( type, indexer );
    133  
    134   case TypeDecl::Ftype:
    135     return isFtype( type, indexer );
    136   }
    137   assert( false );
    138   return false;
    139 }
    140 
    141 bool
    142 bindVar( TypeInstType *typeInst, Type *other, TypeDecl::Kind kind, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
    143 {
    144   OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
    145   assert( tyvar != openVars.end() );
    146   if( !tyVarCompatible( tyvar->second, other, indexer ) ) {
    147     return false;
    148   }
    149   if( occurs( other, typeInst->get_name(), env ) ) {
    150     return false;
    151   }
    152   EqvClass curClass;
    153   if( env.lookup( typeInst->get_name(), curClass ) ) {
    154     if( curClass.type ) {
    155       Type *common = 0;
    156       std::auto_ptr< Type > newType( curClass.type->clone() );
    157       if( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
    158         if( common ) {
    159           common->get_qualifiers() = Type::Qualifiers();
    160           delete curClass.type;
    161           curClass.type = common;
    162           env.add( curClass );
    163         }
    164         return true;
    165       } else {
    166         return false;
    167       }
    168     } else {
    169       curClass.type = other->clone();
    170       curClass.type->get_qualifiers() = Type::Qualifiers();
    171       curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    172       env.add( curClass );
    173     }
    174   } else {
    175     EqvClass newClass;
    176     newClass.vars.insert( typeInst->get_name() );
    177     newClass.type = other->clone();
    178     newClass.type->get_qualifiers() = Type::Qualifiers();
    179     newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    180     newClass.kind = kind;
    181     env.add( newClass );
    182   }
    183   return true;
    184 }
    185 
    186 bool
    187 bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Kind kind, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
    188 {
    189   bool result = true;
    190   EqvClass class1, class2;
    191   bool hasClass1 = false, hasClass2 = false;
    192   bool widen1 = false, widen2 = false;
    193   Type *type1 = 0, *type2 = 0;
    194  
    195   if( env.lookup( var1->get_name(), class1 ) ) {
    196     hasClass1 = true;
    197     if( class1.type ) {
    198       if( occurs( class1.type, var2->get_name(), env ) ) {
    199         return false;
    200       }
    201       type1 = class1.type->clone();
    202     }
    203     widen1 = widenMode.widenFirst && class1.allowWidening;
    204   }
    205   if( env.lookup( var2->get_name(), class2 ) ) {
    206     hasClass2 = true;
    207     if( class2.type ) {
    208       if( occurs( class2.type, var1->get_name(), env ) ) {
    209         return false;
    210       }
    211       type2 = class2.type->clone();
    212     }
    213     widen2 = widenMode.widenSecond && class2.allowWidening;
    214   }
    215  
    216   if( type1 && type2 ) {
     109                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     110                delete newFirst;
     111                delete newSecond;
     112                return result;
     113        }
     114
     115        bool isFtype( Type *type, const SymTab::Indexer &indexer ) {
     116                if ( dynamic_cast< FunctionType* >( type ) ) {
     117                        return true;
     118                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
     119                        return typeInst->get_isFtype();
     120                } // if
     121                return false;
     122        }
     123
     124        bool tyVarCompatible( TypeDecl::Kind kind, Type *type, const SymTab::Indexer &indexer ) {
     125                switch ( kind ) {
     126                  case TypeDecl::Any:
     127                  case TypeDecl::Dtype:
     128                        return ! isFtype( type, indexer );
     129 
     130                  case TypeDecl::Ftype:
     131                        return isFtype( type, indexer );
     132                } // switch
     133                assert( false );
     134                return false;
     135        }
     136
     137        bool bindVar( TypeInstType *typeInst, Type *other, TypeDecl::Kind kind, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     138                OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
     139                assert( tyvar != openVars.end() );
     140                if ( ! tyVarCompatible( tyvar->second, other, indexer ) ) {
     141                        return false;
     142                } // if
     143                if ( occurs( other, typeInst->get_name(), env ) ) {
     144                        return false;
     145                } // if
     146                EqvClass curClass;
     147                if ( env.lookup( typeInst->get_name(), curClass ) ) {
     148                        if ( curClass.type ) {
     149                                Type *common = 0;
     150                                std::auto_ptr< Type > newType( curClass.type->clone() );
     151                                if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
     152                                        if ( common ) {
     153                                                common->get_qualifiers() = Type::Qualifiers();
     154                                                delete curClass.type;
     155                                                curClass.type = common;
     156                                                env.add( curClass );
     157                                        } // if
     158                                        return true;
     159                                } else {
     160                                        return false;
     161                                } // if
     162                        } else {
     163                                curClass.type = other->clone();
     164                                curClass.type->get_qualifiers() = Type::Qualifiers();
     165                                curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
     166                                env.add( curClass );
     167                        } // if
     168                } else {
     169                        EqvClass newClass;
     170                        newClass.vars.insert( typeInst->get_name() );
     171                        newClass.type = other->clone();
     172                        newClass.type->get_qualifiers() = Type::Qualifiers();
     173                        newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
     174                        newClass.kind = kind;
     175                        env.add( newClass );
     176                } // if
     177                return true;
     178        }
     179
     180        bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Kind kind, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     181                bool result = true;
     182                EqvClass class1, class2;
     183                bool hasClass1 = false, hasClass2 = false;
     184                bool widen1 = false, widen2 = false;
     185                Type *type1 = 0, *type2 = 0;
     186 
     187                if ( env.lookup( var1->get_name(), class1 ) ) {
     188                        hasClass1 = true;
     189                        if ( class1.type ) {
     190                                if ( occurs( class1.type, var2->get_name(), env ) ) {
     191                                        return false;
     192                                } // if
     193                                type1 = class1.type->clone();
     194                        } // if
     195                        widen1 = widenMode.widenFirst && class1.allowWidening;
     196                } // if
     197                if ( env.lookup( var2->get_name(), class2 ) ) {
     198                        hasClass2 = true;
     199                        if ( class2.type ) {
     200                                if ( occurs( class2.type, var1->get_name(), env ) ) {
     201                                        return false;
     202                                } // if
     203                                type2 = class2.type->clone();
     204                        } // if
     205                        widen2 = widenMode.widenSecond && class2.allowWidening;
     206                } // if
     207 
     208                if ( type1 && type2 ) {
    217209//    std::cout << "has type1 && type2" << std::endl;
    218     WidenMode newWidenMode ( widen1, widen2 );
    219     Type *common = 0;
    220     if( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
    221       class1.vars.insert( class2.vars.begin(), class2.vars.end() );
    222       class1.allowWidening = widen1 && widen2;
    223       if( common ) {
    224         common->get_qualifiers() = Type::Qualifiers();
    225         delete class1.type;
    226         class1.type = common;
    227       }
    228       env.add( class1 );
    229     } else {
    230       result = false;
    231     }
    232   } else if( hasClass1 && hasClass2 ) {
    233     if( type1 ) {
    234       class1.vars.insert( class2.vars.begin(), class2.vars.end() );
    235       class1.allowWidening = widen1;
    236       env.add( class1 );
    237     } else {
    238       class2.vars.insert( class1.vars.begin(), class1.vars.end() );
    239       class2.allowWidening = widen2;
    240       env.add( class2 );
    241     }
    242   } else if( hasClass1 ) {
    243     class1.vars.insert( var2->get_name() );
    244     class1.allowWidening = widen1;
    245     env.add( class1 );
    246   } else if( hasClass2 ) {
    247     class2.vars.insert( var1->get_name() );
    248     class2.allowWidening = widen2;
    249     env.add( class2 );
    250   } else {
    251     EqvClass newClass;
    252     newClass.vars.insert( var1->get_name() );
    253     newClass.vars.insert( var2->get_name() );
    254     newClass.allowWidening = widen1 && widen2;
    255     newClass.kind = kind;
    256     env.add( newClass );
    257   }
    258   delete type1;
    259   delete type2;
    260   return result;
    261 }
    262 
    263 bool
    264 unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer )
    265 {
    266   OpenVarSet closedVars;
    267   findOpenVars( type1, openVars, closedVars, needAssertions, haveAssertions, false );
    268   findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
    269   Type *commonType = 0;
    270   if( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
    271     if( commonType ) {
    272       delete commonType;
    273     }
    274     return true;
    275   } else {
    276     return false;
    277   }
    278 }
    279 
    280 bool
    281 unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType )
    282 {
    283   OpenVarSet closedVars;
    284   findOpenVars( type1, openVars, closedVars, needAssertions, haveAssertions, false );
    285   findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
    286   return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType );
    287 }
    288 
    289 bool
    290 unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
    291 {
     210                        WidenMode newWidenMode ( widen1, widen2 );
     211                        Type *common = 0;
     212                        if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
     213                                class1.vars.insert( class2.vars.begin(), class2.vars.end() );
     214                                class1.allowWidening = widen1 && widen2;
     215                                if ( common ) {
     216                                        common->get_qualifiers() = Type::Qualifiers();
     217                                        delete class1.type;
     218                                        class1.type = common;
     219                                } // if
     220                                env.add( class1 );
     221                        } else {
     222                                result = false;
     223                        } // if
     224                } else if ( hasClass1 && hasClass2 ) {
     225                        if ( type1 ) {
     226                                class1.vars.insert( class2.vars.begin(), class2.vars.end() );
     227                                class1.allowWidening = widen1;
     228                                env.add( class1 );
     229                        } else {
     230                                class2.vars.insert( class1.vars.begin(), class1.vars.end() );
     231                                class2.allowWidening = widen2;
     232                                env.add( class2 );
     233                        } // if
     234                } else if ( hasClass1 ) {
     235                        class1.vars.insert( var2->get_name() );
     236                        class1.allowWidening = widen1;
     237                        env.add( class1 );
     238                } else if ( hasClass2 ) {
     239                        class2.vars.insert( var1->get_name() );
     240                        class2.allowWidening = widen2;
     241                        env.add( class2 );
     242                } else {
     243                        EqvClass newClass;
     244                        newClass.vars.insert( var1->get_name() );
     245                        newClass.vars.insert( var2->get_name() );
     246                        newClass.allowWidening = widen1 && widen2;
     247                        newClass.kind = kind;
     248                        env.add( newClass );
     249                } // if
     250                delete type1;
     251                delete type2;
     252                return result;
     253        }
     254
     255        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     256                OpenVarSet closedVars;
     257                findOpenVars( type1, openVars, closedVars, needAssertions, haveAssertions, false );
     258                findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
     259                Type *commonType = 0;
     260                if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
     261                        if ( commonType ) {
     262                                delete commonType;
     263                        } // if
     264                        return true;
     265                } else {
     266                        return false;
     267                } // if
     268        }
     269
     270        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType ) {
     271                OpenVarSet closedVars;
     272                findOpenVars( type1, openVars, closedVars, needAssertions, haveAssertions, false );
     273                findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
     274                return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType );
     275        }
     276
     277        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    292278#ifdef DEBUG
    293   TypeEnvironment debugEnv( env );
     279                TypeEnvironment debugEnv( env );
    294280#endif
    295   bool result;
    296   TypeInstType *var1 = dynamic_cast< TypeInstType* >( type1 );
    297   TypeInstType *var2 = dynamic_cast< TypeInstType* >( type2 );
    298   OpenVarSet::const_iterator entry1, entry2;
    299   if( var1 ) {
    300     entry1 = openVars.find( var1->get_name() );
    301   }
    302   if( var2 ) {
    303     entry2 = openVars.find( var2->get_name() );
    304   }
    305   bool isopen1 = var1 && ( entry1 != openVars.end() );
    306   bool isopen2 = var2 && ( entry2 != openVars.end() );
    307   if( type1->get_qualifiers() != type2->get_qualifiers() ) {
    308     return false;
    309   } else if( isopen1 && isopen2 && entry1->second == entry2->second ) {
    310     result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    311   } else if( isopen1 ) {
    312     result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    313   } else if( isopen2 ) {
    314     result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    315   } else {
    316     Unify comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    317     type1->accept( comparator );
    318     result = comparator.get_result();
    319   }
     281                bool result;
     282                TypeInstType *var1 = dynamic_cast< TypeInstType* >( type1 );
     283                TypeInstType *var2 = dynamic_cast< TypeInstType* >( type2 );
     284                OpenVarSet::const_iterator entry1, entry2;
     285                if ( var1 ) {
     286                        entry1 = openVars.find( var1->get_name() );
     287                } // if
     288                if ( var2 ) {
     289                        entry2 = openVars.find( var2->get_name() );
     290                } // if
     291                bool isopen1 = var1 && ( entry1 != openVars.end() );
     292                bool isopen2 = var2 && ( entry2 != openVars.end() );
     293                if ( type1->get_qualifiers() != type2->get_qualifiers() ) {
     294                        return false;
     295                } else if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
     296                        result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     297                } else if ( isopen1 ) {
     298                        result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     299                } else if ( isopen2 ) {
     300                        result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     301                } else {
     302                        Unify comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     303                        type1->accept( comparator );
     304                        result = comparator.get_result();
     305                } // if
    320306#ifdef DEBUG
    321   std::cout << "============ unifyExact" << std::endl;
    322   std::cout << "type1 is ";
    323   type1->print( std::cout );
    324   std::cout << std::endl << "type2 is ";
    325   type2->print( std::cout );
    326   std::cout << std::endl << "openVars are ";
    327   printOpenVarSet( openVars, std::cout, 8 );
    328   std::cout << std::endl << "input env is " << std::endl;
    329   debugEnv.print( std::cout, 8 );
    330   std::cout << std::endl << "result env is " << std::endl;
    331   env.print( std::cout, 8 );
    332   std::cout << "result is " << result << std::endl;
     307                std::cout << "============ unifyExact" << std::endl;
     308                std::cout << "type1 is ";
     309                type1->print( std::cout );
     310                std::cout << std::endl << "type2 is ";
     311                type2->print( std::cout );
     312                std::cout << std::endl << "openVars are ";
     313                printOpenVarSet( openVars, std::cout, 8 );
     314                std::cout << std::endl << "input env is " << std::endl;
     315                debugEnv.print( std::cout, 8 );
     316                std::cout << std::endl << "result env is " << std::endl;
     317                env.print( std::cout, 8 );
     318                std::cout << "result is " << result << std::endl;
    333319#endif
    334   return result;
    335 }
    336 
    337 bool
    338 unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer )
    339 {
    340   return unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    341 }
    342 
    343 bool
    344 unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common )
    345 {
    346   Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
    347   type1->get_qualifiers() = Type::Qualifiers();
    348   type2->get_qualifiers() = Type::Qualifiers();
    349   bool result;
     320                return result;
     321        }
     322
     323        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     324                return unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     325        }
     326
     327        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common ) {
     328                Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
     329                type1->get_qualifiers() = Type::Qualifiers();
     330                type2->get_qualifiers() = Type::Qualifiers();
     331                bool result;
    350332#ifdef DEBUG
    351   std::cout << "unifyInexact type 1 is ";
    352   type1->print( std::cout );
    353   std::cout << "type 2 is ";
    354   type2->print( std::cout );
    355   std::cout << std::endl;
     333                std::cout << "unifyInexact type 1 is ";
     334                type1->print( std::cout );
     335                std::cout << "type 2 is ";
     336                type2->print( std::cout );
     337                std::cout << std::endl;
    356338#endif
    357   if( !unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ) ) {
     339                if ( ! unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ) ) {
    358340#ifdef DEBUG
    359     std::cout << "unifyInexact: no exact unification found" << std::endl;
     341                        std::cout << "unifyInexact: no exact unification found" << std::endl;
    360342#endif
    361     if( ( common = commonType( type1, type2, widenMode.widenFirst, widenMode.widenSecond, indexer, env, openVars ) ) ) {
    362       common->get_qualifiers() = tq1 + tq2;
     343                        if ( ( common = commonType( type1, type2, widenMode.widenFirst, widenMode.widenSecond, indexer, env, openVars ) ) ) {
     344                                common->get_qualifiers() = tq1 + tq2;
    363345#ifdef DEBUG
    364       std::cout << "unifyInexact: common type is ";
    365       common->print( std::cout );
    366       std::cout << std::endl;
     346                                std::cout << "unifyInexact: common type is ";
     347                                common->print( std::cout );
     348                                std::cout << std::endl;
    367349#endif
    368       result = true;
    369     } else {
     350                                result = true;
     351                        } else {
    370352#ifdef DEBUG
    371       std::cout << "unifyInexact: no common type found" << std::endl;
     353                                std::cout << "unifyInexact: no common type found" << std::endl;
    372354#endif
    373       result = false;
    374     }
    375   } else {
    376     if( tq1 != tq2 ) {
    377       if( ( tq1 > tq2 || widenMode.widenFirst ) && ( tq2 > tq1 || widenMode.widenSecond ) ) {
    378         common = type1->clone();
    379         common->get_qualifiers() = tq1 + tq2;
    380         result = true;
    381       } else {
    382         result = false;
    383       }
    384     } else {
    385       result = true;
    386     }
    387   }
    388   type1->get_qualifiers() = tq1;
    389   type2->get_qualifiers() = tq2;
    390   return result;
    391 }
    392 
    393 Unify::Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
    394   : result( false ), type2( type2 ), env( env ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), openVars( openVars ), widenMode( widenMode ), indexer( indexer )
    395 {
    396 }
    397 
    398 void
    399 Unify::visit(VoidType *voidType)
    400 {
    401   result = dynamic_cast< VoidType* >( type2 );
    402 }
    403 
    404 void
    405 Unify::visit(BasicType *basicType)
    406 {
    407   if( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    408     result = basicType->get_kind() == otherBasic->get_kind();
    409   }
    410 }
    411 
    412 void
    413 markAssertionSet( AssertionSet &assertions, DeclarationWithType *assert )
    414 {
     355                                result = false;
     356                        } // if
     357                } else {
     358                        if ( tq1 != tq2 ) {
     359                                if ( ( tq1 > tq2 || widenMode.widenFirst ) && ( tq2 > tq1 || widenMode.widenSecond ) ) {
     360                                        common = type1->clone();
     361                                        common->get_qualifiers() = tq1 + tq2;
     362                                        result = true;
     363                                } else {
     364                                        result = false;
     365                                } // if
     366                        } else {
     367                                result = true;
     368                        } // if
     369                } // if
     370                type1->get_qualifiers() = tq1;
     371                type2->get_qualifiers() = tq2;
     372                return result;
     373        }
     374
     375        Unify::Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
     376                : result( false ), type2( type2 ), env( env ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), openVars( openVars ), widenMode( widenMode ), indexer( indexer ) {
     377        }
     378
     379        void Unify::visit(VoidType *voidType) {
     380                result = dynamic_cast< VoidType* >( type2 );
     381        }
     382
     383        void Unify::visit(BasicType *basicType) {
     384                if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
     385                        result = basicType->get_kind() == otherBasic->get_kind();
     386                } // if
     387        }
     388
     389        void markAssertionSet( AssertionSet &assertions, DeclarationWithType *assert ) {
    415390///   std::cout << "assertion set is" << std::endl;
    416391///   printAssertionSet( assertions, std::cout, 8 );
     
    418393///   assert->print( std::cout );
    419394///   std::cout << std::endl;
    420   AssertionSet::iterator i = assertions.find( assert );
    421   if( i != assertions.end() ) {
     395                AssertionSet::iterator i = assertions.find( assert );
     396                if ( i != assertions.end() ) {
    422397///     std::cout << "found it!" << std::endl;
    423     i->second = true;
    424   }
    425 }
    426 
    427 void
    428 markAssertions( AssertionSet &assertion1, AssertionSet &assertion2, Type *type )
    429 {
    430   for( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    431     for( std::list< DeclarationWithType* >::const_iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
    432       markAssertionSet( assertion1, *assert );
    433       markAssertionSet( assertion2, *assert );
    434     }
    435   }
    436 }
    437 
    438 void
    439 Unify::visit(PointerType *pointerType)
    440 {
    441   if( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    442     result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    443     markAssertions( haveAssertions, needAssertions, pointerType );
    444     markAssertions( haveAssertions, needAssertions, otherPointer );
    445   }
    446 }
    447 
    448 void
    449 Unify::visit(ArrayType *arrayType)
    450 {
    451   // XXX -- compare array dimension
    452   ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
    453   if( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
    454     result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    455   }
    456 }
    457 
    458 template< typename Iterator1, typename Iterator2 >
    459 bool
    460 unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    461   for( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    462     if( !unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    463       return false;
    464     }
    465   }
    466   if( list1Begin != list1End || list2Begin != list2End ) {
    467     return false;
    468   } else {
    469     return true;
    470   }
    471 }
    472 
    473 void
    474 Unify::visit(FunctionType *functionType)
    475 {
    476   FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    477   if( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    478  
    479     if( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    480    
    481       if( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    482 
    483         markAssertions( haveAssertions, needAssertions, functionType );
    484         markAssertions( haveAssertions, needAssertions, otherFunction );
    485 
    486         result = true;
    487       }
    488     }
    489   }
    490 }
    491 
    492 template< typename RefType >
    493 void
    494 Unify::handleRefType( RefType *inst, Type *other )
    495 
    496   RefType *otherStruct = dynamic_cast< RefType* >( other );
    497   result = otherStruct && inst->get_name() == otherStruct->get_name();
    498 
    499 
    500 void
    501 Unify::visit(StructInstType *structInst)
    502 {
    503   handleRefType( structInst, type2 );
    504 }
    505 
    506 void
    507 Unify::visit(UnionInstType *unionInst)
    508 {
    509   handleRefType( unionInst, type2 );
    510 }
    511 
    512 void
    513 Unify::visit(EnumInstType *enumInst)
    514 {
    515   handleRefType( enumInst, type2 );
    516 }
    517 
    518 void
    519 Unify::visit(ContextInstType *contextInst)
    520 {
    521   handleRefType( contextInst, type2 );
    522 }
    523 
    524 void
    525 Unify::visit(TypeInstType *typeInst)
    526 {
    527   assert( openVars.find( typeInst->get_name() ) == openVars.end() );
    528   TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 );
    529   if( otherInst && typeInst->get_name() == otherInst->get_name() ) {
    530     result = true;
     398                        i->second = true;
     399                } // if
     400        }
     401
     402        void markAssertions( AssertionSet &assertion1, AssertionSet &assertion2, Type *type ) {
     403                for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
     404                        for ( std::list< DeclarationWithType* >::const_iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     405                                markAssertionSet( assertion1, *assert );
     406                                markAssertionSet( assertion2, *assert );
     407                        } // for
     408                } // for
     409        }
     410
     411        void Unify::visit(PointerType *pointerType) {
     412                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
     413                        result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     414                        markAssertions( haveAssertions, needAssertions, pointerType );
     415                        markAssertions( haveAssertions, needAssertions, otherPointer );
     416                } // if
     417        }
     418
     419        void Unify::visit(ArrayType *arrayType) {
     420                // XXX -- compare array dimension
     421                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
     422                if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
     423                        result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     424                } // if
     425        }
     426
     427        template< typename Iterator1, typename Iterator2 >
     428        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     429                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     430                        if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
     431                                return false;
     432                        } // if
     433                } // for
     434                if ( list1Begin != list1End || list2Begin != list2End ) {
     435                        return false;
     436                } else {
     437                        return true;
     438                } // if
     439        }
     440
     441        void Unify::visit(FunctionType *functionType) {
     442                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
     443                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
     444 
     445                        if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     446       
     447                                if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     448
     449                                        markAssertions( haveAssertions, needAssertions, functionType );
     450                                        markAssertions( haveAssertions, needAssertions, otherFunction );
     451
     452                                        result = true;
     453                                } // if
     454                        } // if
     455                } // if
     456        }
     457
     458        template< typename RefType >
     459        void Unify::handleRefType( RefType *inst, Type *other ) { 
     460                RefType *otherStruct = dynamic_cast< RefType* >( other );
     461                result = otherStruct && inst->get_name() == otherStruct->get_name();
     462        } 
     463
     464        void Unify::visit(StructInstType *structInst) {
     465                handleRefType( structInst, type2 );
     466        }
     467
     468        void Unify::visit(UnionInstType *unionInst) {
     469                handleRefType( unionInst, type2 );
     470        }
     471
     472        void Unify::visit(EnumInstType *enumInst) {
     473                handleRefType( enumInst, type2 );
     474        }
     475
     476        void Unify::visit(ContextInstType *contextInst) {
     477                handleRefType( contextInst, type2 );
     478        }
     479
     480        void Unify::visit(TypeInstType *typeInst) {
     481                assert( openVars.find( typeInst->get_name() ) == openVars.end() );
     482                TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 );
     483                if ( otherInst && typeInst->get_name() == otherInst->get_name() ) {
     484                        result = true;
    531485///   } else {
    532486///     NamedTypeDecl *nt = indexer.lookupType( typeInst->get_name() );
    533 ///     if( nt ) {
     487///     if ( nt ) {
    534488///       TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
    535489///       assert( type );
    536 ///       if( type->get_base() ) {
     490///       if ( type->get_base() ) {
    537491///         result = unifyExact( type->get_base(), typeInst, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    538492///       }
    539493///     }
    540   }
    541 }
    542 
    543 template< typename Iterator1, typename Iterator2 >
    544 bool
    545 unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    546   for( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    547     Type *commonType = 0;
    548     if( !unifyInexact( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, widenMode, indexer, commonType ) ) {
    549       return false;
    550     }
    551     delete commonType;
    552   }
    553   if( list1Begin != list1End || list2Begin != list2End ) {
    554     return false;
    555   } else {
    556     return true;
    557   }
    558 }
    559 
    560 void
    561 Unify::visit(TupleType *tupleType)
    562 {
    563   if( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
    564     result = unifyList( tupleType->get_types().begin(), tupleType->get_types().end(), otherTuple->get_types().begin(), otherTuple->get_types().end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    565   }
    566 }
     494                } // if
     495        }
     496
     497        template< typename Iterator1, typename Iterator2 >
     498        bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     499                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     500                        Type *commonType = 0;
     501                        if ( ! unifyInexact( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, widenMode, indexer, commonType ) ) {
     502                                return false;
     503                        }
     504                        delete commonType;
     505                } // for
     506                if ( list1Begin != list1End || list2Begin != list2End ) {
     507                        return false;
     508                } else {
     509                        return true;
     510                } //if
     511        }
     512
     513        void Unify::visit(TupleType *tupleType) {
     514                if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
     515                        result = unifyList( tupleType->get_types().begin(), tupleType->get_types().end(), otherTuple->get_types().begin(), otherTuple->get_types().end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     516                } // if
     517        }
    567518
    568519} // namespace ResolvExpr
     520
     521// Local Variables: //
     522// tab-width: 4 //
     523// mode: c++ //
     524// compile-command: "make install" //
     525// End: //
  • translator/ResolvExpr/Unify.h

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Unify.h,v 1.4 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Unify.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 13:09:04 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 13:10:34 2015
     13// Update Count     : 2
     14//
    715
    816#ifndef UNIFY_H
     
    1927
    2028namespace ResolvExpr {
     29        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     30        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
     31        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    2132
    22 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    23 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
    24 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     33        template< typename Iterator1, typename Iterator2 >
     34        bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
     35                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     36                        Type *commonType = 0;
     37                        if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
     38                                return false;
     39                        } // if
     40                        commonTypes.push_back( commonType );
     41                } // for
     42                if ( list1Begin != list1End || list2Begin != list2End ) {
     43                        return false;
     44                } else {
     45                        return true;
     46                } // if
     47        }
    2548
    26 template< typename Iterator1, typename Iterator2 >
    27 bool
    28 unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
    29   for( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    30     Type *commonType = 0;
    31     if( !unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    32       return false;
    33     }
    34     commonTypes.push_back( commonType );
    35   }
    36   if( list1Begin != list1End || list2Begin != list2End ) {
    37     return false;
    38   } else {
    39     return true;
    40   }
    41 }
    42 
    43 template< typename Iterator1, typename Iterator2 >
    44 bool
    45 unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    46   std::list< Type* > commonTypes;
    47   if( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
    48     deleteAll( commonTypes );
    49     return true;
    50   } else {
    51     return false;
    52   }
    53 }
     49        template< typename Iterator1, typename Iterator2 >
     50        bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     51                std::list< Type* > commonTypes;
     52                if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
     53                        deleteAll( commonTypes );
     54                        return true;
     55                } else {
     56                        return false;
     57                } // if
     58        }
    5459
    5560} // namespace ResolvExpr
    5661
    57 #endif /* #ifndef UNIFY_H */
     62#endif // UNIFY_H
     63
     64// Local Variables: //
     65// tab-width: 4 //
     66// mode: c++ //
     67// compile-command: "make install" //
     68// End: //
  • translator/ResolvExpr/typeops.h

    rb87a5ed ra32b204  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: typeops.h,v 1.14 2005/08/29 20:14:17 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// typeops.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 07:28:22 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 07:33:11 2015
     13// Update Count     : 2
     14//
    715
    816#ifndef TYPEOPS_H
     
    1624
    1725namespace ResolvExpr {
     26        // combos: takes a list of sets and returns a set of lists representing every possible way of forming a list by
     27        // picking one element out of each set
     28        template< typename InputIterator, typename OutputIterator >
     29        void combos( InputIterator begin, InputIterator end, OutputIterator out ) {
     30                typedef typename InputIterator::value_type SetType;
     31                typedef typename std::list< typename SetType::value_type > ListType;
     32 
     33                if ( begin == end )     {
     34                        *out++ = ListType();
     35                        return;
     36                } // if
     37 
     38                InputIterator current = begin;
     39                begin++;
    1840
    19 // combos: takes a list of sets and returns a set of lists representing
    20 // every possible way of forming a list by picking one element out of each set
    21 template< typename InputIterator, typename OutputIterator >
    22 void
    23 combos( InputIterator begin, InputIterator end, OutputIterator out )
    24 {
    25   typedef typename InputIterator::value_type SetType;
    26   typedef typename std::list< typename SetType::value_type > ListType;
     41                std::list< ListType > recursiveResult;
     42                combos( begin, end, back_inserter( recursiveResult ) );
    2743 
    28   if( begin == end )
    29   {
    30     *out++ = ListType();
    31     return;
    32   }
     44                for ( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) {
     45                        for ( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) {
     46                                ListType result;
     47                                std::back_insert_iterator< ListType > inserter = back_inserter( result );
     48                                *inserter++ = *j;
     49                                std::copy( i->begin(), i->end(), inserter );
     50                                *out++ = result;
     51                        } // for
     52                } // for
     53        }
    3354 
    34   InputIterator current = begin;
    35   begin++;
     55        // in AdjustExprType.cc
     56        void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    3657
    37   std::list< ListType > recursiveResult;
    38   combos( begin, end, back_inserter( recursiveResult ) );
    39  
    40   for( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) {
    41     for( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) {
    42       ListType result;
    43       std::back_insert_iterator< ListType > inserter = back_inserter( result );
    44       *inserter++ = *j;
    45       std::copy( i->begin(), i->end(), inserter );
    46       *out++ = result;
    47     }
    48   }
    49 }
    50  
    51 // in AdjustExprType.cc
    52 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     58        template< typename ForwardIterator >
     59        void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     60                while ( begin != end ) {
     61                        adjustExprType( *begin++, env, indexer );
     62                } // while
     63        }
    5364
    54 template< typename ForwardIterator >
    55 void
    56 adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    57 {
    58   while( begin != end ) {
    59     adjustExprType( *begin++, env, indexer );
    60   }
    61 }
     65        // in CastCost.cc
     66        Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    6267
    63 // in CastCost.cc
    64 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     68        template< typename SrcIterator, typename DestIterator >
     69        Cost castCostList( SrcIterator srcBegin, SrcIterator srcEnd, DestIterator destBegin, DestIterator destEnd, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     70                Cost ret;
     71                if ( destBegin == destEnd ) {
     72                        if ( srcBegin == srcEnd ) {
     73                                return Cost::zero;
     74                        } else {
     75                                return Cost( 0, 0, 1 );
     76                        } // if
     77                } // if
     78                while ( srcBegin != srcEnd && destBegin != destEnd ) {
     79                        Cost thisCost = castCost( *srcBegin++, *destBegin++, indexer, env );
     80                        if ( thisCost == Cost::infinity ) {
     81                                return Cost::infinity;
     82                        } // if
     83                        ret += thisCost;
     84                } // while
     85                if ( srcBegin == srcEnd && destBegin == destEnd ) {
     86                        return ret;
     87                } else {
     88                        return Cost::infinity;
     89                } // if
     90        }
    6591
    66 template< typename SrcIterator, typename DestIterator >
    67 Cost
    68 castCostList( SrcIterator srcBegin, SrcIterator srcEnd, DestIterator destBegin, DestIterator destEnd, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    69 {
    70   Cost ret;
    71   if( destBegin == destEnd ) {
    72     if( srcBegin == srcEnd ) {
    73       return Cost::zero;
    74     } else {
    75       return Cost( 0, 0, 1 );
    76     }
    77   }
    78   while( srcBegin != srcEnd && destBegin != destEnd ) {
    79     Cost thisCost = castCost( *srcBegin++, *destBegin++, indexer, env );
    80     if( thisCost == Cost::infinity ) {
    81       return Cost::infinity;
    82     }
    83     ret += thisCost;
    84   }
    85   if( srcBegin == srcEnd && destBegin == destEnd ) {
    86     return ret;
    87   } else {
    88     return Cost::infinity;
    89   }
    90 }
     92        // in ConversionCost.cc
     93        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    9194
    92 // in ConversionCost.cc
    93 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     95        template< typename SrcIterator, typename DestIterator >
     96        Cost conversionCostList( SrcIterator srcBegin, SrcIterator srcEnd, DestIterator destBegin, DestIterator destEnd, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     97                Cost ret;
     98                while ( srcBegin != srcEnd && destBegin != destEnd ) {
     99                        Cost thisCost = conversionCost( *srcBegin++, *destBegin++, indexer, env );
     100                        if ( thisCost == Cost::infinity ) {
     101                                return Cost::infinity;
     102                        } // if
     103                        ret += thisCost;
     104                } // while
     105                if ( srcBegin == srcEnd && destBegin == destEnd ) {
     106                        return ret;
     107                } else {
     108                        return Cost::infinity;
     109                } // if
     110        }
    94111
    95 template< typename SrcIterator, typename DestIterator >
    96 Cost
    97 conversionCostList( SrcIterator srcBegin, SrcIterator srcEnd, DestIterator destBegin, DestIterator destEnd, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    98 {
    99   Cost ret;
    100   while( srcBegin != srcEnd && destBegin != destEnd ) {
    101     Cost thisCost = conversionCost( *srcBegin++, *destBegin++, indexer, env );
    102     if( thisCost == Cost::infinity ) {
    103       return Cost::infinity;
    104     }
    105     ret += thisCost;
    106   }
    107   if( srcBegin == srcEnd && destBegin == destEnd ) {
    108     return ret;
    109   } else {
    110     return Cost::infinity;
    111   }
    112 }
     112        // in PtrsAssignable.cc
     113        int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
    113114
    114 // in PtrsAssignable.cc
    115 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
     115        // in PtrsCastable.cc
     116        int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    116117
    117 // in PtrsCastable.cc
    118 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     118        // in Unify.cc
     119        bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     120        bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    119121
    120 // in Unify.cc
    121 bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    122 bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     122        inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
     123                TypeEnvironment env;
     124                return typesCompatible( t1, t2, indexer, env );
     125        }
    123126
    124 inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer )
    125 {
    126   TypeEnvironment env;
    127   return typesCompatible( t1, t2, indexer, env );
    128 }
     127        inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
     128                TypeEnvironment env;
     129                return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
     130        }
    129131
    130 inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer )
    131 {
    132   TypeEnvironment env;
    133   return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
    134 }
     132        template< typename Container1, typename Container2 >
     133        bool typesCompatibleList( Container1 &c1, Container2 &c2, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     134                typename Container1::iterator i1 = c1.begin();
     135                typename Container2::iterator i2 = c2.begin();
     136                for ( ; i1 != c1.end() && i2 != c2.end(); ++i1, ++i2 ) {
     137                        if ( ! typesCompatible( *i1, *i2, indexer ) ) {
     138                                return false;
     139                        } // if
     140                }
     141                return ( i1 == c1.end() ) && ( i2 == c2.end() );
     142        }
    135143
    136 template< typename Container1, typename Container2 >
    137 bool
    138 typesCompatibleList( Container1 &c1, Container2 &c2, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    139 {
    140   typename Container1::iterator i1 = c1.begin();
    141   typename Container2::iterator i2 = c2.begin();
    142   for( ; i1 != c1.end() && i2 != c2.end(); ++i1, ++i2 ) {
    143     if( !typesCompatible( *i1, *i2, indexer ) ) {
    144       return false;
    145     }
    146   }
    147   return ( i1 == c1.end() ) && ( i2 == c2.end() );
    148 }
     144        // in CommonType.cc
     145        Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    149146
    150 // in CommonType.cc
    151 Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     147        // in PolyCost.cc
     148        int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    152149
    153 // in PolyCost.cc
    154 int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    155 
    156 // in Occurs.cc
    157 bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
    158 
     150        // in Occurs.cc
     151        bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
    159152} // namespace ResolvExpr
    160153
    161 #endif /* #ifndef TYPEOPS_H */
     154#endif // TYPEOPS_H
     155
     156// Local Variables: //
     157// tab-width: 4 //
     158// mode: c++ //
     159// compile-command: "make install" //
     160// End: //
Note: See TracChangeset for help on using the changeset viewer.