- Timestamp:
- Apr 23, 2019, 10:26:14 AM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- ffe2fad
- Parents:
- deca0f5 (diff), 8f194ee (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. - Location:
- src
- Files:
-
- 9 edited
-
Parser/ParseNode.h (modified) (2 diffs)
-
Parser/parser.yy (modified) (7 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
ResolvExpr/ResolveAssertions.cc (modified) (6 diffs)
-
ResolvExpr/ResolveAssertions.h (modified) (1 diff)
-
ResolvExpr/TypeEnvironment.cc (modified) (4 diffs)
-
ResolvExpr/TypeEnvironment.h (modified) (1 diff)
-
ResolvExpr/Unify.cc (modified) (1 diff)
-
SynTree/Declaration.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/ParseNode.h
rdeca0f5 r8c3a0336 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 13 17:36:49 201913 // Update Count : 8 6712 // Last Modified On : Mon Apr 15 14:22:39 2019 13 // Update Count : 874 14 14 // 15 15 … … 132 132 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {} 133 133 134 Expression *get_expr() const { return expr.get(); }135 134 template<typename T> 136 135 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); } 137 136 138 137 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); } 138 139 std::unique_ptr<Expression> expr; // public because of lifetime implications 139 140 private: 140 141 bool extension = false; 141 std::unique_ptr<Expression> expr;142 142 }; // ExpressionNode 143 143 -
src/Parser/parser.yy
rdeca0f5 r8c3a0336 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 15 14:25:43201913 // Update Count : 42 4812 // Last Modified On : Mon Apr 15 15:02:56 2019 13 // Update Count : 4290 14 14 // 15 15 … … 185 185 186 186 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 187 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type-> get_expr());187 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get()); 188 188 if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) { 189 189 type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); … … 198 198 199 199 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 200 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index-> get_expr()) ) {200 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) { 201 201 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 202 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index-> get_expr()) ) {202 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) { 203 203 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) { 204 204 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); … … 334 334 %type<en> subrange 335 335 %type<decl> asm_name_opt 336 %type<en> asm_operands_opt asm_operands_listasm_operand336 %type<en> asm_operands_opt asm_operands_list asm_operand 337 337 %type<label> label_list 338 338 %type<en> asm_clobbers_list_opt 339 339 %type<flag> asm_volatile_opt 340 340 %type<en> handler_predicate_opt 341 %type<genexpr> generic_association generic_assoc_list341 %type<genexpr> generic_association generic_assoc_list 342 342 343 343 // statements … … 1164 1164 for_control_expression 1165 1165 | for_control_expression_list ':' for_control_expression 1166 { $$ = $3; } 1166 // ForCtrl + ForCtrl: 1167 // init + init => multiple declaration statements that are hoisted 1168 // condition + condition => (expression) && (expression) 1169 // change + change => (expression), (expression) 1170 { 1171 $1->init->set_last( $3->init ); 1172 if ( $1->condition ) { 1173 if ( $3->condition ) { 1174 $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) ); 1175 } // if 1176 } else $1->condition = $3->condition; 1177 if ( $1->change ) { 1178 if ( $3->change ) { 1179 $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) ); 1180 } // if 1181 } else $1->change = $3->change; 1182 $$ = $1; 1183 } 1167 1184 ; 1168 1185 … … 1174 1191 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1175 1192 { $$ = new ForCtrl( $1, $2, $4 ); } 1193 1176 1194 | comma_expression // CFA 1177 1195 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), … … 1188 1206 | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA 1189 1207 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); } 1208 1209 // There is a S/R conflicit if ~ and -~ are factored out. 1210 | comma_expression ';' comma_expression '~' '@' // CFA 1211 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1212 | comma_expression ';' comma_expression ErangeDown '@' // CFA 1213 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1190 1214 | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA 1191 1215 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); } -
src/ResolvExpr/AlternativeFinder.cc
rdeca0f5 r8c3a0336 258 258 // - necessary pre-requisite to pruning 259 259 AltList candidates; 260 std::list<std::string> errors; 260 261 for ( unsigned i = 0; i < alternatives.size(); ++i ) { 261 resolveAssertions( alternatives[i], indexer, candidates );262 resolveAssertions( alternatives[i], indexer, candidates, errors ); 262 263 } 263 264 // fail early if none such 264 265 if ( mode.failFast && candidates.empty() ) { 265 266 std::ostringstream stream; 266 stream << "No resolvable alternatives for expression " << expr << "\n" 267 << "Alternatives with failing assertions are:\n"; 268 printAlts( alternatives, stream, 1 ); 267 stream << "No alternatives with satisfiable assertions for " << expr << "\n"; 268 // << "Alternatives with failing assertions are:\n"; 269 // printAlts( alternatives, stream, 1 ); 270 for ( const auto& err : errors ) { 271 stream << err; 272 } 269 273 SemanticError( expr->location, stream.str() ); 270 274 } -
src/ResolvExpr/ResolveAssertions.cc
rdeca0f5 r8c3a0336 20 20 #include <list> // for list 21 21 #include <memory> // for unique_ptr 22 #include <string> 22 #include <sstream> // for ostringstream 23 #include <string> // for string 23 24 #include <unordered_map> // for unordered_map, unordered_multimap 24 25 #include <utility> // for move … … 27 28 #include "Alternative.h" // for Alternative, AssertionItem, AssertionList 28 29 #include "Common/FilterCombos.h" // for filterCombos 30 #include "Common/Indenter.h" // for Indenter 29 31 #include "Common/utility.h" // for sort_mins 30 32 #include "ResolvExpr/RenameVars.h" // for renameTyVars … … 97 99 return { item, item.matches[i] }; 98 100 } 101 102 const DeclarationWithType* get_decl() const { return cache->at(key).deferIds[0].decl; } 99 103 100 104 // sortable by key … … 364 368 static const int recursionLimit = /* 10 */ 4; 365 369 366 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out ) {370 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors ) { 367 371 // finish early if no assertions to resolve 368 372 if ( alt.need.empty() ) { … … 385 389 for ( auto& assn : resn.need ) { 386 390 // fail early if any assertion is not resolvable 387 if ( ! resolveAssertion( assn, resn, assnCache ) ) goto nextResn; 391 if ( ! resolveAssertion( assn, resn, assnCache ) ) { 392 Indenter tabs{ Indenter::tabsize, 3 }; 393 std::ostringstream ss; 394 ss << tabs << "Unsatisfiable alternative:\n"; 395 resn.alt.print( ss, ++tabs ); 396 ss << --tabs << "Could not satisfy assertion:\n"; 397 assn.decl->print( ss, ++tabs ); 398 399 errors.emplace_back( ss.str() ); 400 goto nextResn; 401 } 388 402 } 389 403 … … 404 418 resn.deferred, 405 419 CandidateEnvMerger{ resn.alt.env, resn.alt.openVars, resn.indexer } ); 420 // fail early if no mutually-compatible assertion satisfaction 421 if ( compatible.empty() ) { 422 Indenter tabs{ Indenter::tabsize, 3 }; 423 std::ostringstream ss; 424 ss << tabs << "Unsatisfiable alternative:\n"; 425 resn.alt.print( ss, ++tabs ); 426 ss << --tabs << "No mutually-compatible satisfaction for assertions:\n"; 427 ++tabs; 428 for ( const auto& d : resn.deferred ) { 429 d.get_decl()->print( ss, tabs ); 430 } 431 432 errors.emplace_back( ss.str() ); 433 goto nextResn; 434 } 406 435 // sort by cost 407 436 CandidateCost coster{ resn.indexer }; -
src/ResolvExpr/ResolveAssertions.h
rdeca0f5 r8c3a0336 24 24 namespace ResolvExpr { 25 25 /// Recursively resolves all assertions provided in an alternative; returns true iff succeeds 26 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out );26 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors ); 27 27 } // namespace ResolvExpr 28 28 -
src/ResolvExpr/TypeEnvironment.cc
rdeca0f5 r8c3a0336 386 386 } 387 387 388 bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 388 bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, 389 TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, 390 const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 389 391 390 392 auto class1 = internal_lookup( var1->get_name() ); … … 428 430 class1->set_type( common ); 429 431 } 432 class1->data.isComplete |= data.isComplete; 430 433 env.erase( class2 ); 431 434 } else return false; … … 435 438 class1->vars.insert( class2->vars.begin(), class2->vars.end() ); 436 439 class1->allowWidening = widen1; 440 class1->data.isComplete |= data.isComplete; 437 441 env.erase( class2 ); 438 442 } else { 439 443 class2->vars.insert( class1->vars.begin(), class1->vars.end() ); 440 444 class2->allowWidening = widen2; 445 class2->data.isComplete |= data.isComplete; 441 446 env.erase( class1 ); 442 447 } // if … … 445 450 class1->vars.insert( var2->get_name() ); 446 451 class1->allowWidening = widen1; 452 class1->data.isComplete |= data.isComplete; 447 453 } else if ( class2 != env.end() ) { 448 454 // var1 unbound, add to class2 449 455 class2->vars.insert( var1->get_name() ); 450 456 class2->allowWidening = widen2; 457 class2->data.isComplete |= data.isComplete; 451 458 } else { 452 459 // neither var bound, create new class -
src/ResolvExpr/TypeEnvironment.h
rdeca0f5 r8c3a0336 139 139 /// Binds the type classes represented by `var1` and `var2` together; will add 140 140 /// one or both classes if needed. Returns false on failure. 141 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data& data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );141 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 142 142 143 143 /// Disallows widening for all bindings in the environment -
src/ResolvExpr/Unify.cc
rdeca0f5 r8c3a0336 172 172 bool isopen2 = var2 && ( entry2 != openVars.end() ); 173 173 174 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 175 result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 174 if ( isopen1 && isopen2 ) { 175 if ( entry1->second.kind != entry2->second.kind ) { 176 result = false; 177 } else { 178 result = env.bindVarToVar( 179 var1, var2, TypeDecl::Data{ entry1->second, entry2->second }, needAssertions, 180 haveAssertions, openVars, widenMode, indexer ); 181 } 176 182 } else if ( isopen1 ) { 177 183 result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); -
src/SynTree/Declaration.h
rdeca0f5 r8c3a0336 211 211 TypeDecl::Kind kind; 212 212 bool isComplete; 213 213 214 Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {} 214 215 Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {} 215 216 Data( Kind kind, bool isComplete ) : kind( kind ), isComplete( isComplete ) {} 217 Data( const Data& d1, const Data& d2 ) 218 : kind( d1.kind ), isComplete ( d1.isComplete || d2.isComplete ) {} 219 216 220 bool operator==(const Data & other) const { return kind == other.kind && isComplete == other.isComplete; } 217 221 bool operator!=(const Data & other) const { return !(*this == other);}
Note:
See TracChangeset
for help on using the changeset viewer.