Changeset a32b204 for translator/ResolvExpr
- Timestamp:
- May 17, 2015, 1:19:35 PM (11 years ago)
- 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
- Location:
- translator/ResolvExpr
- Files:
-
- 29 edited
-
AdjustExprType.cc (modified) (2 diffs)
-
Alternative.cc (modified) (2 diffs)
-
Alternative.h (modified) (2 diffs)
-
AlternativeFinder.cc (modified) (3 diffs)
-
AlternativeFinder.h (modified) (2 diffs)
-
AlternativePrinter.cc (modified) (2 diffs)
-
AlternativePrinter.h (modified) (2 diffs)
-
CastCost.cc (modified) (2 diffs)
-
CommonType.cc (modified) (2 diffs)
-
ConversionCost.cc (modified) (3 diffs)
-
ConversionCost.h (modified) (2 diffs)
-
Cost.h (modified) (1 diff)
-
FindOpenVars.cc (modified) (3 diffs)
-
FindOpenVars.h (modified) (2 diffs)
-
Occurs.cc (modified) (2 diffs)
-
PolyCost.cc (modified) (2 diffs)
-
PtrsAssignable.cc (modified) (4 diffs)
-
PtrsCastable.cc (modified) (2 diffs)
-
RenameVars.cc (modified) (2 diffs)
-
RenameVars.h (modified) (2 diffs)
-
ResolveTypeof.cc (modified) (3 diffs)
-
ResolveTypeof.h (modified) (2 diffs)
-
Resolver.cc (modified) (2 diffs)
-
Resolver.h (modified) (2 diffs)
-
TypeEnvironment.cc (modified) (2 diffs)
-
TypeEnvironment.h (modified) (2 diffs)
-
Unify.cc (modified) (4 diffs)
-
Unify.h (modified) (2 diffs)
-
typeops.h (modified) (2 diffs)
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 1 16 #include "typeops.h" 2 17 #include "SynTree/Type.h" … … 5 20 6 21 namespace 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 ); 27 38 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 }; 33 42 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 } 37 48 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 } 41 52 42 Type *AdjustExprType::mutate(BasicType *basicType) {43 return basicType;44 }53 Type *AdjustExprType::mutate( VoidType *voidType ) { 54 return voidType; 55 } 45 56 46 Type *AdjustExprType::mutate(PointerType *pointerType) {47 return pointerType;48 }57 Type *AdjustExprType::mutate( BasicType *basicType ) { 58 return basicType; 59 } 49 60 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 } 55 64 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 } 60 70 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 } 64 75 65 Type *AdjustExprType::mutate(UnionInstType *aggregateUseType) {66 return aggregateUseType;67 }76 Type *AdjustExprType::mutate( StructInstType *aggregateUseType ) { 77 return aggregateUseType; 78 } 68 79 69 Type *AdjustExprType::mutate(EnumInstType *aggregateUseType) {70 return aggregateUseType;71 }80 Type *AdjustExprType::mutate( UnionInstType *aggregateUseType ) { 81 return aggregateUseType; 82 } 72 83 73 Type *AdjustExprType::mutate(ContextInstType *aggregateUseType) {74 return aggregateUseType;75 }84 Type *AdjustExprType::mutate( EnumInstType *aggregateUseType ) { 85 return aggregateUseType; 86 } 76 87 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; 91 90 } 92 return typeInst;93 }94 91 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 } 98 113 } // 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 1 16 #include "Alternative.h" 2 17 #include "SynTree/Type.h" … … 5 20 6 21 namespace ResolvExpr { 7 Alternative::Alternative() : expr( 0 ) {}22 Alternative::Alternative() : expr( 0 ) {} 8 23 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 ) {} 11 26 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 ) {} 14 29 15 Alternative::Alternative( const Alternative &other ) {16 initialize( other, *this );17 }30 Alternative::Alternative( const Alternative &other ) { 31 initialize( other, *this ); 32 } 18 33 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 } 24 39 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 } 31 46 32 Alternative::~Alternative() {33 delete expr;34 }47 Alternative::~Alternative() { 48 delete expr; 49 } 35 50 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; 45 64 } 46 os << std::string( indent, ' ' ) << "Environment: ";47 env.print( os, indent+2 );48 os << std::endl;49 }50 65 } // 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 3 18 4 19 #include <list> … … 8 23 9 24 namespace ResolvExpr { 10 struct Alternative;11 typedef std::list< Alternative > AltList;25 struct Alternative; 26 typedef std::list< Alternative > AltList; 12 27 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(); 20 35 21 void initialize( const Alternative &src, Alternative &dest );36 void initialize( const Alternative &src, Alternative &dest ); 22 37 23 void print( std::ostream &os, int indent = 0 ) const;38 void print( std::ostream &os, int indent = 0 ) const; 24 39 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 }; 30 45 } // namespace ResolvExpr 31 46 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 1 16 #include <list> 2 17 #include <iterator> … … 30 45 31 46 namespace 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 } 75 172 76 173 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++; 92 182 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 ) { 97 261 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() ) { 260 319 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; 263 442 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 ); 434 449 /// 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 assertions476 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 ) { 486 501 // PRINT( 487 502 // std::cout << "inferParameters: assertions needed are" << std::endl; 488 503 // printAll( need, std::cout, 8 ); 489 504 // ) 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 ); 500 515 // PRINT( 501 516 // std::cout << "declaration 14 is "; … … 503 518 // *out++ = newAlt; 504 519 // ) 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; 590 796 ) 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 } 903 916 } // 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 1 16 #ifndef ALTERNATIVEFINDER_H 2 17 #define ALTERNATIVEFINDER_H … … 11 26 12 27 namespace 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; } 50 34 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(); } 59 43 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 ); 64 65 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 ); 66 81 } // namespace ResolvExpr 67 82 68 83 #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 1 16 #include "AlternativePrinter.h" 2 17 #include "AlternativeFinder.h" … … 8 23 9 24 namespace ResolvExpr { 10 AlternativePrinter::AlternativePrinter( std::ostream &os ) : SymTab::Indexer( false ), os( os ) {}25 AlternativePrinter::AlternativePrinter( std::ostream &os ) : SymTab::Indexer( false ), os( os ) {} 11 26 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 } // for24 } // AlternativePrinter::visit27 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 25 40 } // 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 1 16 #ifndef ALTERNATIVEPRINTER_H 2 17 #define ALTERNATIVEPRINTER_H … … 8 23 9 24 namespace 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 }; 17 32 } // namespace ResolvExpr 18 33 19 34 #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 1 16 #include "typeops.h" 2 17 #include "Cost.h" … … 8 23 9 24 namespace 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 ); 13 28 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 }; 17 32 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 30 47 } // 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 } 47 62 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 } 51 66 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 } // if58 }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 } 59 74 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 77 94 } // if 78 } // if 79 } // if 80 } 95 } 81 96 } // 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 // 7 15 8 16 #include "typeops.h" … … 14 22 15 23 namespace 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 78 80 #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; 90 92 #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 { 96 98 /* 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 } 239 215 } // 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 // 7 15 8 16 #include "ConversionCost.h" … … 12 20 #include "SymTab/Indexer.h" 13 21 14 15 22 namespace 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; 26 30 /// 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() ) ) ) { 30 34 /// std::cout << " found" << std::endl; 31 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );32 // all typedefs should be gone by this point33 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 38 42 /// std::cout << " not found" << std::endl; 39 } 43 } // if 40 44 /// std::cout << "src is "; 41 45 /// src->print( std::cout ); … … 44 48 /// std::cout << std::endl << "env is" << std::endl; 45 49 /// env.print( std::cout, 8 ); 46 if( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {50 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 47 51 /// 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 } 66 69 67 70 /* 68 Old69 ===70 Double71 |72 Float73 |74 ULong75 / \76 UInt Long77 \ /78 Int79 |80 Ushort81 |82 Short83 |84 Uchar85 / \86 Schar Char87 88 New89 ===90 +-----LongDoubleComplex--+91 LongDouble--+ | +-LongDoubleImag92 | +---DoubleComplex---+ |93 Double------+ | +----DoubleImag94 | +-FloatComplex-+ |95 Float---------+ +-------FloatImag96 |97 ULongLong98 |99 LongLong100 |101 ULong102 / \103 UInt Long104 \ /105 Int106 |107 Ushort108 |109 Short110 |111 Uchar112 / \113 Schar Char114 \ /115 Bool71 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 116 119 */ 117 120 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 } 269 249 } // 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 // 7 15 8 #ifndef RESOLVEXPR_CONVERSIONCOST_PROTECTED_H9 #define RESOLVEXPR_CONVERSIONCOST_PROTECTED_H16 #ifndef CONVERSIONCOST_H 17 #define CONVERSIONCOST_H 10 18 11 19 #include "SynTree/Visitor.h" … … 15 23 16 24 namespace 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; } 17 30 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 }; 44 48 } // namespace ResolvExpr 45 49 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 3 18 4 19 #include <iostream> 5 20 6 21 namespace 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 ); 11 26 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 ); 15 30 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 ); 23 38 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; 28 43 29 int unsafe;30 int poly;31 int safe;32 };44 int unsafe; 45 int poly; 46 int safe; 47 }; 33 48 34 inline Cost::Cost() : unsafe( 0 ), poly( 0 ), safe( 0 ) {}49 inline Cost::Cost() : unsafe( 0 ), poly( 0 ), safe( 0 ) {} 35 50 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 ) {} 37 52 38 inline void 39 Cost::incUnsafe( int inc ) { 40 unsafe += inc; 41 } 53 inline void Cost::incUnsafe( int inc ) { 54 unsafe += inc; 55 } 42 56 43 inline void 44 Cost::incPoly( int inc ) { 45 unsafe += inc; 46 } 57 inline void Cost::incPoly( int inc ) { 58 unsafe += inc; 59 } 47 60 48 inline void 49 Cost::incSafe( int inc ) { 50 unsafe += inc; 51 } 61 inline void Cost::incSafe( int inc ) { 62 unsafe += inc; 63 } 52 64 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 } 56 68 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 } 60 72 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 } 67 79 68 inline bool Cost::operator<( const Cost &other ) const {80 inline bool Cost::operator<( const Cost &other ) const { 69 81 if ( *this == infinity ) return false; 70 82 if ( other == infinity ) return true; 71 83 if ( unsafe > other.unsafe ) { 72 return false;84 return false; 73 85 } else if ( unsafe < other.unsafe ) { 74 return true;86 return true; 75 87 } else if ( poly > other.poly ) { 76 return false;88 return false; 77 89 } else if ( poly < other.poly ) { 78 return true;90 return true; 79 91 } else if ( safe > other.safe ) { 80 return false;92 return false; 81 93 } else if ( safe < other.safe ) { 82 return true;94 return true; 83 95 } else { 84 return false;85 } 96 return false; 97 } // if 86 98 } 87 99 88 inline bool Cost::operator==( const Cost &other ) const {89 return unsafe == other.unsafe90 && poly == other.poly91 && 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 } 93 105 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 } 97 109 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 } 102 114 } // namespace ResolvExpr 103 115 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 // 7 15 8 16 #include "FindOpenVars.h" … … 10 18 #include "SynTree/Visitor.h" 11 19 20 namespace ResolvExpr { 21 class FindOpenVars : public Visitor { 22 public: 23 FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ); 12 24 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); 14 30 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 ); 32 32 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 }; 39 37 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 } 44 42 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 } 54 54 /// cloneAll( (*i)->get_assertions(), needAssertions ); 55 55 /// 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 } 63 63 /// cloneAll( (*i)->get_assertions(), haveAssertions ); 64 64 /// haveAssertions.insert( haveAssertions.end(), (*i)->get_assertions().begin(), (*i)->get_assertions().end() ); 65 } 66 } 65 } // for 66 } // if 67 67 /// std::cout << "type is "; 68 68 /// type->print( std::cout ); … … 71 71 /// std::cout << std::endl << "have is" << std::endl; 72 72 /// printAssertionSet( haveAssertions, std::cout ); 73 }73 } 74 74 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 } 81 79 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 } 88 84 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 } 97 91 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 104 97 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 // 7 15 8 #ifndef RESOLVEXPR_FINDOPENVARS_H9 #define RESOLVEXPR_FINDOPENVARS_H16 #ifndef FINDOPENVARS_H 17 #define FINDOPENVARS_H 10 18 11 19 #include "Unify.h" … … 13 21 14 22 namespace 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 ); 18 24 } // namespace ResolvExpr 19 25 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 // 7 15 8 16 #include <set> … … 13 21 #include "TypeEnvironment.h" 14 22 23 namespace 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 }; 15 34 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 } 17 40 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 } 24 49 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; 56 52 /// std::cout << "searching for vars: "; 57 53 /// std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cout, " " ) ); 58 54 /// 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 ) { 63 59 /// std::cout << typeInst->get_name() << " is bound to"; 64 60 /// eqvClass.type->print( std::cout ); 65 61 /// 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 70 67 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 // 7 15 8 16 #include "typeops.h" … … 12 20 #include "TypeEnvironment.h" 13 21 22 namespace 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 }; 14 33 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 } 16 39 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 } 21 42 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 } 61 57 62 58 } // 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 1 16 #include "typeops.h" 2 17 #include "SynTree/Type.h" … … 6 21 7 22 namespace 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 ); 13 26 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; } 30 28 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 37 60 } 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 ) { 44 63 } 45 }46 64 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 } 49 72 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 ) { 55 74 } 56 }57 75 58 void PtrsAssignable::visit( BasicType *basicType ) {59 }76 void PtrsAssignable::visit( PointerType *pointerType ) { 77 } 60 78 61 void PtrsAssignable::visit( PointerType *pointerType ) {62 }79 void PtrsAssignable::visit( ArrayType *arrayType ) { 80 } 63 81 64 void PtrsAssignable::visit( ArrayType *arrayType ) { 65 } 82 void PtrsAssignable::visit( FunctionType *functionType ) { 83 result = -1; 84 } 66 85 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 } 70 89 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 wrong73 }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 } 74 93 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 } 78 101 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 84 104 } 85 }86 105 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 } 90 114 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 ) { 101 116 /// // This code doesn't belong here, but it might be useful somewhere else 102 117 /// if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) { … … 104 119 /// std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin(); 105 120 /// 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() ) { 107 122 /// int assignResult = ptrsAssignable( *srcIt++, *destIt++ ); 108 123 /// if ( assignResult == 0 ) { … … 121 136 /// } 122 137 /// } 123 }138 } 124 139 } // 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 // 7 15 8 16 #include "typeops.h" … … 14 22 15 23 namespace 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; } 16 29 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 }; 23 47 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 } 35 67 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 } 42 83 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 } 64 87 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 } 82 91 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 } 87 95 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 } 93 99 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 } 99 103 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 } 105 107 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 } 111 111 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 } 117 115 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 } 123 129 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 } 129 133 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 } 145 137 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 151 142 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 // 7 15 8 16 #include <strstream> … … 15 23 16 24 namespace ResolvExpr { 25 RenameVars global_renamer; 17 26 18 RenameVars global_renamer; 27 RenameVars::RenameVars() : level( 0 ) { 28 mapStack.push_front( std::map< std::string, std::string >() ); 29 } 19 30 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 } 25 34 26 void 27 RenameVars::reset() 28 { 29 level = 0; 30 } 35 void RenameVars::visit( VoidType *voidType ) { 36 typeBefore( voidType ); 37 typeAfter( voidType ); 38 } 31 39 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 } 38 44 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 } 45 52 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 } 55 59 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 } 64 69 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 } 76 75 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 } 84 81 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 } 92 87 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 } 100 94 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 } 109 108 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 } 125 114 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() ) { 138 117 /// std::cout << "type with forall: "; 139 118 /// type->print( std::cout ); 140 119 /// 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 } 153 132 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 } 161 138 162 139 } // 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 // 7 15 8 16 #ifndef RESOLVEXPR_RENAMEVARS_H … … 17 25 18 26 namespace 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 ); 19 43 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 }; 44 49 45 extern RenameVars global_renamer; 46 50 extern RenameVars global_renamer; 47 51 } // namespace ResolvExpr 48 52 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 1 16 #include "ResolveTypeof.h" 2 17 #include "Alternative.h" … … 10 25 namespace { 11 26 #if 0 12 void13 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 } 20 35 #endif 21 36 } … … 23 38 class ResolveTypeof : public Mutator { 24 39 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 ); 27 42 28 43 private: 29 const SymTab::Indexer &indexer;44 const SymTab::Indexer &indexer; 30 45 }; 31 46 32 47 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 ); 35 50 } 36 51 37 52 Type *ResolveTypeof::mutate( TypeofType *typeofType ) { 38 53 #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; 42 57 #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; 58 73 } 74 } // namespace ResolvExpr 59 75 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 1 16 #ifndef RESOLVETYPEOF_H 2 17 #define RESOLVETYPEOF_H … … 6 21 7 22 namespace ResolvExpr { 8 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );23 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer ); 9 24 } // namespace ResolvExpr 10 25 11 26 #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 1 16 #include "Resolver.h" 2 17 #include "AlternativeFinder.h" … … 15 30 16 31 namespace 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 ); 84 65 } // 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() ); 115 181 } // 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 274 289 // 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 } // for286 } 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 } // if315 } // for316 } // for317 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );318 assert( fred );319 initContext = fred->get_type();320 (*listInit->begin_initializers())->accept( *this );321 } // if322 } // for323 } 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 } // if328 #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 } 330 345 } // 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 1 16 #ifndef RESOLVER_H 2 17 #define RESOLVER_H … … 6 21 7 22 namespace 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 ); 10 25 } // namespace ResolvExpr 11 26 12 27 #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 // 7 15 8 16 #include <algorithm> … … 15 23 16 24 namespace 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() ) { 91 85 /// std::cout << var << " is in class "; 92 86 /// i->print( std::cout ); 93 eqvClass = *i;94 return true;95 }87 eqvClass = *i; 88 return true; 89 } 96 90 /// std::cout << var << " is not in class "; 97 91 /// 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 ) { 135 123 /// std::cout << "adding " << *theVar; 136 if( theClass->type ) {124 if ( theClass->type ) { 137 125 /// std::cout << " bound to "; 138 126 /// theClass->type->print( std::cout ); 139 127 /// 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 ); 143 131 /// 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 149 137 /// std::cerr << "input env is:" << std::endl; 150 138 /// print( std::cerr, 8 ); 151 139 /// std::cerr << "sub is:" << std::endl; 152 140 /// 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 } 222 200 223 201 } // 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 // 7 15 8 #ifndef RESOLVEXPR_TYPEENVIRONMENT_H9 #define RESOLVEXPR_TYPEENVIRONMENT_H16 #ifndef TYPEENVIRONMENT_H 17 #define TYPEENVIRONMENT_H 10 18 11 19 #include <string> … … 20 28 21 29 namespace ResolvExpr { 30 typedef std::map< DeclarationWithType*, bool > AssertionSet; 31 typedef std::map< std::string, TypeDecl::Kind > OpenVarSet; 22 32 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 ); 25 35 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 }; 28 49 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 ); } 35 64 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 }; 43 75 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 } 71 82 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 } 90 89 } // namespace ResolvExpr 91 90 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 // 7 15 8 16 #include <set> … … 23 31 24 32 namespace 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(); 100 100 /// std::cout << "first is "; 101 101 /// first->print( std::cout ); … … 107 107 /// newSecond->print( std::cout ); 108 108 /// 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 ) { 217 209 // 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 ) { 292 278 #ifdef DEBUG 293 TypeEnvironment debugEnv( env );279 TypeEnvironment debugEnv( env ); 294 280 #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 320 306 #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; 333 319 #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; 350 332 #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; 356 338 #endif 357 if( !unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ) ) {339 if ( ! unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ) ) { 358 340 #ifdef DEBUG 359 std::cout << "unifyInexact: no exact unification found" << std::endl;341 std::cout << "unifyInexact: no exact unification found" << std::endl; 360 342 #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; 363 345 #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; 367 349 #endif 368 result = true;369 } else {350 result = true; 351 } else { 370 352 #ifdef DEBUG 371 std::cout << "unifyInexact: no common type found" << std::endl;353 std::cout << "unifyInexact: no common type found" << std::endl; 372 354 #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 ) { 415 390 /// std::cout << "assertion set is" << std::endl; 416 391 /// printAssertionSet( assertions, std::cout, 8 ); … … 418 393 /// assert->print( std::cout ); 419 394 /// 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() ) { 422 397 /// 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; 531 485 /// } else { 532 486 /// NamedTypeDecl *nt = indexer.lookupType( typeInst->get_name() ); 533 /// if ( nt ) {487 /// if ( nt ) { 534 488 /// TypeDecl *type = dynamic_cast< TypeDecl* >( nt ); 535 489 /// assert( type ); 536 /// if ( type->get_base() ) {490 /// if ( type->get_base() ) { 537 491 /// result = unifyExact( type->get_base(), typeInst, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 538 492 /// } 539 493 /// } 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 } 567 518 568 519 } // 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 // 7 15 8 16 #ifndef UNIFY_H … … 19 27 20 28 namespace 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 ); 21 32 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 } 25 48 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 } 54 59 55 60 } // namespace ResolvExpr 56 61 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 // 7 15 8 16 #ifndef TYPEOPS_H … … 16 24 17 25 namespace 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++; 18 40 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 ) ); 27 43 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 } 33 54 34 InputIterator current = begin; 35 begin++;55 // in AdjustExprType.cc 56 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 36 57 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 } 53 64 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 ); 62 67 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 } 65 91 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 ); 91 94 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 } 94 111 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 ); 113 114 114 // in PtrsAssignable.cc115 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 ); 116 117 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 ); 119 121 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 } 123 126 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 } 129 131 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 } 135 143 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 ); 149 146 150 // in CommonType.cc151 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 ); 152 149 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 ); 159 152 } // namespace ResolvExpr 160 153 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.