[AST] Check described template at structural equivalence check.

Summary:
When checking a class or function the described class or function template
is checked too.
Split StructuralEquivalenceContext::Finish into multiple functions.
Improved test with symmetric check, added new tests.

Reviewers: martong, a.sidorin, a_sidorin, bruno

Reviewed By: martong, a.sidorin

Subscribers: rnkovacs, cfe-commits

Tags: #clang

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

llvm-svn: 339256
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index d5b529c..41477dd 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -78,11 +78,18 @@
   }
 
   bool testStructuralMatch(Decl *D0, Decl *D1) {
-    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls;
-    StructuralEquivalenceContext Ctx(
-        D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls,
-        StructuralEquivalenceKind::Default, false, false);
-    return Ctx.IsEquivalent(D0, D1);
+    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
+    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
+    StructuralEquivalenceContext Ctx01(
+        D0->getASTContext(), D1->getASTContext(),
+        NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
+    StructuralEquivalenceContext Ctx10(
+        D1->getASTContext(), D0->getASTContext(),
+        NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
+    bool Eq01 = Ctx01.IsEquivalent(D0, D1);
+    bool Eq10 = Ctx10.IsEquivalent(D1, D0);
+    EXPECT_EQ(Eq01, Eq10);
+    return Eq01;
   }
 
   bool testStructuralMatch(std::tuple<Decl *, Decl *> t) {
@@ -215,6 +222,14 @@
 struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
 };
 
+TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
+  auto t = makeNamedDecls(
+      "void foo();",
+      "template<class T> void foo();",
+      Lang_CXX);
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
   auto t = makeNamedDecls("void foo(int&);",
                           "void foo(const int&);", Lang_CXX);
@@ -618,6 +633,14 @@
   EXPECT_FALSE(testStructuralMatch(R0, R1));
 }
 
+TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
+  auto t = makeDecls<CXXRecordDecl>(
+      "struct A { };",
+      "template<class T> struct A { };",
+      Lang_CXX,
+      cxxRecordDecl(hasName("A")));
+  EXPECT_FALSE(testStructuralMatch(t));
+}
 
 TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
   auto t = makeNamedDecls(