Changes in / [6625727:04396aa]
- Location:
- src
- Files:
-
- 2 deleted
- 17 edited
-
AST/Print.hpp (modified) (2 diffs)
-
AST/porting.md (modified) (1 diff)
-
Makefile.in (modified) (4 diffs)
-
ResolvExpr/AdjustExprType.cc (modified) (6 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (6 diffs)
-
ResolvExpr/AlternativeFinder.h (modified) (1 diff)
-
ResolvExpr/Candidate.hpp (modified) (3 diffs)
-
ResolvExpr/CandidateFinder.cpp (modified) (6 diffs)
-
ResolvExpr/ExplodedActual.cc (modified) (2 diffs)
-
ResolvExpr/ExplodedActual.h (modified) (2 diffs)
-
ResolvExpr/ExplodedArg.cpp (deleted)
-
ResolvExpr/ExplodedArg.hpp (deleted)
-
ResolvExpr/Resolver.cc (modified) (3 diffs)
-
ResolvExpr/Resolver.h (modified) (3 diffs)
-
ResolvExpr/module.mk (modified) (1 diff)
-
ResolvExpr/typeops.h (modified) (1 diff)
-
Tuples/Explode.h (modified) (2 diffs)
-
Tuples/TupleAssignment.cc (modified) (1 diff)
-
Tuples/Tuples.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Print.hpp
r6625727 r04396aa 16 16 #pragma once 17 17 18 #include <ios tream>19 #include <utility> // for forward18 #include <iosfwd> 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 /// 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 } 34 inline void printShort( std::ostream & os, const ast::Decl * node, unsigned int indent ) { 35 printShort( os, node, Indenter{ indent } ); 44 36 } 45 37 -
src/AST/porting.md
r6625727 r04396aa 299 299 * `openVars` => `open` 300 300 301 `ExplodedActual` => `ExplodedArg`302 * `ExplodedActual.h` => `ExplodedArg.hpp`303 304 301 [1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes 305 302 -
src/Makefile.in
r6625727 r04396aa 195 195 ResolvExpr/CurrentObject.$(OBJEXT) \ 196 196 ResolvExpr/ExplodedActual.$(OBJEXT) \ 197 ResolvExpr/ExplodedArg.$(OBJEXT) \198 197 ResolvExpr/FindOpenVars.$(OBJEXT) ResolvExpr/Occurs.$(OBJEXT) \ 199 198 ResolvExpr/PolyCost.$(OBJEXT) \ … … 634 633 ResolvExpr/CurrentObject.cc \ 635 634 ResolvExpr/ExplodedActual.cc \ 636 ResolvExpr/ExplodedArg.cpp \637 635 ResolvExpr/FindOpenVars.cc \ 638 636 ResolvExpr/Occurs.cc \ … … 897 895 ResolvExpr/ExplodedActual.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 898 896 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 899 ResolvExpr/ExplodedArg.$(OBJEXT): ResolvExpr/$(am__dirstamp) \900 ResolvExpr/$(DEPDIR)/$(am__dirstamp)901 897 ResolvExpr/FindOpenVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 902 898 ResolvExpr/$(DEPDIR)/$(am__dirstamp) … … 1281 1277 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CurrentObject.Po@am__quote@ 1282 1278 @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@1284 1279 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/FindOpenVars.Po@am__quote@ 1285 1280 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Occurs.Po@am__quote@ -
src/ResolvExpr/AdjustExprType.cc
r6625727 r04396aa 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AdjustExprType _old.cc --7 // AdjustExprType.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"21 16 #include "Common/PassVisitor.h" 22 17 #include "SymTab/Indexer.h" // for Indexer … … 27 22 28 23 namespace ResolvExpr { 29 30 namespace { 31 class AdjustExprType_old final : public WithShortCircuiting { 32 public: 33 AdjustExprType_old( const TypeEnvironment & env, const SymTab::Indexer & indexer ); 24 class AdjustExprType : public WithShortCircuiting { 25 public: 26 AdjustExprType( const TypeEnvironment & env, const SymTab::Indexer & indexer ); 34 27 void premutate( VoidType * ) { visit_children = false; } 35 28 void premutate( BasicType * ) { visit_children = false; } … … 51 44 Type * postmutate( TypeInstType *aggregateUseType ); 52 45 53 private:46 private: 54 47 const TypeEnvironment & env; 55 48 const SymTab::Indexer & indexer; 56 49 }; 57 50 58 AdjustExprType_old::AdjustExprType_old( const TypeEnvironment &env, const SymTab::Indexer &indexer ) 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 ) 59 64 : env( env ), indexer( indexer ) { 60 65 } 61 66 62 Type * AdjustExprType _old::postmutate( ArrayType * arrayType ) {67 Type * AdjustExprType::postmutate( ArrayType * arrayType ) { 63 68 PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base }; 64 69 arrayType->base = nullptr; … … 67 72 } 68 73 69 Type * AdjustExprType _old::postmutate( FunctionType * functionType ) {74 Type * AdjustExprType::postmutate( FunctionType * functionType ) { 70 75 return new PointerType{ Type::Qualifiers(), functionType }; 71 76 } 72 77 73 Type * AdjustExprType _old::postmutate( TypeInstType * typeInst ) {78 Type * AdjustExprType::postmutate( TypeInstType * typeInst ) { 74 79 if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) { 75 80 if ( eqvClass->data.kind == TypeDecl::Ftype ) { … … 85 90 return typeInst; 86 91 } 87 } // anonymous namespace88 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-function134 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 namespace149 150 const ast::Type * adjustExprType(151 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab152 ) {153 ast::Pass<AdjustExprType_new> adjuster{ env, symtab };154 return type->accept( adjuster );155 }156 157 92 } // namespace ResolvExpr 158 93 -
src/ResolvExpr/AlternativeFinder.cc
r6625727 r04396aa 29 29 #include "AlternativeFinder.h" 30 30 #include "AST/Expr.hpp" 31 #include "AST/SymbolTable.hpp"32 31 #include "AST/Type.hpp" 33 32 #include "Common/SemanticError.h" // for SemanticError … … 116 115 /// Finds matching alternatives for a function, given a set of arguments 117 116 template<typename OutputIterator> 118 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs _old& args, OutputIterator out );117 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out ); 119 118 /// Sets up parameter inference for an output alternative 120 119 template< typename OutputIterator > … … 593 592 594 593 /// Gets the list of exploded alternatives for this pack 595 const ExplodedActual& getExpl( const ExplodedArgs _old& args ) const {594 const ExplodedActual& getExpl( const ExplodedArgs& args ) const { 596 595 return args[nextArg-1][explAlt]; 597 596 } … … 617 616 /// Instantiates an argument to match a formal, returns false if no results left 618 617 bool instantiateArgument( Type* formalType, Initializer* initializer, 619 const ExplodedArgs _old& args, std::vector<ArgPack>& results, std::size_t& genStart,618 const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart, 620 619 const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 621 620 if ( TupleType * tupleType = dynamic_cast<TupleType*>( formalType ) ) { … … 889 888 template<typename OutputIterator> 890 889 void AlternativeFinder::Finder::makeFunctionAlternatives( const Alternative &func, 891 FunctionType *funcType, const ExplodedArgs _old&args, OutputIterator out ) {890 FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) { 892 891 OpenVarSet funcOpenVars; 893 892 AssertionSet funcNeed, funcHave; … … 1021 1020 1022 1021 // pre-explode arguments 1023 ExplodedArgs _oldargExpansions;1022 ExplodedArgs argExpansions; 1024 1023 argExpansions.reserve( argAlternatives.size() ); 1025 1024 -
src/ResolvExpr/AlternativeFinder.h
r6625727 r04396aa 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 _old= std::vector< std::vector< ExplodedActual > >;39 using ExplodedArgs = std::vector< std::vector< ExplodedActual > >; 40 40 41 41 class AlternativeFinder { -
src/ResolvExpr/Candidate.hpp
r6625727 r04396aa 30 30 /// A list of unresolved assertions 31 31 using AssertionList = std::vector<AssertionSet::value_type>; 32 33 /// Convenience to merge AssertionList into AssertionSet34 static inline void mergeAssertionSet( AssertionSet & dst, const AssertionList & src ) {35 for ( const auto & s : src ) { dst.emplace( s ); }36 }37 32 } 38 33 … … 47 42 ast::OpenVarSet open; ///< Open variables for environment 48 43 ast::AssertionList need; ///< Assertions which need to be resolved 49 50 Candidate() : expr(), cost( Cost::zero ), cvtCost( Cost::zero ), env(), open(), need() {}51 52 Candidate( const ast::Expr * x, const ast::TypeEnvironment & e )53 : expr( x ), cost( Cost::zero ), cvtCost( Cost::zero ), env( e ), open(), need() {}54 55 Candidate( const Candidate & o, const ast::Expr * x )56 : expr( x ), cost( o.cost ), cvtCost( Cost::zero ), env( o.env ), open( o.open ),57 need( o.need ) {}58 59 Candidate(60 const ast::Expr * x, ast::TypeEnvironment && e, ast::OpenVarSet && o,61 ast::AssertionSet && n, const Cost & c )62 : expr( x ), cost( c ), cvtCost( Cost::zero ), env( std::move( e ) ), open( std::move( o ) ),63 need( n.begin(), n.end() ) {}64 44 }; 65 45 … … 69 49 /// List of candidates 70 50 using CandidateList = std::vector< CandidateRef >; 71 72 /// Splice src after dst, clearing src73 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 dst80 static inline void spliceBegin( CandidateList & dst, CandidateList & src ) {81 splice( src, dst );82 dst.swap( src );83 }84 85 /// Sum the cost of a list of candidates86 static inline Cost sumCost( const CandidateList & candidates ) {87 Cost total = Cost::zero;88 for ( const CandidateRef & r : candidates ) { total += r->cost; }89 return total;90 }91 92 /// Holdover behaviour from old `findMinCost` -- xxx -- can maybe be eliminated?93 static inline void promoteCvtCost( CandidateList & candidates ) {94 for ( CandidateRef & r : candidates ) {95 r->cost = r->cvtCost;96 }97 }98 51 99 52 void print( std::ostream & os, const Candidate & cand, Indenter indent = {} ); -
src/ResolvExpr/CandidateFinder.cpp
r6625727 r04396aa 16 16 #include "CandidateFinder.hpp" 17 17 18 #include <deque>19 #include <iterator> // for back_inserter20 18 #include <sstream> 21 #include <string>22 #include <unordered_map>23 #include <vector>24 19 25 20 #include "Candidate.hpp" 26 21 #include "CompilationState.h" 27 #include "Cost.h"28 #include "ExplodedArg.hpp"29 #include "Resolver.h"30 22 #include "SatisfyAssertions.hpp" 31 #include "typeops.h" // for adjustExprType32 #include "Unify.h"33 23 #include "AST/Expr.hpp" 34 24 #include "AST/Node.hpp" 35 25 #include "AST/Pass.hpp" 36 #include "AST/Print.hpp"37 #include "AST/SymbolTable.hpp"38 #include "AST/Type.hpp"39 #include "SymTab/Mangler.h"40 #include "Tuples/Tuples.h" // for handleTupleAssignment41 26 42 27 #define PRINT( text ) if ( resolvep ) { text } … … 46 31 namespace { 47 32 48 /// First index is which argument, second is which alternative, third is which exploded element49 using ExplodedArgs_new = std::deque< std::vector< ExplodedArg > >;50 51 /// Returns a list of alternatives with the minimum cost in the given list52 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 candidate68 Cost computeApplicationConversionCost(69 const CandidateRef & cand, const ast::SymbolTable & symtab70 ) {71 #warning unimplemented72 (void)cand; (void)symtab;73 assert(false);74 return Cost::infinity;75 }76 77 33 /// Actually visits expressions to find their candidate interpretations 78 struct Finder final : public ast::WithShortCircuiting{79 CandidateFinder & selfFinder;34 struct Finder { 35 CandidateFinder & candFinder; 80 36 const ast::SymbolTable & symtab; 81 37 CandidateList & candidates; … … 84 40 85 41 Finder( CandidateFinder & f ) 86 : selfFinder( f ), symtab( f.symtab ), candidates( f.candidates ), tenv( f.env ),42 : candFinder( f ), symtab( f.symtab ), candidates( f.candidates ), tenv( f.env ), 87 43 targetType( f.targetType ) {} 88 44 89 void previsit( const ast::Node * ) { visit_children = false; } 90 91 /// Convenience to add candidate to list 92 template<typename... Args> 93 void addCandidate( Args &&... args ) { 94 candidates.emplace_back( new Candidate{ std::forward<Args>( args )... } ); 95 } 96 97 void postvisit( const ast::ApplicationExpr * applicationExpr ) { 98 addCandidate( applicationExpr, tenv ); 99 } 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 118 void postvisit( const ast::UntypedExpr * untypedExpr ) { 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 } 266 } 267 268 /// true if expression is an lvalue 269 static bool isLvalue( const ast::Expr * x ) { 270 return x->result && ( x->result->is_lvalue() || x->result.as< ast::ReferenceType >() ); 271 } 272 273 void postvisit( const ast::AddressExpr * addressExpr ) { 274 CandidateFinder finder{ symtab, tenv }; 275 finder.find( addressExpr->arg ); 276 for ( CandidateRef & r : finder.candidates ) { 277 if ( ! isLvalue( r->expr ) ) continue; 278 addCandidate( *r, new ast::AddressExpr{ addressExpr->location, r->expr } ); 279 } 280 } 281 282 void postvisit( const ast::LabelAddressExpr * labelExpr ) { 283 addCandidate( labelExpr, tenv ); 284 } 285 286 void postvisit( const ast::CastExpr * castExpr ) { 287 #warning unimplemented 288 (void)castExpr; 289 assert(false); 290 } 291 292 void postvisit( const ast::VirtualCastExpr * castExpr ) { 293 assertf( castExpr->result, "Implicit virtual cast targets not yet supported." ); 294 CandidateFinder finder{ symtab, tenv }; 295 // don't prune here, all alternatives guaranteed to have same type 296 finder.find( castExpr->arg, ResolvMode::withoutPrune() ); 297 for ( CandidateRef & r : finder.candidates ) { 298 addCandidate( 299 *r, new ast::VirtualCastExpr{ castExpr->location, r->expr, castExpr->result } ); 300 } 301 } 302 303 void postvisit( const ast::UntypedMemberExpr * memberExpr ) { 304 #warning unimplemented 305 (void)memberExpr; 306 assert(false); 307 } 308 309 void postvisit( const ast::MemberExpr * memberExpr ) { 310 addCandidate( memberExpr, tenv ); 311 } 312 313 void postvisit( const ast::NameExpr * variableExpr ) { 314 #warning unimplemented 315 (void)variableExpr; 316 assert(false); 317 } 318 319 void postvisit( const ast::VariableExpr * variableExpr ) { 320 // not sufficient to just pass `variableExpr` here, type might have changed since 321 // creation 322 addCandidate( 323 new ast::VariableExpr{ variableExpr->location, variableExpr->var }, tenv ); 324 } 325 326 void postvisit( const ast::ConstantExpr * constantExpr ) { 327 addCandidate( constantExpr, tenv ); 328 } 329 330 void postvisit( const ast::SizeofExpr * sizeofExpr ) { 331 #warning unimplemented 332 (void)sizeofExpr; 333 assert(false); 334 } 335 336 void postvisit( const ast::AlignofExpr * alignofExpr ) { 337 #warning unimplemented 338 (void)alignofExpr; 339 assert(false); 340 } 341 342 void postvisit( const ast::UntypedOffsetofExpr * offsetofExpr ) { 343 #warning unimplemented 344 (void)offsetofExpr; 345 assert(false); 346 } 347 348 void postvisit( const ast::OffsetofExpr * offsetofExpr ) { 349 addCandidate( offsetofExpr, tenv ); 350 } 351 352 void postvisit( const ast::OffsetPackExpr * offsetPackExpr ) { 353 addCandidate( offsetPackExpr, tenv ); 354 } 355 356 void postvisit( const ast::LogicalExpr * logicalExpr ) { 357 CandidateFinder finder1{ symtab, tenv }; 358 finder1.find( logicalExpr->arg1, ResolvMode::withAdjustment() ); 359 if ( finder1.candidates.empty() ) return; 360 361 CandidateFinder finder2{ symtab, tenv }; 362 finder2.find( logicalExpr->arg2, ResolvMode::withAdjustment() ); 363 if ( finder2.candidates.empty() ) return; 364 365 for ( const CandidateRef & r1 : finder1.candidates ) { 366 for ( const CandidateRef & r2 : finder2.candidates ) { 367 ast::TypeEnvironment env{ r1->env }; 368 env.simpleCombine( r2->env ); 369 ast::OpenVarSet open{ r1->open }; 370 mergeOpenVars( open, r2->open ); 371 ast::AssertionSet need; 372 mergeAssertionSet( need, r1->need ); 373 mergeAssertionSet( need, r2->need ); 374 375 addCandidate( 376 new ast::LogicalExpr{ 377 logicalExpr->location, r1->expr, r2->expr, logicalExpr->isAnd }, 378 std::move( env ), std::move( open ), std::move( need ), 379 r1->cost + r2->cost ); 380 } 381 } 382 } 383 384 void postvisit( const ast::ConditionalExpr * conditionalExpr ) { 385 // candidates for condition 386 CandidateFinder finder1{ symtab, tenv }; 387 finder1.find( conditionalExpr->arg1, ResolvMode::withAdjustment() ); 388 if ( finder1.candidates.empty() ) return; 389 390 // candidates for true result 391 CandidateFinder finder2{ symtab, tenv }; 392 finder2.find( conditionalExpr->arg2, ResolvMode::withAdjustment() ); 393 if ( finder2.candidates.empty() ) return; 394 395 // candidates for false result 396 CandidateFinder finder3{ symtab, tenv }; 397 finder3.find( conditionalExpr->arg3, ResolvMode::withAdjustment() ); 398 if ( finder3.candidates.empty() ) return; 399 400 for ( const CandidateRef & r1 : finder1.candidates ) { 401 for ( const CandidateRef & r2 : finder2.candidates ) { 402 for ( const CandidateRef & r3 : finder3.candidates ) { 403 ast::TypeEnvironment env{ r1->env }; 404 env.simpleCombine( r2->env ); 405 env.simpleCombine( r3->env ); 406 ast::OpenVarSet open{ r1->open }; 407 mergeOpenVars( open, r2->open ); 408 mergeOpenVars( open, r3->open ); 409 ast::AssertionSet need; 410 mergeAssertionSet( need, r1->need ); 411 mergeAssertionSet( need, r2->need ); 412 mergeAssertionSet( need, r3->need ); 413 ast::AssertionSet have; 414 415 // unify true and false results, then infer parameters to produce new 416 // candidates 417 ast::ptr< ast::Type > common; 418 if ( 419 unify( 420 r2->expr->result, r3->expr->result, env, need, have, open, symtab, 421 common ) 422 ) { 423 #warning unimplemented 424 assert(false); 425 } 426 } 427 } 428 } 429 } 430 431 void postvisit( const ast::CommaExpr * commaExpr ) { 432 ast::TypeEnvironment env{ tenv }; 433 ast::ptr< ast::Expr > arg1 = resolveInVoidContext( commaExpr->arg1, symtab, env ); 434 435 CandidateFinder finder2{ symtab, env }; 436 finder2.find( commaExpr->arg2, ResolvMode::withAdjustment() ); 437 438 for ( const CandidateRef & r2 : finder2.candidates ) { 439 addCandidate( *r2, new ast::CommaExpr{ commaExpr->location, arg1, r2->expr } ); 440 } 441 } 442 443 void postvisit( const ast::ImplicitCopyCtorExpr * ctorExpr ) { 444 addCandidate( ctorExpr, tenv ); 445 } 446 447 void postvisit( const ast::ConstructorExpr * ctorExpr ) { 448 CandidateFinder finder{ symtab, tenv }; 449 finder.find( ctorExpr->callExpr, ResolvMode::withoutPrune() ); 450 for ( CandidateRef & r : finder.candidates ) { 451 addCandidate( *r, new ast::ConstructorExpr{ ctorExpr->location, r->expr } ); 452 } 453 } 454 455 void postvisit( const ast::RangeExpr * rangeExpr ) { 456 // resolve low and high, accept candidates where low and high types unify 457 CandidateFinder finder1{ symtab, tenv }; 458 finder1.find( rangeExpr->low, ResolvMode::withAdjustment() ); 459 if ( finder1.candidates.empty() ) return; 460 461 CandidateFinder finder2{ symtab, tenv }; 462 finder2.find( rangeExpr->high, ResolvMode::withAdjustment() ); 463 if ( finder2.candidates.empty() ) return; 464 465 for ( const CandidateRef & r1 : finder1.candidates ) { 466 for ( const CandidateRef & r2 : finder2.candidates ) { 467 ast::TypeEnvironment env{ r1->env }; 468 env.simpleCombine( r2->env ); 469 ast::OpenVarSet open{ r1->open }; 470 mergeOpenVars( open, r2->open ); 471 ast::AssertionSet need; 472 mergeAssertionSet( need, r1->need ); 473 mergeAssertionSet( need, r2->need ); 474 ast::AssertionSet have; 475 476 ast::ptr< ast::Type > common; 477 if ( 478 unify( 479 r1->expr->result, r2->expr->result, env, need, have, open, symtab, 480 common ) 481 ) { 482 ast::RangeExpr * newExpr = 483 new ast::RangeExpr{ rangeExpr->location, r1->expr, r2->expr }; 484 newExpr->result = common ? common : r1->expr->result; 485 486 #warning unimplemented 487 assert(false); 488 } 489 } 490 } 491 } 492 493 void postvisit( const ast::UntypedTupleExpr * tupleExpr ) { 494 std::vector< CandidateFinder > subCandidates = 495 selfFinder.findSubExprs( tupleExpr->exprs ); 496 std::vector< CandidateList > possibilities; 497 combos( subCandidates.begin(), subCandidates.end(), back_inserter( possibilities ) ); 498 499 for ( const CandidateList & subs : possibilities ) { 500 std::vector< ast::ptr< ast::Expr > > exprs; 501 exprs.reserve( subs.size() ); 502 for ( const CandidateRef & sub : subs ) { exprs.emplace_back( sub->expr ); } 503 504 ast::TypeEnvironment env; 505 ast::OpenVarSet open; 506 ast::AssertionSet need; 507 for ( const CandidateRef & sub : subs ) { 508 env.simpleCombine( sub->env ); 509 mergeOpenVars( open, sub->open ); 510 mergeAssertionSet( need, sub->need ); 511 } 512 513 addCandidate( 514 new ast::TupleExpr{ tupleExpr->location, std::move( exprs ) }, 515 std::move( env ), std::move( open ), std::move( need ), sumCost( subs ) ); 516 } 517 } 518 519 void postvisit( const ast::TupleExpr * tupleExpr ) { 520 addCandidate( tupleExpr, tenv ); 521 } 522 523 void postvisit( const ast::TupleIndexExpr * tupleExpr ) { 524 addCandidate( tupleExpr, tenv ); 525 } 526 527 void postvisit( const ast::TupleAssignExpr * tupleExpr ) { 528 addCandidate( tupleExpr, tenv ); 529 } 530 531 void postvisit( const ast::UniqueExpr * unqExpr ) { 532 CandidateFinder finder{ symtab, tenv }; 533 finder.find( unqExpr->expr, ResolvMode::withAdjustment() ); 534 for ( CandidateRef & r : finder.candidates ) { 535 // ensure that the the id is passed on so that the expressions are "linked" 536 addCandidate( *r, new ast::UniqueExpr{ unqExpr->location, r->expr, unqExpr->id } ); 537 } 538 } 539 540 void postvisit( const ast::StmtExpr * stmtExpr ) { 541 #warning unimplemented 542 (void)stmtExpr; 543 assert(false); 544 } 545 546 void postvisit( const ast::UntypedInitExpr * initExpr ) { 547 #warning unimplemented 548 (void)initExpr; 549 assert(false); 550 } 551 552 void postvisit( const ast::InitExpr * ) { 553 assertf( false, "CandidateFinder should never see a resolved InitExpr." ); 554 } 555 556 void postvisit( const ast::DeletedExpr * ) { 557 assertf( false, "CandidateFinder should never see a DeletedExpr." ); 558 } 559 560 void postvisit( const ast::GenericExpr * ) { 561 assertf( false, "_Generic is not yet supported." ); 562 } 45 #warning unimplemented 563 46 }; 564 47 … … 566 49 /// return type. Skips ambiguous candidates. 567 50 CandidateList pruneCandidates( CandidateList & candidates ) { 568 struct PruneStruct { 569 CandidateRef candidate; 570 bool ambiguous; 571 572 PruneStruct() = default; 573 PruneStruct( const CandidateRef & c ) : candidate( c ), ambiguous( false ) {} 574 }; 575 576 // find lowest-cost candidate for each type 577 std::unordered_map< std::string, PruneStruct > selected; 578 for ( CandidateRef & candidate : candidates ) { 579 std::string mangleName; 580 { 581 ast::ptr< ast::Type > newType = candidate->expr->result; 582 candidate->env.apply( newType ); 583 mangleName = Mangle::mangle( newType ); 584 } 585 586 auto found = selected.find( mangleName ); 587 if ( found != selected.end() ) { 588 if ( candidate->cost < found->second.candidate->cost ) { 589 PRINT( 590 std::cerr << "cost " << candidate->cost << " beats " 591 << found->second.candidate->cost << std::endl; 592 ) 593 594 found->second = PruneStruct{ candidate }; 595 } else if ( candidate->cost == found->second.candidate->cost ) { 596 // if one of the candidates contains a deleted identifier, can pick the other, 597 // since deleted expressions should not be ambiguous if there is another option 598 // that is at least as good 599 if ( findDeletedExpr( candidate->expr ) ) { 600 // do nothing 601 PRINT( std::cerr << "candidate is deleted" << std::endl; ) 602 } else if ( findDeletedExpr( found->second.candidate->expr ) ) { 603 PRINT( std::cerr << "current is deleted" << std::endl; ) 604 found->second = PruneStruct{ candidate }; 605 } else { 606 PRINT( std::cerr << "marking ambiguous" << std::endl; ) 607 found->second.ambiguous = true; 608 } 609 } else { 610 PRINT( 611 std::cerr << "cost " << candidate->cost << " loses to " 612 << found->second.candidate->cost << std::endl; 613 ) 614 } 615 } else { 616 selected.emplace_hint( found, mangleName, candidate ); 617 } 618 } 619 620 // report unambiguous min-cost candidates 621 CandidateList out; 622 for ( auto & target : selected ) { 623 if ( target.second.ambiguous ) continue; 624 625 CandidateRef cand = target.second.candidate; 626 627 ast::ptr< ast::Type > newResult = cand->expr->result; 628 cand->env.applyFree( newResult ); 629 cand->expr = ast::mutate_field( 630 cand->expr.get(), &ast::Expr::result, std::move( newResult ) ); 631 632 out.emplace_back( cand ); 633 } 634 return out; 51 #warning unimplemented 52 (void)candidates; 53 assert(false); 54 return {}; 635 55 } 636 56 … … 671 91 if ( mode.prune ) { 672 92 // trim candidates to single best one 93 auto oldsize = candidates.size(); 673 94 PRINT( 674 95 std::cerr << "alternatives before prune:" << std::endl; … … 677 98 678 99 CandidateList pruned = pruneCandidates( candidates ); 679 680 100 if ( mode.failFast && pruned.empty() ) { 681 101 std::ostringstream stream; 682 CandidateList winners = findMinCost( candidates ); 683 stream << "Cannot choose between " << winners.size() << " alternatives for " 684 "expression\n"; 685 ast::print( stream, expr ); 686 stream << " Alternatives are:\n"; 687 print( stream, winners, 1 ); 688 SemanticError( expr->location, stream.str() ); 689 } 690 691 auto oldsize = candidates.size(); 692 candidates = std::move( pruned ); 693 694 PRINT( 695 std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl; 696 ) 697 PRINT( 698 std::cerr << "there are " << candidates.size() << " alternatives after elimination" 699 << std::endl; 700 ) 701 } 702 703 // adjust types after pruning so that types substituted by pruneAlternatives are correctly 704 // adjusted 705 if ( mode.adjust ) { 706 for ( CandidateRef & r : candidates ) { 707 r->expr = ast::mutate_field( 708 r->expr.get(), &ast::Expr::result, 709 adjustExprType( r->expr->result, r->env, symtab ) ); 102 CandidateList winners; 103 104 #warning unimplemented 105 assert(false); 710 106 } 711 107 } 712 108 713 // Central location to handle gcc extension keyword, etc. for all expressions 714 for ( CandidateRef & r : candidates ) { 715 if ( r->expr->extension != expr->extension ) { 716 r->expr.get_and_mutate()->extension = expr->extension; 717 } 718 } 109 #warning unimplemented 110 assert(false); 719 111 } 720 112 -
src/ResolvExpr/ExplodedActual.cc
r6625727 r04396aa 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ExplodedActual.cc--7 // Alternative.h -- 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
r6625727 r04396aa 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ExplodedActual.h --7 // Alternative.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/Resolver.cc
r6625727 r04396aa 957 957 } 958 958 }; 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 { 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 969 967 /// always-accept candidate filter 970 968 bool anyCandidate( const Candidate & ) { return true; } … … 1026 1024 1027 1025 // promote candidate.cvtCost to .cost 1028 promoteCvtCost( winners ); 1026 for ( CandidateRef & cand : winners ) { 1027 cand->cost = cand->cvtCost; 1028 } 1029 1029 1030 1030 // produce ambiguous errors, if applicable … … 1100 1100 StripCasts_new::strip( expr ); 1101 1101 } 1102 } // anonymous namespace 1103 1104 1105 ast::ptr< ast::Expr > resolveInVoidContext( 1106 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env 1107 ) { 1108 assertf( expr, "expected a non-null expression" ); 1109 1110 // set up and resolve expression cast to void 1111 ast::CastExpr * untyped = new ast::CastExpr{ expr->location, expr }; 1112 CandidateRef choice = findUnfinishedKindExpression( 1113 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); 1114 1115 // a cast expression has either 0 or 1 interpretations (by language rules); 1116 // if 0, an exception has already been thrown, and this code will not run 1117 const ast::CastExpr * castExpr = choice->expr.strict_as< ast::CastExpr >(); 1118 env = std::move( choice->env ); 1119 1120 return castExpr->arg; 1121 } 1122 1123 namespace { 1102 1103 /// Find the expression candidate that is the unique best match for `untyped` in a `void` 1104 /// context. 1105 ast::ptr< ast::Expr > resolveInVoidContext( 1106 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env 1107 ) { 1108 assertf( expr, "expected a non-null expression" ); 1109 1110 // set up and resolve expression cast to void 1111 ast::CastExpr * untyped = new ast::CastExpr{ expr->location, expr }; 1112 CandidateRef choice = findUnfinishedKindExpression( 1113 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); 1114 1115 // a cast expression has either 0 or 1 interpretations (by language rules); 1116 // if 0, an exception has already been thrown, and this code will not run 1117 const ast::CastExpr * castExpr = choice->expr.strict_as< ast::CastExpr >(); 1118 env = std::move( choice->env ); 1119 1120 return castExpr->arg; 1121 } 1122 1124 1123 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1125 1124 /// context. -
src/ResolvExpr/Resolver.h
r6625727 r04396aa 17 17 18 18 #include <list> // for list 19 20 #include "AST/Node.hpp" // for ptr 19 #include <AST/Node.hpp> // for ptr 21 20 22 21 class ConstructorInit; … … 30 29 namespace ast { 31 30 class Decl; 32 class DeletedExpr;33 class SymbolTable;34 class TypeEnvironment;35 31 } // namespace ast 36 32 … … 52 48 /// Checks types and binds syntactic constructs to typed representations 53 49 void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ); 54 /// Searches expr and returns the first DeletedExpr found, otherwise nullptr55 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr );56 /// Find the expression candidate that is the unique best match for `untyped` in a `void`57 /// context.58 ast::ptr< ast::Expr > resolveInVoidContext(59 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env );60 50 } // namespace ResolvExpr 61 51 -
src/ResolvExpr/module.mk
r6625727 r04396aa 26 26 ResolvExpr/CurrentObject.cc \ 27 27 ResolvExpr/ExplodedActual.cc \ 28 ResolvExpr/ExplodedArg.cpp \29 28 ResolvExpr/FindOpenVars.cc \ 30 29 ResolvExpr/Occurs.cc \ -
src/ResolvExpr/typeops.h
r6625727 r04396aa 71 71 } // while 72 72 } 73 74 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function75 const ast::Type * adjustExprType(76 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );77 73 78 74 // in CastCost.cc -
src/Tuples/Explode.h
r6625727 r04396aa 19 19 #include <utility> // for forward 20 20 21 #include "AST/Expr.hpp"22 21 #include "ResolvExpr/Alternative.h" // for Alternative, AltList 23 #include "ResolvExpr/Candidate.hpp" // for Candidate, CandidateList24 22 #include "ResolvExpr/ExplodedActual.h" // for ExplodedActual 25 #include "ResolvExpr/ExplodedArg.hpp" // for ExplodedArg26 23 #include "SynTree/Expression.h" // for Expression, UniqueExpr, AddressExpr 27 24 #include "SynTree/Type.h" // for TupleType, Type 28 25 #include "Tuples.h" // for maybeImpure 29 30 namespace ast {31 class SymbolTable;32 }33 26 34 27 namespace SymTab { … … 137 130 explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign ); 138 131 } 139 140 /// helper function used by explode141 template< typename Output >142 void explodeUnique(143 const ast::Expr * expr, const ResolvExpr::Candidate & arg, const ast::SymbolTable & symtab,144 Output && out, bool isTupleAssign145 ) {146 #warning unimplemented147 (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 type152 template< typename Output >153 void explode(154 const ResolvExpr::Candidate & arg, const ast::SymbolTable & symtab, Output && out,155 bool isTupleAssign = false156 ) {157 explodeUnique( arg.expr, arg, symtab, std::forward< Output >( out ), isTupleAssign );158 }159 160 132 } // namespace Tuples 161 133 -
src/Tuples/TupleAssignment.cc
r6625727 r04396aa 377 377 } 378 378 } 379 380 void handleTupleAssignment(381 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,382 std::vector< ResolvExpr::CandidateFinder > & args383 ) {384 #warning unimplmented385 (void)finder; (void)assign; (void)args;386 assert(false);387 }388 379 } // namespace Tuples 389 380 -
src/Tuples/Tuples.h
r6625727 r04396aa 26 26 27 27 #include "ResolvExpr/AlternativeFinder.h" 28 #include "ResolvExpr/CandidateFinder.hpp"29 28 30 29 namespace Tuples { … … 32 31 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, 33 32 std::vector< ResolvExpr::AlternativeFinder >& args ); 34 void handleTupleAssignment(35 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,36 std::vector< ResolvExpr::CandidateFinder > & args );37 33 38 34 // TupleExpansion.cc
Note:
See TracChangeset
for help on using the changeset viewer.