Changes in / [6625727:04396aa]


Ignore:
Location:
src
Files:
2 deleted
17 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Print.hpp

    r6625727 r04396aa  
    1616#pragma once
    1717
    18 #include <iostream>
    19 #include <utility>   // for forward
     18#include <iosfwd>
     19#include <utility> // for forward
    2020
    2121#include "AST/Node.hpp"
     
    3232void printShort( std::ostream & os, const ast::Decl * node, Indenter indent = {} );
    3333
    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     }
     34inline void printShort( std::ostream & os, const ast::Decl * node, unsigned int indent ) {
     35    printShort( os, node, Indenter{ indent } );
    4436}
    4537
  • src/AST/porting.md

    r6625727 r04396aa  
    299299* `openVars` => `open`
    300300
    301 `ExplodedActual` => `ExplodedArg`
    302 * `ExplodedActual.h` => `ExplodedArg.hpp`
    303 
    304301[1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes
    305302
  • src/Makefile.in

    r6625727 r04396aa  
    195195        ResolvExpr/CurrentObject.$(OBJEXT) \
    196196        ResolvExpr/ExplodedActual.$(OBJEXT) \
    197         ResolvExpr/ExplodedArg.$(OBJEXT) \
    198197        ResolvExpr/FindOpenVars.$(OBJEXT) ResolvExpr/Occurs.$(OBJEXT) \
    199198        ResolvExpr/PolyCost.$(OBJEXT) \
     
    634633      ResolvExpr/CurrentObject.cc \
    635634      ResolvExpr/ExplodedActual.cc \
    636       ResolvExpr/ExplodedArg.cpp \
    637635      ResolvExpr/FindOpenVars.cc \
    638636      ResolvExpr/Occurs.cc \
     
    897895ResolvExpr/ExplodedActual.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    898896        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    899 ResolvExpr/ExplodedArg.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    900         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    901897ResolvExpr/FindOpenVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    902898        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     
    12811277@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CurrentObject.Po@am__quote@
    12821278@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@
    12841279@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/FindOpenVars.Po@am__quote@
    12851280@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Occurs.Po@am__quote@
  • src/ResolvExpr/AdjustExprType.cc

    r6625727 r04396aa  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AdjustExprType_old.cc --
     7// AdjustExprType.cc --
    88//
    99// Author           : Richard C. Bilson
     
    1414//
    1515
    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"
    2116#include "Common/PassVisitor.h"
    2217#include "SymTab/Indexer.h"       // for Indexer
     
    2722
    2823namespace 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 );
    3427                void premutate( VoidType * ) { visit_children = false; }
    3528                void premutate( BasicType * ) { visit_children = false; }
     
    5144                Type * postmutate( TypeInstType *aggregateUseType );
    5245
    53                 private:
     46          private:
    5447                const TypeEnvironment & env;
    5548                const SymTab::Indexer & indexer;
    5649        };
    5750
    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 )
    5964                : env( env ), indexer( indexer ) {
    6065        }
    6166
    62         Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) {
     67        Type * AdjustExprType::postmutate( ArrayType * arrayType ) {
    6368                PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
    6469                arrayType->base = nullptr;
     
    6772        }
    6873
    69         Type * AdjustExprType_old::postmutate( FunctionType * functionType ) {
     74        Type * AdjustExprType::postmutate( FunctionType * functionType ) {
    7075                return new PointerType{ Type::Qualifiers(), functionType };
    7176        }
    7277
    73         Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) {
     78        Type * AdjustExprType::postmutate( TypeInstType * typeInst ) {
    7479                if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) {
    7580                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
     
    8590                return typeInst;
    8691        }
    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 
    15792} // namespace ResolvExpr
    15893
  • src/ResolvExpr/AlternativeFinder.cc

    r6625727 r04396aa  
    2929#include "AlternativeFinder.h"
    3030#include "AST/Expr.hpp"
    31 #include "AST/SymbolTable.hpp"
    3231#include "AST/Type.hpp"
    3332#include "Common/SemanticError.h"  // for SemanticError
     
    116115                /// Finds matching alternatives for a function, given a set of arguments
    117116                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 );
    119118                /// Sets up parameter inference for an output alternative
    120119                template< typename OutputIterator >
     
    593592
    594593                /// 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 {
    596595                        return args[nextArg-1][explAlt];
    597596                }
     
    617616        /// Instantiates an argument to match a formal, returns false if no results left
    618617        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,
    620619                        const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
    621620                if ( TupleType * tupleType = dynamic_cast<TupleType*>( formalType ) ) {
     
    889888        template<typename OutputIterator>
    890889        void AlternativeFinder::Finder::makeFunctionAlternatives( const Alternative &func,
    891                         FunctionType *funcType, const ExplodedArgs_old &args, OutputIterator out ) {
     890                        FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {
    892891                OpenVarSet funcOpenVars;
    893892                AssertionSet funcNeed, funcHave;
     
    10211020
    10221021                // pre-explode arguments
    1023                 ExplodedArgs_old argExpansions;
     1022                ExplodedArgs argExpansions;
    10241023                argExpansions.reserve( argAlternatives.size() );
    10251024
  • src/ResolvExpr/AlternativeFinder.h

    r6625727 r04396aa  
    3737        /// First index is which argument, second index is which alternative for that argument,
    3838        /// 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 > >;
    4040
    4141        class AlternativeFinder {
  • src/ResolvExpr/Candidate.hpp

    r6625727 r04396aa  
    3030        /// A list of unresolved assertions
    3131        using AssertionList = std::vector<AssertionSet::value_type>;
    32 
    33         /// Convenience to merge AssertionList into AssertionSet
    34         static inline void mergeAssertionSet( AssertionSet & dst, const AssertionList & src ) {
    35                 for ( const auto & s : src ) { dst.emplace( s ); }
    36         }
    3732}
    3833
     
    4742        ast::OpenVarSet open;      ///< Open variables for environment
    4843        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() ) {}
    6444};
    6545
     
    6949/// List of candidates
    7050using CandidateList = std::vector< CandidateRef >;
    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 
    85 /// Sum the cost of a list of candidates
    86 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 }
    9851
    9952void print( std::ostream & os, const Candidate & cand, Indenter indent = {} );
  • src/ResolvExpr/CandidateFinder.cpp

    r6625727 r04396aa  
    1616#include "CandidateFinder.hpp"
    1717
    18 #include <deque>
    19 #include <iterator>               // for back_inserter
    2018#include <sstream>
    21 #include <string>
    22 #include <unordered_map>
    23 #include <vector>
    2419
    2520#include "Candidate.hpp"
    2621#include "CompilationState.h"
    27 #include "Cost.h"
    28 #include "ExplodedArg.hpp"
    29 #include "Resolver.h"
    3022#include "SatisfyAssertions.hpp"
    31 #include "typeops.h"              // for adjustExprType
    32 #include "Unify.h"
    3323#include "AST/Expr.hpp"
    3424#include "AST/Node.hpp"
    3525#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 handleTupleAssignment
    4126
    4227#define PRINT( text ) if ( resolvep ) { text }
     
    4631namespace {
    4732
    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         }
    76 
    7733        /// Actually visits expressions to find their candidate interpretations
    78         struct Finder final : public ast::WithShortCircuiting {
    79                 CandidateFinder & selfFinder;
     34        struct Finder {
     35                CandidateFinder & candFinder;
    8036                const ast::SymbolTable & symtab;
    8137                CandidateList & candidates;
     
    8440
    8541                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 ),
    8743                  targetType( f.targetType ) {}
    8844               
    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
    56346        };
    56447
     
    56649        /// return type. Skips ambiguous candidates.
    56750        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 {};
    63555        }
    63656
     
    67191        if ( mode.prune ) {
    67292                // trim candidates to single best one
     93                auto oldsize = candidates.size();
    67394                PRINT(
    67495                        std::cerr << "alternatives before prune:" << std::endl;
     
    67798
    67899                CandidateList pruned = pruneCandidates( candidates );
    679                
    680100                if ( mode.failFast && pruned.empty() ) {
    681101                        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);
    710106                }
    711107        }
    712108
    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);
    719111}
    720112
  • src/ResolvExpr/ExplodedActual.cc

    r6625727 r04396aa  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ExplodedActual.cc --
     7// Alternative.h --
    88//
    99// Author           : Aaron B. Moss
     
    2424        }
    2525}
    26 
    27 // Local Variables: //
    28 // tab-width: 4 //
    29 // mode: c++ //
    30 // compile-command: "make install" //
    31 // End: //
  • src/ResolvExpr/ExplodedActual.h

    r6625727 r04396aa  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ExplodedActual.h --
     7// Alternative.h --
    88//
    99// Author           : Aaron B. Moss
     
    3737        };
    3838}
    39 
    40 // Local Variables: //
    41 // tab-width: 4 //
    42 // mode: c++ //
    43 // compile-command: "make install" //
    44 // End: //
  • src/ResolvExpr/Resolver.cc

    r6625727 r04396aa  
    957957                        }
    958958                };
    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
    969967                /// always-accept candidate filter
    970968                bool anyCandidate( const Candidate & ) { return true; }
     
    10261024
    10271025                        // promote candidate.cvtCost to .cost
    1028                         promoteCvtCost( winners );
     1026                        for ( CandidateRef & cand : winners ) {
     1027                                cand->cost = cand->cvtCost;
     1028                        }
    10291029
    10301030                        // produce ambiguous errors, if applicable
     
    11001100                        StripCasts_new::strip( expr );
    11011101                }
    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
    11241123                /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
    11251124                /// context.
  • src/ResolvExpr/Resolver.h

    r6625727 r04396aa  
    1717
    1818#include <list>          // for list
    19 
    20 #include "AST/Node.hpp"  // for ptr
     19#include <AST/Node.hpp>  // for ptr
    2120
    2221class ConstructorInit;
     
    3029namespace ast {
    3130        class Decl;
    32         class DeletedExpr;
    33         class SymbolTable;
    34         class TypeEnvironment;
    3531} // namespace ast
    3632
     
    5248        /// Checks types and binds syntactic constructs to typed representations
    5349        void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit );
    54         /// Searches expr and returns the first DeletedExpr found, otherwise nullptr
    55         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 );
    6050} // namespace ResolvExpr
    6151
  • src/ResolvExpr/module.mk

    r6625727 r04396aa  
    2626      ResolvExpr/CurrentObject.cc \
    2727      ResolvExpr/ExplodedActual.cc \
    28       ResolvExpr/ExplodedArg.cpp \
    2928      ResolvExpr/FindOpenVars.cc \
    3029      ResolvExpr/Occurs.cc \
  • src/ResolvExpr/typeops.h

    r6625727 r04396aa  
    7171                } // while
    7272        }
    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 );
    7773
    7874        // in CastCost.cc
  • src/Tuples/Explode.h

    r6625727 r04396aa  
    1919#include <utility>                      // for forward
    2020
    21 #include "AST/Expr.hpp"
    2221#include "ResolvExpr/Alternative.h"     // for Alternative, AltList
    23 #include "ResolvExpr/Candidate.hpp"     // for Candidate, CandidateList
    2422#include "ResolvExpr/ExplodedActual.h"  // for ExplodedActual
    25 #include "ResolvExpr/ExplodedArg.hpp"   // for ExplodedArg
    2623#include "SynTree/Expression.h"         // for Expression, UniqueExpr, AddressExpr
    2724#include "SynTree/Type.h"               // for TupleType, Type
    2825#include "Tuples.h"                     // for maybeImpure
    29 
    30 namespace ast {
    31         class SymbolTable;
    32 }
    3326
    3427namespace SymTab {
     
    137130                explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign );
    138131        }
    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 
    160132} // namespace Tuples
    161133
  • src/Tuples/TupleAssignment.cc

    r6625727 r04396aa  
    377377                }
    378378        }
    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         }
    388379} // namespace Tuples
    389380
  • src/Tuples/Tuples.h

    r6625727 r04396aa  
    2626
    2727#include "ResolvExpr/AlternativeFinder.h"
    28 #include "ResolvExpr/CandidateFinder.hpp"
    2928
    3029namespace Tuples {
     
    3231        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign,
    3332                std::vector< ResolvExpr::AlternativeFinder >& args );
    34         void handleTupleAssignment(
    35                 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,
    36                 std::vector< ResolvExpr::CandidateFinder > & args );
    3733
    3834        // TupleExpansion.cc
Note: See TracChangeset for help on using the changeset viewer.