| 6470 | } |
| 6471 | |
| 6472 | void parser:: |
| 6473 | parse_assert (token& t, type& tt) |
| 6474 | { |
| 6475 | bool neg (t.value.back () == '!'); |
| 6476 | const location al (get_location (t)); |
| 6477 | |
| 6478 | // Parse the next chunk (the condition) similar to a value on the RHS of |
| 6479 | // an assignment. We allow attributes (which will only apply to the |
| 6480 | // condition) for the same reason as in if-else (see parse_if_else()). |
| 6481 | // |
| 6482 | mode (lexer_mode::value); |
| 6483 | next_with_attributes (t, tt); |
| 6484 | |
| 6485 | const location el (get_location (t)); |
| 6486 | |
| 6487 | try |
| 6488 | { |
| 6489 | // Should evaluate to 'true' or 'false'. |
| 6490 | // |
| 6491 | bool e ( |
| 6492 | convert<bool> ( |
| 6493 | parse_value_with_attributes (t, tt, |
| 6494 | pattern_mode::expand, |
| 6495 | "expression", |
| 6496 | nullptr, |
| 6497 | true /* chunk */))); |
| 6498 | e = (neg ? !e : e); |
| 6499 | |
| 6500 | if (e) |
| 6501 | { |
| 6502 | skip_line (t, tt); |
| 6503 | |
| 6504 | if (tt != type::eos) |
| 6505 | next (t, tt); // Swallow newline. |
| 6506 | |
| 6507 | return; |
| 6508 | } |
| 6509 | } |
| 6510 | catch (const invalid_argument& e) { fail (el) << e; } |
| 6511 | |
| 6512 | // Being here means things didn't end up well. Parse the description, if |
| 6513 | // any, with expansion. Then fail. |
| 6514 | // |
| 6515 | names ns (tt != type::newline && tt != type::eos |
| 6516 | ? parse_names (t, tt, |
| 6517 | pattern_mode::ignore, |
| 6518 | "description", |
| 6519 | nullptr) |
| 6520 | : names ()); |
| 6521 | |
| 6522 | diag_record dr (fail (al)); |
| 6523 | |
| 6524 | if (ns.empty ()) |
| 6525 | dr << "assertion failed"; |
| 6526 | else |
| 6527 | dr << ns; |
| 6528 | } |
| 6529 |
nothing calls this directly
no test coverage detected