Changeset c8e4d2f8


Ignore:
Timestamp:
Jun 18, 2019, 11:47:44 AM (2 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
a2a85658, b408364
Parents:
bc92bee
Message:

Start porting CastExpr? resolution

Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Candidate.hpp

    rbc92bee rc8e4d2f8  
    5353        : expr( x ), cost( Cost::zero ), cvtCost( Cost::zero ), env( e ), open(), need() {}
    5454
    55         Candidate( const Candidate & o, const ast::Expr * x )
    56         : expr( x ), cost( o.cost ), cvtCost( Cost::zero ), env( o.env ), open( o.open ),
     55        Candidate( const Candidate & o, const ast::Expr * x, const Cost & addedCost = Cost::zero )
     56        : expr( x ), cost( o.cost + addedCost ), cvtCost( Cost::zero ), env( o.env ), open( o.open ),
    5757          need( o.need ) {}
    5858
  • src/ResolvExpr/CandidateFinder.cpp

    rbc92bee rc8e4d2f8  
    2828#include "ExplodedArg.hpp"
    2929#include "Resolver.h"
     30#include "ResolveTypeof.h"
    3031#include "SatisfyAssertions.hpp"
    3132#include "typeops.h"              // for adjustExprType, conversionCost, polyCost, specCost
     
    3839#include "AST/Type.hpp"
    3940#include "SymTab/Mangler.h"
     41#include "SymTab/Validate.h"      // for validateType
    4042#include "Tuples/Tuples.h"        // for handleTupleAssignment
    4143
     
    554556        }
    555557
     558        /// Generate a cast expression from `arg` to `toType`
     559        const ast::Expr * restructureCast( const ast::Expr * arg, const ast::Type * toType, bool isGenerated ) {
     560                #warning unimplemented
     561                (void)arg; (void)toType; (void)isGenerated;
     562                assert(false);
     563                return nullptr;
     564        }
     565
    556566        /// Actually visits expressions to find their candidate interpretations
    557567        struct Finder final : public ast::WithShortCircuiting {
     
    741751                /// Adds implicit struct-conversions to the alternative list
    742752                void addAnonConversions( const CandidateRef & cand ) {
    743                         #warning unimplemented
    744                         (void)cand;
    745                         assert(false);
     753                        // adds anonymous member interpretations whenever an aggregate value type is seen.
     754                        // it's okay for the aggregate expression to have reference type -- cast it to the
     755                        // base type to treat the aggregate as the referenced value
     756                        ast::ptr< ast::Expr > aggrExpr( cand->expr );
     757                        ast::ptr< ast::Type > & aggrType = aggrExpr.get_and_mutate()->result;
     758                        cand->env.apply( aggrType );
     759                       
     760                        if ( aggrType.as< ast::ReferenceType >() ) {
     761                                aggrExpr =
     762                                        new ast::CastExpr{ aggrExpr->location, aggrExpr, aggrType->stripReferences() };
     763                        }
     764
     765                        if ( auto structInst = aggrExpr->result.as< ast::StructInstType >() ) {
     766                                addAggMembers( structInst, aggrExpr, cand, Cost::safe, "" );
     767                        } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) {
     768                                addAggMembers( unionInst, aggrExpr, cand, Cost::safe, "" );
     769                        }
     770                }
     771
     772                /// Adds aggregate member interpretations
     773                void addAggMembers(
     774                        const ast::ReferenceToType * aggrInst, const ast::Expr * expr,
     775                        const CandidateRef & cand, const Cost & addedCost, const std::string & name
     776                ) {
     777                        for ( const ast::Decl * decl : aggrInst->lookup( name ) ) {
     778                                auto dwt = strict_dynamic_cast< const ast::DeclWithType * >( decl );
     779                                CandidateRef newCand = std::make_shared<Candidate>(
     780                                        *cand, new ast::MemberExpr{ expr->location, dwt, expr }, addedCost );
     781                                // add anonymous member interpretations whenever an aggregate value type is seen
     782                                // as a member expression
     783                                addAnonConversions( newCand );
     784                                candidates.emplace_back( move( newCand ) );
     785                        }
    746786                }
    747787
     
    915955
    916956                void postvisit( const ast::CastExpr * castExpr ) {
     957                        ast::ptr< ast::Type > toType = castExpr->result;
     958                        assert( toType );
     959                        toType = resolveTypeof( toType, symtab );
     960                        toType = SymTab::validateType( toType, symtab );
     961                        toType = adjustExprType( toType, tenv, symtab );
     962
     963                        CandidateFinder finder{ symtab, tenv, toType };
     964                        finder.find( castExpr->arg, ResolvMode::withAdjustment() );
     965
     966                        CandidateList matches;
     967                        for ( CandidateRef & cand : finder.candidates ) {
     968                                ast::AssertionSet need( cand->need.begin(), cand->need.end() ), have;
     969                                ast::OpenVarSet open( cand->open );
     970
     971                                cand->env.extractOpenVars( open );
     972
     973                                // It is possible that a cast can throw away some values in a multiply-valued
     974                                // expression, e.g. cast-to-void, one value to zero. Figure out the prefix of the
     975                                // subexpression results that are cast directly. The candidate is invalid if it
     976                                // has fewer results than there are types to cast to.
     977                                int discardedValues = cand->expr->result->size() - toType->size();
     978                                if ( discardedValues < 0 ) continue;
     979
     980                                // unification run for side-effects
     981                                unify( toType, cand->expr->result, cand->env, need, have, open, symtab );
     982                                Cost thisCost = castCost( cand->expr->result, toType, symtab, cand->env );
     983                                PRINT(
     984                                        std::cerr << "working on cast with result: " << toType << std::endl;
     985                                        std::cerr << "and expr type: " << cand->expr->result << std::endl;
     986                                        std::cerr << "env: " << cand->env << std::endl;
     987                                )
     988                                if ( thisCost != Cost::infinity ) {
     989                                        PRINT(
     990                                                std::cerr << "has finite cost." << std::endl;
     991                                        )
     992                                        // count one safe conversion for each value that is thrown away
     993                                        thisCost.incSafe( discardedValues );
     994                                        CandidateRef newCand = std::make_shared<Candidate>(
     995                                                restructureCast( cand->expr, toType, castExpr->isGenerated ),
     996                                                copy( cand->env ), move( open ), move( need ), cand->cost,
     997                                                cand->cost + thisCost );
     998                                        inferParameters( newCand, matches );
     999                                }
     1000                        }
     1001
     1002                        // castExpr->result should be replaced with toType
     1003                        // candidates => matches
     1004
    9171005                        #warning unimplemented
    9181006                        (void)castExpr;
     
    9271015                        for ( CandidateRef & r : finder.candidates ) {
    9281016                                addCandidate(
    929                                         *r, new ast::VirtualCastExpr{ castExpr->location, r->expr, castExpr->result } );
     1017                                        *r,
     1018                                        new ast::VirtualCastExpr{ castExpr->location, r->expr, castExpr->result } );
    9301019                        }
    9311020                }
  • src/ResolvExpr/CandidateFinder.hpp

    rbc92bee rc8e4d2f8  
    2727/// Data to perform expression resolution
    2828struct CandidateFinder {
    29         CandidateList candidates;                ///< List of candidate resolutions
    30         const ast::SymbolTable & symtab;         ///< Symbol table to lookup candidates
    31         const ast::TypeEnvironment & env;        ///< Substitutions performed in this resolution
    32         ast::ptr< ast::Type > targetType = nullptr;  ///< Target type for resolution
     29        CandidateList candidates;          ///< List of candidate resolutions
     30        const ast::SymbolTable & symtab;   ///< Symbol table to lookup candidates
     31        const ast::TypeEnvironment & env;  ///< Substitutions performed in this resolution
     32        ast::ptr< ast::Type > targetType;  ///< Target type for resolution
    3333
    34         CandidateFinder( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env )
    35         : candidates(), symtab( symtab ), env( env ) {}
     34        CandidateFinder(
     35                const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
     36                const ast::Type * tt = nullptr )
     37        : candidates(), symtab( symtab ), env( env ), targetType( tt ) {}
    3638
    3739        /// Fill candidates with feasible resolutions for `expr`
  • src/ResolvExpr/CastCost.cc

    rbc92bee rc8e4d2f8  
    7878                        });
    7979                } else {
    80                         PassVisitor<CastCost> converter( dest, indexer, env, castCost );
     80                        #warning cast on castCost artifact of having two functions, remove when port done
     81                        PassVisitor<CastCost> converter(
     82                                dest, indexer, env,
     83                                (Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & ))
     84                                        castCost );
    8185                        src->accept( converter );
    8286                        if ( converter.pass.get_cost() == Cost::infinity ) {
     
    125129                }
    126130        }
     131
     132        Cost castCost(
     133                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     134                const ast::TypeEnvironment & env
     135        ) {
     136                #warning unimplmented
     137                (void)src; (void)dst; (void)symtab; (void)env;
     138                assert(false);
     139                return Cost::zero;
     140        }
    127141} // namespace ResolvExpr
    128142
  • src/ResolvExpr/ResolveTypeof.cc

    rbc92bee rc8e4d2f8  
    107107                return newType;
    108108        }
     109
     110        const ast::Type * resolveTypeof( const ast::Type * type , const ast::SymbolTable & symtab ) {
     111                #warning unimplemented
     112                (void)type; (void)symtab;
     113                assert(false);
     114                return nullptr;
     115        }
    109116} // namespace ResolvExpr
    110117
  • src/ResolvExpr/ResolveTypeof.h

    rbc92bee rc8e4d2f8  
    2020class Indexer;
    2121}  // namespace SymTab
     22namespace ast {
     23        class Type;
     24        class SymbolTable;
     25}
    2226
    2327namespace ResolvExpr {
    2428        Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
     29        const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & );
    2530} // namespace ResolvExpr
    2631
  • src/ResolvExpr/typeops.h

    rbc92bee rc8e4d2f8  
    7878        // in CastCost.cc
    7979        Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     80        Cost castCost(
     81                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     82                const ast::TypeEnvironment & env );
    8083
    8184        // in ConversionCost.cc
  • src/SymTab/Validate.cc

    rbc92bee rc8e4d2f8  
    13671367                return addrExpr;
    13681368        }
     1369
     1370        const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) {
     1371                #warning unimplemented
     1372                (void)type; (void)symtab;
     1373                assert(false);
     1374                return nullptr;
     1375        }
    13691376} // namespace SymTab
    13701377
  • src/SymTab/Validate.h

    rbc92bee rc8e4d2f8  
    2222class Type;
    2323
     24namespace ast {
     25        class Type;
     26        class SymbolTable;
     27}
     28
    2429namespace SymTab {
    2530        class Indexer;
     
    2833        void validate( std::list< Declaration * > &translationUnit, bool doDebug = false );
    2934        void validateType( Type *type, const Indexer *indexer );
     35
     36        const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab );
    3037} // namespace SymTab
    3138
Note: See TracChangeset for help on using the changeset viewer.