Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    rb7d92b96 r99d4584  
    2929#include "typeops.h"                     // for extractResultType
    3030#include "Unify.h"                       // for unify
    31 #include "AST/Chain.hpp"
    3231#include "AST/Decl.hpp"
    3332#include "AST/Init.hpp"
     
    165164                void removeExtraneousCast( Expression *& expr, const SymTab::Indexer & indexer ) {
    166165                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    167                                 if ( typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {
     166                                if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {
    168167                                        // cast is to the same type as its argument, so it's unnecessary -- remove it
    169168                                        expr = castExpr->arg;
     
    411410
    412411        void Resolver_old::previsit( ObjectDecl * objectDecl ) {
    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
     412                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 
     413                // class-variable initContext is changed multiple time because the LHS is analysed twice. 
     414                // The second analysis changes initContext because of a function type can contain object 
     415                // declarations in the return and parameter types. So each value of initContext is 
    417416                // retained, so the type on the first analysis is preserved and used for selecting the RHS.
    418417                GuardValue( currentObject );
     
    451450
    452451        void Resolver_old::postvisit( FunctionDecl * functionDecl ) {
    453                 // default value expressions have an environment which shouldn't be there and trips up
     452                // default value expressions have an environment which shouldn't be there and trips up 
    454453                // later passes.
    455454                // xxx - it might be necessary to somehow keep the information from this environment, but I
     
    965964                }
    966965
    967                 /// always-accept candidate filter
    968                 bool anyCandidate( const Candidate & ) { return true; }
    969 
    970966                /// Calls the CandidateFinder and finds the single best candidate
    971967                CandidateRef findUnfinishedKindExpression(
    972968                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
    973                         std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {}
     969                        std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
    974970                ) {
    975971                        if ( ! untyped ) return nullptr;
     
    10591055                                ) {
    10601056                                        // generated cast is the same type as its argument, remove it after keeping env
    1061                                         return ast::mutate_field(
    1062                                                 castExpr->arg.get(), &ast::Expr::env, castExpr->env );
     1057                                        ast::ptr<ast::Expr> arg = castExpr->arg;
     1058                                        arg.get_and_mutate()->env = castExpr->env;
     1059                                        return arg;
    10631060                                }
    10641061                                return castExpr;
     
    10701067                        }
    10711068                };
    1072 
    1073                 /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts)
    1074                 void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) {
    1075                         if ( const ast::CastExpr * castExpr = expr.as< ast::CastExpr >() ) {
    1076                                 if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) {
    1077                                         // cast is to the same type as its argument, remove it
    1078                                         ast::ptr< ast::TypeSubstitution > env = castExpr->env;
    1079                                         expr.set_and_mutate( castExpr->arg )->env = env;
    1080                                 }
    1081                         }
    1082                 }
    10831069
    10841070                /// Establish post-resolver invariants for expressions
     
    10951081                        StripCasts_new::strip( expr );
    10961082                }
    1097 
    1098                 /// Find the expression candidate that is the unique best match for `untyped` in a `void`
    1099                 /// context.
    1100                 ast::ptr< ast::Expr > resolveInVoidContext(
    1101                         const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
    1102                 ) {
    1103                         assertf( expr, "expected a non-null expression" );
    1104                        
    1105                         // set up and resolve expression cast to void
    1106                         ast::CastExpr * untyped = new ast::CastExpr{ expr->location, expr };
    1107                         CandidateRef choice = findUnfinishedKindExpression(
    1108                                 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
    1109                        
    1110                         // a cast expression has either 0 or 1 interpretations (by language rules);
    1111                         // if 0, an exception has already been thrown, and this code will not run
    1112                         const ast::CastExpr * castExpr = choice->expr.strict_as< ast::CastExpr >();
    1113                         env = std::move( choice->env );
    1114 
    1115                         return castExpr->arg;
    1116                 }
    1117 
    1118                 /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
    1119                 /// context.
    1120                 ast::ptr< ast::Expr > findVoidExpression(
    1121                         const ast::Expr * untyped, const ast::SymbolTable & symtab
    1122                 ) {
    1123                         resetTyVarRenaming();
    1124                         ast::TypeEnvironment env;
    1125                         ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env );
    1126                         finishExpr( newExpr, env, untyped->env );
    1127                         return newExpr;
    1128                 }
    1129 
     1083               
    11301084                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
    11311085                /// lowest cost, returning the resolved version
     
    11391093                        finishExpr( choice->expr, choice->env, untyped->env );
    11401094                        return std::move( choice->expr );
    1141                 }
    1142 
    1143                 /// Resolve `untyped` to the single expression whose candidate is the best match for the
    1144                 /// given type.
    1145                 ast::ptr< ast::Expr > findSingleExpression(
    1146                         const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
    1147                 ) {
    1148                         assert( untyped && type );
    1149                         const ast::Expr * castExpr = new ast::CastExpr{ untyped->location, untyped, type };
    1150                         ast::ptr< ast::Expr > newExpr =
    1151                                 findKindExpression( castExpr, symtab, "", anyCandidate );
    1152                         removeExtraneousCast( newExpr, symtab );
    1153                         return newExpr;
    11541095                }
    11551096
     
    11771118        }
    11781119
    1179         class Resolver_new final
    1180         : public ast::WithSymbolTable, public ast::WithGuards,
    1181           public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting,
     1120        class Resolver_new final 
     1121        : public ast::WithSymbolTable, public ast::WithGuards, 
     1122          public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting, 
    11821123          public ast::WithStmtsToAdd<> {
    1183 
     1124       
    11841125                ast::ptr< ast::Type > functionReturn = nullptr;
    1185                 ast::CurrentObject currentObject = nullptr;
     1126                // ast::CurrentObject currentObject = nullptr;
    11861127                bool inEnumDecl = false;
    11871128
    1188         public:
     1129        public: 
    11891130                Resolver_new() = default;
    11901131                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
     
    11991140                void previsit( const ast::PointerType * );
    12001141
    1201                 const ast::ExprStmt * previsit( const ast::ExprStmt * );
    1202                 const ast::AsmExpr * previsit( const ast::AsmExpr * );
     1142                void previsit( const ast::ExprStmt * );
     1143                void previsit( const ast::AsmExpr * );
    12031144                void previsit( const ast::AsmStmt * );
    1204                 const ast::IfStmt * previsit( const ast::IfStmt * );
    1205                 const ast::WhileStmt * previsit( const ast::WhileStmt * );
    1206                 const ast::ForStmt * previsit( const ast::ForStmt * );
    1207                 const ast::SwitchStmt * previsit( const ast::SwitchStmt * );
    1208                 const ast::CaseStmt * previsit( const ast::CaseStmt * );
    1209                 const ast::BranchStmt * previsit( const ast::BranchStmt * );
     1145                void previsit( const ast::IfStmt * );
     1146                void previsit( const ast::WhileStmt * );
     1147                void previsit( const ast::ForStmt * );
     1148                void previsit( const ast::SwitchStmt * );
     1149                void previsit( const ast::CaseStmt * );
     1150                void previsit( const ast::BranchStmt * );
    12101151                void previsit( const ast::ReturnStmt * );
    12111152                void previsit( const ast::ThrowStmt * );
     
    12291170
    12301171        const ast::FunctionDecl * Resolver_new::postvisit( const ast::FunctionDecl * functionDecl ) {
    1231                 // default value expressions have an environment which shouldn't be there and trips up
     1172                // default value expressions have an environment which shouldn't be there and trips up 
    12321173                // later passes.
    12331174                ast::ptr< ast::FunctionDecl > ret = functionDecl;
    12341175                for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {
    12351176                        const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i];
    1236 
     1177                       
    12371178                        if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {
    12381179                                if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) {
    12391180                                        if ( init->value->env == nullptr ) continue;
    12401181                                        // clone initializer minus the initializer environment
    1241                                         ast::chain_mutate( ret )
    1242                                                 ( &ast::FunctionDecl::type )
    1243                                                         ( &ast::FunctionType::params )[i]
    1244                                                                 ( &ast::ObjectDecl::init )
    1245                                                                         ( &ast::SingleInit::value )->env = nullptr;
    1246 
    1247                                         assert( functionDecl != ret.get() || functionDecl->unique() );
    1248                                         assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env );
     1182                                        strict_dynamic_cast< ast::SingleInit * >(
     1183                                                strict_dynamic_cast< ast::ObjectDecl * >(
     1184                                                        ret.get_and_mutate()->type.get_and_mutate()->params[i].get_and_mutate()
     1185                                                )->init.get_and_mutate()
     1186                                        )->value.get_and_mutate()->env = nullptr;
    12491187                                }
    12501188                        }
     
    12541192
    12551193        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    1256                 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
    1257                 // class-variable `initContext` is changed multiple times because the LHS is analyzed
    1258                 // twice. The second analysis changes `initContext` because a function type can contain
    1259                 // object declarations in the return and parameter types. Therefore each value of
    1260                 // `initContext` is retained so the type on the first analysis is preserved and used for
    1261                 // selecting the RHS.
    1262                 GuardValue( currentObject );
    1263                 currentObject = ast::CurrentObject{ objectDecl->get_type() };
    1264                 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    1265                         // enumerator initializers should not use the enum type to initialize, since the
    1266                         // enum type is still incomplete at this point. Use `int` instead.
    1267                         currentObject = ast::CurrentObject{ new ast::BasicType{ ast::BasicType::SignedInt } };
    1268                 }
     1194                #warning unimplemented; Resolver port in progress
     1195                (void)objectDecl;
     1196                assert(false);
    12691197        }
    12701198
     
    12781206                const ast::StaticAssertDecl * assertDecl
    12791207        ) {
    1280                 return ast::mutate_field(
    1281                         assertDecl, &ast::StaticAssertDecl::cond,
    1282                         findIntegralExpression( assertDecl->cond, symtab ) );
    1283         }
    1284 
    1285         template< typename PtrType >
    1286         void handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) {
    1287                 #warning unimplemented; needs support for new Validate::SizeType global
    1288                 (void)type; (void)symtab;
    1289                 assert( false );
     1208                ast::ptr< ast::Expr > cond = findIntegralExpression( assertDecl->cond, symtab );
     1209                if ( cond == assertDecl->cond ) return assertDecl;
     1210               
     1211                ast::StaticAssertDecl * ret = mutate( assertDecl );
     1212                ret->cond = cond;
     1213                return ret;
    12901214        }
    12911215
    12921216        void Resolver_new::previsit( const ast::ArrayType * at ) {
    1293                 handlePtrType( at, symtab );
     1217                #warning unimplemented; Resolver port in progress
     1218                (void)at;
     1219                assert(false);
    12941220        }
    12951221
    12961222        void Resolver_new::previsit( const ast::PointerType * pt ) {
    1297                 handlePtrType( pt, symtab );
    1298         }
    1299 
    1300         const ast::ExprStmt * Resolver_new::previsit( const ast::ExprStmt * exprStmt ) {
    1301                 visit_children = false;
    1302                 assertf( exprStmt->expr, "ExprStmt has null expression in resolver" );
    1303                
    1304                 return ast::mutate_field(
    1305                         exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) );
    1306         }
    1307 
    1308         const ast::AsmExpr * Resolver_new::previsit( const ast::AsmExpr * asmExpr ) {
    1309                 visit_children = false;
    1310 
    1311                 asmExpr = ast::mutate_field(
    1312                         asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
    1313                
    1314                 if ( asmExpr->inout ) {
    1315                         asmExpr = ast::mutate_field(
    1316                                 asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) );
    1317                 }
    1318                
    1319                 return asmExpr;
     1223                #warning unimplemented; Resolver port in progress
     1224                (void)pt;
     1225                assert(false);
     1226        }
     1227
     1228        void Resolver_new::previsit( const ast::ExprStmt * exprStmt ) {
     1229                #warning unimplemented; Resolver port in progress
     1230                (void)exprStmt;
     1231                assert(false);
     1232        }
     1233
     1234        void Resolver_new::previsit( const ast::AsmExpr * asmExpr ) {
     1235                #warning unimplemented; Resolver port in progress
     1236                (void)asmExpr;
     1237                assert(false);
    13201238        }
    13211239
     
    13261244        }
    13271245
    1328         const ast::IfStmt * Resolver_new::previsit( const ast::IfStmt * ifStmt ) {
    1329                 return ast::mutate_field(
    1330                         ifStmt, &ast::IfStmt::cond, findIntegralExpression( ifStmt->cond, symtab ) );
    1331         }
    1332 
    1333         const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
    1334                 return ast::mutate_field(
    1335                         whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) );
    1336         }
    1337 
    1338         const ast::ForStmt * Resolver_new::previsit( const ast::ForStmt * forStmt ) {
    1339                 if ( forStmt->cond ) {
    1340                         forStmt = ast::mutate_field(
    1341                                 forStmt, &ast::ForStmt::cond, findIntegralExpression( forStmt->cond, symtab ) );
    1342                 }
    1343 
    1344                 if ( forStmt->inc ) {
    1345                         forStmt = ast::mutate_field(
    1346                                 forStmt, &ast::ForStmt::inc, findVoidExpression( forStmt->inc, symtab ) );
    1347                 }
    1348 
    1349                 return forStmt;
    1350         }
    1351 
    1352         const ast::SwitchStmt * Resolver_new::previsit( const ast::SwitchStmt * switchStmt ) {
    1353                 GuardValue( currentObject );
    1354                 switchStmt = ast::mutate_field(
    1355                         switchStmt, &ast::SwitchStmt::cond,
    1356                         findIntegralExpression( switchStmt->cond, symtab ) );
    1357                 currentObject = ast::CurrentObject{ switchStmt->cond->result };
    1358                 return switchStmt;
    1359         }
    1360 
    1361         const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    1362                 if ( caseStmt->cond ) {
    1363                         #warning unimplemented, depends on currentObject implementation
    1364                         assert(false);
    1365                 }
    1366                 return caseStmt;
    1367         }
    1368 
    1369         const ast::BranchStmt * Resolver_new::previsit( const ast::BranchStmt * branchStmt ) {
    1370                 visit_children = false;
    1371                 // must resolve the argument of a computed goto
    1372                 if ( branchStmt->kind == ast::BranchStmt::Goto && branchStmt->computedTarget ) {
    1373                         // computed goto argument is void*
    1374                         branchStmt = ast::mutate_field(
    1375                                 branchStmt, &ast::BranchStmt::computedTarget,
    1376                                 findSingleExpression(
    1377                                         branchStmt->computedTarget, new ast::PointerType{ new ast::VoidType{} },
    1378                                         symtab ) );
    1379                 }
    1380                 return branchStmt;
     1246        void Resolver_new::previsit( const ast::IfStmt * ifStmt ) {
     1247                #warning unimplemented; Resolver port in progress
     1248                (void)ifStmt;
     1249                assert(false);
     1250        }
     1251
     1252        void Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
     1253                #warning unimplemented; Resolver port in progress
     1254                (void)whileStmt;
     1255                assert(false);
     1256        }
     1257
     1258        void Resolver_new::previsit( const ast::ForStmt * forStmt ) {
     1259                #warning unimplemented; Resolver port in progress
     1260                (void)forStmt;
     1261                assert(false);
     1262        }
     1263
     1264        void Resolver_new::previsit( const ast::SwitchStmt * switchStmt ) {
     1265                #warning unimplemented; Resolver port in progress
     1266                (void)switchStmt;
     1267                assert(false);
     1268        }
     1269
     1270        void Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
     1271                #warning unimplemented; Resolver port in progress
     1272                (void)caseStmt;
     1273                assert(false);
     1274        }
     1275
     1276        void Resolver_new::previsit( const ast::BranchStmt * branchStmt ) {
     1277                #warning unimplemented; Resolver port in progress
     1278                (void)branchStmt;
     1279                assert(false);
    13811280        }
    13821281
Note: See TracChangeset for help on using the changeset viewer.