Changeset c6a1e8a for src/ResolvExpr/Resolver.cc
- Timestamp:
- Jun 5, 2019, 8:36:48 PM (5 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r67130fe rc6a1e8a 21 21 #include "Alternative.h" // for Alternative, AltList 22 22 #include "AlternativeFinder.h" // for AlternativeFinder, resolveIn... 23 #include "Candidate.hpp" 24 #include "CandidateFinder.hpp" 23 25 #include "CurrentObject.h" // for CurrentObject 24 26 #include "RenameVars.h" // for RenameVars, global_renamer … … 27 29 #include "typeops.h" // for extractResultType 28 30 #include "Unify.h" // for unify 31 #include "AST/Chain.hpp" 32 #include "AST/Decl.hpp" 33 #include "AST/Init.hpp" 29 34 #include "AST/Pass.hpp" 35 #include "AST/Print.hpp" 30 36 #include "AST/SymbolTable.hpp" 31 37 #include "Common/PassVisitor.h" // for PassVisitor … … 113 119 114 120 namespace { 115 struct DeleteFinder : public WithShortCircuiting {121 struct DeleteFinder_old : public WithShortCircuiting { 116 122 DeletedExpr * delExpr = nullptr; 117 123 void previsit( DeletedExpr * expr ) { … … 127 133 128 134 DeletedExpr * findDeletedExpr( Expression * expr ) { 129 PassVisitor<DeleteFinder > finder;135 PassVisitor<DeleteFinder_old> finder; 130 136 expr->accept( finder ); 131 137 return finder.pass.delExpr; … … 133 139 134 140 namespace { 135 struct StripCasts {141 struct StripCasts_old { 136 142 Expression * postmutate( CastExpr * castExpr ) { 137 143 if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) { … … 146 152 147 153 static void strip( Expression *& expr ) { 148 PassVisitor<StripCasts > stripper;154 PassVisitor<StripCasts_old> stripper; 149 155 expr = expr->acceptMutator( stripper ); 150 156 } … … 154 160 expr->env = oldenv ? oldenv->clone() : new TypeSubstitution; 155 161 env.makeSubstitution( *expr->env ); 156 StripCasts ::strip( expr ); // remove unnecessary casts that may be buried in an expression162 StripCasts_old::strip( expr ); // remove unnecessary casts that may be buried in an expression 157 163 } 158 164 … … 405 411 406 412 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 411 417 // retained, so the type on the first analysis is preserved and used for selecting the RHS. 412 418 GuardValue( currentObject ); … … 445 451 446 452 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 448 454 // later passes. 449 455 // xxx - it might be necessary to somehow keep the information from this environment, but I … … 937 943 /////////////////////////////////////////////////////////////////////////// 938 944 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: 944 1131 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 * ); 973 1160 }; 974 1161 … … 978 1165 } 979 1166 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 ) { 994 1198 #warning unimplemented; Resolver port in progress 995 1199 (void)objectDecl; … … 997 1201 } 998 1202 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 ) { 1012 1221 #warning unimplemented; Resolver port in progress 1013 1222 (void)at; … … 1015 1224 } 1016 1225 1017 void previsit(ast::PointerType * pt ) {1226 void Resolver_new::previsit( const ast::PointerType * pt ) { 1018 1227 #warning unimplemented; Resolver port in progress 1019 1228 (void)pt; … … 1021 1230 } 1022 1231 1023 void previsit(ast::ExprStmt * exprStmt ) {1232 void Resolver_new::previsit( const ast::ExprStmt * exprStmt ) { 1024 1233 #warning unimplemented; Resolver port in progress 1025 1234 (void)exprStmt; … … 1027 1236 } 1028 1237 1029 void previsit(ast::AsmExpr * asmExpr ) {1238 void Resolver_new::previsit( const ast::AsmExpr * asmExpr ) { 1030 1239 #warning unimplemented; Resolver port in progress 1031 1240 (void)asmExpr; … … 1033 1242 } 1034 1243 1035 void previsit(ast::AsmStmt * asmStmt ) {1244 void Resolver_new::previsit( const ast::AsmStmt * asmStmt ) { 1036 1245 #warning unimplemented; Resolver port in progress 1037 1246 (void)asmStmt; … … 1039 1248 } 1040 1249 1041 void previsit(ast::IfStmt * ifStmt ) {1250 void Resolver_new::previsit( const ast::IfStmt * ifStmt ) { 1042 1251 #warning unimplemented; Resolver port in progress 1043 1252 (void)ifStmt; … … 1045 1254 } 1046 1255 1047 void previsit(ast::WhileStmt * whileStmt ) {1256 void Resolver_new::previsit( const ast::WhileStmt * whileStmt ) { 1048 1257 #warning unimplemented; Resolver port in progress 1049 1258 (void)whileStmt; … … 1051 1260 } 1052 1261 1053 void previsit(ast::ForStmt * forStmt ) {1262 void Resolver_new::previsit( const ast::ForStmt * forStmt ) { 1054 1263 #warning unimplemented; Resolver port in progress 1055 1264 (void)forStmt; … … 1057 1266 } 1058 1267 1059 void previsit(ast::SwitchStmt * switchStmt ) {1268 void Resolver_new::previsit( const ast::SwitchStmt * switchStmt ) { 1060 1269 #warning unimplemented; Resolver port in progress 1061 1270 (void)switchStmt; … … 1063 1272 } 1064 1273 1065 void previsit(ast::CaseStmt * caseStmt ) {1274 void Resolver_new::previsit( const ast::CaseStmt * caseStmt ) { 1066 1275 #warning unimplemented; Resolver port in progress 1067 1276 (void)caseStmt; … … 1069 1278 } 1070 1279 1071 void previsit(ast::BranchStmt * branchStmt ) {1280 void Resolver_new::previsit( const ast::BranchStmt * branchStmt ) { 1072 1281 #warning unimplemented; Resolver port in progress 1073 1282 (void)branchStmt; … … 1075 1284 } 1076 1285 1077 void previsit(ast::ReturnStmt * returnStmt ) {1286 void Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) { 1078 1287 #warning unimplemented; Resolver port in progress 1079 1288 (void)returnStmt; … … 1081 1290 } 1082 1291 1083 void previsit(ast::ThrowStmt * throwStmt ) {1292 void Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) { 1084 1293 #warning unimplemented; Resolver port in progress 1085 1294 (void)throwStmt; … … 1087 1296 } 1088 1297 1089 void previsit(ast::CatchStmt * catchStmt ) {1298 void Resolver_new::previsit( const ast::CatchStmt * catchStmt ) { 1090 1299 #warning unimplemented; Resolver port in progress 1091 1300 (void)catchStmt; … … 1093 1302 } 1094 1303 1095 void previsit(ast::WaitForStmt * stmt ) {1304 void Resolver_new::previsit( const ast::WaitForStmt * stmt ) { 1096 1305 #warning unimplemented; Resolver port in progress 1097 1306 (void)stmt; … … 1099 1308 } 1100 1309 1101 void previsit(ast::SingleInit * singleInit ) {1310 void Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1102 1311 #warning unimplemented; Resolver port in progress 1103 1312 (void)singleInit; … … 1105 1314 } 1106 1315 1107 void previsit(ast::ListInit * listInit ) {1316 void Resolver_new::previsit( const ast::ListInit * listInit ) { 1108 1317 #warning unimplemented; Resolver port in progress 1109 1318 (void)listInit; … … 1111 1320 } 1112 1321 1113 void previsit(ast::ConstructorInit * ctorInit ) {1322 void Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) { 1114 1323 #warning unimplemented; Resolver port in progress 1115 1324 (void)ctorInit;
Note: See TracChangeset
for help on using the changeset viewer.