Evaluate sizeof(type) * @throws std::runtime_error thrown on missing arguments or invalid expression */
| 2601 | * @throws std::runtime_error thrown on missing arguments or invalid expression |
| 2602 | */ |
| 2603 | static void simplifySizeof(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType) |
| 2604 | { |
| 2605 | for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { |
| 2606 | if (tok->str() != "sizeof") |
| 2607 | continue; |
| 2608 | const simplecpp::Token *tok1 = tok->next; |
| 2609 | if (!tok1) { |
| 2610 | throw std::runtime_error("missing sizeof argument"); |
| 2611 | } |
| 2612 | const simplecpp::Token *tok2 = tok1->next; |
| 2613 | if (!tok2) { |
| 2614 | throw std::runtime_error("missing sizeof argument"); |
| 2615 | } |
| 2616 | if (tok1->op == '(') { |
| 2617 | tok1 = tok1->next; |
| 2618 | while (tok2->op != ')') { |
| 2619 | tok2 = tok2->next; |
| 2620 | if (!tok2) { |
| 2621 | throw std::runtime_error("invalid sizeof expression"); |
| 2622 | } |
| 2623 | } |
| 2624 | } |
| 2625 | |
| 2626 | std::string type; |
| 2627 | for (const simplecpp::Token *typeToken = tok1; typeToken != tok2; typeToken = typeToken->next) { |
| 2628 | if ((typeToken->str() == "unsigned" || typeToken->str() == "signed") && typeToken->next->name) |
| 2629 | continue; |
| 2630 | if (typeToken->str() == "*" && type.find('*') != std::string::npos) |
| 2631 | continue; |
| 2632 | if (!type.empty()) |
| 2633 | type += ' '; |
| 2634 | type += typeToken->str(); |
| 2635 | } |
| 2636 | |
| 2637 | const std::map<std::string, std::size_t>::const_iterator it = sizeOfType.find(type); |
| 2638 | if (it != sizeOfType.end()) |
| 2639 | tok->setstr(toString(it->second)); |
| 2640 | else |
| 2641 | continue; |
| 2642 | |
| 2643 | tok2 = tok2->next; |
| 2644 | while (tok->next != tok2) |
| 2645 | expr.deleteToken(tok->next); |
| 2646 | } |
| 2647 | } |
| 2648 | |
| 2649 | static bool isCpp17OrLater(const simplecpp::DUI &dui) |
| 2650 | { |