* @throws Error thrown in case of __VA_OPT__ issues */
| 1758 | * @throws Error thrown in case of __VA_OPT__ issues |
| 1759 | */ |
| 1760 | bool parseDefine(const Token *nametoken) { |
| 1761 | nameTokDef = nametoken; |
| 1762 | variadic = false; |
| 1763 | variadicOpt = false; |
| 1764 | delete optExpandValue; |
| 1765 | optExpandValue = nullptr; |
| 1766 | delete optNoExpandValue; |
| 1767 | optNoExpandValue = nullptr; |
| 1768 | if (!nameTokDef) { |
| 1769 | valueToken = endToken = nullptr; |
| 1770 | args.clear(); |
| 1771 | return false; |
| 1772 | } |
| 1773 | |
| 1774 | // function like macro.. |
| 1775 | if (functionLike()) { |
| 1776 | args.clear(); |
| 1777 | const Token *argtok = nameTokDef->next->next; |
| 1778 | while (sameline(nametoken, argtok) && argtok->op != ')') { |
| 1779 | if (argtok->str() == "..." && |
| 1780 | argtok->next && argtok->next->op == ')') { |
| 1781 | variadic = true; |
| 1782 | if (!argtok->previous->name) |
| 1783 | args.emplace_back("__VA_ARGS__"); |
| 1784 | argtok = argtok->next; // goto ')' |
| 1785 | break; |
| 1786 | } |
| 1787 | if (argtok->op != ',') |
| 1788 | args.emplace_back(argtok->str()); |
| 1789 | argtok = argtok->next; |
| 1790 | } |
| 1791 | if (!sameline(nametoken, argtok)) { |
| 1792 | endToken = argtok ? argtok->previous : argtok; |
| 1793 | valueToken = nullptr; |
| 1794 | return false; |
| 1795 | } |
| 1796 | valueToken = argtok ? argtok->next : nullptr; |
| 1797 | } else { |
| 1798 | args.clear(); |
| 1799 | valueToken = nameTokDef->next; |
| 1800 | } |
| 1801 | |
| 1802 | if (!sameline(valueToken, nameTokDef)) |
| 1803 | valueToken = nullptr; |
| 1804 | endToken = valueToken; |
| 1805 | while (sameline(endToken, nameTokDef)) { |
| 1806 | if (variadic && endToken->str() == "__VA_OPT__") |
| 1807 | variadicOpt = true; |
| 1808 | endToken = endToken->next; |
| 1809 | } |
| 1810 | |
| 1811 | if (variadicOpt) { |
| 1812 | TokenList expandValue(files); |
| 1813 | TokenList noExpandValue(files); |
| 1814 | for (const Token *tok = valueToken; tok && tok != endToken;) { |
| 1815 | if (tok->str() == "__VA_OPT__") { |
| 1816 | if (!sameline(tok, tok->next) || tok->next->op != '(') |
| 1817 | throw Error(tok->location, "In definition of '" + nameTokDef->str() + "': Missing opening parenthesis for __VA_OPT__"); |