riccibruno updated this revision to Diff 282296.
riccibruno added a comment.

Make the unit tests in `NamedDeclPrinterTest.cpp` more robust.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85033/new/

https://reviews.llvm.org/D85033

Files:
  clang/lib/AST/Decl.cpp
  clang/test/AST/ast-dump-record-definition-data-json.cpp
  clang/test/Analysis/explain-svals.cpp
  clang/test/Index/annotate-tokens.cpp
  clang/test/Index/linkage.c
  clang/test/Index/load-decls.c
  clang/test/Index/load-namespaces.cpp
  clang/test/Index/preamble.c
  clang/test/Index/print-type.c
  clang/test/Index/print-type.cpp
  clang/test/Index/recursive-cxx-member-calls.cpp
  clang/test/Index/usrs.m
  clang/test/Modules/module-private.cpp
  clang/test/SemaCXX/lambda-expressions.cpp
  clang/test/SemaCXX/warn-large-by-value-copy.cpp
  clang/test/Tooling/clang-diff-ast.cpp
  clang/unittests/AST/ASTTraverserTest.cpp
  clang/unittests/AST/NamedDeclPrinterTest.cpp

Index: clang/unittests/AST/NamedDeclPrinterTest.cpp
===================================================================
--- clang/unittests/AST/NamedDeclPrinterTest.cpp
+++ clang/unittests/AST/NamedDeclPrinterTest.cpp
@@ -6,7 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file contains tests for NamedDecl::printQualifiedName().
+// This file contains tests for NamedDecl::printName()
+// and NamedDecl::printQualifiedName().
 //
 // These tests have a coding convention:
 // * declaration to be printed is named 'A' unless it should have some special
@@ -93,11 +94,10 @@
   return ::testing::AssertionSuccess();
 }
 
-::testing::AssertionResult
-PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
-                        bool SuppressUnwrittenScope,
-                        const DeclarationMatcher &NodeMatch,
-                        StringRef ExpectedPrinted, StringRef FileName) {
+::testing::AssertionResult PrintedQualifiedNamedDeclMatches(
+    StringRef Code, const std::vector<std::string> &Args,
+    bool SuppressUnwrittenScope, const DeclarationMatcher &NodeMatch,
+    StringRef ExpectedPrinted, StringRef FileName) {
   return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, FileName,
                             [=](llvm::raw_ostream &Out, const NamedDecl *ND) {
                               auto Policy =
@@ -108,34 +108,43 @@
                             });
 }
 
+::testing::AssertionResult PrintedUnqualifiedNamedDeclMatches(
+    StringRef Code, const std::vector<std::string> &Args,
+    const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted,
+    StringRef FileName) {
+  return PrintedDeclMatches(
+      Code, Args, NodeMatch, ExpectedPrinted, FileName,
+      [=](llvm::raw_ostream &Out, const NamedDecl *ND) { ND->printName(Out); });
+}
+
 ::testing::AssertionResult
-PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,
-                             StringRef ExpectedPrinted) {
+PrintedQualifiedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,
+                                      StringRef ExpectedPrinted) {
   std::vector<std::string> Args(1, "-std=c++98");
-  return PrintedNamedDeclMatches(Code, Args,
-                                 /*SuppressUnwrittenScope*/ false,
-                                 namedDecl(hasName(DeclName)).bind("id"),
-                                 ExpectedPrinted, "input.cc");
+  return PrintedQualifiedNamedDeclMatches(
+      Code, Args,
+      /*SuppressUnwrittenScope*/ false, namedDecl(hasName(DeclName)).bind("id"),
+      ExpectedPrinted, "input.cc");
 }
 
 ::testing::AssertionResult
-PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,
-                                    StringRef ExpectedPrinted) {
+PrintedWrittenQualifiedNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,
+                                             StringRef ExpectedPrinted) {
   std::vector<std::string> Args(1, "-std=c++11");
-  return PrintedNamedDeclMatches(Code, Args,
-                                 /*SuppressUnwrittenScope*/ true,
-                                 namedDecl(hasName(DeclName)).bind("id"),
-                                 ExpectedPrinted, "input.cc");
+  return PrintedQualifiedNamedDeclMatches(
+      Code, Args,
+      /*SuppressUnwrittenScope*/ true, namedDecl(hasName(DeclName)).bind("id"),
+      ExpectedPrinted, "input.cc");
 }
 
-::testing::AssertionResult
-PrintedWrittenPropertyDeclObjCMatches(StringRef Code, StringRef DeclName,
-                                   StringRef ExpectedPrinted) {
+::testing::AssertionResult PrintedWrittenQualifiedPropertyDeclObjCMatches(
+    StringRef Code, StringRef DeclName, StringRef ExpectedPrinted) {
   std::vector<std::string> Args{"-std=c++11", "-xobjective-c++"};
-  return PrintedNamedDeclMatches(Code, Args,
-                                 /*SuppressUnwrittenScope*/ true,
-                                 objcPropertyDecl(hasName(DeclName)).bind("id"),
-                                 ExpectedPrinted, "input.m");
+  return PrintedQualifiedNamedDeclMatches(
+      Code, Args,
+      /*SuppressUnwrittenScope*/ true,
+      objcPropertyDecl(hasName(DeclName)).bind("id"), ExpectedPrinted,
+      "input.m");
 }
 
 ::testing::AssertionResult
@@ -149,69 +158,60 @@
                             });
 }
 
