Changeset 432ce7a
- Timestamp:
- Jun 11, 2019, 5:52:50 PM (6 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:
- 6625727
- Parents:
- 4b7cce6
- Location:
- src
- Files:
-
- 2 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Print.hpp
r4b7cce6 r432ce7a 16 16 #pragma once 17 17 18 #include <ios fwd>19 #include <utility> // for forward18 #include <iostream> 19 #include <utility> // for forward 20 20 21 21 #include "AST/Node.hpp" … … 32 32 void printShort( std::ostream & os, const ast::Decl * node, Indenter indent = {} ); 33 33 34 inline void printShort( std::ostream & os, const ast::Decl * node, unsigned int indent ) { 35 printShort( os, node, Indenter{ indent } ); 34 /// Print a collection of items 35 template< typename Coll > 36 void printAll( std::ostream & os, const Coll & c, Indenter indent = {} ) { 37 for ( const auto & i : c ) { 38 if ( ! i ) continue; 39 40 os << indent; 41 print( os, i, indent ); 42 os << std::endl; 43 } 36 44 } 37 45 -
src/AST/porting.md
r4b7cce6 r432ce7a 299 299 * `openVars` => `open` 300 300 301 `ExplodedActual` => `ExplodedArg` 302 * `ExplodedActual.h` => `ExplodedArg.hpp` 303 301 304 [1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes 302 305 -
src/Makefile.in
r4b7cce6 r432ce7a 195 195 ResolvExpr/CurrentObject.$(OBJEXT) \ 196 196 ResolvExpr/ExplodedActual.$(OBJEXT) \ 197 ResolvExpr/ExplodedArg.$(OBJEXT) \ 197 198 ResolvExpr/FindOpenVars.$(OBJEXT) ResolvExpr/Occurs.$(OBJEXT) \ 198 199 ResolvExpr/PolyCost.$(OBJEXT) \ … … 633 634 ResolvExpr/CurrentObject.cc \ 634 635 ResolvExpr/ExplodedActual.cc \ 636 ResolvExpr/ExplodedArg.cpp \ 635 637 ResolvExpr/FindOpenVars.cc \ 636 638 ResolvExpr/Occurs.cc \ … … 895 897 ResolvExpr/ExplodedActual.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 896 898 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 899 ResolvExpr/ExplodedArg.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 900 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 897 901 ResolvExpr/FindOpenVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 898 902 ResolvExpr/$(DEPDIR)/$(am__dirstamp) … … 1277 1281 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CurrentObject.Po@am__quote@ 1278 1282 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ExplodedActual.Po@am__quote@ 1283 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ExplodedArg.Po@am__quote@ 1279 1284 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/FindOpenVars.Po@am__quote@ 1280 1285 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Occurs.Po@am__quote@ -
src/ResolvExpr/AlternativeFinder.cc
r4b7cce6 r432ce7a 116 116 /// Finds matching alternatives for a function, given a set of arguments 117 117 template<typename OutputIterator> 118 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs & args, OutputIterator out );118 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs_old& args, OutputIterator out ); 119 119 /// Sets up parameter inference for an output alternative 120 120 template< typename OutputIterator > … … 593 593 594 594 /// Gets the list of exploded alternatives for this pack 595 const ExplodedActual& getExpl( const ExplodedArgs & args ) const {595 const ExplodedActual& getExpl( const ExplodedArgs_old& args ) const { 596 596 return args[nextArg-1][explAlt]; 597 597 } … … 617 617 /// Instantiates an argument to match a formal, returns false if no results left 618 618 bool instantiateArgument( Type* formalType, Initializer* initializer, 619 const ExplodedArgs & args, std::vector<ArgPack>& results, std::size_t& genStart,619 const ExplodedArgs_old& args, std::vector<ArgPack>& results, std::size_t& genStart, 620 620 const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 621 621 if ( TupleType * tupleType = dynamic_cast<TupleType*>( formalType ) ) { … … 889 889 template<typename OutputIterator> 890 890 void AlternativeFinder::Finder::makeFunctionAlternatives( const Alternative &func, 891 FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {891 FunctionType *funcType, const ExplodedArgs_old &args, OutputIterator out ) { 892 892 OpenVarSet funcOpenVars; 893 893 AssertionSet funcNeed, funcHave; … … 1021 1021 1022 1022 // pre-explode arguments 1023 ExplodedArgs argExpansions;1023 ExplodedArgs_old argExpansions; 1024 1024 argExpansions.reserve( argAlternatives.size() ); 1025 1025 -
src/ResolvExpr/AlternativeFinder.h
r4b7cce6 r432ce7a 37 37 /// First index is which argument, second index is which alternative for that argument, 38 38 /// third index is which exploded element of that alternative 39 using ExplodedArgs = std::vector< std::vector< ExplodedActual > >;39 using ExplodedArgs_old = std::vector< std::vector< ExplodedActual > >; 40 40 41 41 class AlternativeFinder { -
src/ResolvExpr/Candidate.hpp
r4b7cce6 r432ce7a 70 70 using CandidateList = std::vector< CandidateRef >; 71 71 72 /// Splice src after dst, clearing src 73 static inline void splice( CandidateList & dst, CandidateList & src ) { 74 dst.reserve( dst.size() + src.size() ); 75 for ( CandidateRef & r : src ) { dst.emplace_back( std::move( r ) ); } 76 src.clear(); 77 } 78 79 /// Splice src before dst 80 static inline void spliceBegin( CandidateList & dst, CandidateList & src ) { 81 splice( src, dst ); 82 dst.swap( src ); 83 } 84 72 85 /// Sum the cost of a list of candidates 73 86 static inline Cost sumCost( const CandidateList & candidates ) { -
src/ResolvExpr/CandidateFinder.cpp
r4b7cce6 r432ce7a 16 16 #include "CandidateFinder.hpp" 17 17 18 #include <deque> 18 19 #include <iterator> // for back_inserter 19 20 #include <sstream> 20 21 #include <string> 21 22 #include <unordered_map> 23 #include <vector> 22 24 23 25 #include "Candidate.hpp" 24 26 #include "CompilationState.h" 25 27 #include "Cost.h" 28 #include "ExplodedArg.hpp" 26 29 #include "Resolver.h" 27 30 #include "SatisfyAssertions.hpp" … … 33 36 #include "AST/Print.hpp" 34 37 #include "AST/SymbolTable.hpp" 38 #include "AST/Type.hpp" 35 39 #include "SymTab/Mangler.h" 40 #include "Tuples/Tuples.h" // for handleTupleAssignment 36 41 37 42 #define PRINT( text ) if ( resolvep ) { text } … … 40 45 41 46 namespace { 47 48 /// First index is which argument, second is which alternative, third is which exploded element 49 using ExplodedArgs_new = std::deque< std::vector< ExplodedArg > >; 50 51 /// Returns a list of alternatives with the minimum cost in the given list 52 CandidateList findMinCost( const CandidateList & candidates ) { 53 CandidateList out; 54 Cost minCost = Cost::infinity; 55 for ( const CandidateRef & r : candidates ) { 56 if ( r->cost < minCost ) { 57 minCost = r->cost; 58 out.clear(); 59 out.emplace_back( r ); 60 } else if ( r->cost == minCost ) { 61 out.emplace_back( r ); 62 } 63 } 64 return out; 65 } 66 67 /// Computes conversion cost for a given candidate 68 Cost computeApplicationConversionCost( 69 const CandidateRef & cand, const ast::SymbolTable & symtab 70 ) { 71 #warning unimplemented 72 (void)cand; (void)symtab; 73 assert(false); 74 return Cost::infinity; 75 } 42 76 43 77 /// Actually visits expressions to find their candidate interpretations … … 65 99 } 66 100 101 /// Builds a list of candidates for a function, storing them in out 102 void makeFunctionCandidates( 103 const CandidateRef & func, const ast::FunctionType * funcType, 104 const ExplodedArgs_new & args, CandidateList & out 105 ) { 106 #warning unimplemented 107 (void)func; (void)funcType; (void)args; (void)out; 108 assert(false); 109 } 110 111 /// Adds implicit struct-conversions to the alternative list 112 void addAnonConversions( const CandidateRef & cand ) { 113 #warning unimplemented 114 (void)cand; 115 assert(false); 116 } 117 67 118 void postvisit( const ast::UntypedExpr * untypedExpr ) { 68 #warning unimplemented 69 (void)untypedExpr; 70 assert(false); 119 CandidateFinder funcFinder{ symtab, tenv }; 120 funcFinder.find( untypedExpr->func, ResolvMode::withAdjustment() ); 121 // short-circuit if no candidates 122 if ( funcFinder.candidates.empty() ) return; 123 124 std::vector< CandidateFinder > argCandidates = 125 selfFinder.findSubExprs( untypedExpr->args ); 126 127 // take care of possible tuple assignments 128 // if not tuple assignment, handled as normal function call 129 Tuples::handleTupleAssignment( selfFinder, untypedExpr, argCandidates ); 130 131 // find function operators 132 ast::ptr< ast::Expr > opExpr = new ast::NameExpr{ untypedExpr->location, "?()" }; 133 CandidateFinder opFinder{ symtab, tenv }; 134 // okay if there aren't any function operations 135 opFinder.find( opExpr, ResolvMode::withoutFailFast() ); 136 PRINT( 137 std::cerr << "known function ops:" << std::endl; 138 print( std::cerr, opFinder.candidates, 1 ); 139 ) 140 141 // pre-explode arguments 142 ExplodedArgs_new argExpansions; 143 for ( const CandidateFinder & args : argCandidates ) { 144 argExpansions.emplace_back(); 145 auto & argE = argExpansions.back(); 146 for ( const CandidateRef & arg : args ) { argE.emplace_back( *arg, symtab ); } 147 } 148 149 // Find function matches 150 CandidateList found; 151 SemanticErrorException errors; 152 for ( CandidateRef & func : funcFinder ) { 153 try { 154 PRINT( 155 std::cerr << "working on alternative:" << std::endl; 156 print( std::cerr, *func, 2 ); 157 ) 158 159 // check if the type is a pointer to function 160 const ast::Type * funcResult = func->expr->result->stripReferences(); 161 if ( auto pointer = dynamic_cast< const ast::PointerType * >( funcResult ) ) { 162 if ( auto function = pointer->base.as< ast::FunctionType >() ) { 163 CandidateRef newFunc{ new Candidate{ *func } }; 164 newFunc->expr = 165 referenceToRvalueConversion( newFunc->expr, newFunc->cost ); 166 makeFunctionCandidates( newFunc, function, argExpansions, found ); 167 } 168 } else if ( 169 auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult ) 170 ) { 171 if ( const ast::EqvClass * clz = func->env.lookup( inst->name ) ) { 172 if ( auto function = clz->bound.as< ast::FunctionType >() ) { 173 CandidateRef newFunc{ new Candidate{ *func } }; 174 newFunc->expr = 175 referenceToRvalueConversion( newFunc->expr, newFunc->cost ); 176 makeFunctionCandidates( newFunc, function, argExpansions, found ); 177 } 178 } 179 } 180 } catch ( SemanticErrorException & e ) { errors.append( e ); } 181 } 182 183 // Find matches on function operators `?()` 184 if ( ! opFinder.candidates.empty() ) { 185 // add exploded function alternatives to front of argument list 186 std::vector< ExplodedArg > funcE; 187 funcE.reserve( funcFinder.candidates.size() ); 188 for ( const CandidateRef & func : funcFinder ) { 189 funcE.emplace_back( *func, symtab ); 190 } 191 argExpansions.emplace_front( std::move( funcE ) ); 192 193 for ( const CandidateRef & op : opFinder ) { 194 try { 195 // check if type is pointer-to-function 196 const ast::Type * opResult = op->expr->result->stripReferences(); 197 if ( auto pointer = dynamic_cast< const ast::PointerType * >( opResult ) ) { 198 if ( auto function = pointer->base.as< ast::FunctionType >() ) { 199 CandidateRef newOp{ new Candidate{ *op} }; 200 newOp->expr = 201 referenceToRvalueConversion( newOp->expr, newOp->cost ); 202 makeFunctionCandidates( newOp, function, argExpansions, found ); 203 } 204 } 205 } catch ( SemanticErrorException & e ) { errors.append( e ); } 206 } 207 } 208 209 // Implement SFINAE; resolution errors are only errors if there aren't any non-error 210 // candidates 211 if ( found.empty() && ! errors.isEmpty() ) { throw errors; } 212 213 // Compute conversion costs 214 for ( CandidateRef & withFunc : found ) { 215 Cost cvtCost = computeApplicationConversionCost( withFunc, symtab ); 216 217 PRINT( 218 auto appExpr = withFunc->expr.strict_as< ast::ApplicationExpr >(); 219 auto pointer = appExpr->func->result.strict_as< ast::PointerType >(); 220 auto function = pointer->base.strict_as< ast::FunctionType >(); 221 222 std::cerr << "Case +++++++++++++ " << appExpr->func << std::endl; 223 std::cerr << "parameters are:" << std::endl; 224 ast::printAll( std::cerr, function->params, 2 ); 225 std::cerr << "arguments are:" << std::endl; 226 ast::printAll( std::cerr, appExpr->args, 2 ); 227 std::cerr << "bindings are:" << std::endl; 228 ast::print( std::cerr, withFunc->env, 2 ); 229 std::cerr << "cost is: " << withFunc->cost << std::endl; 230 std::cerr << "cost of conversion is:" << cvtCost << std::endl; 231 ) 232 233 if ( cvtCost != Cost::infinity ) { 234 withFunc->cvtCost = cvtCost; 235 candidates.emplace_back( std::move( withFunc ) ); 236 } 237 } 238 found = std::move( candidates ); 239 240 // use a new list so that candidates are not examined by addAnonConversions twice 241 CandidateList winners = findMinCost( found ); 242 promoteCvtCost( winners ); 243 244 // function may return a struct/union value, in which case we need to add candidates 245 // for implicit conversions to each of the anonymous members, which must happen after 246 // `findMinCost`, since anon conversions are never the cheapest 247 for ( const CandidateRef & c : winners ) { 248 addAnonConversions( c ); 249 } 250 spliceBegin( candidates, winners ); 251 252 if ( candidates.empty() && targetType && ! targetType->isVoid() ) { 253 // If resolution is unsuccessful with a target type, try again without, since it 254 // will sometimes succeed when it wouldn't with a target type binding. 255 // For example: 256 // forall( otype T ) T & ?[]( T *, ptrdiff_t ); 257 // const char * x = "hello world"; 258 // unsigned char ch = x[0]; 259 // Fails with simple return type binding (xxx -- check this!) as follows: 260 // * T is bound to unsigned char 261 // * (x: const char *) is unified with unsigned char *, which fails 262 // xxx -- fix this better 263 targetType = nullptr; 264 postvisit( untypedExpr ); 265 } 71 266 } 72 267 … … 440 635 } 441 636 442 /// Returns a list of alternatives with the minimum cost in the given list443 CandidateList findMinCost( const CandidateList & candidates ) {444 CandidateList out;445 Cost minCost = Cost::infinity;446 for ( const CandidateRef & r : candidates ) {447 if ( r->cost < minCost ) {448 minCost = r->cost;449 out.clear();450 out.emplace_back( r );451 } else if ( r->cost == minCost ) {452 out.emplace_back( r );453 }454 }455 return out;456 }457 458 637 } // anonymous namespace 459 638 -
src/ResolvExpr/ExplodedActual.cc
r4b7cce6 r432ce7a 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Alternative.h--7 // ExplodedActual.cc -- 8 8 // 9 9 // Author : Aaron B. Moss … … 24 24 } 25 25 } 26 27 // Local Variables: // 28 // tab-width: 4 // 29 // mode: c++ // 30 // compile-command: "make install" // 31 // End: // -
src/ResolvExpr/ExplodedActual.h
r4b7cce6 r432ce7a 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Alternative.h --7 // ExplodedActual.h -- 8 8 // 9 9 // Author : Aaron B. Moss … … 37 37 }; 38 38 } 39 40 // Local Variables: // 41 // tab-width: 4 // 42 // mode: c++ // 43 // compile-command: "make install" // 44 // End: // -
src/ResolvExpr/module.mk
r4b7cce6 r432ce7a 26 26 ResolvExpr/CurrentObject.cc \ 27 27 ResolvExpr/ExplodedActual.cc \ 28 ResolvExpr/ExplodedArg.cpp \ 28 29 ResolvExpr/FindOpenVars.cc \ 29 30 ResolvExpr/Occurs.cc \ -
src/Tuples/Explode.h
r4b7cce6 r432ce7a 19 19 #include <utility> // for forward 20 20 21 #include "AST/Expr.hpp" 21 22 #include "ResolvExpr/Alternative.h" // for Alternative, AltList 23 #include "ResolvExpr/Candidate.hpp" // for Candidate, CandidateList 22 24 #include "ResolvExpr/ExplodedActual.h" // for ExplodedActual 25 #include "ResolvExpr/ExplodedArg.hpp" // for ExplodedArg 23 26 #include "SynTree/Expression.h" // for Expression, UniqueExpr, AddressExpr 24 27 #include "SynTree/Type.h" // for TupleType, Type 25 28 #include "Tuples.h" // for maybeImpure 29 30 namespace ast { 31 class SymbolTable; 32 } 26 33 27 34 namespace SymTab { … … 130 137 explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign ); 131 138 } 139 140 /// helper function used by explode 141 template< typename Output > 142 void explodeUnique( 143 const ast::Expr * expr, const ResolvExpr::Candidate & arg, const ast::SymbolTable & symtab, 144 Output && out, bool isTupleAssign 145 ) { 146 #warning unimplemented 147 (void)expr; (void)arg; (void)symtab; (void)out; (void)isTupleAssign; 148 assert(false); 149 } 150 151 /// expands a tuple-valued candidate into multiple candidates, each with a non-tuple type 152 template< typename Output > 153 void explode( 154 const ResolvExpr::Candidate & arg, const ast::SymbolTable & symtab, Output && out, 155 bool isTupleAssign = false 156 ) { 157 explodeUnique( arg.expr, arg, symtab, std::forward< Output >( out ), isTupleAssign ); 158 } 159 132 160 } // namespace Tuples 133 161 -
src/Tuples/TupleAssignment.cc
r4b7cce6 r432ce7a 377 377 } 378 378 } 379 380 void handleTupleAssignment( 381 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 382 std::vector< ResolvExpr::CandidateFinder > & args 383 ) { 384 #warning unimplmented 385 (void)finder; (void)assign; (void)args; 386 assert(false); 387 } 379 388 } // namespace Tuples 380 389 -
src/Tuples/Tuples.h
r4b7cce6 r432ce7a 26 26 27 27 #include "ResolvExpr/AlternativeFinder.h" 28 #include "ResolvExpr/CandidateFinder.hpp" 28 29 29 30 namespace Tuples { … … 31 32 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, 32 33 std::vector< ResolvExpr::AlternativeFinder >& args ); 34 void handleTupleAssignment( 35 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 36 std::vector< ResolvExpr::CandidateFinder > & args ); 33 37 34 38 // TupleExpansion.cc
Note: See TracChangeset
for help on using the changeset viewer.