[c++20] Add support for explicit(bool), as described in P0892R2.

Patch by Tyker!

Differential Revision: https://reviews.llvm.org/D60934

llvm-svn: 360311
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 211b953..5bb4f7e 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -806,6 +806,26 @@
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceTest, ExplicitBoolDifferent) {
+  auto Decls = makeNamedDecls("struct foo {explicit(false) foo(int);};",
+                              "struct foo {explicit(true) foo(int);};", Lang_CXX2a);
+  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
+      get<0>(Decls), cxxConstructorDecl(hasName("foo")));
+  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
+      get<1>(Decls), cxxConstructorDecl(hasName("foo")));
+  EXPECT_FALSE(testStructuralMatch(First, Second));
+}
+
+TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
+  auto Decls = makeNamedDecls("struct foo {explicit(true) foo(int);};",
+                              "struct foo {explicit(true) foo(int);};", Lang_CXX2a);
+  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
+      get<0>(Decls), cxxConstructorDecl(hasName("foo")));
+  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
+      get<1>(Decls), cxxConstructorDecl(hasName("foo")));
+  EXPECT_TRUE(testStructuralMatch(First, Second));
+}
+
 struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
 
 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
@@ -853,5 +873,25 @@
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
+  auto Decls = makeNamedDecls("template <bool b> struct foo {explicit(b) foo(int);};",
+                              "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX2a);
+  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
+      get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
+  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
+      get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
+  EXPECT_TRUE(testStructuralMatch(First, Second));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
+  auto Decls = makeNamedDecls("template <bool b> struct foo {explicit(b) foo(int);};",
+                              "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX2a);
+  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
+      get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
+  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
+      get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
+  EXPECT_FALSE(testStructuralMatch(First, Second));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang