Changeset d57e349 for src/ResolvExpr
- Timestamp:
- Jun 11, 2019, 1:36:00 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 3da7c19
- Parents:
- 396037d
- Location:
- src/ResolvExpr
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AdjustExprType.cc
r396037d rd57e349 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AdjustExprType .cc --7 // AdjustExprType_old.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 14 14 // 15 15 16 #include "AST/Node.hpp" 17 #include "AST/Pass.hpp" 18 #include "AST/SymbolTable.hpp" 19 #include "AST/Type.hpp" 20 #include "AST/TypeEnvironment.hpp" 16 21 #include "Common/PassVisitor.h" 17 22 #include "SymTab/Indexer.h" // for Indexer … … 22 27 23 28 namespace ResolvExpr { 24 class AdjustExprType : public WithShortCircuiting { 25 public: 26 AdjustExprType( const TypeEnvironment & env, const SymTab::Indexer & indexer ); 29 30 namespace { 31 class AdjustExprType_old final : public WithShortCircuiting { 32 public: 33 AdjustExprType_old( const TypeEnvironment & env, const SymTab::Indexer & indexer ); 27 34 void premutate( VoidType * ) { visit_children = false; } 28 35 void premutate( BasicType * ) { visit_children = false; } … … 44 51 Type * postmutate( TypeInstType *aggregateUseType ); 45 52 46 53 private: 47 54 const TypeEnvironment & env; 48 55 const SymTab::Indexer & indexer; 49 56 }; 50 57 51 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 52 PassVisitor<AdjustExprType> adjuster( env, indexer ); 53 Type *newType = type->acceptMutator( adjuster ); 54 type = newType; 55 } 56 57 void adjustExprType( Type *& type ) { 58 TypeEnvironment env; 59 SymTab::Indexer indexer; 60 adjustExprType( type, env, indexer ); 61 } 62 63 AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer ) 58 AdjustExprType_old::AdjustExprType_old( const TypeEnvironment &env, const SymTab::Indexer &indexer ) 64 59 : env( env ), indexer( indexer ) { 65 60 } 66 61 67 Type * AdjustExprType ::postmutate( ArrayType * arrayType ) {62 Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) { 68 63 PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base }; 69 64 arrayType->base = nullptr; … … 72 67 } 73 68 74 Type * AdjustExprType ::postmutate( FunctionType * functionType ) {69 Type * AdjustExprType_old::postmutate( FunctionType * functionType ) { 75 70 return new PointerType{ Type::Qualifiers(), functionType }; 76 71 } 77 72 78 Type * AdjustExprType ::postmutate( TypeInstType * typeInst ) {73 Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) { 79 74 if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) { 80 75 if ( eqvClass->data.kind == TypeDecl::Ftype ) { … … 90 85 return typeInst; 91 86 } 87 } // anonymous namespace 88 89 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 90 PassVisitor<AdjustExprType_old> adjuster( env, indexer ); 91 Type *newType = type->acceptMutator( adjuster ); 92 type = newType; 93 } 94 95 void adjustExprType( Type *& type ) { 96 TypeEnvironment env; 97 SymTab::Indexer indexer; 98 adjustExprType( type, env, indexer ); 99 } 100 101 namespace { 102 struct AdjustExprType_new final : public ast::WithShortCircuiting { 103 const ast::TypeEnvironment & tenv; 104 const ast::SymbolTable & symtab; 105 106 AdjustExprType_new( const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 107 : tenv( e ), symtab( syms ) {} 108 109 void premutate( const ast::VoidType * ) { visit_children = false; } 110 void premutate( const ast::BasicType * ) { visit_children = false; } 111 void premutate( const ast::PointerType * ) { visit_children = false; } 112 void premutate( const ast::ArrayType * ) { visit_children = false; } 113 void premutate( const ast::FunctionType * ) { visit_children = false; } 114 void premutate( const ast::StructInstType * ) { visit_children = false; } 115 void premutate( const ast::UnionInstType * ) { visit_children = false; } 116 void premutate( const ast::EnumInstType * ) { visit_children = false; } 117 void premutate( const ast::TraitInstType * ) { visit_children = false; } 118 void premutate( const ast::TypeInstType * ) { visit_children = false; } 119 void premutate( const ast::TupleType * ) { visit_children = false; } 120 void premutate( const ast::VarArgsType * ) { visit_children = false; } 121 void premutate( const ast::ZeroType * ) { visit_children = false; } 122 void premutate( const ast::OneType * ) { visit_children = false; } 123 124 const ast::Type * postmutate( const ast::ArrayType * at ) { 125 return new ast::PointerType{ at->base, at->qualifiers }; 126 } 127 128 const ast::Type * postmutate( const ast::FunctionType * ft ) { 129 return new ast::PointerType{ ft }; 130 } 131 132 const ast::Type * postmutate( const ast::TypeInstType * inst ) { 133 // replace known function-type-variables with pointer-to-function 134 if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name ) ) { 135 if ( eqvClass->data.kind == ast::TypeVar::Ftype ) { 136 return new ast::PointerType{ inst }; 137 } 138 } else if ( const ast::NamedTypeDecl * ntDecl = symtab.lookupType( inst->name ) ) { 139 if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( ntDecl ) ) { 140 if ( tyDecl->kind == ast::TypeVar::Ftype ) { 141 return new ast::PointerType{ inst }; 142 } 143 } 144 } 145 return inst; 146 } 147 }; 148 } // anonymous namespace 149 150 const ast::Type * adjustExprType( 151 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 152 ) { 153 ast::Pass<AdjustExprType_new> adjuster{ env, symtab }; 154 return type->accept( adjuster ); 155 } 156 92 157 } // namespace ResolvExpr 93 158 -
src/ResolvExpr/Candidate.hpp
r396037d rd57e349 42 42 ast::OpenVarSet open; ///< Open variables for environment 43 43 ast::AssertionList need; ///< Assertions which need to be resolved 44 45 Candidate() = default; 44 46 }; 45 47 … … 49 51 /// List of candidates 50 52 using CandidateList = std::vector< CandidateRef >; 53 54 /// Holdover behaviour from old `findMinCost` -- xxx -- can maybe be eliminated? 55 static inline void promoteCvtCost( CandidateList & candidates ) { 56 for ( CandidateRef & r : candidates ) { 57 r->cost = r->cvtCost; 58 } 59 } 51 60 52 61 void print( std::ostream & os, const Candidate & cand, Indenter indent = {} ); -
src/ResolvExpr/CandidateFinder.cpp
r396037d rd57e349 17 17 18 18 #include <sstream> 19 #include <string> 20 #include <unordered_map> 19 21 20 22 #include "Candidate.hpp" 21 23 #include "CompilationState.h" 24 #include "Cost.h" 25 #include "Resolver.h" 22 26 #include "SatisfyAssertions.hpp" 27 #include "typeops.h" // for adjustExprType 23 28 #include "AST/Expr.hpp" 24 29 #include "AST/Node.hpp" 25 30 #include "AST/Pass.hpp" 31 #include "AST/Print.hpp" 32 #include "SymTab/Mangler.h" 26 33 27 34 #define PRINT( text ) if ( resolvep ) { text } … … 49 56 /// return type. Skips ambiguous candidates. 50 57 CandidateList pruneCandidates( CandidateList & candidates ) { 51 #warning unimplemented 52 (void)candidates; 53 assert(false); 54 return {}; 58 struct PruneStruct { 59 CandidateRef candidate; 60 bool ambiguous; 61 62 PruneStruct() = default; 63 PruneStruct( const CandidateRef & c ) : candidate( c ), ambiguous( false ) {} 64 }; 65 66 // find lowest-cost candidate for each type 67 std::unordered_map< std::string, PruneStruct > selected; 68 for ( CandidateRef & candidate : candidates ) { 69 std::string mangleName; 70 { 71 ast::ptr< ast::Type > newType = candidate->expr->result; 72 candidate->env.apply( newType ); 73 mangleName = Mangle::mangle( newType ); 74 } 75 76 auto found = selected.find( mangleName ); 77 if ( found != selected.end() ) { 78 if ( candidate->cost < found->second.candidate->cost ) { 79 PRINT( 80 std::cerr << "cost " << candidate->cost << " beats " 81 << found->second.candidate->cost << std::endl; 82 ) 83 84 found->second = PruneStruct{ candidate }; 85 } else if ( candidate->cost == found->second.candidate->cost ) { 86 // if one of the candidates contains a deleted identifier, can pick the other, 87 // since deleted expressions should not be ambiguous if there is another option 88 // that is at least as good 89 if ( findDeletedExpr( candidate->expr ) ) { 90 // do nothing 91 PRINT( std::cerr << "candidate is deleted" << std::endl; ) 92 } else if ( findDeletedExpr( found->second.candidate->expr ) ) { 93 PRINT( std::cerr << "current is deleted" << std::endl; ) 94 found->second = PruneStruct{ candidate }; 95 } else { 96 PRINT( std::cerr << "marking ambiguous" << std::endl; ) 97 found->second.ambiguous = true; 98 } 99 } else { 100 PRINT( 101 std::cerr << "cost " << candidate->cost << " loses to " 102 << found->second.candidate->cost << std::endl; 103 ) 104 } 105 } else { 106 selected.emplace_hint( found, mangleName, candidate ); 107 } 108 } 109 110 // report unambiguous min-cost candidates 111 CandidateList out; 112 for ( auto & target : selected ) { 113 if ( target.second.ambiguous ) continue; 114 115 CandidateRef cand = target.second.candidate; 116 117 ast::ptr< ast::Type > newResult = cand->expr->result; 118 cand->env.applyFree( newResult ); 119 cand->expr = ast::mutate_field( 120 cand->expr.get(), &ast::Expr::result, std::move( newResult ) ); 121 122 out.emplace_back( cand ); 123 } 124 return out; 125 } 126 127 /// Returns a list of alternatives with the minimum cost in the given list 128 CandidateList findMinCost( const CandidateList & candidates ) { 129 CandidateList out; 130 Cost minCost = Cost::infinity; 131 for ( const CandidateRef & r : candidates ) { 132 if ( r->cost < minCost ) { 133 minCost = r->cost; 134 out.clear(); 135 out.emplace_back( r ); 136 } else if ( r->cost == minCost ) { 137 out.emplace_back( r ); 138 } 139 } 140 return out; 55 141 } 56 142 … … 91 177 if ( mode.prune ) { 92 178 // trim candidates to single best one 93 auto oldsize = candidates.size();94 179 PRINT( 95 180 std::cerr << "alternatives before prune:" << std::endl; … … 98 183 99 184 CandidateList pruned = pruneCandidates( candidates ); 185 100 186 if ( mode.failFast && pruned.empty() ) { 101 187 std::ostringstream stream; 102 CandidateList winners; 103 104 #warning unimplemented 105 assert(false); 106 } 107 } 108 109 #warning unimplemented 110 assert(false); 188 CandidateList winners = findMinCost( candidates ); 189 stream << "Cannot choose between " << winners.size() << " alternatives for " 190 "expression\n"; 191 ast::print( stream, expr ); 192 stream << " Alternatives are:\n"; 193 print( stream, winners, 1 ); 194 SemanticError( expr->location, stream.str() ); 195 } 196 197 auto oldsize = candidates.size(); 198 candidates = std::move( pruned ); 199 200 PRINT( 201 std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl; 202 ) 203 PRINT( 204 std::cerr << "there are " << candidates.size() << " alternatives after elimination" 205 << std::endl; 206 ) 207 } 208 209 // adjust types after pruning so that types substituted by pruneAlternatives are correctly 210 // adjusted 211 if ( mode.adjust ) { 212 for ( CandidateRef & r : candidates ) { 213 r->expr = ast::mutate_field( 214 r->expr.get(), &ast::Expr::result, 215 adjustExprType( r->expr->result, r->env, symtab ) ); 216 } 217 } 218 219 // Central location to handle gcc extension keyword, etc. for all expressions 220 for ( CandidateRef & r : candidates ) { 221 if ( r->expr->extension != expr->extension ) { 222 r->expr.get_and_mutate()->extension = expr->extension; 223 } 224 } 111 225 } 112 226 -
src/ResolvExpr/Resolver.cc
r396037d rd57e349 957 957 } 958 958 }; 959 960 /// Check if this expression is or includes a deleted expression 961 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) { 962 ast::Pass<DeleteFinder_new> finder; 963 expr->accept( finder ); 964 return finder.pass.delExpr; 965 } 966 959 } // anonymous namespace 960 961 /// Check if this expression is or includes a deleted expression 962 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) { 963 ast::Pass<DeleteFinder_new> finder; 964 expr->accept( finder ); 965 return finder.pass.delExpr; 966 } 967 968 namespace { 967 969 /// always-accept candidate filter 968 970 bool anyCandidate( const Candidate & ) { return true; } … … 1024 1026 1025 1027 // promote candidate.cvtCost to .cost 1026 for ( CandidateRef & cand : winners ) { 1027 cand->cost = cand->cvtCost; 1028 } 1028 promoteCvtCost( winners ); 1029 1029 1030 1030 // produce ambiguous errors, if applicable -
src/ResolvExpr/Resolver.h
r396037d rd57e349 29 29 namespace ast { 30 30 class Decl; 31 class DeletedExpr; 31 32 } // namespace ast 32 33 … … 48 49 /// Checks types and binds syntactic constructs to typed representations 49 50 void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ); 51 /// Searches expr and returns the first DeletedExpr found, otherwise nullptr 52 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ); 50 53 } // namespace ResolvExpr 51 54 -
src/ResolvExpr/typeops.h
r396037d rd57e349 71 71 } // while 72 72 } 73 74 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function 75 const ast::Type * adjustExprType( 76 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab ); 73 77 74 78 // in CastCost.cc
Note: See TracChangeset
for help on using the changeset viewer.