+::testing::AssertionResult
+PrintedUnqualifiedNamedDeclCXX20Matches(StringRef Code,
+                                        const DeclarationMatcher &NodeMatcher,
+                                        StringRef ExpectedPrinted) {
+  std::vector<std::string> Args(1, "-std=c++20");
+  return PrintedUnqualifiedNamedDeclMatches(Code, Args, NodeMatcher,
+                                            ExpectedPrinted, "input.cc");
+}
+
 } // unnamed namespace
 
 TEST(NamedDeclPrinter, TestNamespace1) {
-  ASSERT_TRUE(PrintedNamedDeclCXX98Matches(
-    "namespace { int A; }",
-    "A",
-    "(anonymous namespace)::A"));
+  ASSERT_TRUE(PrintedQualifiedNamedDeclCXX98Matches(
+      "namespace { int A; }", "A", "(anonymous namespace)::A"));
 }
 
 TEST(NamedDeclPrinter, TestNamespace2) {
-  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
-    "inline namespace Z { namespace { int A; } }",
-    "A",
-    "A"));
+  ASSERT_TRUE(PrintedWrittenQualifiedNamedDeclCXX11Matches(
+      "inline namespace Z { namespace { int A; } }", "A", "A"));
 }
 
 TEST(NamedDeclPrinter, TestUnscopedUnnamedEnum) {
-  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
-    "enum { A };",
-    "A",
-    "A"));
+  ASSERT_TRUE(
+      PrintedWrittenQualifiedNamedDeclCXX11Matches("enum { A };", "A", "A"));
 }
 
 TEST(NamedDeclPrinter, TestNamedEnum) {
-  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
-    "enum X { A };",
-    "A",
-    "A"));
+  ASSERT_TRUE(
+      PrintedWrittenQualifiedNamedDeclCXX11Matches("enum X { A };", "A", "A"));
 }
 
 TEST(NamedDeclPrinter, TestScopedNamedEnum) {
-  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
-    "enum class X { A };",
-    "A",
-    "X::A"));
+  ASSERT_TRUE(PrintedWrittenQualifiedNamedDeclCXX11Matches(
+      "enum class X { A };", "A", "X::A"));
 }
 
 TEST(NamedDeclPrinter, TestClassWithUnscopedUnnamedEnum) {
-  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
-    "class X { enum { A }; };",
-    "A",
-    "X::A"));
+  ASSERT_TRUE(PrintedWrittenQualifiedNamedDeclCXX11Matches(
+      "class X { enum { A }; };", "A", "X::A"));
 }
 
 TEST(NamedDeclPrinter, TestClassWithUnscopedNamedEnum) {
-  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
-    "class X { enum Y { A }; };",
-    "A",
-    "X::A"));
+  ASSERT_TRUE(PrintedWrittenQualifiedNamedDeclCXX11Matches(
+      "class X { enum Y { A }; };", "A", "X::A"));
 }
 
 TEST(NamedDeclPrinter, TestClassWithScopedNamedEnum) {
-  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
-    "class X { enum class Y { A }; };",
-    "A",
-    "X::Y::A"));
+  ASSERT_TRUE(PrintedWrittenQualifiedNamedDeclCXX11Matches(
+      "class X { enum class Y { A }; };", "A", "X::Y::A"));
 }
 
 TEST(NamedDeclPrinter, TestLinkageInNamespace) {
-  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
-    "namespace X { extern \"C\" { int A; } }",
-    "A",
-    "X::A"));
+  ASSERT_TRUE(PrintedWrittenQualifiedNamedDeclCXX11Matches(
+      "namespace X { extern \"C\" { int A; } }", "A", "X::A"));
 }
 
 TEST(NamedDeclPrinter, TestObjCClassExtension) {
@@ -224,10 +224,8 @@
   @property(nonatomic) int property;
   @end
 )";
-  ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(
-    Code,
-    "property",
-    "Obj::property"));
+  ASSERT_TRUE(PrintedWrittenQualifiedPropertyDeclObjCMatches(Code, "property",
+                                                             "Obj::property"));
 }
 
 TEST(NamedDeclPrinter, TestInstanceObjCClassExtension) {
@@ -244,11 +242,11 @@
   std::vector<std::string> Args{
       "-std=c++11", "-xobjective-c++",
       "-fobjc-runtime=macosx" /*force to use non-fragile ABI*/};
-  ASSERT_TRUE(PrintedNamedDeclMatches(Code, Args,
-                                      /*SuppressUnwrittenScope*/ true,
-                                      namedDecl(hasName("data")).bind("id"),
-                                      // not "::data"
-                                      "ObjC::data", "input.mm"));
+  ASSERT_TRUE(PrintedQualifiedNamedDeclMatches(
+      Code, Args,
+      /*SuppressUnwrittenScope*/ true, namedDecl(hasName("data")).bind("id"),
+      // not "::data"
+      "ObjC::data", "input.mm"));
 }
 
 TEST(NamedDeclPrinter, TestObjCClassExtensionWithGetter) {
@@ -261,10 +259,8 @@
   @property(nonatomic, getter=myPropertyGetter) int property;
   @end
 )";
-  ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(
-    Code,
-    "property",
-    "Obj::property"));
+  ASSERT_TRUE(PrintedWrittenQualifiedPropertyDeclObjCMatches(Code, "property",
+                                                             "Obj::property"));
 }
 
 TEST(NamedDeclPrinter, NestedNameSpecifierSimple) {
@@ -284,3 +280,176 @@
   ASSERT_TRUE(
       PrintedNestedNameSpecifierMatches(Code, "method", "vector<int>::"));
 }
+
+TEST(NamedDeclPrinter, TestLambdaImplicitCapture1) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { int A; [=] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "A"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaImplicitCapture2) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { int A; [&] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "A"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaImplicitCapture3) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "struct X { int A; void Test() const; };"
+      "void X::Test() const { [=] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "this"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaImplicitCapture4) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "struct X { int A; void Test() const; };"
+      "void X::Test() const { [&] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "this"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaExplicitCapture1) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { int A; [A] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "A"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaExplicitCapture2) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { int A; [&A] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "A"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaExplicitCapture3) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "struct X { int A; void Test() const; };"
+      "void X::Test() const { [this] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "this"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaExplicitCapture4) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "struct X { int A; void Test() const; };"
+      "void X::Test() const { [*this] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "*this"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaInitCapture1) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { int X; [A=X] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "A"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaInitCapture2) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { int X; [&A=X] { return A; }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "A"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaVLA) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test(int n) { int X[n]; [&X] { return X[0]; }; }",
+      fieldDecl(allOf(isImplicit(), hasType(references(variableArrayType()))))
+          .bind("id"),
+      "(unnamed field at input.cc:1:32 of type int (&)[n])"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaPack1) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "template <typename... Ts> void Test(Ts... ts) {"
+      "[ts...] { return (ts + ...); }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "ts"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaPack2) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "template <typename... Ts> void Test(Ts... ts) {"
+      "[&ts...] { return (ts + ...); }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "ts"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaPack3) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "template <typename... Ts> void Test(Ts... ts) {"
+      "[...vs=ts] { return (vs + ...); }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "vs"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaPack4) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "template <typename... Ts> void Test(Ts... ts) {"
+      "[&...vs=ts] { return (vs + ...); }; }",
+      fieldDecl(allOf(isImplicit(), hasParent(cxxRecordDecl(isLambda()))))
+          .bind("id"),
+      "vs"));
+}
+
+TEST(NamedDeclPrinter, TestUnnamedParameter1) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test(int, float);",
+      functionDecl(
+          allOf(hasName("Test"), hasParameter(1, varDecl().bind("id")))),
+      "(unnamed parameter at input.cc:1:21 of type float)"));
+}
+
+TEST(NamedDeclPrinter, TestUnnamedParameter2) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "struct {} x;"
+      "void Test(decltype(x) &);",
+      functionDecl(
+          allOf(hasName("Test"), hasParameter(0, varDecl().bind("id")))),
+      "(unnamed parameter at input.cc:1:36 of type decltype(x) &)"));
+}
+
+TEST(NamedDeclPrinter, TestAnonymousUnion) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { union { int i; }; }",
+      varDecl(hasType(recordType(hasDeclaration(tagDecl(isUnion())))))
+          .bind("id"),
+      "(unnamed variable of type (anonymous union at input.cc:1:15))"));
+}
+
+TEST(NamedDeclPrinter, TestUnnamedStruct) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { struct { int i; } s; }",
+      cxxRecordDecl(has(fieldDecl(hasName("i")))).bind("id"),
+      "(unnamed struct at input.cc:1:15)"));
+}
+
+TEST(NamedDeclPrinter, TestLambdaClass) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "void Test() { [] {}; }", cxxRecordDecl(isLambda()).bind("id"),
+      "(lambda at input.cc:1:15)"));
+}
+
+TEST(NamedDeclPrinter, TestUnnamedField) {
+  ASSERT_TRUE(PrintedUnqualifiedNamedDeclCXX20Matches(
+      "struct X { struct { int A; }; };",
+      cxxRecordDecl(has(fieldDecl(hasType(recordType())).bind("id"))),
+      "(unnamed field of type X::(anonymous struct at input.cc:1:12))"));
+}
Index: clang/unittests/AST/ASTTraverserTest.cpp
===================================================================
--- clang/unittests/AST/ASTTraverserTest.cpp
+++ clang/unittests/AST/ASTTraverserTest.cpp
@@ -825,7 +825,7 @@
 | |-FieldDecl ''
 | |-FieldDecl ''
 | |-FieldDecl ''
-| `-CXXDestructorDecl '~(unnamed class at input.cc:9:3)'
+| `-CXXDestructorDecl '~(lambda at input.cc:9:3)'
 |-ImplicitCastExpr
 | `-DeclRefExpr 'a'
 |-DeclRefExpr 'b'
Index: clang/test/Tooling/clang-diff-ast.cpp
===================================================================
--- clang/test/Tooling/clang-diff-ast.cpp
+++ clang/test/Tooling/clang-diff-ast.cpp
@@ -56,7 +56,7 @@
   int not_initialized;
   // CHECK: CXXConstructorDecl: :X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})(
   // CHECK-NEXT: ParmVarDecl: s(char)
-  // CHECK-NEXT: ParmVarDecl: (unnamed variable at {{.*}}:64:16 of type int)(int)
+  // CHECK-NEXT: ParmVarDecl: (unnamed parameter at {{.*}}:64:16 of type int)(int)
   // CHECK-NEXT: CXXCtorInitializer: Base
   // CHECK-NEXT: CXXConstructExpr
   // CHECK-NEXT: CXXCtorInitializer: m
Index: clang/test/SemaCXX/warn-large-by-value-copy.cpp
===================================================================
--- clang/test/SemaCXX/warn-large-by-value-copy.cpp
+++ clang/test/SemaCXX/warn-large-by-value-copy.cpp
@@ -16,13 +16,13 @@
 S101 f101(S101 s) { return s; } // expected-warning {{return value of 'f101' is a large (101 bytes) pass-by-value object}} \
                                 // expected-warning {{'s' is a large (101 bytes) pass-by-value argument}}
 
-void f101_no_param_name(S101) {} // expected-warning-re {{'(unnamed variable at {{.*}}:19:29 of type rdar8548050::S101)' is a large (101 bytes) pass-by-value argument}}
+void f101_no_param_name(S101) {} // expected-warning-re {{'(unnamed parameter at {{.*}}:19:29 of type rdar8548050::S101)' is a large (101 bytes) pass-by-value argument}}
 
 // FIXME: Don't warn when when the return value is subject to (N)RVO.
 
 template <typename T> T foo_template(T);
 template <> S101 foo_template(S101) { return S101(); } // expected-warning {{return value of 'foo_template<rdar8548050::S101>' is a large}}
-                                                       // expected-warning-re@-1 {{'(unnamed variable at {{.*}}:24:35 of type rdar8548050::S101)' is a large (101 bytes) pass-by-value argument}}
+                                                       // expected-warning-re@-1 {{'(unnamed parameter at {{.*}}:24:35 of type rdar8548050::S101)' is a large (101 bytes) pass-by-value argument}}
 
 typedef int Arr[200];
 void farr(Arr a) { }
Index: clang/test/SemaCXX/lambda-expressions.cpp
===================================================================
--- clang/test/SemaCXX/lambda-expressions.cpp
+++ clang/test/SemaCXX/lambda-expressions.cpp
@@ -119,19 +119,18 @@
     R &operator=(R&&) = delete;
   };
   void g(P &p, Q &q, R &r) {
-    // FIXME: The note attached to the second error here is just amazingly bad.
     auto pp = [p] {}; // expected-error {{call to deleted constructor of 'SpecialMembers::P'}}
-                      // expected-cxx14-error-re@-1 {{call to implicitly-deleted copy constructor of '(lambda at {{.*}}:123:15)'}}
-                      // expected-cxx14-note-re@-2 {{copy constructor of '(unnamed class at {{.*}}:123:15)' is implicitly deleted because field '(unnamed field at {{.*}}:123:16 of type SpecialMembers::P)' has a deleted copy constructor}}
+                      // expected-cxx14-error-re@-1 {{call to implicitly-deleted copy constructor of '(lambda at {{.*}}:122:15)'}}
+                      // expected-cxx14-note-re@-2 {{copy constructor of '(lambda at {{.*}}:122:15)' is implicitly deleted because field 'p' has a deleted copy constructor}}
 
     auto qq = [q] {}; // expected-error {{attempt to use a deleted function}}
-                      // expected-note-re@-1 {{destructor of '(unnamed class at {{.*}}:127:15)' is implicitly deleted because field '(unnamed field at {{.*}}:127:16 of type SpecialMembers::Q)' has a deleted destructor}}
+                      // expected-note-re@-1 {{destructor of '(lambda at {{.*}}:126:15)' is implicitly deleted because field 'q' has a deleted destructor}}
 
     auto a = [r] {}; // expected-note 2{{lambda expression begins here}}
     decltype(a) b = a;
     decltype(a) c = static_cast<decltype(a)&&>(a); // ok, copies R
-    a = a;                                         // expected-error-re {{object of type '(lambda at {{.*}}:130:14)' cannot be assigned because its copy assignment operator is implicitly deleted}}
-    a = static_cast<decltype(a) &&>(a);            // expected-error-re {{object of type '(lambda at {{.*}}:130:14)' cannot be assigned because its copy assignment operator is implicitly deleted}}
+    a = a;                                         // expected-error-re {{object of type '(lambda at {{.*}}:129:14)' cannot be assigned because its copy assignment operator is implicitly deleted}}
+    a = static_cast<decltype(a) &&>(a);            // expected-error-re {{object of type '(lambda at {{.*}}:129:14)' cannot be assigned because its copy assignment operator is implicitly deleted}}
   }
 }
 
@@ -655,10 +654,10 @@
 
 namespace captured_name {
 void Test() {
-  union { // expected-note-re {{'(unnamed variable of type (anonymous union at {{.*}}:658:3))' declared here}}
+  union { // expected-note-re {{'(unnamed variable of type (anonymous union at {{.*}}:657:3))' declared here}}
     int i;
   };
-  [] { return i; }; // expected-error-re {{variable '(unnamed variable of type (anonymous union at {{.*}}:658:3))' cannot be implicitly captured in a lambda with no capture-default specified}}
+  [] { return i; }; // expected-error-re {{variable '(unnamed variable of type (anonymous union at {{.*}}:657:3))' cannot be implicitly captured in a lambda with no capture-default specified}}
                     // expected-note@-1 {{lambda expression begins here}}
 }
-};
+} // namespace captured_name
Index: clang/test/Modules/module-private.cpp
===================================================================
--- clang/test/Modules/module-private.cpp
+++ clang/test/Modules/module-private.cpp
@@ -86,7 +86,7 @@
   typedef __module_private__ int local_typedef; // expected-error{{typedef 'local_typedef' cannot be declared __module_private__}}
 }
 
-void param_private(__module_private__ int) {} // expected-error-re {{parameter '(unnamed variable at {{.*}}:89:42 of type int)' cannot be declared __module_private__}}
+void param_private(__module_private__ int) {} // expected-error-re {{parameter '(unnamed parameter at {{.*}}:89:42 of type int)' cannot be declared __module_private__}}
 
 // Check struct size
 struct LikeVisibleStruct {
Index: clang/test/Index/usrs.m
===================================================================
--- clang/test/Index/usrs.m
+++ clang/test/Index/usrs.m
@@ -281,9 +281,9 @@
 // CHECK-source: usrs.m:69:23: UnexposedExpr= Extent=[69:23 - 69:24]
 // CHECK-source: usrs.m:69:23: IntegerLiteral= Extent=[69:23 - 69:24]
 // CHECK-source: usrs.m:72:6: FunctionDecl=aux_1:72:6 Extent=[72:1 - 72:26]
-// CHECK-source: usrs.m:72:15: ParmDecl=(unnamed variable at {{.*}}:72:15 of type int):72:15 (Definition) Extent=[72:12 - 72:15]
-// CHECK-source: usrs.m:72:20: ParmDecl=(unnamed variable at {{.*}}:72:20 of type int):72:20 (Definition) Extent=[72:17 - 72:20]
-// CHECK-source: usrs.m:72:25: ParmDecl=(unnamed variable at {{.*}}:72:25 of type int):72:25 (Definition) Extent=[72:22 - 72:25]
+// CHECK-source: usrs.m:72:15: ParmDecl=(unnamed parameter at {{.*}}:72:15 of type int):72:15 (Definition) Extent=[72:12 - 72:15]
+// CHECK-source: usrs.m:72:20: ParmDecl=(unnamed parameter at {{.*}}:72:20 of type int):72:20 (Definition) Extent=[72:17 - 72:20]
+// CHECK-source: usrs.m:72:25: ParmDecl=(unnamed parameter at {{.*}}:72:25 of type int):72:25 (Definition) Extent=[72:22 - 72:25]
 // CHECK-source: usrs.m:73:5: FunctionDecl=test_multi_declaration:73:5 (Definition) Extent=[73:1 - 77:2]
 // CHECK-source: usrs.m:73:34: CompoundStmt= Extent=[73:34 - 77:2]
 // CHECK-source: usrs.m:74:3: DeclStmt= Extent=[74:3 - 74:33]
Index: clang/test/Index/recursive-cxx-member-calls.cpp
===================================================================
--- clang/test/Index/recursive-cxx-member-calls.cpp
+++ clang/test/Index/recursive-cxx-member-calls.cpp
@@ -222,13 +222,13 @@
 // CHECK-tokens: Keyword: "int" [7:3 - 7:6] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Identifier: "memcmp" [7:7 - 7:13] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Punctuation: "(" [7:13 - 7:14] FunctionDecl=memcmp:7:7
-// CHECK-tokens: Keyword: "const" [7:14 - 7:19] ParmDecl=(unnamed variable at {{.*}}:7:26 of type const void *):7:26 (Definition)
-// CHECK-tokens: Keyword: "void" [7:20 - 7:24] ParmDecl=(unnamed variable at {{.*}}:7:26 of type const void *):7:26 (Definition)
-// CHECK-tokens: Punctuation: "*" [7:25 - 7:26] ParmDecl=(unnamed variable at {{.*}}:7:26 of type const void *):7:26 (Definition)
+// CHECK-tokens: Keyword: "const" [7:14 - 7:19] ParmDecl=(unnamed parameter at {{.*}}:7:26 of type const void *):7:26 (Definition)
+// CHECK-tokens: Keyword: "void" [7:20 - 7:24] ParmDecl=(unnamed parameter at {{.*}}:7:26 of type const void *):7:26 (Definition)
+// CHECK-tokens: Punctuation: "*" [7:25 - 7:26] ParmDecl=(unnamed parameter at {{.*}}:7:26 of type const void *):7:26 (Definition)
 // CHECK-tokens: Punctuation: "," [7:26 - 7:27] FunctionDecl=memcmp:7:7
-// CHECK-tokens: Keyword: "const" [7:28 - 7:33] ParmDecl=(unnamed variable at {{.*}}:7:40 of type const void *):7:40 (Definition)
-// CHECK-tokens: Keyword: "void" [7:34 - 7:38] ParmDecl=(unnamed variable at {{.*}}:7:40 of type const void *):7:40 (Definition)
-// CHECK-tokens: Punctuation: "*" [7:39 - 7:40] ParmDecl=(unnamed variable at {{.*}}:7:40 of type const void *):7:40 (Definition)
+// CHECK-tokens: Keyword: "const" [7:28 - 7:33] ParmDecl=(unnamed parameter at {{.*}}:7:40 of type const void *):7:40 (Definition)
+// CHECK-tokens: Keyword: "void" [7:34 - 7:38] ParmDecl=(unnamed parameter at {{.*}}:7:40 of type const void *):7:40 (Definition)
+// CHECK-tokens: Punctuation: "*" [7:39 - 7:40] ParmDecl=(unnamed parameter at {{.*}}:7:40 of type const void *):7:40 (Definition)
 // CHECK-tokens: Punctuation: "," [7:40 - 7:41] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Identifier: "size_t" [7:42 - 7:48] TypeRef=size_t:2:25
 // CHECK-tokens: Punctuation: ")" [7:48 - 7:49] FunctionDecl=memcmp:7:7
@@ -236,9 +236,9 @@
 // CHECK-tokens: Identifier: "size_t" [8:3 - 8:9] TypeRef=size_t:2:25
 // CHECK-tokens: Identifier: "strlen" [8:10 - 8:16] FunctionDecl=strlen:8:10
 // CHECK-tokens: Punctuation: "(" [8:16 - 8:17] FunctionDecl=strlen:8:10
-// CHECK-tokens: Keyword: "const" [8:17 - 8:22] ParmDecl=(unnamed variable at {{.*}}:8:29 of type const char *):8:29 (Definition)
-// CHECK-tokens: Keyword: "char" [8:23 - 8:27] ParmDecl=(unnamed variable at {{.*}}:8:29 of type const char *):8:29 (Definition)
-// CHECK-tokens: Punctuation: "*" [8:28 - 8:29] ParmDecl=(unnamed variable at {{.*}}:8:29 of type const char *):8:29 (Definition)
+// CHECK-tokens: Keyword: "const" [8:17 - 8:22] ParmDecl=(unnamed parameter at {{.*}}:8:29 of type const char *):8:29 (Definition)
+// CHECK-tokens: Keyword: "char" [8:23 - 8:27] ParmDecl=(unnamed parameter at {{.*}}:8:29 of type const char *):8:29 (Definition)
+// CHECK-tokens: Punctuation: "*" [8:28 - 8:29] ParmDecl=(unnamed parameter at {{.*}}:8:29 of type const char *):8:29 (Definition)
 // CHECK-tokens: Punctuation: ")" [8:29 - 8:30] FunctionDecl=strlen:8:10
 // CHECK-tokens: Punctuation: ";" [8:30 - 8:31]
 // CHECK-tokens: Punctuation: "}" [9:1 - 9:2]
@@ -1534,13 +1534,13 @@
 // CHECK: 4:55: FieldDecl=second:4:55 (Definition) Extent=[4:51 - 4:61]
 // CHECK: 6:8: UnexposedDecl=:6:8 (Definition) Extent=[6:1 - 9:2]
 // CHECK: 7:7: FunctionDecl=memcmp:7:7 Extent=[7:3 - 7:49]
-// CHECK: 7:26: ParmDecl=(unnamed variable at {{.*}}:7:26 of type const void *):7:26 (Definition) Extent=[7:14 - 7:26]
-// CHECK: 7:40: ParmDecl=(unnamed variable at {{.*}}:7:40 of type const void *):7:40 (Definition) Extent=[7:28 - 7:40]
-// CHECK: 7:48: ParmDecl=(unnamed variable at {{.*}}:7:48 of type size_t):7:48 (Definition) Extent=[7:42 - 7:48]
+// CHECK: 7:26: ParmDecl=(unnamed parameter at {{.*}}:7:26 of type const void *):7:26 (Definition) Extent=[7:14 - 7:26]
+// CHECK: 7:40: ParmDecl=(unnamed parameter at {{.*}}:7:40 of type const void *):7:40 (Definition) Extent=[7:28 - 7:40]
+// CHECK: 7:48: ParmDecl=(unnamed parameter at {{.*}}:7:48 of type size_t):7:48 (Definition) Extent=[7:42 - 7:48]
 // CHECK: 7:42: TypeRef=size_t:2:25 Extent=[7:42 - 7:48]
 // CHECK: 8:10: FunctionDecl=strlen:8:10 Extent=[8:3 - 8:30]
 // CHECK: 8:3: TypeRef=size_t:2:25 Extent=[8:3 - 8:9]
-// CHECK: 8:29: ParmDecl=(unnamed variable at {{.*}}:8:29 of type const char *):8:29 (Definition) Extent=[8:17 - 8:29]
+// CHECK: 8:29: ParmDecl=(unnamed parameter at {{.*}}:8:29 of type const char *):8:29 (Definition) Extent=[8:17 - 8:29]
 // CHECK: 10:17: Namespace=clang:10:17 (Definition) Extent=[10:1 - 35:2]
 // CHECK: 11:9: ClassDecl=IdentifierInfo:11:9 Extent=[11:3 - 11:23]
 // CHECK: 12:9: ClassDecl=AttributeList:12:9 (Definition) Extent=[12:3 - 34:4]
Index: clang/test/Index/print-type.cpp
===================================================================
--- clang/test/Index/print-type.cpp
+++ clang/test/Index/print-type.cpp
@@ -142,17 +142,17 @@
 // CHECK: FunctionTemplate=tbar:36:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
 // CHECK: TemplateTypeParameter=T:35:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: TypeRef=T:35:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: ParmDecl=(unnamed variable at {{.*}}:36:11 of type int):36:11 (Definition) [type=int] [typekind=Int] [isPOD=1]
+// CHECK: ParmDecl=(unnamed parameter at {{.*}}:36:11 of type int):36:11 (Definition) [type=int] [typekind=Int] [isPOD=1]
 // CHECK: FunctionTemplate=tbar:39:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
 // CHECK: TemplateTypeParameter=T:38:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: TypeRef=T:38:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: ParmDecl=(unnamed variable at {{.*}}:39:11 of type int *):39:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
+// CHECK: ParmDecl=(unnamed parameter at {{.*}}:39:11 of type int *):39:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
 // CHECK: FunctionTemplate=tbar:42:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
 // CHECK: TemplateTypeParameter=T:41:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: NonTypeTemplateParameter=size:41:27 (Definition) [type=int] [typekind=Int] [isPOD=1]
 // CHECK: TypeRef=T:41:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: ParmDecl=(unnamed variable at {{.*}}:42:11 of type int *):42:11 (Definition) [type=int [size]] [typekind=DependentSizedArray] [isPOD=0]
+// CHECK: ParmDecl=(unnamed parameter at {{.*}}:42:11 of type int *):42:11 (Definition) [type=int [size]] [typekind=DependentSizedArray] [isPOD=0]
 // CHECK: DeclRefExpr=size:41:27 [type=int] [typekind=Int] [isPOD=1]
 // CHECK: FunctionDecl=foo:44:6 (Definition) [type=void (int, int *)] [typekind=FunctionProto] [canonicaltype=void (int, int *)] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int] [int []] [IncompleteArray]] [isPOD=0]
 // CHECK: ParmDecl=i:44:14 (Definition) [type=int] [typekind=Int] [isPOD=1]
Index: clang/test/Index/print-type.c
===================================================================
--- clang/test/Index/print-type.c
+++ clang/test/Index/print-type.c
@@ -40,7 +40,7 @@
 // CHECK: ParmDecl=arr:3:40 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
 // CHECK: ParmDecl=fn:3:55 (Definition) [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=void (int)] [pointeekind=FunctionProto]
-// CHECK: ParmDecl=(unnamed variable at {{.*}}:3:62 of type int):3:62 (Definition) [type=int] [typekind=Int] [isPOD=1]
+// CHECK: ParmDecl=(unnamed parameter at {{.*}}:3:62 of type int):3:62 (Definition) [type=int] [typekind=Int] [isPOD=1]
 // CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: CallExpr=fn:3:55 [type=void] [typekind=Void] [args= [int] [Int]] [isPOD=0]
 // CHECK: DeclRefExpr=fn:3:55 [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=void (int)] [pointeekind=FunctionProto]
Index: clang/test/Index/preamble.c
===================================================================
--- clang/test/Index/preamble.c
+++ clang/test/Index/preamble.c
@@ -20,7 +20,7 @@
 // CHECK: preamble.h:4:9: DeclRefExpr=ptr1:3:10 Extent=[4:9 - 4:13]
 // CHECK: preamble.h:5:10: IntegerLiteral= Extent=[5:10 - 5:11]
 // CHECK: preamble.c:8:5: FunctionDecl=wibble:8:5 Extent=[8:1 - 8:16]
-// CHECK: preamble.c:8:15: ParmDecl=(unnamed variable at {{.*}}:8:15 of type int):8:15 (Definition) Extent=[8:12 - 8:15]
+// CHECK: preamble.c:8:15: ParmDecl=(unnamed parameter at {{.*}}:8:15 of type int):8:15 (Definition) Extent=[8:12 - 8:15]
 // CHECK-DIAG: preamble.h:4:7:{4:9-4:13}: warning: incompatible pointer types assigning to 'int *' from 'float *'
 // FIXME: Should see:
 //     preamble.c:5:9: warning: macro is not used
Index: clang/test/Index/load-namespaces.cpp
===================================================================
--- clang/test/Index/load-namespaces.cpp
+++ clang/test/Index/load-namespaces.cpp
@@ -40,7 +40,7 @@
 // CHECK: load-namespaces.cpp:16:17: NamespaceRef=std0x:14:11 Extent=[16:17 - 16:22]
 // CHECK: load-namespaces.cpp:18:11: Namespace=std:18:11 (Definition) Extent=[18:1 - 20:2]
 // CHECK: load-namespaces.cpp:19:7: FunctionDecl=g:19:7 Extent=[19:3 - 19:13]
-// CHECK: load-namespaces.cpp:19:12: ParmDecl=(unnamed variable at {{.*}}:19:12 of type int):19:12 (Definition) Extent=[19:9 - 19:12]
+// CHECK: load-namespaces.cpp:19:12: ParmDecl=(unnamed parameter at {{.*}}:19:12 of type int):19:12 (Definition) Extent=[19:9 - 19:12]
 // CHECK: load-namespaces.cpp:22:12: UsingDeclaration=g[19:7, 10:8] Extent=[22:1 - 22:13]
 // CHECK: load-namespaces.cpp:22:7: NamespaceRef=std:18:11 Extent=[22:7 - 22:10]
 // CHECK: load-namespaces.cpp:24:11: FunctionDecl=g:24:11 (Definition) Extent=[24:1 - 25:2]
Index: clang/test/Index/load-decls.c
===================================================================
--- clang/test/Index/load-decls.c
+++ clang/test/Index/load-decls.c
@@ -17,6 +17,6 @@
 // CHECK: load-decls.c:6:11: DeclRefExpr=Red:2:3 Extent=[6:11 - 6:14]
 //
 // CHECK: load-decls.c:9:6: FunctionDecl=PR17970:9:6 Extent=[9:1 - 9:35]
-// CHECK: load-decls.c:9:21: ParmDecl=(unnamed variable at {{.*}}:9:21 of type void (*)(int)):9:21 (Definition) Extent=[9:14 - 9:27]
-// CHECK: load-decls.c:9:26: ParmDecl=(unnamed variable at {{.*}}:9:26 of type int):9:26 (Definition) Extent=[9:23 - 9:26]
-// CHECK: load-decls.c:9:34: ParmDecl=(unnamed variable at {{.*}}:9:34 of type float):9:34 (Definition) Extent=[9:29 - 9:34]
+// CHECK: load-decls.c:9:21: ParmDecl=(unnamed parameter at {{.*}}:9:21 of type void (*)(int)):9:21 (Definition) Extent=[9:14 - 9:27]
+// CHECK: load-decls.c:9:26: ParmDecl=(unnamed parameter at {{.*}}:9:26 of type int):9:26 (Definition) Extent=[9:23 - 9:26]
+// CHECK: load-decls.c:9:34: ParmDecl=(unnamed parameter at {{.*}}:9:34 of type float):9:34 (Definition) Extent=[9:29 - 9:34]
Index: clang/test/Index/linkage.c
===================================================================
--- clang/test/Index/linkage.c
+++ clang/test/Index/linkage.c
@@ -30,7 +30,7 @@
 // CHECK: VarDecl=k:9:7 (Definition)linkage=NoLinkage
 // CHECK: VarDecl=n:11:12linkage=External
 // CHECK: FunctionDecl=wibble:12:12linkage=Internal
-// CHECK: ParmDecl=(unnamed variable at {{.*}}:12:22 of type int):12:22 (Definition)linkage=NoLinkage
+// CHECK: ParmDecl=(unnamed parameter at {{.*}}:12:22 of type int):12:22 (Definition)linkage=NoLinkage
 // CHECK: FunctionDecl=ena:14:6linkage=External
 // CHECK: ParmDecl=dio:14:16 (Definition)linkage=NoLinkage
 // CHECK: ParmDecl=tria:14:25 (Definition)linkage=NoLinkage
Index: clang/test/Index/annotate-tokens.cpp
===================================================================
--- clang/test/Index/annotate-tokens.cpp
+++ clang/test/Index/annotate-tokens.cpp
@@ -77,7 +77,7 @@
 // CHECK: Keyword: "operator" [9:5 - 9:13] CXXMethod=operator++:9:5
 // CHECK: Punctuation: "++" [9:13 - 9:15] CXXMethod=operator++:9:5
 // CHECK: Punctuation: "(" [9:15 - 9:16] CXXMethod=operator++:9:5
-// CHECK: Keyword: "int" [9:16 - 9:19] ParmDecl=(unnamed variable at {{.*}}:9:19 of type int):9:19 (Definition
+// CHECK: Keyword: "int" [9:16 - 9:19] ParmDecl=(unnamed parameter at {{.*}}:9:19 of type int):9:19 (Definition
 // CHECK: Punctuation: ")" [9:19 - 9:20] CXXMethod=operator++:9:5
 // CHECK: Punctuation: ";" [9:20 - 9:21] StructDecl=X:7:8 (Definition)
 // CHECK: Punctuation: "}" [10:1 - 10:2] StructDecl=X:7:8 (Definition)
@@ -148,7 +148,7 @@
 // CHECK: Punctuation: ")" [23:21 - 23:22] NonTypeTemplateParameter=tfn:23:18 (Definition)
 // CHECK: Punctuation: "(" [23:22 - 23:23] NonTypeTemplateParameter=tfn:23:18 (Definition)
 // CHECK: Identifier: "X" [23:23 - 23:24] TypeRef=struct X:7:8
-// CHECK: Punctuation: "*" [23:24 - 23:25] ParmDecl=(unnamed variable at {{.*}}:23:25 of type X *):23:25 (Definition)
+// CHECK: Punctuation: "*" [23:24 - 23:25] ParmDecl=(unnamed parameter at {{.*}}:23:25 of type X *):23:25 (Definition)
 // CHECK: Punctuation: ")" [23:25 - 23:26] NonTypeTemplateParameter=tfn:23:18 (Definition)
 // CHECK: Punctuation: ">" [23:26 - 23:27] ClassTemplate=TS:24:8 (Definition)
 // CHECK: Keyword: "struct" [24:1 - 24:7] ClassTemplate=TS:24:8 (Definition)
@@ -170,7 +170,7 @@
 // CHECK: Punctuation: ")" [28:21 - 28:22] NonTypeTemplateParameter=tfn:28:18 (Definition)
 // CHECK: Punctuation: "(" [28:22 - 28:23] NonTypeTemplateParameter=tfn:28:18 (Definition)
 // CHECK: Identifier: "X" [28:23 - 28:24] TypeRef=struct X:7:8
-// CHECK: Punctuation: "*" [28:24 - 28:25] ParmDecl=(unnamed variable at {{.*}}:28:25 of type X *):28:25 (Definition)
+// CHECK: Punctuation: "*" [28:24 - 28:25] ParmDecl=(unnamed parameter at {{.*}}:28:25 of type X *):28:25 (Definition)
 // CHECK: Punctuation: ")" [28:25 - 28:26] NonTypeTemplateParameter=tfn:28:18 (Definition)
 // CHECK: Punctuation: ">" [28:26 - 28:27] CXXMethod=foo:29:15 (Definition)
 // CHECK: Keyword: "void" [29:1 - 29:5] CXXMethod=foo:29:15 (Definition)
Index: clang/test/Analysis/explain-svals.cpp
===================================================================
--- clang/test/Analysis/explain-svals.cpp
+++ clang/test/Analysis/explain-svals.cpp
@@ -98,7 +98,7 @@
 } // end of anonymous namespace
 
 void test_6() {
-  clang_analyzer_explain(conjure_S());   // expected-warning-re{{{{^lazily frozen compound value of parameter '\(unnamed variable at .*:23:30 of type S\)'$}}}}
+  clang_analyzer_explain(conjure_S());   // expected-warning-re{{{{^lazily frozen compound value of parameter '\(unnamed parameter at .*:23:30 of type S\)'$}}}}
   clang_analyzer_explain(conjure_S().z); // expected-warning-re{{{{^value derived from \(symbol of type 'int' conjured at statement 'conjure_S\(\)'\) for field 'z' of temporary object constructed at statement 'conjure_S\(\)'$}}}}
 }
 
Index: clang/test/AST/ast-dump-record-definition-data-json.cpp
===================================================================
--- clang/test/AST/ast-dump-record-definition-data-json.cpp
+++ clang/test/AST/ast-dump-record-definition-data-json.cpp
@@ -323,7 +323,7 @@
 // CHECK-NEXT:    },
 // CHECK-NEXT:    "isImplicit": true,
 // CHECK-NEXT:    "isReferenced": true,
-// CHECK-NEXT:    "name": "~(unnamed class at {{.*}}:4:29)",
+// CHECK-NEXT:    "name": "~(lambda at {{.*}}:4:29)",
 // CHECK-NEXT:    "mangledName": "_ZZ1fvEN3$_0D1Ev",
 // CHECK-NEXT:    "type": {
 // CHECK-NEXT:     "qualType": "void () noexcept"
@@ -708,7 +708,7 @@
 // CHECK-NEXT:    },
 // CHECK-NEXT:    "isImplicit": true,
 // CHECK-NEXT:    "isReferenced": true,
-// CHECK-NEXT:    "name": "~(unnamed class at {{.*}}:5:26)",
+// CHECK-NEXT:    "name": "~(lambda at {{.*}}:5:26)",
 // CHECK-NEXT:    "mangledName": "_ZZ1fvEN3$_1D1Ev",
 // CHECK-NEXT:    "type": {
 // CHECK-NEXT:     "qualType": "void () noexcept"
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -2043,9 +2043,14 @@
   // will be mistakenly used (since the default is to assume that the record
   // is not anonymous). This is a relatively uncommon case and therefore the
   // additional complexity needed to prevent this is not worthwhile.
-  OS << Policy.getOpenDelimiterForUnnamedEntity()
-     << (IsAnonymousStructOrUnion ? "anonymous " : "unnamed ")
-     << TD->getKindName();
+  OS << Policy.getOpenDelimiterForUnnamedEntity();
+
+  if (isa<RecordDecl>(TD) && cast<RecordDecl>(TD)->isLambda()) {
+    OS << "lambda";
+  } else {
+    OS << (IsAnonymousStructOrUnion ? "anonymous " : "unnamed ")
+       << TD->getKindName();
+  }
 
   if (Policy.AnonymousTagLocations)
     printPresumedLocationAt(OS, Ctx.getSourceManager(), Policy,
@@ -2054,6 +2059,62 @@
   OS << Policy.getCloseDelimiterForUnnamedEntity();
 }
 
+/// If \p FD is an unnamed field corresponding to a lambda capture print
+/// the pretty-printed name of the capture and return true. Return false
+/// otherwise.
+static bool maybePrintFieldForLambdaCapture(raw_ostream &OS,
+                                            const PrintingPolicy &Policy,
+                                            const FieldDecl *FD) {
+  assert(FD && "missing field decl!");
+  struct Result {
+    LambdaCaptureKind LCK;
+    const VarDecl *VD;
+  };
+  auto getVarForLambdaField =
+      [](const FieldDecl *FD) -> llvm::Optional<Result> {
+    if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(FD->getParent())) {
+      if (CXXRD->isLambda()) {
+        // For a simple-capture, refer to the captured variable.
+        // For an init-capture, refer to the introduced variable.
+        //
+        // The captures and the fields are in 1-to-1 correspondance.
+        // Look at the fields until we find the corresponding capture.
+        RecordDecl::field_iterator Field = CXXRD->field_begin();
+        for (const LambdaCapture &C : CXXRD->captures()) {
+          if (*Field == FD)
+            return Result{C.getCaptureKind(),
+                          C.capturesVariable() ? C.getCapturedVar() : nullptr};
+        }
+      }
+    }
+    return llvm::None;
+  };
+
+  llvm::Optional<Result> VarForLambdaField = getVarForLambdaField(FD);
+  if (VarForLambdaField) {
+    switch (VarForLambdaField->LCK) {
+    case LCK_This:
+      OS << "this";
+      return true;
+    case LCK_StarThis:
+      OS << "*this";
+      return true;
+    case LCK_ByCopy:
+    case LCK_ByRef:
+      VarForLambdaField->VD->getNameForDiagnostic(OS, Policy,
+                                                  /*Qualified=*/false);
+      return true;
+    case LCK_VLAType:
+      // FIXME: The captured VLA is not stored in the LambdaCapture, so fall
+      // back to displaying (unnamed field at ...).
+      return false;
+    }
+    llvm_unreachable("unexpected LambdaCaptureKind!");
+  }
+
+  return false;
+}
+
 static void printUnnamedDeclarator(raw_ostream &OS, const ASTContext &Ctx,
                                    const DeclaratorDecl *DD) {
   assert(DD && "missing DeclaratorDecl!");
@@ -2062,8 +2123,16 @@
          isa<VarDecl>(DD) && "expected a field or variable declaration!");
   const PrintingPolicy &Policy = Ctx.getPrintingPolicy();
 
+  // The field in a lambda class for a capture is formally unnamed. However if
+  // this field correspond to a capture (either implicit or explicit) we can use
+  // the pretty-printed name of the capture instead.
+  if (isa<FieldDecl>(DD) &&
+      maybePrintFieldForLambdaCapture(OS, Policy, cast<FieldDecl>(DD)))
+    return;
+
   OS << Policy.getOpenDelimiterForUnnamedEntity() << "unnamed "
-     << (isa<FieldDecl>(DD) ? "field" : "variable");
+     << (isa<FieldDecl>(DD) ? "field"
+                            : isa<ParmVarDecl>(DD) ? "parameter" : "variable");
 
   // Don't print the location of anonymous records twice.
   bool SuppressLocation = false;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to