summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/Asyncify.cpp3
-rw-r--r--src/support/string.h42
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,