summaryrefslogtreecommitdiff
path: root/lib/Demangle
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2017-05-27 01:48:34 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2017-05-27 01:48:34 +0000
commitbf14f47c785867727f58f24bc9dcb8e4052d4b54 (patch)
tree3044218261fbba4fce53195eff49948178b80995 /lib/Demangle
parent6a19144d2b978acdb0290b9592aa050a5dcbf73f (diff)
[Demangler] copy changes made in libcxxabi's r303718 to ItaniumDemangle
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304053 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Demangle')
-rw-r--r--lib/Demangle/ItaniumDemangle.cpp49
1 files changed, 28 insertions, 21 deletions
diff --git a/lib/Demangle/ItaniumDemangle.cpp b/lib/Demangle/ItaniumDemangle.cpp
index d6e76e49c0f..03d11a703ab 100644
--- a/lib/Demangle/ItaniumDemangle.cpp
+++ b/lib/Demangle/ItaniumDemangle.cpp
@@ -2612,39 +2612,45 @@ static const char *parse_unnamed_type_name(const char *first, const char *last,
first = t0 + 1;
} break;
case 'l': {
+ size_t lambda_pos = db.names.size();
db.names.push_back(std::string("'lambda'("));
const char *t0 = first + 2;
if (first[2] == 'v') {
db.names.back().first += ')';
++t0;
} else {
- const char *t1 = parse_type(t0, last, db);
- if (t1 == t0) {
- if (!db.names.empty())
- db.names.pop_back();
- return first;
- }
- if (db.names.size() < 2)
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first.append(tmp);
- t0 = t1;
+ bool is_first_it = true;
while (true) {
- t1 = parse_type(t0, last, db);
+ long k0 = static_cast<long>(db.names.size());
+ const char *t1 = parse_type(t0, last, db);
+ long k1 = static_cast<long>(db.names.size());
if (t1 == t0)
break;
- if (db.names.size() < 2)
+ if (k0 >= k1)
return first;
- tmp = db.names.back().move_full();
- db.names.pop_back();
- if (!tmp.empty()) {
- db.names.back().first.append(", ");
- db.names.back().first.append(tmp);
- }
+ // If the call to parse_type above found a pack expansion
+ // substitution, then multiple names could have been
+ // inserted into the name table. Walk through the names,
+ // appending each onto the lambda's parameter list.
+ std::for_each(db.names.begin() + k0, db.names.begin() + k1,
+ [&](typename C::sub_type::value_type &pair) {
+ if (pair.empty())
+ return;
+ auto &lambda = db.names[lambda_pos].first;
+ if (!is_first_it)
+ lambda.append(", ");
+ is_first_it = false;
+ lambda.append(pair.move_full());
+ });
+ db.names.erase(db.names.begin() + k0, db.names.end());
t0 = t1;
}
- if (db.names.empty())
+ if (is_first_it) {
+ if (!db.names.empty())
+ db.names.pop_back();
+ return first;
+ }
+ if (db.names.empty() || db.names.size() - 1 != lambda_pos)
return first;
db.names.back().first.append(")");
}
@@ -4231,6 +4237,7 @@ template <class StrT> struct string_pair {
template <size_t N> string_pair(const char (&s)[N]) : first(s, N - 1) {}
size_t size() const { return first.size() + second.size(); }
+ bool empty() const { return first.empty() && second.empty(); }
StrT full() const { return first + second; }
StrT move_full() { return std::move(first) + std::move(second); }
};