diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/Asyncify.cpp | 3 | ||||
-rw-r--r-- | src/support/string.h | 42 |
2 files changed, 45 insertions, 0 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index 361976fc3..379452d42 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -1043,6 +1043,9 @@ struct Asyncify : public Pass { String::Split whitelist( runner->options.getArgumentOrDefault("asyncify-whitelist", ""), ","); + blacklist = handleBracketingOperators(blacklist); + whitelist = handleBracketingOperators(whitelist); + // The lists contain human-readable strings. Turn them into the internal // escaped names for later comparisons auto processList = [module](String::Split& list, const std::string& which) { diff --git a/src/support/string.h b/src/support/string.h index c8a8cb445..72bbdb509 100644 --- a/src/support/string.h +++ b/src/support/string.h @@ -31,6 +31,8 @@ namespace String { // Creates a vector of the split parts of a string, by a delimiter. class Split : public std::vector<std::string> { public: + Split() = default; + Split(const std::string& input, const std::string& delim) { size_t lastEnd = 0; while (lastEnd < input.size()) { @@ -44,6 +46,46 @@ public: } }; +// Handles bracketing in a list initially split by ",", but the list may +// contain nested ","s. For example, +// void foo(int, double) +// must be kept together because of the "(". Likewise, "{", "<", "[" are +// handled. +inline String::Split handleBracketingOperators(String::Split split) { + String::Split ret; + std::string last; + int nesting = 0; + auto handlePart = [&](std::string part) { + if (part.empty()) { + return; + } + for (const char c : part) { + if (c == '(' || c == '<' || c == '[' || c == '{') { + nesting++; + } else if (c == ')' || c == '>' || c == ']' || c == '}') { + nesting--; + } + } + if (last.empty()) { + last = part; + } else { + last += ',' + part; + } + if (nesting == 0) { + ret.push_back(last); + last.clear(); + } + }; + for (auto& part : split) { + handlePart(part); + } + handlePart(""); + if (nesting != 0) { + Fatal() << "Asyncify: failed to parse lists"; + } + return ret; +} + // Does a simple wildcard match between a pattern and a value. Currently // supports a '*' at the end of the pattern. inline bool wildcardMatch(const std::string& pattern, |