Ignore:
Timestamp:
Jun 5, 2019, 8:36:48 PM (5 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
866545b
Parents:
67130fe (diff), 3cd5fdd (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

fix conflicit

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r67130fe rc6a1e8a  
    2121#include "Alternative.h"                 // for Alternative, AltList
    2222#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
     23#include "Candidate.hpp"
     24#include "CandidateFinder.hpp"
    2325#include "CurrentObject.h"               // for CurrentObject
    2426#include "RenameVars.h"                  // for RenameVars, global_renamer
     
    2729#include "typeops.h"                     // for extractResultType
    2830#include "Unify.h"                       // for unify
     31#include "AST/Chain.hpp"
     32#include "AST/Decl.hpp"
     33#include "AST/Init.hpp"
    2934#include "AST/Pass.hpp"
     35#include "AST/Print.hpp"
    3036#include "AST/SymbolTable.hpp"
    3137#include "Common/PassVisitor.h"          // for PassVisitor
     
    113119
    114120        namespace {
    115                 struct DeleteFinder : public WithShortCircuiting        {
     121                struct DeleteFinder_old : public WithShortCircuiting    {
    116122                        DeletedExpr * delExpr = nullptr;
    117123                        void previsit( DeletedExpr * expr ) {
     
    127133
    128134        DeletedExpr * findDeletedExpr( Expression * expr ) {
    129                 PassVisitor<DeleteFinder> finder;
     135                PassVisitor<DeleteFinder_old> finder;
    130136                expr->accept( finder );
    131137                return finder.pass.delExpr;
     
    133139
    134140        namespace {
    135                 struct StripCasts {
     141                struct StripCasts_old {
    136142                        Expression * postmutate( CastExpr * castExpr ) {
    137143                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     
    146152
    147153                        static void strip( Expression *& expr ) {
    148                                 PassVisitor<StripCasts> stripper;
     154                                PassVisitor<StripCasts_old> stripper;
    149155                                expr = expr->acceptMutator( stripper );
    150156                        }
     
    154160                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    155161                        env.makeSubstitution( *expr->env );
    156                         StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
     162                        StripCasts_old::strip( expr ); // remove unnecessary casts that may be buried in an expression
    157163                }
    158164
     
    405411
    406412        void Resolver_old::previsit( ObjectDecl * objectDecl ) {
    407                 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 
    408                 // class-variable initContext is changed multiple time because the LHS is analysed twice. 
    409                 // The second analysis changes initContext because of a function type can contain object 
    410                 // declarations in the return and parameter types. So each value of initContext is 
     413                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that
     414                // class-variable initContext is changed multiple time because the LHS is analysed twice.
     415                // The second analysis changes initContext because of a function type can contain object
     416                // declarations in the return and parameter types. So each value of initContext is
    411417                // retained, so the type on the first analysis is preserved and used for selecting the RHS.
    412418                GuardValue( currentObject );
     
    445451
    446452        void Resolver_old::postvisit( FunctionDecl * functionDecl ) {
    447                 // default value expressions have an environment which shouldn't be there and trips up 
     453                // default value expressions have an environment which shouldn't be there and trips up
    448454                // later passes.
    449455                // xxx - it might be necessary to somehow keep the information from this environment, but I
     
    937943        ///////////////////////////////////////////////////////////////////////////
    938944
    939         class Resolver_new final
    940         : public ast::WithIndexer, public ast::WithGuards, public ast::WithVisitorRef<Resolver_new>,
    941           public ast::WithShortCircuiting, public ast::WithStmtsToAdd<> {
    942                  
    943         public:
     945        namespace {
     946                /// Finds deleted expressions in an expression tree
     947                struct DeleteFinder_new final : public ast::WithShortCircuiting {
     948                        const ast::DeletedExpr * delExpr = nullptr;
     949
     950                        void previsit( const ast::DeletedExpr * expr ) {
     951                                if ( delExpr ) { visit_children = false; }
     952                                else { delExpr = expr; }
     953                        }
     954
     955                        void previsit( const ast::Expr * ) {
     956                                if ( delExpr ) { visit_children = false; }
     957                        }
     958                };
     959
     960                /// Check if this expression is or includes a deleted expression
     961                const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
     962                        ast::Pass<DeleteFinder_new> finder;
     963                        expr->accept( finder );
     964                        return finder.pass.delExpr;
     965                }
     966
     967                /// Calls the CandidateFinder and finds the single best candidate
     968                CandidateRef findUnfinishedKindExpression(
     969                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
     970                        std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
     971                ) {
     972                        if ( ! untyped ) return nullptr;
     973
     974                        // xxx - this isn't thread-safe, but should work until we parallelize the resolver
     975                        static unsigned recursion_level = 0;
     976
     977                        ++recursion_level;
     978                        ast::TypeEnvironment env;
     979                        CandidateFinder finder{ symtab, env };
     980                        finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode );
     981                        --recursion_level;
     982
     983                        // produce a filtered list of candidates
     984                        CandidateList candidates;
     985                        for ( auto & cand : finder.candidates ) {
     986                                if ( pred( *cand ) ) { candidates.emplace_back( cand ); }
     987                        }
     988
     989                        // produce invalid error if no candidates
     990                        if ( candidates.empty() ) {
     991                                SemanticError( untyped,
     992                                        toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
     993                                        "expression: ") );
     994                        }
     995
     996                        // search for cheapest candidate
     997                        CandidateList winners;
     998                        bool seen_undeleted = false;
     999                        for ( CandidateRef & cand : candidates ) {
     1000                                int c = winners.empty() ? -1 : cand->cost.compare( winners.front()->cost );
     1001
     1002                                if ( c > 0 ) continue;  // skip more expensive than winner
     1003
     1004                                if ( c < 0 ) {
     1005                                        // reset on new cheapest
     1006                                        seen_undeleted = ! findDeletedExpr( cand->expr );
     1007                                        winners.clear();
     1008                                } else /* if ( c == 0 ) */ {
     1009                                        if ( findDeletedExpr( cand->expr ) ) {
     1010                                                // skip deleted expression if already seen one equivalent-cost not
     1011                                                if ( seen_undeleted ) continue;
     1012                                        } else if ( ! seen_undeleted ) {
     1013                                                // replace list of equivalent-cost deleted expressions with one non-deleted
     1014                                                winners.clear();
     1015                                                seen_undeleted = true;
     1016                                        }
     1017                                }
     1018
     1019                                winners.emplace_back( std::move( cand ) );
     1020                        }
     1021
     1022                        // promote candidate.cvtCost to .cost
     1023                        for ( CandidateRef & cand : winners ) {
     1024                                cand->cost = cand->cvtCost;
     1025                        }
     1026
     1027                        // produce ambiguous errors, if applicable
     1028                        if ( winners.size() != 1 ) {
     1029                                std::ostringstream stream;
     1030                                stream << "Cannot choose between " << winners.size() << " alternatives for "
     1031                                        << kind << (kind != "" ? " " : "") << "expression\n";
     1032                                ast::print( stream, untyped );
     1033                                stream << " Alternatives are:\n";
     1034                                print( stream, winners, 1 );
     1035                                SemanticError( untyped->location, stream.str() );
     1036                        }
     1037
     1038                        // single selected choice
     1039                        CandidateRef & choice = winners.front();
     1040
     1041                        // fail on only expression deleted
     1042                        if ( ! seen_undeleted ) {
     1043                                SemanticError( untyped->location, choice->expr.get(), "Unique best alternative "
     1044                                "includes deleted identifier in " );
     1045                        }
     1046
     1047                        return std::move( choice );
     1048                }
     1049
     1050                /// Strips extraneous casts out of an expression
     1051                struct StripCasts_new final {
     1052                        const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
     1053                                if (
     1054                                        castExpr->isGenerated
     1055                                        && typesCompatible( castExpr->arg->result, castExpr->result )
     1056                                ) {
     1057                                        // generated cast is the same type as its argument, remove it after keeping env
     1058                                        ast::ptr<ast::Expr> arg = castExpr->arg;
     1059                                        arg.get_and_mutate()->env = castExpr->env;
     1060                                        return arg;
     1061                                }
     1062                                return castExpr;
     1063                        }
     1064
     1065                        static void strip( ast::ptr< ast::Expr > & expr ) {
     1066                                ast::Pass< StripCasts_new > stripper;
     1067                                expr = expr->accept( stripper );
     1068                        }
     1069                };
     1070
     1071                /// Establish post-resolver invariants for expressions
     1072                void finishExpr(
     1073                        ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
     1074                        const ast::TypeSubstitution * oldenv = nullptr
     1075                ) {
     1076                        // set up new type substitution for expression
     1077                        ast::ptr< ast::TypeSubstitution > newenv =
     1078                                 oldenv ? oldenv : new ast::TypeSubstitution{};
     1079                        env.writeToSubstitution( *newenv.get_and_mutate() );
     1080                        expr.get_and_mutate()->env = std::move( newenv );
     1081                        // remove unncecessary casts
     1082                        StripCasts_new::strip( expr );
     1083                }
     1084               
     1085                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
     1086                /// lowest cost, returning the resolved version
     1087                ast::ptr< ast::Expr > findKindExpression(
     1088                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
     1089                        std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
     1090                ) {
     1091                        if ( ! untyped ) return {};
     1092                        CandidateRef choice =
     1093                                findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
     1094                        finishExpr( choice->expr, choice->env, untyped->env );
     1095                        return std::move( choice->expr );
     1096                }
     1097
     1098                /// Predicate for "Candidate has integral type"
     1099                bool hasIntegralType( const Candidate & i ) {
     1100                        const ast::Type * type = i.expr->result;
     1101                       
     1102                        if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
     1103                                return bt->isInteger();
     1104                        } else if (
     1105                                dynamic_cast< const ast::EnumInstType * >( type )
     1106                                || dynamic_cast< const ast::ZeroType * >( type )
     1107                                || dynamic_cast< const ast::OneType * >( type )
     1108                        ) {
     1109                                return true;
     1110                        } else return false;
     1111                }
     1112
     1113                /// Resolve `untyped` as an integral expression, returning the resolved version
     1114                ast::ptr< ast::Expr > findIntegralExpression(
     1115                        const ast::Expr * untyped, const ast::SymbolTable & symtab
     1116                ) {
     1117                        return findKindExpression( untyped, symtab, "condition", hasIntegralType );
     1118                }
     1119        }
     1120
     1121        class Resolver_new final
     1122        : public ast::WithSymbolTable, public ast::WithGuards,
     1123          public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting,
     1124          public ast::WithStmtsToAdd<> {
     1125
     1126                ast::ptr< ast::Type > functionReturn = nullptr;
     1127                // ast::CurrentObject currentObject = nullptr;
     1128                bool inEnumDecl = false;
     1129
     1130        public:
    9441131                Resolver_new() = default;
    945                 Resolver_new( const ast::SymbolTable & syms ) { /*symtab = syms;*/ }
    946 
    947                 void previsit( ast::FunctionDecl * functionDecl );
    948                 ast::DeclWithType * postvisit( ast::FunctionDecl * functionDecl );
    949                 void previsit( ast::ObjectDecl * objectDecl );
    950                 void previsit( ast::EnumDecl * enumDecl );
    951                 void previsit( ast::StaticAssertDecl * assertDecl );
    952 
    953                 void previsit( ast::ArrayType * at );
    954                 void previsit( ast::PointerType * pt );
    955 
    956                 void previsit( ast::ExprStmt * exprStmt );
    957                 void previsit( ast::AsmExpr * asmExpr );
    958                 void previsit( ast::AsmStmt * asmStmt );
    959                 void previsit( ast::IfStmt * ifStmt );
    960                 void previsit( ast::WhileStmt * whileStmt );
    961                 void previsit( ast::ForStmt * forStmt );
    962                 void previsit( ast::SwitchStmt * switchStmt );
    963                 void previsit( ast::CaseStmt * caseStmt );
    964                 void previsit( ast::BranchStmt * branchStmt );
    965                 void previsit( ast::ReturnStmt * returnStmt );
    966                 void previsit( ast::ThrowStmt * throwStmt );
    967                 void previsit( ast::CatchStmt * catchStmt );
    968                 void previsit( ast::WaitForStmt * stmt );
    969 
    970                 void previsit( ast::SingleInit * singleInit );
    971                 void previsit( ast::ListInit * listInit );
    972                 void previsit( ast::ConstructorInit * ctorInit );
     1132                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
     1133
     1134                void previsit( const ast::FunctionDecl * );
     1135                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
     1136                void previsit( const ast::ObjectDecl * );
     1137                void previsit( const ast::EnumDecl * );
     1138                const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
     1139
     1140                void previsit( const ast::ArrayType * );
     1141                void previsit( const ast::PointerType * );
     1142
     1143                void previsit( const ast::ExprStmt * );
     1144                void previsit( const ast::AsmExpr * );
     1145                void previsit( const ast::AsmStmt * );
     1146                void previsit( const ast::IfStmt * );
     1147                void previsit( const ast::WhileStmt * );
     1148                void previsit( const ast::ForStmt * );
     1149                void previsit( const ast::SwitchStmt * );
     1150                void previsit( const ast::CaseStmt * );
     1151                void previsit( const ast::BranchStmt * );
     1152                void previsit( const ast::ReturnStmt * );
     1153                void previsit( const ast::ThrowStmt * );
     1154                void previsit( const ast::CatchStmt * );
     1155                void previsit( const ast::WaitForStmt * );
     1156
     1157                void previsit( const ast::SingleInit * );
     1158                void previsit( const ast::ListInit * );
     1159                void previsit( const ast::ConstructorInit * );
    9731160        };
    9741161
     
    9781165        }
    9791166
    980         void previsit( ast::FunctionDecl * functionDecl ) {
    981                 #warning unimplemented; Resolver port in progress
    982                 (void)functionDecl;
    983                 assert(false);
    984         }
    985 
    986         ast::DeclWithType * postvisit( ast::FunctionDecl * functionDecl ) {
    987                 #warning unimplemented; Resolver port in progress
    988                 (void)functionDecl;
    989                 assert(false);
    990                 return nullptr;
    991         }
    992 
    993         void previsit( ast::ObjectDecl * objectDecl ) {
     1167        void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
     1168                GuardValue( functionReturn );
     1169                functionReturn = extractResultType( functionDecl->type );
     1170        }
     1171
     1172        const ast::FunctionDecl * Resolver_new::postvisit( const ast::FunctionDecl * functionDecl ) {
     1173                // default value expressions have an environment which shouldn't be there and trips up
     1174                // later passes.
     1175                ast::ptr< ast::FunctionDecl > ret = functionDecl;
     1176                for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {
     1177                        const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i];
     1178
     1179                        if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {
     1180                                if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) {
     1181                                        if ( init->value->env == nullptr ) continue;
     1182                                        // clone initializer minus the initializer environment
     1183                                        ast::chain_mutate( ret )
     1184                                                ( &ast::FunctionDecl::type )
     1185                                                        ( &ast::FunctionType::params )[i]
     1186                                                                ( &ast::ObjectDecl::init )
     1187                                                                        ( &ast::SingleInit::value )->env = nullptr;
     1188
     1189                                        assert( functionDecl != ret.get() || functionDecl->unique() );
     1190                                        assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env );
     1191                                }
     1192                        }
     1193                }
     1194                return ret.get();
     1195        }
     1196
     1197        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    9941198                #warning unimplemented; Resolver port in progress
    9951199                (void)objectDecl;
     
    9971201        }
    9981202
    999         void previsit( ast::EnumDecl * enumDecl ) {
    1000                 #warning unimplemented; Resolver port in progress
    1001                 (void)enumDecl;
    1002                 assert(false);
    1003         }
    1004 
    1005         void previsit( ast::StaticAssertDecl * assertDecl ) {
    1006                 #warning unimplemented; Resolver port in progress
    1007                 (void)assertDecl;
    1008                 assert(false);
    1009         }
    1010 
    1011         void previsit( ast::ArrayType * at ) {
     1203        void Resolver_new::previsit( const ast::EnumDecl * ) {
     1204                // in case we decide to allow nested enums
     1205                GuardValue( inEnumDecl );
     1206                inEnumDecl = false;
     1207        }
     1208
     1209        const ast::StaticAssertDecl * Resolver_new::previsit(
     1210                const ast::StaticAssertDecl * assertDecl
     1211        ) {
     1212                ast::ptr< ast::Expr > cond = findIntegralExpression( assertDecl->cond, symtab );
     1213                if ( cond == assertDecl->cond ) return assertDecl;
     1214               
     1215                ast::StaticAssertDecl * ret = mutate( assertDecl );
     1216                ret->cond = cond;
     1217                return ret;
     1218        }
     1219
     1220        void Resolver_new::previsit( const ast::ArrayType * at ) {
    10121221                #warning unimplemented; Resolver port in progress
    10131222                (void)at;
     
    10151224        }
    10161225
    1017         void previsit( ast::PointerType * pt ) {
     1226        void Resolver_new::previsit( const ast::PointerType * pt ) {
    10181227                #warning unimplemented; Resolver port in progress
    10191228                (void)pt;
     
    10211230        }
    10221231
    1023         void previsit( ast::ExprStmt * exprStmt ) {
     1232        void Resolver_new::previsit( const ast::ExprStmt * exprStmt ) {
    10241233                #warning unimplemented; Resolver port in progress
    10251234                (void)exprStmt;
     
    10271236        }
    10281237
    1029         void previsit( ast::AsmExpr * asmExpr ) {
     1238        void Resolver_new::previsit( const ast::AsmExpr * asmExpr ) {
    10301239                #warning unimplemented; Resolver port in progress
    10311240                (void)asmExpr;
     
    10331242        }
    10341243
    1035         void previsit( ast::AsmStmt * asmStmt ) {
     1244        void Resolver_new::previsit( const ast::AsmStmt * asmStmt ) {
    10361245                #warning unimplemented; Resolver port in progress
    10371246                (void)asmStmt;
     
    10391248        }
    10401249
    1041         void previsit( ast::IfStmt * ifStmt ) {
     1250        void Resolver_new::previsit( const ast::IfStmt * ifStmt ) {
    10421251                #warning unimplemented; Resolver port in progress
    10431252                (void)ifStmt;
     
    10451254        }
    10461255
    1047         void previsit( ast::WhileStmt * whileStmt ) {
     1256        void Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
    10481257                #warning unimplemented; Resolver port in progress
    10491258                (void)whileStmt;
     
    10511260        }
    10521261
    1053         void previsit( ast::ForStmt * forStmt ) {
     1262        void Resolver_new::previsit( const ast::ForStmt * forStmt ) {
    10541263                #warning unimplemented; Resolver port in progress
    10551264                (void)forStmt;
     
    10571266        }
    10581267
    1059         void previsit( ast::SwitchStmt * switchStmt ) {
     1268        void Resolver_new::previsit( const ast::SwitchStmt * switchStmt ) {
    10601269                #warning unimplemented; Resolver port in progress
    10611270                (void)switchStmt;
     
    10631272        }
    10641273
    1065         void previsit( ast::CaseStmt * caseStmt ) {
     1274        void Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    10661275                #warning unimplemented; Resolver port in progress
    10671276                (void)caseStmt;
     
    10691278        }
    10701279
    1071         void previsit( ast::BranchStmt * branchStmt ) {
     1280        void Resolver_new::previsit( const ast::BranchStmt * branchStmt ) {
    10721281                #warning unimplemented; Resolver port in progress
    10731282                (void)branchStmt;
     
    10751284        }
    10761285
    1077         void previsit( ast::ReturnStmt * returnStmt ) {
     1286        void Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) {
    10781287                #warning unimplemented; Resolver port in progress
    10791288                (void)returnStmt;
     
    10811290        }
    10821291
    1083         void previsit( ast::ThrowStmt * throwStmt ) {
     1292        void Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) {
    10841293                #warning unimplemented; Resolver port in progress
    10851294                (void)throwStmt;
     
    10871296        }
    10881297
    1089         void previsit( ast::CatchStmt * catchStmt ) {
     1298        void Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
    10901299                #warning unimplemented; Resolver port in progress
    10911300                (void)catchStmt;
     
    10931302        }
    10941303
    1095         void previsit( ast::WaitForStmt * stmt ) {
     1304        void Resolver_new::previsit( const ast::WaitForStmt * stmt ) {
    10961305                #warning unimplemented; Resolver port in progress
    10971306                (void)stmt;
     
    10991308        }
    11001309
    1101         void previsit( ast::SingleInit * singleInit ) {
     1310        void Resolver_new::previsit( const ast::SingleInit * singleInit ) {
    11021311                #warning unimplemented; Resolver port in progress
    11031312                (void)singleInit;
     
    11051314        }
    11061315
    1107         void previsit( ast::ListInit * listInit ) {
     1316        void Resolver_new::previsit( const ast::ListInit * listInit ) {
    11081317                #warning unimplemented; Resolver port in progress
    11091318                (void)listInit;
     
    11111320        }
    11121321
    1113         void previsit( ast::ConstructorInit * ctorInit ) {
     1322        void Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
    11141323                #warning unimplemented; Resolver port in progress
    11151324                (void)ctorInit;
Note: See TracChangeset for help on using the changeset viewer.