1 #include "clang/AST/ASTContext.h"
2 #include "clang/ASTMatchers/ASTMatchers.h"
3 #include "clang/AST/ASTStructuralEquivalence.h"
4 #include "clang/Frontend/ASTUnit.h"
5 #include "clang/Tooling/Tooling.h"
6 
7 #include "Language.h"
8 #include "DeclMatcher.h"
9 
10 #include "gtest/gtest.h"
11 
12 namespace clang {
13 namespace ast_matchers {
14 
15 using std::get;
16 
17 struct StructuralEquivalenceTest : ::testing::Test {
18   std::unique_ptr<ASTUnit> AST0, AST1;
19   std::string Code0, Code1; // Buffers for SourceManager
20 
21   // Get a pair of node pointers into the synthesized AST from the given code
22   // snippets. To determine the returned node, a separate matcher is specified
23   // for both snippets. The first matching node is returned.
24   template <typename NodeType, typename MatcherType>
25   std::tuple<NodeType *, NodeType *> makeDecls(
26       const std::string &SrcCode0, const std::string &SrcCode1, Language Lang,
27       const MatcherType &Matcher0, const MatcherType &Matcher1) {
28     this->Code0 = SrcCode0;
29     this->Code1 = SrcCode1;
30     ArgVector Args = getBasicRunOptionsForLanguage(Lang);
31 
32     const char *const InputFileName = "input.cc";
33 
34     AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName);
35     AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName);
36 
37     NodeType *D0 = FirstDeclMatcher<NodeType>().match(
38         AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
39     NodeType *D1 = FirstDeclMatcher<NodeType>().match(
40         AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
41 
42     return std::make_tuple(D0, D1);
43   }
44 
45   std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> makeTuDecls(
46       const std::string &SrcCode0, const std::string &SrcCode1, Language Lang) {
47     this->Code0 = SrcCode0;
48     this->Code1 = SrcCode1;
49     ArgVector Args = getBasicRunOptionsForLanguage(Lang);
50 
51     const char *const InputFileName = "input.cc";
52 
53     AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName);
54     AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName);
55 
56     return std::make_tuple(AST0->getASTContext().getTranslationUnitDecl(),
57                            AST1->getASTContext().getTranslationUnitDecl());
58   }
59 
60   // Get a pair of node pointers into the synthesized AST from the given code
61   // snippets. The same matcher is used for both snippets.
62   template <typename NodeType, typename MatcherType>
63   std::tuple<NodeType *, NodeType *> makeDecls(
64       const std::string &SrcCode0, const std::string &SrcCode1, Language Lang,
65       const MatcherType &AMatcher) {
66     return makeDecls<NodeType, MatcherType>(
67           SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
68   }
69 
70   // Get a pair of Decl pointers to the synthesized declarations from the given
71   // code snippets. We search for the first NamedDecl with given name in both
72   // snippets.
73   std::tuple<NamedDecl *, NamedDecl *> makeNamedDecls(
74       const std::string &SrcCode0, const std::string &SrcCode1,
75       Language Lang, const char *const Identifier = "foo") {
76     auto Matcher = namedDecl(hasName(Identifier));
77     return makeDecls<NamedDecl>(SrcCode0, SrcCode1, Lang, Matcher);
78   }
79 
80   bool testStructuralMatch(Decl *D0, Decl *D1) {
81     llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
82     llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
83     StructuralEquivalenceContext Ctx01(
84         D0->getASTContext(), D1->getASTContext(),
85         NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
86     StructuralEquivalenceContext Ctx10(
87         D1->getASTContext(), D0->getASTContext(),
88         NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
89     bool Eq01 = Ctx01.IsEquivalent(D0, D1);
90     bool Eq10 = Ctx10.IsEquivalent(D1, D0);
91     EXPECT_EQ(Eq01, Eq10);
92     return Eq01;
93   }
94 
95   bool testStructuralMatch(std::tuple<Decl *, Decl *> t) {
96     return testStructuralMatch(get<0>(t), get<1>(t));
97   }
98 };
99 
100 TEST_F(StructuralEquivalenceTest, Int) {
101   auto Decls = makeNamedDecls("int foo;", "int foo;", Lang_CXX);
102   EXPECT_TRUE(testStructuralMatch(Decls));
103 }
104 
105 TEST_F(StructuralEquivalenceTest, IntVsSignedInt) {
106   auto Decls = makeNamedDecls("int foo;", "signed int foo;", Lang_CXX);
107   EXPECT_TRUE(testStructuralMatch(Decls));
108 }
109 
110 TEST_F(StructuralEquivalenceTest, Char) {
111   auto Decls = makeNamedDecls("char foo;", "char foo;", Lang_CXX);
112   EXPECT_TRUE(testStructuralMatch(Decls));
113 }
114 
115 // This test is disabled for now.
116 // FIXME Whether this is equivalent is dependendant on the target.
117 TEST_F(StructuralEquivalenceTest, DISABLED_CharVsSignedChar) {
118   auto Decls = makeNamedDecls("char foo;", "signed char foo;", Lang_CXX);
119   EXPECT_FALSE(testStructuralMatch(Decls));
120 }
121 
122 TEST_F(StructuralEquivalenceTest, ForwardRecordDecl) {
123   auto Decls = makeNamedDecls("struct foo;", "struct foo;", Lang_CXX);
124   EXPECT_TRUE(testStructuralMatch(Decls));
125 }
126 
127 TEST_F(StructuralEquivalenceTest, IntVsSignedIntInStruct) {
128   auto Decls = makeNamedDecls("struct foo { int x; };",
129                               "struct foo { signed int x; };", Lang_CXX);
130   EXPECT_TRUE(testStructuralMatch(Decls));
131 }
132 
133 TEST_F(StructuralEquivalenceTest, CharVsSignedCharInStruct) {
134   auto Decls = makeNamedDecls("struct foo { char x; };",
135                               "struct foo { signed char x; };", Lang_CXX);
136   EXPECT_FALSE(testStructuralMatch(Decls));
137 }
138 
139 TEST_F(StructuralEquivalenceTest, IntVsSignedIntTemplateSpec) {
140   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
141       R"(template <class T> struct foo; template<> struct foo<int>{};)",
142       R"(template <class T> struct foo; template<> struct foo<signed int>{};)",
143       Lang_CXX,
144       classTemplateSpecializationDecl());
145   auto Spec0 = get<0>(Decls);
146   auto Spec1 = get<1>(Decls);
147   EXPECT_TRUE(testStructuralMatch(Spec0, Spec1));
148 }
149 
150 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpec) {
151   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
152       R"(template <class T> struct foo; template<> struct foo<char>{};)",
153       R"(template <class T> struct foo; template<> struct foo<signed char>{};)",
154       Lang_CXX,
155       classTemplateSpecializationDecl());
156   auto Spec0 = get<0>(Decls);
157   auto Spec1 = get<1>(Decls);
158   EXPECT_FALSE(testStructuralMatch(Spec0, Spec1));
159 }
160 
161 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpecWithInheritance) {
162   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
163       R"(
164       struct true_type{};
165       template <class T> struct foo;
166       template<> struct foo<char> : true_type {};
167       )",
168       R"(
169       struct true_type{};
170       template <class T> struct foo;
171       template<> struct foo<signed char> : true_type {};
172       )",
173       Lang_CXX,
174       classTemplateSpecializationDecl());
175   EXPECT_FALSE(testStructuralMatch(Decls));
176 }
177 
178 // This test is disabled for now.
179 // FIXME Enable it, once the check is implemented.
180 TEST_F(StructuralEquivalenceTest, DISABLED_WrongOrderInNamespace) {
181   auto Code =
182       R"(
183       namespace NS {
184       template <class T> class Base {
185           int a;
186       };
187       class Derived : Base<Derived> {
188       };
189       }
190       void foo(NS::Derived &);
191       )";
192   auto Decls = makeNamedDecls(Code, Code, Lang_CXX);
193 
194   NamespaceDecl *NS =
195       LastDeclMatcher<NamespaceDecl>().match(get<1>(Decls), namespaceDecl());
196   ClassTemplateDecl *TD = LastDeclMatcher<ClassTemplateDecl>().match(
197       get<1>(Decls), classTemplateDecl(hasName("Base")));
198 
199   // Reorder the decls, move the TD to the last place in the DC.
200   NS->removeDecl(TD);
201   NS->addDeclInternal(TD);
202 
203   EXPECT_FALSE(testStructuralMatch(Decls));
204 }
205 
206 TEST_F(StructuralEquivalenceTest, WrongOrderOfFieldsInClass) {
207   auto Code = "class X { int a; int b; };";
208   auto Decls = makeNamedDecls(Code, Code, Lang_CXX, "X");
209 
210   CXXRecordDecl *RD = FirstDeclMatcher<CXXRecordDecl>().match(
211       get<1>(Decls), cxxRecordDecl(hasName("X")));
212   FieldDecl *FD =
213       FirstDeclMatcher<FieldDecl>().match(get<1>(Decls), fieldDecl(hasName("a")));
214 
215   // Reorder the FieldDecls
216   RD->removeDecl(FD);
217   RD->addDeclInternal(FD);
218 
219   EXPECT_FALSE(testStructuralMatch(Decls));
220 }
221 
222 struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
223 };
224 
225 TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
226   auto t = makeNamedDecls(
227       "void foo();",
228       "template<class T> void foo();",
229       Lang_CXX);
230   EXPECT_FALSE(testStructuralMatch(t));
231 }
232 
233 TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
234   auto t = makeDecls<FunctionDecl>(
235       "struct X{}; bool operator<(X, X);",
236       "struct X{}; bool operator==(X, X);", Lang_CXX,
237       functionDecl(hasOverloadedOperatorName("<")),
238       functionDecl(hasOverloadedOperatorName("==")));
239   EXPECT_FALSE(testStructuralMatch(t));
240 }
241 
242 TEST_F(StructuralEquivalenceFunctionTest, SameOperators) {
243   auto t = makeDecls<FunctionDecl>(
244       "struct X{}; bool operator<(X, X);",
245       "struct X{}; bool operator<(X, X);", Lang_CXX,
246       functionDecl(hasOverloadedOperatorName("<")),
247       functionDecl(hasOverloadedOperatorName("<")));
248   EXPECT_TRUE(testStructuralMatch(t));
249 }
250 
251 TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) {
252   auto t = makeDecls<FunctionDecl>(
253       "struct X{ X(); };",
254       "struct X{ ~X(); };", Lang_CXX,
255       cxxConstructorDecl(),
256       cxxDestructorDecl());
257   EXPECT_FALSE(testStructuralMatch(t));
258 }
259 
260 TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
261   auto t = makeNamedDecls("void foo(int&);",
262                           "void foo(const int&);", Lang_CXX);
263   EXPECT_FALSE(testStructuralMatch(t));
264 }
265 
266 TEST_F(StructuralEquivalenceFunctionTest, ParamConstSimple) {
267   auto t = makeNamedDecls("void foo(int);",
268                           "void foo(const int);", Lang_CXX);
269   EXPECT_TRUE(testStructuralMatch(t));
270   // consider this OK
271 }
272 
273 TEST_F(StructuralEquivalenceFunctionTest, Throw) {
274   auto t = makeNamedDecls("void foo();",
275                           "void foo() throw();", Lang_CXX);
276   EXPECT_FALSE(testStructuralMatch(t));
277 }
278 
279 TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
280   auto t = makeNamedDecls("void foo();",
281                           "void foo() noexcept;", Lang_CXX11);
282   EXPECT_FALSE(testStructuralMatch(t));
283 }
284 
285 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexcept) {
286   auto t = makeNamedDecls("void foo() throw();",
287                           "void foo() noexcept;", Lang_CXX11);
288   EXPECT_FALSE(testStructuralMatch(t));
289 }
290 
291 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptFalse) {
292   auto t = makeNamedDecls("void foo() throw();",
293                           "void foo() noexcept(false);", Lang_CXX11);
294   EXPECT_FALSE(testStructuralMatch(t));
295 }
296 
297 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptTrue) {
298   auto t = makeNamedDecls("void foo() throw();",
299                           "void foo() noexcept(true);", Lang_CXX11);
300   EXPECT_FALSE(testStructuralMatch(t));
301 }
302 
303 TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
304   auto t = makeNamedDecls("void foo() noexcept(false);",
305                           "void foo() noexcept(true);", Lang_CXX11);
306   EXPECT_FALSE(testStructuralMatch(t));
307 }
308 
309 TEST_F(StructuralEquivalenceFunctionTest, NoexceptMatch) {
310   auto t = makeNamedDecls("void foo() noexcept(false);",
311                           "void foo() noexcept(false);", Lang_CXX11);
312   EXPECT_TRUE(testStructuralMatch(t));
313 }
314 
315 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptFalse) {
316   auto t = makeNamedDecls("void foo() noexcept;",
317                           "void foo() noexcept(false);", Lang_CXX11);
318   EXPECT_FALSE(testStructuralMatch(t));
319 }
320 
321 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptTrue) {
322   auto t = makeNamedDecls("void foo() noexcept;",
323                           "void foo() noexcept(true);", Lang_CXX11);
324   EXPECT_FALSE(testStructuralMatch(t));
325 }
326 
327 TEST_F(StructuralEquivalenceFunctionTest, ReturnType) {
328   auto t = makeNamedDecls("char foo();",
329                           "int foo();", Lang_CXX);
330   EXPECT_FALSE(testStructuralMatch(t));
331 }
332 
333 TEST_F(StructuralEquivalenceFunctionTest, ReturnConst) {
334   auto t = makeNamedDecls("char foo();",
335                           "const char foo();", Lang_CXX);
336   EXPECT_FALSE(testStructuralMatch(t));
337 }
338 
339 TEST_F(StructuralEquivalenceFunctionTest, ReturnRef) {
340   auto t = makeNamedDecls("char &foo();",
341                           "char &&foo();", Lang_CXX11);
342   EXPECT_FALSE(testStructuralMatch(t));
343 }
344 
345 TEST_F(StructuralEquivalenceFunctionTest, ParamCount) {
346   auto t = makeNamedDecls("void foo(int);",
347                           "void foo(int, int);", Lang_CXX);
348   EXPECT_FALSE(testStructuralMatch(t));
349 }
350 
351 TEST_F(StructuralEquivalenceFunctionTest, ParamType) {
352   auto t = makeNamedDecls("void foo(int);",
353                           "void foo(char);", Lang_CXX);
354   EXPECT_FALSE(testStructuralMatch(t));
355 }
356 
357 TEST_F(StructuralEquivalenceFunctionTest, ParamName) {
358   auto t = makeNamedDecls("void foo(int a);",
359                           "void foo(int b);", Lang_CXX);
360   EXPECT_TRUE(testStructuralMatch(t));
361 }
362 
363 TEST_F(StructuralEquivalenceFunctionTest, Variadic) {
364   auto t = makeNamedDecls("void foo(int x...);",
365                           "void foo(int x);", Lang_CXX);
366   EXPECT_FALSE(testStructuralMatch(t));
367 }
368 
369 TEST_F(StructuralEquivalenceFunctionTest, ParamPtr) {
370   auto t = makeNamedDecls("void foo(int *);",
371                           "void foo(int);", Lang_CXX);
372   EXPECT_FALSE(testStructuralMatch(t));
373 }
374 
375 TEST_F(StructuralEquivalenceFunctionTest, NameInParen) {
376   auto t = makeNamedDecls(
377       "void ((foo))();",
378       "void foo();",
379       Lang_CXX);
380   EXPECT_TRUE(testStructuralMatch(t));
381 }
382 
383 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithExceptionSpec) {
384   auto t = makeNamedDecls(
385       "void (foo)() throw(int);",
386       "void (foo)() noexcept;",
387       Lang_CXX11);
388   EXPECT_FALSE(testStructuralMatch(t));
389 }
390 
391 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) {
392   auto t = makeNamedDecls(
393       "struct A { void (foo)() const; };",
394       "struct A { void (foo)(); };",
395       Lang_CXX11);
396   EXPECT_FALSE(testStructuralMatch(t));
397 }
398 
399 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
400   auto t = makeNamedDecls(
401       "__attribute__((noreturn)) void foo();",
402       "                          void foo();",
403       Lang_C);
404   EXPECT_TRUE(testStructuralMatch(t));
405 }
406 
407 TEST_F(StructuralEquivalenceFunctionTest,
408     FunctionsWithDifferentCallingConventions) {
409   // These attributes may not be available on certain platforms.
410   if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
411       llvm::Triple::x86_64)
412     return;
413   auto t = makeNamedDecls(
414       "__attribute__((preserve_all)) void foo();",
415       "__attribute__((ms_abi))   void foo();",
416       Lang_C);
417   EXPECT_FALSE(testStructuralMatch(t));
418 }
419 
420 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) {
421   if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
422       llvm::Triple::x86_64)
423     return;
424   auto t = makeNamedDecls(
425       "__attribute__((no_caller_saved_registers)) void foo();",
426       "                                           void foo();",
427       Lang_C);
428   EXPECT_FALSE(testStructuralMatch(t));
429 }
430 
431 struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
432 };
433 
434 TEST_F(StructuralEquivalenceCXXMethodTest, Virtual) {
435   auto t = makeDecls<CXXMethodDecl>(
436       "struct X { void foo(); };",
437       "struct X { virtual void foo(); };", Lang_CXX,
438       cxxMethodDecl(hasName("foo")));
439   EXPECT_FALSE(testStructuralMatch(t));
440 }
441 
442 TEST_F(StructuralEquivalenceCXXMethodTest, Pure) {
443   auto t = makeNamedDecls("struct X { virtual void foo(); };",
444                           "struct X { virtual void foo() = 0; };", Lang_CXX);
445   EXPECT_FALSE(testStructuralMatch(t));
446 }
447 
448 TEST_F(StructuralEquivalenceCXXMethodTest, DISABLED_Final) {
449   // The final-ness is not checked yet.
450   auto t = makeNamedDecls("struct X { virtual void foo(); };",
451                           "struct X { virtual void foo() final; };", Lang_CXX);
452   EXPECT_FALSE(testStructuralMatch(t));
453 }
454 
455 TEST_F(StructuralEquivalenceCXXMethodTest, Const) {
456   auto t = makeNamedDecls("struct X { void foo(); };",
457                           "struct X { void foo() const; };", Lang_CXX);
458   EXPECT_FALSE(testStructuralMatch(t));
459 }
460 
461 TEST_F(StructuralEquivalenceCXXMethodTest, Static) {
462   auto t = makeNamedDecls("struct X { void foo(); };",
463                           "struct X { static void foo(); };", Lang_CXX);
464   EXPECT_FALSE(testStructuralMatch(t));
465 }
466 
467 TEST_F(StructuralEquivalenceCXXMethodTest, Ref1) {
468   auto t = makeNamedDecls("struct X { void foo(); };",
469                           "struct X { void foo() &&; };", Lang_CXX11);
470   EXPECT_FALSE(testStructuralMatch(t));
471 }
472 
473 TEST_F(StructuralEquivalenceCXXMethodTest, Ref2) {
474   auto t = makeNamedDecls("struct X { void foo() &; };",
475                           "struct X { void foo() &&; };", Lang_CXX11);
476   EXPECT_FALSE(testStructuralMatch(t));
477 }
478 
479 TEST_F(StructuralEquivalenceCXXMethodTest, AccessSpecifier) {
480   auto t = makeDecls<CXXMethodDecl>(
481       "struct X { public: void foo(); };",
482       "struct X { private: void foo(); };", Lang_CXX,
483       cxxMethodDecl(hasName("foo")));
484   EXPECT_FALSE(testStructuralMatch(t));
485 }
486 
487 TEST_F(StructuralEquivalenceCXXMethodTest, Delete) {
488   auto t = makeNamedDecls("struct X { void foo(); };",
489                           "struct X { void foo() = delete; };", Lang_CXX11);
490   EXPECT_FALSE(testStructuralMatch(t));
491 }
492 
493 TEST_F(StructuralEquivalenceCXXMethodTest, Constructor) {
494   auto t = makeDecls<FunctionDecl>(
495       "void foo();", "struct foo { foo(); };", Lang_CXX,
496       functionDecl(hasName("foo")), cxxConstructorDecl(hasName("foo")));
497   EXPECT_FALSE(testStructuralMatch(t));
498 }
499 
500 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorParam) {
501   auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
502                                          "struct X { X(int); };", Lang_CXX,
503                                          cxxConstructorDecl(hasName("X")));
504   EXPECT_FALSE(testStructuralMatch(t));
505 }
506 
507 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorExplicit) {
508   auto t = makeDecls<CXXConstructorDecl>("struct X { X(int); };",
509                                          "struct X { explicit X(int); };",
510                                          Lang_CXX11,
511                                          cxxConstructorDecl(hasName("X")));
512   EXPECT_FALSE(testStructuralMatch(t));
513 }
514 
515 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorDefault) {
516   auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
517                                          "struct X { X() = default; };",
518                                          Lang_CXX11,
519                                          cxxConstructorDecl(hasName("X")));
520   EXPECT_FALSE(testStructuralMatch(t));
521 }
522 
523 TEST_F(StructuralEquivalenceCXXMethodTest, Conversion) {
524   auto t = makeDecls<CXXConversionDecl>("struct X { operator bool(); };",
525                                         "struct X { operator char(); };",
526                                          Lang_CXX11,
527                                          cxxConversionDecl());
528   EXPECT_FALSE(testStructuralMatch(t));
529 }
530 
531 TEST_F(StructuralEquivalenceCXXMethodTest, Operator) {
532   auto t = makeDecls<FunctionDecl>(
533       "struct X { int operator +(int); };",
534       "struct X { int operator -(int); };", Lang_CXX,
535       functionDecl(hasOverloadedOperatorName("+")),
536       functionDecl(hasOverloadedOperatorName("-")));
537   EXPECT_FALSE(testStructuralMatch(t));
538 }
539 
540 TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass1) {
541   auto t = makeDecls<FunctionDecl>(
542       "struct X { virtual void f(); }; void X::f() { }",
543       "struct X { virtual void f() { }; };",
544       Lang_CXX,
545       functionDecl(allOf(hasName("f"), isDefinition())));
546   EXPECT_TRUE(testStructuralMatch(t));
547 }
548 
549 TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass2) {
550   auto t = makeDecls<FunctionDecl>(
551       "struct X { virtual void f(); }; void X::f() { }",
552       "struct X { void f(); }; void X::f() { }",
553       Lang_CXX,
554       functionDecl(allOf(hasName("f"), isDefinition())));
555   EXPECT_FALSE(testStructuralMatch(t));
556 }
557 
558 struct StructuralEquivalenceRecordTest : StructuralEquivalenceTest {
559   // FIXME Use a common getRecordDecl with ASTImporterTest.cpp!
560   RecordDecl *getRecordDecl(FieldDecl *FD) {
561     auto *ET = cast<ElaboratedType>(FD->getType().getTypePtr());
562     return cast<RecordType>(ET->getNamedType().getTypePtr())->getDecl();
563   };
564 };
565 
566 TEST_F(StructuralEquivalenceRecordTest, Name) {
567   auto t = makeDecls<CXXRecordDecl>(
568       "struct A{ };",
569       "struct B{ };",
570       Lang_CXX,
571       cxxRecordDecl(hasName("A")),
572       cxxRecordDecl(hasName("B")));
573   EXPECT_FALSE(testStructuralMatch(t));
574 }
575 
576 TEST_F(StructuralEquivalenceRecordTest, Fields) {
577   auto t = makeNamedDecls(
578       "struct foo{ int x; };",
579       "struct foo{ char x; };",
580       Lang_CXX);
581   EXPECT_FALSE(testStructuralMatch(t));
582 }
583 
584 TEST_F(StructuralEquivalenceRecordTest, DISABLED_Methods) {
585   // Currently, methods of a class are not checked at class equivalence.
586   auto t = makeNamedDecls(
587       "struct foo{ int x(); };",
588       "struct foo{ char x(); };",
589       Lang_CXX);
590   EXPECT_FALSE(testStructuralMatch(t));
591 }
592 
593 TEST_F(StructuralEquivalenceRecordTest, Bases) {
594   auto t = makeNamedDecls(
595       "struct A{ }; struct foo: A { };",
596       "struct B{ }; struct foo: B { };",
597       Lang_CXX);
598   EXPECT_FALSE(testStructuralMatch(t));
599 }
600 
601 TEST_F(StructuralEquivalenceRecordTest, InheritanceVirtual) {
602   auto t = makeNamedDecls(
603       "struct A{ }; struct foo: A { };",
604       "struct A{ }; struct foo: virtual A { };",
605       Lang_CXX);
606   EXPECT_FALSE(testStructuralMatch(t));
607 }
608 
609 TEST_F(StructuralEquivalenceRecordTest, DISABLED_InheritanceType) {
610   // Access specifier in inheritance is not checked yet.
611   auto t = makeNamedDecls(
612       "struct A{ }; struct foo: public A { };",
613       "struct A{ }; struct foo: private A { };",
614       Lang_CXX);
615   EXPECT_FALSE(testStructuralMatch(t));
616 }
617 
618 TEST_F(StructuralEquivalenceRecordTest, Match) {
619   auto Code = R"(
620       struct A{ };
621       struct B{ };
622       struct foo: A, virtual B {
623         void x();
624         int a;
625       };
626       )";
627   auto t = makeNamedDecls(Code, Code, Lang_CXX);
628   EXPECT_TRUE(testStructuralMatch(t));
629 }
630 
631 TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) {
632   auto t = makeTuDecls(
633       R"(
634       struct A {
635         struct {
636           struct A *next;
637         } entry0;
638         struct {
639           struct A *next;
640         } entry1;
641       };
642       )",
643       "", Lang_C);
644   auto *TU = get<0>(t);
645   auto *Entry0 =
646       FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry0")));
647   auto *Entry1 =
648       FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry1")));
649   auto *R0 = getRecordDecl(Entry0);
650   auto *R1 = getRecordDecl(Entry1);
651 
652   ASSERT_NE(R0, R1);
653   EXPECT_TRUE(testStructuralMatch(R0, R0));
654   EXPECT_TRUE(testStructuralMatch(R1, R1));
655   EXPECT_FALSE(testStructuralMatch(R0, R1));
656 }
657 
658 TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
659   auto t = makeTuDecls(
660       R"(
661       struct X {
662         struct {
663           int a;
664         };
665         struct {
666           int b;
667         };
668       };
669       )",
670       "", Lang_C);
671   auto *TU = get<0>(t);
672   auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
673       TU, indirectFieldDecl(hasName("a")));
674   auto *FA = cast<FieldDecl>(A->chain().front());
675   RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
676   auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
677       TU, indirectFieldDecl(hasName("b")));
678   auto *FB = cast<FieldDecl>(B->chain().front());
679   RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
680 
681   ASSERT_NE(RA, RB);
682   EXPECT_TRUE(testStructuralMatch(RA, RA));
683   EXPECT_TRUE(testStructuralMatch(RB, RB));
684   EXPECT_FALSE(testStructuralMatch(RA, RB));
685 }
686 
687 TEST_F(StructuralEquivalenceRecordTest,
688        RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) {
689   auto t = makeTuDecls(
690       R"(
691       struct X {
692         struct { int a; };
693         struct { int b; };
694       };
695       )",
696       R"(
697       struct X { // The order is reversed.
698         struct { int b; };
699         struct { int a; };
700       };
701       )",
702       Lang_C);
703 
704   auto *TU = get<0>(t);
705   auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
706       TU, indirectFieldDecl(hasName("a")));
707   auto *FA = cast<FieldDecl>(A->chain().front());
708   RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
709 
710   auto *TU1 = get<1>(t);
711   auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
712       TU1, indirectFieldDecl(hasName("a")));
713   auto *FA1 = cast<FieldDecl>(A1->chain().front());
714   RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
715 
716   RecordDecl *X =
717       FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
718   RecordDecl *X1 =
719       FirstDeclMatcher<RecordDecl>().match(TU1, recordDecl(hasName("X")));
720   ASSERT_NE(X, X1);
721   EXPECT_FALSE(testStructuralMatch(X, X1));
722 
723   ASSERT_NE(RA, RA1);
724   EXPECT_TRUE(testStructuralMatch(RA, RA));
725   EXPECT_TRUE(testStructuralMatch(RA1, RA1));
726   EXPECT_FALSE(testStructuralMatch(RA1, RA));
727 }
728 
729 TEST_F(StructuralEquivalenceRecordTest,
730        UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) {
731   auto Code =
732       R"(
733       struct A {
734         struct {
735           struct A *next;
736         } entry0;
737         struct {
738           struct A *next;
739         } entry1;
740       };
741       )";
742   auto t = makeTuDecls(Code, Code, Lang_C);
743 
744   auto *FromTU = get<0>(t);
745   auto *Entry1 =
746       FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("entry1")));
747 
748   auto *ToTU = get<1>(t);
749   auto *Entry0 =
750       FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
751   auto *A =
752       FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
753   A->startDefinition(); // Set isBeingDefined, getDefinition() will return a
754                         // nullptr. This may be the case during ASTImport.
755 
756   auto *R0 = getRecordDecl(Entry0);
757   auto *R1 = getRecordDecl(Entry1);
758 
759   ASSERT_NE(R0, R1);
760   EXPECT_TRUE(testStructuralMatch(R0, R0));
761   EXPECT_TRUE(testStructuralMatch(R1, R1));
762   EXPECT_FALSE(testStructuralMatch(R0, R1));
763 }
764 
765 TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
766   auto t = makeDecls<CXXRecordDecl>(
767       "struct A { };",
768       "template<class T> struct A { };",
769       Lang_CXX,
770       cxxRecordDecl(hasName("A")));
771   EXPECT_FALSE(testStructuralMatch(t));
772 }
773 
774 TEST_F(StructuralEquivalenceRecordTest,
775     FwdDeclRecordShouldBeEqualWithFwdDeclRecord) {
776   auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11);
777   EXPECT_TRUE(testStructuralMatch(t));
778 }
779 
780 TEST_F(StructuralEquivalenceRecordTest,
781        FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) {
782   auto t =
783       makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11);
784   EXPECT_TRUE(testStructuralMatch(t));
785 }
786 
787 TEST_F(StructuralEquivalenceRecordTest,
788        RecordShouldBeEqualWithRecordWhichHasDefinition) {
789   auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };",
790                           Lang_CXX11);
791   EXPECT_TRUE(testStructuralMatch(t));
792 }
793 
794 TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) {
795   auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };",
796                           Lang_CXX11);
797   EXPECT_FALSE(testStructuralMatch(t));
798 }
799 
800 struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {};
801 
802 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) {
803   // Get the LambdaExprs, unfortunately we can't match directly the underlying
804   // implicit CXXRecordDecl of the Lambda classes.
805   auto t = makeDecls<LambdaExpr>(
806       "void f() { auto L0 = [](int){}; }",
807       "void f() { auto L1 = [](){}; }",
808       Lang_CXX11,
809       lambdaExpr(),
810       lambdaExpr());
811   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
812   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
813   EXPECT_FALSE(testStructuralMatch(L0, L1));
814 }
815 
816 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqMethods) {
817   auto t = makeDecls<LambdaExpr>(
818       "void f() { auto L0 = [](int){}; }",
819       "void f() { auto L1 = [](int){}; }",
820       Lang_CXX11,
821       lambdaExpr(),
822       lambdaExpr());
823   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
824   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
825   EXPECT_TRUE(testStructuralMatch(L0, L1));
826 }
827 
828 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentFields) {
829   auto t = makeDecls<LambdaExpr>(
830       "void f() { char* X; auto L0 = [X](){}; }",
831       "void f() { float X; auto L1 = [X](){}; }",
832       Lang_CXX11,
833       lambdaExpr(),
834       lambdaExpr());
835   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
836   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
837   EXPECT_FALSE(testStructuralMatch(L0, L1));
838 }
839 
840 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqFields) {
841   auto t = makeDecls<LambdaExpr>(
842       "void f() { float X; auto L0 = [X](){}; }",
843       "void f() { float X; auto L1 = [X](){}; }",
844       Lang_CXX11,
845       lambdaExpr(),
846       lambdaExpr());
847   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
848   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
849   EXPECT_TRUE(testStructuralMatch(L0, L1));
850 }
851 
852 TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
853   auto t = makeNamedDecls(
854       "struct A{ }; struct B{ }; void foo(A a, A b);",
855       "struct A{ }; struct B{ }; void foo(A a, B b);",
856       Lang_CXX);
857   EXPECT_FALSE(testStructuralMatch(t));
858 }
859 
860 TEST_F(StructuralEquivalenceTest, ExplicitBoolDifferent) {
861   auto Decls = makeNamedDecls("struct foo {explicit(false) foo(int);};",
862                               "struct foo {explicit(true) foo(int);};", Lang_CXX2a);
863   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
864       get<0>(Decls), cxxConstructorDecl(hasName("foo")));
865   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
866       get<1>(Decls), cxxConstructorDecl(hasName("foo")));
867   EXPECT_FALSE(testStructuralMatch(First, Second));
868 }
869 
870 TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
871   auto Decls = makeNamedDecls("struct foo {explicit(true) foo(int);};",
872                               "struct foo {explicit(true) foo(int);};", Lang_CXX2a);
873   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
874       get<0>(Decls), cxxConstructorDecl(hasName("foo")));
875   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
876       get<1>(Decls), cxxConstructorDecl(hasName("foo")));
877   EXPECT_TRUE(testStructuralMatch(First, Second));
878 }
879 
880 struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
881 
882 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
883   auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
884   EXPECT_TRUE(testStructuralMatch(t));
885 }
886 
887 TEST_F(StructuralEquivalenceEnumTest,
888        FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
889   auto t =
890       makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
891   EXPECT_TRUE(testStructuralMatch(t));
892 }
893 
894 TEST_F(StructuralEquivalenceEnumTest,
895        EnumShouldBeEqualWithEnumWhichHasDefinition) {
896   auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
897                           Lang_CXX11);
898   EXPECT_TRUE(testStructuralMatch(t));
899 }
900 
901 TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
902   auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
903                           Lang_CXX11);
904   EXPECT_FALSE(testStructuralMatch(t));
905 }
906 
907 struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
908 
909 TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
910   auto t = makeNamedDecls("template <class T> struct foo;",
911                           "template <class T> struct foo;", Lang_CXX);
912   EXPECT_TRUE(testStructuralMatch(t));
913 }
914 
915 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
916   auto t = makeNamedDecls("template <class T> struct foo;",
917                           "template <class U> struct foo;", Lang_CXX);
918   EXPECT_TRUE(testStructuralMatch(t));
919 }
920 
921 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
922   auto t = makeNamedDecls("template <class T> struct foo;",
923                           "template <int T> struct foo;", Lang_CXX);
924   EXPECT_FALSE(testStructuralMatch(t));
925 }
926 
927 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
928   auto Decls = makeNamedDecls("template <bool b> struct foo {explicit(b) foo(int);};",
929                               "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX2a);
930   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
931       get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
932   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
933       get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
934   EXPECT_TRUE(testStructuralMatch(First, Second));
935 }
936 
937 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
938   auto Decls = makeNamedDecls("template <bool b> struct foo {explicit(b) foo(int);};",
939                               "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX2a);
940   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
941       get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
942   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
943       get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
944   EXPECT_FALSE(testStructuralMatch(First, Second));
945 }
946 
947 TEST_F(StructuralEquivalenceTemplateTest,
948        TemplateVsSubstTemplateTemplateParmInArgEq) {
949   auto t = makeDecls<ClassTemplateSpecializationDecl>(
950       R"(
951 template <typename P1> class Arg { };
952 template <template <typename PP1> class P1> class Primary { };
953 
954 void f() {
955   // Make specialization with simple template.
956   Primary <Arg> A;
957 }
958       )",
959       R"(
960 template <typename P1> class Arg { };
961 template <template <typename PP1> class P1> class Primary { };
962 
963 template <template <typename PP1> class P1> class Templ {
964   void f() {
965     // Make specialization with substituted template template param.
966     Primary <P1> A;
967   };
968 };
969 
970 // Instantiate with substitution Arg into P1.
971 template class Templ <Arg>;
972       )",
973       Lang_CXX, classTemplateSpecializationDecl(hasName("Primary")));
974   EXPECT_TRUE(testStructuralMatch(t));
975 }
976 
977 TEST_F(StructuralEquivalenceTemplateTest,
978        TemplateVsSubstTemplateTemplateParmInArgNotEq) {
979   auto t = makeDecls<ClassTemplateSpecializationDecl>(
980       R"(
981 template <typename P1> class Arg { };
982 template <template <typename PP1> class P1> class Primary { };
983 
984 void f() {
985   // Make specialization with simple template.
986   Primary <Arg> A;
987 }
988       )",
989       R"(
990 // Arg is different from the other, this should cause non-equivalence.
991 template <typename P1> class Arg { int X; };
992 template <template <typename PP1> class P1> class Primary { };
993 
994 template <template <typename PP1> class P1> class Templ {
995   void f() {
996     // Make specialization with substituted template template param.
997     Primary <P1> A;
998   };
999 };
1000 
1001 // Instantiate with substitution Arg into P1.
1002 template class Templ <Arg>;
1003       )",
1004       Lang_CXX, classTemplateSpecializationDecl(hasName("Primary")));
1005   EXPECT_FALSE(testStructuralMatch(t));
1006 }
1007 
1008 struct StructuralEquivalenceDependentTemplateArgsTest
1009     : StructuralEquivalenceTemplateTest {};
1010 
1011 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1012        SameStructsInDependentArgs) {
1013   std::string Code =
1014       R"(
1015       template <typename>
1016       struct S1;
1017 
1018       template <typename>
1019       struct enable_if;
1020 
1021       struct S
1022       {
1023         template <typename T, typename enable_if<S1<T>>::type>
1024         void f();
1025       };
1026       )";
1027   auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1028                                            functionTemplateDecl(hasName("f")));
1029   EXPECT_TRUE(testStructuralMatch(t));
1030 }
1031 
1032 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1033        DifferentStructsInDependentArgs) {
1034   std::string Code =
1035       R"(
1036       template <typename>
1037       struct S1;
1038 
1039       template <typename>
1040       struct S2;
1041 
1042       template <typename>
1043       struct enable_if;
1044       )";
1045   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1046       struct S
1047       {
1048         template <typename T, typename enable_if<S1<T>>::type>
1049         void f();
1050       };
1051       )",
1052                                            Code + R"(
1053       struct S
1054       {
1055         template <typename T, typename enable_if<S2<T>>::type>
1056         void f();
1057       };
1058       )",
1059                                            Lang_CXX11,
1060                                            functionTemplateDecl(hasName("f")));
1061   EXPECT_FALSE(testStructuralMatch(t));
1062 }
1063 
1064 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1065        SameStructsInDependentScopeDeclRefExpr) {
1066   std::string Code =
1067       R"(
1068       template <typename>
1069       struct S1;
1070 
1071       template <bool>
1072       struct enable_if;
1073 
1074       struct S
1075       {
1076         template <typename T, typename enable_if<S1<T>::value>::type>
1077         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1078       };
1079       )";
1080   auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1081                                            functionTemplateDecl(hasName("f")));
1082   EXPECT_TRUE(testStructuralMatch(t));
1083 }
1084 
1085 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1086        DifferentStructsInDependentScopeDeclRefExpr) {
1087   std::string Code =
1088       R"(
1089       template <typename>
1090       struct S1;
1091 
1092       template <typename>
1093       struct S2;
1094 
1095       template <bool>
1096       struct enable_if;
1097       )";
1098   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1099       struct S
1100       {
1101         template <typename T, typename enable_if<S1<T>::value>::type>
1102         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1103       };
1104       )",
1105                                            Code + R"(
1106       struct S
1107       {
1108         template <typename T, typename enable_if<S2<T>::value>::type>
1109         void f();
1110       };
1111       )",
1112                                            Lang_CXX,
1113                                            functionTemplateDecl(hasName("f")));
1114   EXPECT_FALSE(testStructuralMatch(t));
1115 }
1116 
1117 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1118        DifferentValueInDependentScopeDeclRefExpr) {
1119   std::string Code =
1120       R"(
1121       template <typename>
1122       struct S1;
1123 
1124       template <bool>
1125       struct enable_if;
1126       )";
1127   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1128       struct S
1129       {
1130         template <typename T, typename enable_if<S1<T>::value1>::type>
1131         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1132       };
1133       )",
1134                                            Code + R"(
1135       struct S
1136       {
1137         template <typename T, typename enable_if<S1<T>::value2>::type>
1138         void f();
1139       };
1140       )",
1141                                            Lang_CXX,
1142                                            functionTemplateDecl(hasName("f")));
1143   EXPECT_FALSE(testStructuralMatch(t));
1144 }
1145 
1146 TEST_F(
1147     StructuralEquivalenceTemplateTest,
1148     ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) {
1149   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1150       R"(
1151       template <class T> struct Primary {};
1152       namespace N {
1153         struct Arg;
1154       }
1155       // Explicit instantiation with qualified name.
1156       template struct Primary<N::Arg>;
1157       )",
1158       R"(
1159       template <class T> struct Primary {};
1160       namespace N {
1161         struct Arg;
1162       }
1163       using namespace N;
1164       // Explicit instantiation with UNqualified name.
1165       template struct Primary<Arg>;
1166       )",
1167       Lang_CXX,
1168       classTemplateSpecializationDecl(hasName("Primary")));
1169   EXPECT_TRUE(testStructuralMatch(t));
1170 }
1171 
1172 TEST_F(
1173     StructuralEquivalenceTemplateTest,
1174     ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) {
1175   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1176       R"(
1177       template <class T> struct Primary {};
1178       namespace N {
1179         struct Arg { int a; };
1180       }
1181       // Explicit instantiation with qualified name.
1182       template struct Primary<N::Arg>;
1183       )",
1184       R"(
1185       template <class T> struct Primary {};
1186       namespace N {
1187         // This struct is not equivalent with the other in the prev TU.
1188         struct Arg { double b; }; // -- Field mismatch.
1189       }
1190       using namespace N;
1191       // Explicit instantiation with UNqualified name.
1192       template struct Primary<Arg>;
1193       )",
1194       Lang_CXX,
1195       classTemplateSpecializationDecl(hasName("Primary")));
1196   EXPECT_FALSE(testStructuralMatch(t));
1197 }
1198 
1199 TEST_F(
1200     StructuralEquivalenceTemplateTest,
1201     ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) {
1202   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1203       R"(
1204       template <template <class> class T> struct Primary {};
1205       namespace N {
1206         template <class T> struct Arg;
1207       }
1208       // Explicit instantiation with qualified name.
1209       template struct Primary<N::Arg>;
1210       )",
1211       R"(
1212       template <template <class> class T> struct Primary {};
1213       namespace N {
1214         template <class T> struct Arg;
1215       }
1216       using namespace N;
1217       // Explicit instantiation with UNqualified name.
1218       template struct Primary<Arg>;
1219       )",
1220       Lang_CXX,
1221       classTemplateSpecializationDecl(hasName("Primary")));
1222   EXPECT_TRUE(testStructuralMatch(t));
1223 }
1224 
1225 TEST_F(
1226     StructuralEquivalenceTemplateTest,
1227     ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) {
1228   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1229       R"(
1230       template <template <class> class T> struct Primary {};
1231       namespace N {
1232         template <class T> struct Arg { int a; };
1233       }
1234       // Explicit instantiation with qualified name.
1235       template struct Primary<N::Arg>;
1236       )",
1237       R"(
1238       template <template <class> class T> struct Primary {};
1239       namespace N {
1240         // This template is not equivalent with the other in the prev TU.
1241         template <class T> struct Arg { double b; }; // -- Field mismatch.
1242       }
1243       using namespace N;
1244       // Explicit instantiation with UNqualified name.
1245       template struct Primary<Arg>;
1246       )",
1247       Lang_CXX,
1248       classTemplateSpecializationDecl(hasName("Primary")));
1249   EXPECT_FALSE(testStructuralMatch(t));
1250 }
1251 
1252 TEST_F(
1253     StructuralEquivalenceTemplateTest,
1254     ClassTemplSpecWithInequivalentShadowedTemplArg) {
1255   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1256       R"(
1257       template <template <class> class T> struct Primary {};
1258       template <class T> struct Arg { int a; };
1259       // Explicit instantiation with ::Arg
1260       template struct Primary<Arg>;
1261       )",
1262       R"(
1263       template <template <class> class T> struct Primary {};
1264       template <class T> struct Arg { int a; };
1265       namespace N {
1266         // This template is not equivalent with the other in the global scope.
1267         template <class T> struct Arg { double b; }; // -- Field mismatch.
1268         // Explicit instantiation with N::Arg which shadows ::Arg
1269         template struct Primary<Arg>;
1270       }
1271       )",
1272       Lang_CXX,
1273       classTemplateSpecializationDecl(hasName("Primary")));
1274   EXPECT_FALSE(testStructuralMatch(t));
1275 }
1276 
1277 } // end namespace ast_matchers
1278 } // end namespace clang
1279