[demangler] Support for structured bindings.
git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@327226 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/src/cxa_demangle.cpp b/src/cxa_demangle.cpp
index ffd887a..5c313cb 100644
--- a/src/cxa_demangle.cpp
+++ b/src/cxa_demangle.cpp
@@ -197,6 +197,7 @@
KDtorName,
KUnnamedTypeName,
KClosureTypeName,
+ KStructuredBindingName,
KExpr,
KBracedExpr,
KBracedRangeExpr,
@@ -1337,6 +1338,19 @@
}
};
+class StructuredBindingName : public Node {
+ NodeArray Bindings;
+public:
+ StructuredBindingName(NodeArray Bindings_)
+ : Node(KStructuredBindingName), Bindings(Bindings_) {}
+
+ void printLeft(OutputStream &S) const override {
+ S += "'structured-binding'[";
+ Bindings.printWithComma(S);
+ S += ']';
+ }
+};
+
// -- Expression Nodes --
struct Expr : public Node {
@@ -2217,7 +2231,7 @@
// ::= <ctor-dtor-name>
// ::= <source-name>
// ::= <unnamed-type-name>
-// FIXME: ::= DC <source-name>+ E # structured binding declaration
+// ::= DC <source-name>+ E # structured binding declaration
Node *Db::parseUnqualifiedName(NameState *State) {
// <ctor-dtor-name>s are special-cased in parseNestedName().
Node *Result;
@@ -2225,7 +2239,16 @@
Result = parseUnnamedTypeName(State);
else if (look() >= '1' && look() <= '9')
Result = parseSourceName(State);
- else
+ else if (consumeIf("DC")) {
+ size_t BindingsBegin = Names.size();
+ do {
+ Node *Binding = parseSourceName(State);
+ if (Binding == nullptr)
+ return nullptr;
+ Names.push_back(Binding);
+ } while (!consumeIf('E'));
+ Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
+ } else
Result = parseOperatorName(State);
if (Result != nullptr)
Result = parseAbiTags(Result);
@@ -2689,7 +2712,7 @@
}
// Parse an <unqualified-name> thats actually a <ctor-dtor-name>.
- if (look() == 'C' || look() == 'D') {
+ if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
if (SoFar == nullptr)
return nullptr;
Node *CtorDtor = parseCtorDtorName(SoFar, State);
diff --git a/test/test_demangle.pass.cpp b/test/test_demangle.pass.cpp
index ef2821c..8e97a7f 100644
--- a/test/test_demangle.pass.cpp
+++ b/test/test_demangle.pass.cpp
@@ -29718,6 +29718,10 @@
{"_Z1fSsB1XS_", "f(std::string[abi:X], std::string[abi:X])"},
{"___Z10blocksNRVOv_block_invoke", "invocation function for block in blocksNRVO()"},
+
+ // Structured bindings:
+ {"_ZDC2a12a2E", "'structured-binding'[a1, a2]"},
+ {"_ZN2NSDC1x1yEE", "NS::'structured-binding'[x, y]"},
};
const unsigned N = sizeof(cases) / sizeof(cases[0]);
@@ -29848,7 +29852,6 @@
const char *xfail_cases[] = {
"_Z1fUa9enable_ifIXLi1EEEv", // enable_if attribute
- "_ZDC2a12a2E", // decomposition decl
"_ZW6FooBarE2f3v", // C++ modules TS
// FIXME: Why does clang generate the "cp" expr?