[demangler] Support for <template-param>s in generic lambdas.
authorErik Pilkington <erik.pilkington@gmail.com>
Fri, 16 Mar 2018 03:06:30 +0000 (03:06 +0000)
committerErik Pilkington <erik.pilkington@gmail.com>
Fri, 16 Mar 2018 03:06:30 +0000 (03:06 +0000)
These <template-param>s refer to "artifical" <template-arg>s that don't appear
in the mangled name, so we just print them as "auto".

llvm-svn: 327690

libcxxabi/src/cxa_demangle.cpp
libcxxabi/test/test_demangle.pass.cpp

index cbf0498..d642e67 100644 (file)
@@ -2013,6 +2013,7 @@ struct Db {
   bool TagTemplates = true;
   bool FixForwardReferences = false;
   bool TryToParseTemplateArgs = true;
+  bool ParsingLambdaParams = false;
 
   BumpPointerAllocator ASTAllocator;
 
@@ -2270,6 +2271,7 @@ Node *Db::parseUnnamedTypeName(NameState *) {
   }
   if (consumeIf("Ul")) {
     NodeArray Params;
+    SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true);
     if (!consumeIf("vE")) {
       size_t ParamsBegin = Names.size();
       do {
@@ -4658,20 +4660,20 @@ Node *Db::parseTemplateParam() {
   if (!consumeIf('T'))
     return nullptr;
 
-  if (consumeIf('_')) {
-    if (TemplateParams.empty()) {
-      FixForwardReferences = true;
-      return make<NameType>("FORWARD_REFERENCE");
-    }
-    return TemplateParams[0];
+  size_t Index = 0;
+  if (!consumeIf('_')) {
+    if (parsePositiveInteger(&Index))
+      return nullptr;
+    ++Index;
+    if (!consumeIf('_'))
+      return nullptr;
   }
 
-  size_t Index;
-  if (parsePositiveInteger(&Index))
-    return nullptr;
-  ++Index;
-  if (!consumeIf('_'))
-    return nullptr;
+  // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list
+  // are mangled as the corresponding artificial template type parameter.
+  if (ParsingLambdaParams)
+    return make<NameType>("auto");
+
   if (Index >= TemplateParams.size()) {
     FixForwardReferences = true;
     return make<NameType>("FORWARD_REFERENCE");
index b155559..e7fb0cf 100644 (file)
@@ -29604,7 +29604,7 @@ const char* cases[][2] =
     {"PFvRmOE", "void (*)(unsigned long&) &&"},
     {"_ZTW1x", "thread-local wrapper routine for x"},
     {"_ZTHN3fooE", "thread-local initialization routine for foo"},
-    {"_Z4algoIJiiiEEvZ1gEUlDpT_E_", "void algo<int, int, int>(g::'lambda'(int, int, int))"},
+
     // attribute abi_tag
     {"_Z1fB3foov", "f[abi:foo]()"},
     {"_Z1fB3fooB3barv", "f[abi:foo][abi:bar]()"},
@@ -29725,6 +29725,8 @@ const char* cases[][2] =
 
     {"_ZGRDC1x1yE_", "reference temporary for [x, y]"},
     {"_ZGR1bIvE2_", "reference temporary for b<void>"},
+
+    {"_ZZ18test_assign_throwsI20small_throws_on_copyLb0EEvvENKUlRNSt3__13anyEOT_E_clIRS0_EEDaS3_S5_", "auto void test_assign_throws<small_throws_on_copy, false>()::'lambda'(std::__1::any&, auto&&)::operator()<small_throws_on_copy&>(std::__1::any&, auto&&) const"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);