xref: /llvm-project/clang/unittests/AST/StructuralEquivalenceTest.cpp (revision 7a1fdbb9c0f3becdbe539f0518d182f56a9f99f8)
1 #include "clang/AST/ASTContext.h"
2 #include "clang/AST/ASTStructuralEquivalence.h"
3 #include "clang/AST/Decl.h"
4 #include "clang/AST/DeclTemplate.h"
5 #include "clang/ASTMatchers/ASTMatchers.h"
6 #include "clang/Frontend/ASTUnit.h"
7 #include "clang/Testing/CommandLineArgs.h"
8 #include "clang/Tooling/Tooling.h"
9 #include "llvm/TargetParser/Host.h"
10 
11 #include "DeclMatcher.h"
12 
13 #include "gtest/gtest.h"
14 
15 namespace clang {
16 namespace ast_matchers {
17 
18 using std::get;
19 
20 struct StructuralEquivalenceTest : ::testing::Test {
21   std::unique_ptr<ASTUnit> AST0, AST1;
22   std::string Code0, Code1; // Buffers for SourceManager
23 
24   // Parses the source code in the specified language and sets the ASTs of
25   // the current test instance to the parse result.
26   void makeASTUnits(const std::string &SrcCode0, const std::string &SrcCode1,
27                     TestLanguage Lang) {
28     this->Code0 = SrcCode0;
29     this->Code1 = SrcCode1;
30     std::vector<std::string> Args = getCommandLineArgsForTesting(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 
38   // Get a pair of node pointers into the synthesized AST from the given code
39   // snippets. To determine the returned node, a separate matcher is specified
40   // for both snippets. The first matching node is returned.
41   template <typename NodeType, typename MatcherType>
42   std::tuple<NodeType *, NodeType *>
43   makeDecls(const std::string &SrcCode0, const std::string &SrcCode1,
44             TestLanguage Lang, const MatcherType &Matcher0,
45             const MatcherType &Matcher1) {
46     makeASTUnits(SrcCode0, SrcCode1, Lang);
47 
48     NodeType *D0 = FirstDeclMatcher<NodeType>().match(
49         AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
50     NodeType *D1 = FirstDeclMatcher<NodeType>().match(
51         AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
52 
53     return std::make_tuple(D0, D1);
54   }
55 
56   std::tuple<TranslationUnitDecl *, TranslationUnitDecl *>
57   makeTuDecls(const std::string &SrcCode0, const std::string &SrcCode1,
58               TestLanguage Lang) {
59     makeASTUnits(SrcCode0, SrcCode1, Lang);
60 
61     return std::make_tuple(AST0->getASTContext().getTranslationUnitDecl(),
62                            AST1->getASTContext().getTranslationUnitDecl());
63   }
64 
65   // Get a pair of node pointers into the synthesized AST from the given code
66   // snippets. The same matcher is used for both snippets.
67   template <typename NodeType, typename MatcherType>
68   std::tuple<NodeType *, NodeType *>
69   makeDecls(const std::string &SrcCode0, const std::string &SrcCode1,
70             TestLanguage Lang, const MatcherType &AMatcher) {
71     return makeDecls<NodeType, MatcherType>(
72           SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
73   }
74 
75   // Get a pair of Decl pointers to the synthesized declarations from the given
76   // code snippets. We search for the first NamedDecl with given name in both
77   // snippets.
78   std::tuple<NamedDecl *, NamedDecl *>
79   makeNamedDecls(const std::string &SrcCode0, const std::string &SrcCode1,
80                  TestLanguage Lang, const char *const Identifier = "foo") {
81     auto Matcher = namedDecl(hasName(Identifier));
82     return makeDecls<NamedDecl>(SrcCode0, SrcCode1, Lang, Matcher);
83   }
84 
85   // Wraps a Stmt and the ASTContext that contains it.
86   struct StmtWithASTContext {
87     Stmt *S;
88     ASTContext *Context;
89     explicit StmtWithASTContext(Stmt &S, ASTContext &Context)
90         : S(&S), Context(&Context) {}
91     explicit StmtWithASTContext(FunctionDecl *FD)
92         : S(FD->getBody()), Context(&FD->getASTContext()) {}
93   };
94 
95   // Get a pair of node pointers into the synthesized AST from the given code
96   // snippets. To determine the returned node, a separate matcher is specified
97   // for both snippets. The first matching node is returned.
98   template <typename MatcherType>
99   std::tuple<StmtWithASTContext, StmtWithASTContext>
100   makeStmts(const std::string &SrcCode0, const std::string &SrcCode1,
101             TestLanguage Lang, const MatcherType &Matcher0,
102             const MatcherType &Matcher1) {
103     makeASTUnits(SrcCode0, SrcCode1, Lang);
104 
105     Stmt *S0 = FirstDeclMatcher<Stmt>().match(
106         AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
107     Stmt *S1 = FirstDeclMatcher<Stmt>().match(
108         AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
109 
110     return std::make_tuple(StmtWithASTContext(*S0, AST0->getASTContext()),
111                            StmtWithASTContext(*S1, AST1->getASTContext()));
112   }
113 
114   // Get a pair of node pointers into the synthesized AST from the given code
115   // snippets. The same matcher is used for both snippets.
116   template <typename MatcherType>
117   std::tuple<StmtWithASTContext, StmtWithASTContext>
118   makeStmts(const std::string &SrcCode0, const std::string &SrcCode1,
119             TestLanguage Lang, const MatcherType &AMatcher) {
120     return makeStmts(SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
121   }
122 
123   // Convenience function for makeStmts that wraps the code inside a function
124   // body.
125   template <typename MatcherType>
126   std::tuple<StmtWithASTContext, StmtWithASTContext>
127   makeWrappedStmts(const std::string &SrcCode0, const std::string &SrcCode1,
128                    TestLanguage Lang, const MatcherType &AMatcher) {
129     auto Wrap = [](const std::string &Src) {
130       return "void wrapped() {" + Src + ";}";
131     };
132     return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
133   }
134 
135   bool testStructuralMatch(Decl *D0, Decl *D1,
136                            bool IgnoreTemplateParmDepth = false) {
137     StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls01;
138     StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls10;
139     StructuralEquivalenceContext Ctx01(
140         D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
141         StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
142         /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
143         IgnoreTemplateParmDepth);
144     StructuralEquivalenceContext Ctx10(
145         D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
146         StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
147         /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
148         IgnoreTemplateParmDepth);
149     bool Eq01 = Ctx01.IsEquivalent(D0, D1);
150     bool Eq10 = Ctx10.IsEquivalent(D1, D0);
151     EXPECT_EQ(Eq01, Eq10);
152     return Eq01;
153   }
154 
155   bool testStructuralMatch(StmtWithASTContext S0, StmtWithASTContext S1) {
156     StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls01;
157     StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls10;
158     StructuralEquivalenceContext Ctx01(
159         *S0.Context, *S1.Context, NonEquivalentDecls01,
160         StructuralEquivalenceKind::Default, false, false);
161     StructuralEquivalenceContext Ctx10(
162         *S1.Context, *S0.Context, NonEquivalentDecls10,
163         StructuralEquivalenceKind::Default, false, false);
164     bool Eq01 = Ctx01.IsEquivalent(S0.S, S1.S);
165     bool Eq10 = Ctx10.IsEquivalent(S1.S, S0.S);
166     EXPECT_EQ(Eq01, Eq10);
167     return Eq01;
168   }
169 
170   bool
171   testStructuralMatch(std::tuple<StmtWithASTContext, StmtWithASTContext> t) {
172     return testStructuralMatch(get<0>(t), get<1>(t));
173   }
174 
175   bool testStructuralMatch(std::tuple<Decl *, Decl *> t,
176                            bool IgnoreTemplateParmDepth = false) {
177     return testStructuralMatch(get<0>(t), get<1>(t), IgnoreTemplateParmDepth);
178   }
179 };
180 
181 TEST_F(StructuralEquivalenceTest, Int) {
182   auto Decls = makeNamedDecls("int foo;", "int foo;", Lang_CXX03);
183   EXPECT_TRUE(testStructuralMatch(Decls));
184 }
185 
186 TEST_F(StructuralEquivalenceTest, IntVsSignedInt) {
187   auto Decls = makeNamedDecls("int foo;", "signed int foo;", Lang_CXX03);
188   EXPECT_TRUE(testStructuralMatch(Decls));
189 }
190 
191 TEST_F(StructuralEquivalenceTest, Char) {
192   auto Decls = makeNamedDecls("char foo;", "char foo;", Lang_CXX03);
193   EXPECT_TRUE(testStructuralMatch(Decls));
194 }
195 
196 // This test is disabled for now.
197 // FIXME Whether this is equivalent is dependent on the target.
198 TEST_F(StructuralEquivalenceTest, DISABLED_CharVsSignedChar) {
199   auto Decls = makeNamedDecls("char foo;", "signed char foo;", Lang_CXX03);
200   EXPECT_FALSE(testStructuralMatch(Decls));
201 }
202 
203 TEST_F(StructuralEquivalenceTest, ForwardRecordDecl) {
204   auto Decls = makeNamedDecls("struct foo;", "struct foo;", Lang_CXX03);
205   EXPECT_TRUE(testStructuralMatch(Decls));
206 }
207 
208 TEST_F(StructuralEquivalenceTest, IntVsSignedIntInStruct) {
209   auto Decls = makeNamedDecls("struct foo { int x; };",
210                               "struct foo { signed int x; };", Lang_CXX03);
211   EXPECT_TRUE(testStructuralMatch(Decls));
212 }
213 
214 TEST_F(StructuralEquivalenceTest, CharVsSignedCharInStruct) {
215   auto Decls = makeNamedDecls("struct foo { char x; };",
216                               "struct foo { signed char x; };", Lang_CXX03);
217   EXPECT_FALSE(testStructuralMatch(Decls));
218 }
219 
220 TEST_F(StructuralEquivalenceTest, IntVsSignedIntTemplateSpec) {
221   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
222       R"(template <class T> struct foo; template<> struct foo<int>{};)",
223       R"(template <class T> struct foo; template<> struct foo<signed int>{};)",
224       Lang_CXX03, classTemplateSpecializationDecl());
225   auto Spec0 = get<0>(Decls);
226   auto Spec1 = get<1>(Decls);
227   EXPECT_TRUE(testStructuralMatch(Spec0, Spec1));
228 }
229 
230 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpec) {
231   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
232       R"(template <class T> struct foo; template<> struct foo<char>{};)",
233       R"(template <class T> struct foo; template<> struct foo<signed char>{};)",
234       Lang_CXX03, classTemplateSpecializationDecl());
235   auto Spec0 = get<0>(Decls);
236   auto Spec1 = get<1>(Decls);
237   EXPECT_FALSE(testStructuralMatch(Spec0, Spec1));
238 }
239 
240 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpecWithInheritance) {
241   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
242       R"(
243       struct true_type{};
244       template <class T> struct foo;
245       template<> struct foo<char> : true_type {};
246       )",
247       R"(
248       struct true_type{};
249       template <class T> struct foo;
250       template<> struct foo<signed char> : true_type {};
251       )",
252       Lang_CXX03, classTemplateSpecializationDecl());
253   EXPECT_FALSE(testStructuralMatch(Decls));
254 }
255 
256 // This test is disabled for now.
257 // FIXME Enable it, once the check is implemented.
258 TEST_F(StructuralEquivalenceTest, DISABLED_WrongOrderInNamespace) {
259   auto Code =
260       R"(
261       namespace NS {
262       template <class T> class Base {
263           int a;
264       };
265       class Derived : Base<Derived> {
266       };
267       }
268       void foo(NS::Derived &);
269       )";
270   auto Decls = makeNamedDecls(Code, Code, Lang_CXX03);
271 
272   NamespaceDecl *NS =
273       LastDeclMatcher<NamespaceDecl>().match(get<1>(Decls), namespaceDecl());
274   ClassTemplateDecl *TD = LastDeclMatcher<ClassTemplateDecl>().match(
275       get<1>(Decls), classTemplateDecl(hasName("Base")));
276 
277   // Reorder the decls, move the TD to the last place in the DC.
278   NS->removeDecl(TD);
279   NS->addDeclInternal(TD);
280 
281   EXPECT_FALSE(testStructuralMatch(Decls));
282 }
283 
284 TEST_F(StructuralEquivalenceTest, WrongOrderOfFieldsInClass) {
285   auto Code = "class X { int a; int b; };";
286   auto Decls = makeNamedDecls(Code, Code, Lang_CXX03, "X");
287 
288   CXXRecordDecl *RD = FirstDeclMatcher<CXXRecordDecl>().match(
289       get<1>(Decls), cxxRecordDecl(hasName("X")));
290   FieldDecl *FD =
291       FirstDeclMatcher<FieldDecl>().match(get<1>(Decls), fieldDecl(hasName("a")));
292 
293   // Reorder the FieldDecls
294   RD->removeDecl(FD);
295   RD->addDeclInternal(FD);
296 
297   EXPECT_FALSE(testStructuralMatch(Decls));
298 }
299 
300 struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
301 };
302 
303 TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
304   auto t = makeNamedDecls("void foo();", "template<class T> void foo();",
305                           Lang_CXX03);
306   EXPECT_FALSE(testStructuralMatch(t));
307 }
308 
309 TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
310   auto t = makeDecls<FunctionDecl>(
311       "struct X{}; bool operator<(X, X);", "struct X{}; bool operator==(X, X);",
312       Lang_CXX03, functionDecl(hasOverloadedOperatorName("<")),
313       functionDecl(hasOverloadedOperatorName("==")));
314   EXPECT_FALSE(testStructuralMatch(t));
315 }
316 
317 TEST_F(StructuralEquivalenceFunctionTest, SameOperators) {
318   auto t = makeDecls<FunctionDecl>(
319       "struct X{}; bool operator<(X, X);", "struct X{}; bool operator<(X, X);",
320       Lang_CXX03, functionDecl(hasOverloadedOperatorName("<")),
321       functionDecl(hasOverloadedOperatorName("<")));
322   EXPECT_TRUE(testStructuralMatch(t));
323 }
324 
325 TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) {
326   auto t = makeDecls<FunctionDecl>("struct X{ X(); };", "struct X{ ~X(); };",
327                                    Lang_CXX03, cxxConstructorDecl(),
328                                    cxxDestructorDecl());
329   EXPECT_FALSE(testStructuralMatch(t));
330 }
331 
332 TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
333   auto t =
334       makeNamedDecls("void foo(int&);", "void foo(const int&);", Lang_CXX03);
335   EXPECT_FALSE(testStructuralMatch(t));
336 }
337 
338 TEST_F(StructuralEquivalenceFunctionTest, ParamConstSimple) {
339   auto t = makeNamedDecls("void foo(int);", "void foo(const int);", Lang_CXX03);
340   EXPECT_TRUE(testStructuralMatch(t));
341   // consider this OK
342 }
343 
344 TEST_F(StructuralEquivalenceFunctionTest, Throw) {
345   auto t = makeNamedDecls("void foo();", "void foo() throw();", Lang_CXX03);
346   EXPECT_FALSE(testStructuralMatch(t));
347 }
348 
349 TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
350   auto t = makeNamedDecls("void foo();",
351                           "void foo() noexcept;", Lang_CXX11);
352   EXPECT_FALSE(testStructuralMatch(t));
353 }
354 
355 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexcept) {
356   auto t = makeNamedDecls("void foo() throw();",
357                           "void foo() noexcept;", Lang_CXX11);
358   EXPECT_FALSE(testStructuralMatch(t));
359 }
360 
361 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptFalse) {
362   auto t = makeNamedDecls("void foo() throw();",
363                           "void foo() noexcept(false);", Lang_CXX11);
364   EXPECT_FALSE(testStructuralMatch(t));
365 }
366 
367 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptTrue) {
368   auto t = makeNamedDecls("void foo() throw();",
369                           "void foo() noexcept(true);", Lang_CXX11);
370   EXPECT_FALSE(testStructuralMatch(t));
371 }
372 
373 TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
374   auto t = makeNamedDecls("void foo() noexcept(false);",
375                           "void foo() noexcept(true);", Lang_CXX11);
376   EXPECT_FALSE(testStructuralMatch(t));
377 }
378 
379 TEST_F(StructuralEquivalenceFunctionTest, NoexceptMatch) {
380   auto t = makeNamedDecls("void foo() noexcept(false);",
381                           "void foo() noexcept(false);", Lang_CXX11);
382   EXPECT_TRUE(testStructuralMatch(t));
383 }
384 
385 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptFalse) {
386   auto t = makeNamedDecls("void foo() noexcept;",
387                           "void foo() noexcept(false);", Lang_CXX11);
388   EXPECT_FALSE(testStructuralMatch(t));
389 }
390 
391 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptTrue) {
392   auto t = makeNamedDecls("void foo() noexcept;",
393                           "void foo() noexcept(true);", Lang_CXX11);
394   EXPECT_FALSE(testStructuralMatch(t));
395 }
396 
397 TEST_F(StructuralEquivalenceFunctionTest, ReturnType) {
398   auto t = makeNamedDecls("char foo();", "int foo();", Lang_CXX03);
399   EXPECT_FALSE(testStructuralMatch(t));
400 }
401 
402 TEST_F(StructuralEquivalenceFunctionTest, ReturnConst) {
403   auto t = makeNamedDecls("char foo();", "const char foo();", Lang_CXX03);
404   EXPECT_FALSE(testStructuralMatch(t));
405 }
406 
407 TEST_F(StructuralEquivalenceFunctionTest, ReturnRef) {
408   auto t = makeNamedDecls("char &foo();",
409                           "char &&foo();", Lang_CXX11);
410   EXPECT_FALSE(testStructuralMatch(t));
411 }
412 
413 TEST_F(StructuralEquivalenceFunctionTest, ParamCount) {
414   auto t = makeNamedDecls("void foo(int);", "void foo(int, int);", Lang_CXX03);
415   EXPECT_FALSE(testStructuralMatch(t));
416 }
417 
418 TEST_F(StructuralEquivalenceFunctionTest, ParamType) {
419   auto t = makeNamedDecls("void foo(int);", "void foo(char);", Lang_CXX03);
420   EXPECT_FALSE(testStructuralMatch(t));
421 }
422 
423 TEST_F(StructuralEquivalenceFunctionTest, ParamName) {
424   auto t = makeNamedDecls("void foo(int a);", "void foo(int b);", Lang_CXX03);
425   EXPECT_TRUE(testStructuralMatch(t));
426 }
427 
428 TEST_F(StructuralEquivalenceFunctionTest, Variadic) {
429   auto t =
430       makeNamedDecls("void foo(int x...);", "void foo(int x);", Lang_CXX03);
431   EXPECT_FALSE(testStructuralMatch(t));
432 }
433 
434 TEST_F(StructuralEquivalenceFunctionTest, ParamPtr) {
435   auto t = makeNamedDecls("void foo(int *);", "void foo(int);", Lang_CXX03);
436   EXPECT_FALSE(testStructuralMatch(t));
437 }
438 
439 TEST_F(StructuralEquivalenceFunctionTest, NameInParen) {
440   auto t = makeNamedDecls("void ((foo))();", "void foo();", Lang_CXX03);
441   EXPECT_TRUE(testStructuralMatch(t));
442 }
443 
444 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithExceptionSpec) {
445   auto t = makeNamedDecls(
446       "void (foo)() throw(int);",
447       "void (foo)() noexcept;",
448       Lang_CXX11);
449   EXPECT_FALSE(testStructuralMatch(t));
450 }
451 
452 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) {
453   auto t = makeNamedDecls(
454       "struct A { void (foo)() const; };",
455       "struct A { void (foo)(); };",
456       Lang_CXX11);
457   EXPECT_FALSE(testStructuralMatch(t));
458 }
459 
460 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
461   auto t = makeNamedDecls("__attribute__((noreturn)) void foo();",
462                           "                          void foo();", Lang_C99);
463   EXPECT_TRUE(testStructuralMatch(t));
464 }
465 
466 TEST_F(StructuralEquivalenceFunctionTest,
467     FunctionsWithDifferentCallingConventions) {
468   // These attributes may not be available on certain platforms.
469   if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
470       llvm::Triple::x86_64)
471     GTEST_SKIP();
472   auto t = makeNamedDecls("__attribute__((preserve_all)) void foo();",
473                           "__attribute__((ms_abi))   void foo();", Lang_C99);
474   EXPECT_FALSE(testStructuralMatch(t));
475 }
476 
477 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) {
478   if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
479       llvm::Triple::x86_64)
480     GTEST_SKIP();
481   auto t = makeNamedDecls(
482       "__attribute__((no_caller_saved_registers)) void foo();",
483       "                                           void foo();", Lang_C99);
484   EXPECT_FALSE(testStructuralMatch(t));
485 }
486 
487 struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
488 };
489 
490 TEST_F(StructuralEquivalenceCXXMethodTest, Virtual) {
491   auto t = makeDecls<CXXMethodDecl>("struct X { void foo(); };",
492                                     "struct X { virtual void foo(); };",
493                                     Lang_CXX03, cxxMethodDecl(hasName("foo")));
494   EXPECT_FALSE(testStructuralMatch(t));
495 }
496 
497 TEST_F(StructuralEquivalenceCXXMethodTest, Pure) {
498   auto t = makeNamedDecls("struct X { virtual void foo(); };",
499                           "struct X { virtual void foo() = 0; };", Lang_CXX03);
500   EXPECT_FALSE(testStructuralMatch(t));
501 }
502 
503 TEST_F(StructuralEquivalenceCXXMethodTest, DISABLED_Final) {
504   // The final-ness is not checked yet.
505   auto t =
506       makeNamedDecls("struct X { virtual void foo(); };",
507                      "struct X { virtual void foo() final; };", Lang_CXX03);
508   EXPECT_FALSE(testStructuralMatch(t));
509 }
510 
511 TEST_F(StructuralEquivalenceCXXMethodTest, Const) {
512   auto t = makeNamedDecls("struct X { void foo(); };",
513                           "struct X { void foo() const; };", Lang_CXX03);
514   EXPECT_FALSE(testStructuralMatch(t));
515 }
516 
517 TEST_F(StructuralEquivalenceCXXMethodTest, Static) {
518   auto t = makeNamedDecls("struct X { void foo(); };",
519                           "struct X { static void foo(); };", Lang_CXX03);
520   EXPECT_FALSE(testStructuralMatch(t));
521 }
522 
523 TEST_F(StructuralEquivalenceCXXMethodTest, Ref1) {
524   auto t = makeNamedDecls("struct X { void foo(); };",
525                           "struct X { void foo() &&; };", Lang_CXX11);
526   EXPECT_FALSE(testStructuralMatch(t));
527 }
528 
529 TEST_F(StructuralEquivalenceCXXMethodTest, Ref2) {
530   auto t = makeNamedDecls("struct X { void foo() &; };",
531                           "struct X { void foo() &&; };", Lang_CXX11);
532   EXPECT_FALSE(testStructuralMatch(t));
533 }
534 
535 TEST_F(StructuralEquivalenceCXXMethodTest, AccessSpecifier) {
536   auto t = makeDecls<CXXMethodDecl>("struct X { public: void foo(); };",
537                                     "struct X { private: void foo(); };",
538                                     Lang_CXX03, cxxMethodDecl(hasName("foo")));
539   EXPECT_FALSE(testStructuralMatch(t));
540 }
541 
542 TEST_F(StructuralEquivalenceCXXMethodTest, Delete) {
543   auto t = makeNamedDecls("struct X { void foo(); };",
544                           "struct X { void foo() = delete; };", Lang_CXX11);
545   EXPECT_FALSE(testStructuralMatch(t));
546 }
547 
548 TEST_F(StructuralEquivalenceCXXMethodTest, Constructor) {
549   auto t = makeDecls<FunctionDecl>("void foo();", "struct foo { foo(); };",
550                                    Lang_CXX03, functionDecl(hasName("foo")),
551                                    cxxConstructorDecl(hasName("foo")));
552   EXPECT_FALSE(testStructuralMatch(t));
553 }
554 
555 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorParam) {
556   auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
557                                          "struct X { X(int); };", Lang_CXX03,
558                                          cxxConstructorDecl(hasName("X")));
559   EXPECT_FALSE(testStructuralMatch(t));
560 }
561 
562 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorExplicit) {
563   auto t = makeDecls<CXXConstructorDecl>("struct X { X(int); };",
564                                          "struct X { explicit X(int); };",
565                                          Lang_CXX11,
566                                          cxxConstructorDecl(hasName("X")));
567   EXPECT_FALSE(testStructuralMatch(t));
568 }
569 
570 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorDefault) {
571   auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
572                                          "struct X { X() = default; };",
573                                          Lang_CXX11,
574                                          cxxConstructorDecl(hasName("X")));
575   EXPECT_FALSE(testStructuralMatch(t));
576 }
577 
578 TEST_F(StructuralEquivalenceCXXMethodTest, Conversion) {
579   auto t = makeDecls<CXXConversionDecl>("struct X { operator bool(); };",
580                                         "struct X { operator char(); };",
581                                          Lang_CXX11,
582                                          cxxConversionDecl());
583   EXPECT_FALSE(testStructuralMatch(t));
584 }
585 
586 TEST_F(StructuralEquivalenceCXXMethodTest, Operator) {
587   auto t =
588       makeDecls<FunctionDecl>("struct X { int operator +(int); };",
589                               "struct X { int operator -(int); };", Lang_CXX03,
590                               functionDecl(hasOverloadedOperatorName("+")),
591                               functionDecl(hasOverloadedOperatorName("-")));
592   EXPECT_FALSE(testStructuralMatch(t));
593 }
594 
595 TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass1) {
596   auto t = makeDecls<FunctionDecl>(
597       "struct X { virtual void f(); }; void X::f() { }",
598       "struct X { virtual void f() { }; };", Lang_CXX03,
599       functionDecl(allOf(hasName("f"), isDefinition())));
600   EXPECT_TRUE(testStructuralMatch(t));
601 }
602 
603 TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass2) {
604   auto t = makeDecls<FunctionDecl>(
605       "struct X { virtual void f(); }; void X::f() { }",
606       "struct X { void f(); }; void X::f() { }", Lang_CXX03,
607       functionDecl(allOf(hasName("f"), isDefinition())));
608   EXPECT_FALSE(testStructuralMatch(t));
609 }
610 
611 struct StructuralEquivalenceRecordTest : StructuralEquivalenceTest {
612   // FIXME Use a common getRecordDecl with ASTImporterTest.cpp!
613   RecordDecl *getRecordDecl(FieldDecl *FD) {
614     auto *ET = cast<ElaboratedType>(FD->getType().getTypePtr());
615     return cast<RecordType>(ET->getNamedType().getTypePtr())->getDecl();
616   };
617 };
618 
619 TEST_F(StructuralEquivalenceRecordTest, Name) {
620   auto t = makeDecls<CXXRecordDecl>("struct A{ };", "struct B{ };", Lang_CXX03,
621                                     cxxRecordDecl(hasName("A")),
622                                     cxxRecordDecl(hasName("B")));
623   EXPECT_FALSE(testStructuralMatch(t));
624 }
625 
626 TEST_F(StructuralEquivalenceRecordTest, Fields) {
627   auto t = makeNamedDecls("struct foo{ int x; };", "struct foo{ char x; };",
628                           Lang_CXX03);
629   EXPECT_FALSE(testStructuralMatch(t));
630 }
631 
632 TEST_F(StructuralEquivalenceRecordTest, DISABLED_Methods) {
633   // Currently, methods of a class are not checked at class equivalence.
634   auto t = makeNamedDecls("struct foo{ int x(); };", "struct foo{ char x(); };",
635                           Lang_CXX03);
636   EXPECT_FALSE(testStructuralMatch(t));
637 }
638 
639 TEST_F(StructuralEquivalenceRecordTest, Bases) {
640   auto t = makeNamedDecls("struct A{ }; struct foo: A { };",
641                           "struct B{ }; struct foo: B { };", Lang_CXX03);
642   EXPECT_FALSE(testStructuralMatch(t));
643 }
644 
645 TEST_F(StructuralEquivalenceRecordTest, InheritanceVirtual) {
646   auto t =
647       makeNamedDecls("struct A{ }; struct foo: A { };",
648                      "struct A{ }; struct foo: virtual A { };", Lang_CXX03);
649   EXPECT_FALSE(testStructuralMatch(t));
650 }
651 
652 TEST_F(StructuralEquivalenceRecordTest, DISABLED_InheritanceType) {
653   // Access specifier in inheritance is not checked yet.
654   auto t =
655       makeNamedDecls("struct A{ }; struct foo: public A { };",
656                      "struct A{ }; struct foo: private A { };", Lang_CXX03);
657   EXPECT_FALSE(testStructuralMatch(t));
658 }
659 
660 TEST_F(StructuralEquivalenceRecordTest, Match) {
661   auto Code = R"(
662       struct A{ };
663       struct B{ };
664       struct foo: A, virtual B {
665         void x();
666         int a;
667       };
668       )";
669   auto t = makeNamedDecls(Code, Code, Lang_CXX03);
670   EXPECT_TRUE(testStructuralMatch(t));
671 }
672 
673 TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) {
674   auto t = makeTuDecls(
675       R"(
676       struct A {
677         struct {
678           struct A *next;
679         } entry0;
680         struct {
681           struct A *next;
682         } entry1;
683       };
684       )",
685       "", Lang_C99);
686   auto *TU = get<0>(t);
687   auto *Entry0 =
688       FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry0")));
689   auto *Entry1 =
690       FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry1")));
691   auto *R0 = getRecordDecl(Entry0);
692   auto *R1 = getRecordDecl(Entry1);
693 
694   ASSERT_NE(R0, R1);
695   EXPECT_TRUE(testStructuralMatch(R0, R0));
696   EXPECT_TRUE(testStructuralMatch(R1, R1));
697   EXPECT_FALSE(testStructuralMatch(R0, R1));
698 }
699 
700 TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
701   auto t = makeTuDecls(
702       R"(
703       struct X {
704         struct {
705           int a;
706         };
707         struct {
708           int b;
709         };
710       };
711       )",
712       "", Lang_C99);
713   auto *TU = get<0>(t);
714   auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
715       TU, indirectFieldDecl(hasName("a")));
716   auto *FA = cast<FieldDecl>(A->chain().front());
717   RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
718   auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
719       TU, indirectFieldDecl(hasName("b")));
720   auto *FB = cast<FieldDecl>(B->chain().front());
721   RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
722 
723   ASSERT_NE(RA, RB);
724   EXPECT_TRUE(testStructuralMatch(RA, RA));
725   EXPECT_TRUE(testStructuralMatch(RB, RB));
726   EXPECT_FALSE(testStructuralMatch(RA, RB));
727 }
728 
729 TEST_F(StructuralEquivalenceRecordTest,
730        RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) {
731   auto t = makeTuDecls(
732       R"(
733       struct X {
734         struct { int a; };
735         struct { int b; };
736       };
737       )",
738       R"(
739       struct X { // The order is reversed.
740         struct { int b; };
741         struct { int a; };
742       };
743       )",
744       Lang_C99);
745 
746   auto *TU = get<0>(t);
747   auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
748       TU, indirectFieldDecl(hasName("a")));
749   auto *FA = cast<FieldDecl>(A->chain().front());
750   RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
751 
752   auto *TU1 = get<1>(t);
753   auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
754       TU1, indirectFieldDecl(hasName("a")));
755   auto *FA1 = cast<FieldDecl>(A1->chain().front());
756   RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
757 
758   RecordDecl *X =
759       FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
760   RecordDecl *X1 =
761       FirstDeclMatcher<RecordDecl>().match(TU1, recordDecl(hasName("X")));
762   ASSERT_NE(X, X1);
763   EXPECT_FALSE(testStructuralMatch(X, X1));
764 
765   ASSERT_NE(RA, RA1);
766   EXPECT_TRUE(testStructuralMatch(RA, RA));
767   EXPECT_TRUE(testStructuralMatch(RA1, RA1));
768   EXPECT_FALSE(testStructuralMatch(RA1, RA));
769 }
770 
771 TEST_F(StructuralEquivalenceRecordTest,
772        UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) {
773   auto Code =
774       R"(
775       struct A {
776         struct {
777           struct A *next;
778         } entry0;
779         struct {
780           struct A *next;
781         } entry1;
782       };
783       )";
784   auto t = makeTuDecls(Code, Code, Lang_C99);
785 
786   auto *FromTU = get<0>(t);
787   auto *Entry1 =
788       FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("entry1")));
789 
790   auto *ToTU = get<1>(t);
791   auto *Entry0 =
792       FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
793   auto *A =
794       FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
795   A->startDefinition(); // Set isBeingDefined, getDefinition() will return a
796                         // nullptr. This may be the case during ASTImport.
797 
798   auto *R0 = getRecordDecl(Entry0);
799   auto *R1 = getRecordDecl(Entry1);
800 
801   ASSERT_NE(R0, R1);
802   EXPECT_TRUE(testStructuralMatch(R0, R0));
803   EXPECT_TRUE(testStructuralMatch(R1, R1));
804   EXPECT_FALSE(testStructuralMatch(R0, R1));
805 }
806 
807 TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
808   auto t = makeDecls<CXXRecordDecl>("struct A { };",
809                                     "template<class T> struct A { };",
810                                     Lang_CXX03, cxxRecordDecl(hasName("A")));
811   EXPECT_FALSE(testStructuralMatch(t));
812 }
813 
814 TEST_F(StructuralEquivalenceRecordTest,
815     FwdDeclRecordShouldBeEqualWithFwdDeclRecord) {
816   auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11);
817   EXPECT_TRUE(testStructuralMatch(t));
818 }
819 
820 TEST_F(StructuralEquivalenceRecordTest,
821        FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) {
822   auto t =
823       makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11);
824   EXPECT_TRUE(testStructuralMatch(t));
825 }
826 
827 TEST_F(StructuralEquivalenceRecordTest,
828        RecordShouldBeEqualWithRecordWhichHasDefinition) {
829   auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };",
830                           Lang_CXX11);
831   EXPECT_TRUE(testStructuralMatch(t));
832 }
833 
834 TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) {
835   auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };",
836                           Lang_CXX11);
837   EXPECT_FALSE(testStructuralMatch(t));
838 }
839 
840 TEST_F(StructuralEquivalenceRecordTest, SameFriendMultipleTimes) {
841   auto t = makeNamedDecls("struct foo { friend class X; };",
842                           "struct foo { friend class X; friend class X; };",
843                           Lang_CXX11);
844   EXPECT_FALSE(testStructuralMatch(t));
845 }
846 
847 TEST_F(StructuralEquivalenceRecordTest, SameFriendsDifferentOrder) {
848   auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };",
849                           "struct foo { friend class Y; friend class X; };",
850                           Lang_CXX11);
851   EXPECT_FALSE(testStructuralMatch(t));
852 }
853 
854 TEST_F(StructuralEquivalenceRecordTest, SameFriendsSameOrder) {
855   auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };",
856                           "struct foo { friend class X; friend class Y; };",
857                           Lang_CXX11);
858   EXPECT_TRUE(testStructuralMatch(t));
859 }
860 
861 struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {};
862 
863 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) {
864   // Get the LambdaExprs, unfortunately we can't match directly the underlying
865   // implicit CXXRecordDecl of the Lambda classes.
866   auto t = makeDecls<LambdaExpr>(
867       "void f() { auto L0 = [](int){}; }",
868       "void f() { auto L1 = [](){}; }",
869       Lang_CXX11,
870       lambdaExpr(),
871       lambdaExpr());
872   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
873   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
874   EXPECT_FALSE(testStructuralMatch(L0, L1));
875 }
876 
877 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqMethods) {
878   auto t = makeDecls<LambdaExpr>(
879       "void f() { auto L0 = [](int){}; }",
880       "void f() { auto L1 = [](int){}; }",
881       Lang_CXX11,
882       lambdaExpr(),
883       lambdaExpr());
884   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
885   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
886   EXPECT_TRUE(testStructuralMatch(L0, L1));
887 }
888 
889 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentFields) {
890   auto t = makeDecls<LambdaExpr>(
891       "void f() { char* X; auto L0 = [X](){}; }",
892       "void f() { float X; auto L1 = [X](){}; }",
893       Lang_CXX11,
894       lambdaExpr(),
895       lambdaExpr());
896   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
897   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
898   EXPECT_FALSE(testStructuralMatch(L0, L1));
899 }
900 
901 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqFields) {
902   auto t = makeDecls<LambdaExpr>(
903       "void f() { float X; auto L0 = [X](){}; }",
904       "void f() { float X; auto L1 = [X](){}; }",
905       Lang_CXX11,
906       lambdaExpr(),
907       lambdaExpr());
908   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
909   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
910   EXPECT_TRUE(testStructuralMatch(L0, L1));
911 }
912 
913 TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
914   auto t = makeNamedDecls("struct A{ }; struct B{ }; void foo(A a, A b);",
915                           "struct A{ }; struct B{ }; void foo(A a, B b);",
916                           Lang_CXX03);
917   EXPECT_FALSE(testStructuralMatch(t));
918 }
919 
920 TEST_F(StructuralEquivalenceTest, ExplicitBoolDifferent) {
921   auto Decls = makeNamedDecls("struct foo {explicit(false) foo(int);};",
922                               "struct foo {explicit(true) foo(int);};", Lang_CXX20);
923   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
924       get<0>(Decls), cxxConstructorDecl(hasName("foo")));
925   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
926       get<1>(Decls), cxxConstructorDecl(hasName("foo")));
927   EXPECT_FALSE(testStructuralMatch(First, Second));
928 }
929 
930 TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
931   auto Decls = makeNamedDecls("struct foo {explicit(true) foo(int);};",
932                               "struct foo {explicit(true) foo(int);};", Lang_CXX20);
933   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
934       get<0>(Decls), cxxConstructorDecl(hasName("foo")));
935   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
936       get<1>(Decls), cxxConstructorDecl(hasName("foo")));
937   EXPECT_TRUE(testStructuralMatch(First, Second));
938 }
939 
940 struct StructuralEquivalenceRecordContextTest : StructuralEquivalenceTest {};
941 
942 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsNamed) {
943   auto Decls =
944       makeNamedDecls("class X;", "namespace N { class X; }", Lang_CXX03, "X");
945   EXPECT_FALSE(testStructuralMatch(Decls));
946 }
947 
948 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsNamed) {
949   auto Decls = makeNamedDecls("namespace A { class X; }",
950                               "namespace B { class X; }", Lang_CXX03, "X");
951   EXPECT_FALSE(testStructuralMatch(Decls));
952 }
953 
954 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsNamed) {
955   auto Decls = makeNamedDecls("namespace { class X; }",
956                               "namespace N { class X; }", Lang_CXX03, "X");
957   EXPECT_FALSE(testStructuralMatch(Decls));
958 }
959 
960 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsAnon) {
961   auto Decls =
962       makeNamedDecls("class X;", "namespace { class X; }", Lang_CXX03, "X");
963   EXPECT_FALSE(testStructuralMatch(Decls));
964 }
965 
966 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnon) {
967   auto Decls = makeNamedDecls("namespace { class X; }",
968                               "namespace { class X; }", Lang_CXX03, "X");
969   EXPECT_TRUE(testStructuralMatch(Decls));
970 }
971 
972 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnonAnon) {
973   auto Decls =
974       makeNamedDecls("namespace { class X; }",
975                      "namespace { namespace { class X; } }", Lang_CXX03, "X");
976   EXPECT_FALSE(testStructuralMatch(Decls));
977 }
978 
979 TEST_F(StructuralEquivalenceRecordContextTest,
980        NamespaceNamedNamedVsNamedNamed) {
981   auto Decls = makeNamedDecls("namespace A { namespace N { class X; } }",
982                               "namespace B { namespace N { class X; } }",
983                               Lang_CXX03, "X");
984   EXPECT_FALSE(testStructuralMatch(Decls));
985 }
986 
987 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsInline) {
988   auto Decls = makeNamedDecls("namespace A { namespace A { class X; } }",
989                               "namespace A { inline namespace A { class X; } }",
990                               Lang_CXX17, "X");
991   EXPECT_FALSE(testStructuralMatch(Decls));
992 }
993 
994 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineVsInline) {
995   auto Decls = makeNamedDecls("namespace A { inline namespace A { class X; } }",
996                               "namespace A { inline namespace B { class X; } }",
997                               Lang_CXX17, "X");
998   EXPECT_TRUE(testStructuralMatch(Decls));
999 }
1000 
1001 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineTopLevel) {
1002   auto Decls =
1003       makeNamedDecls("inline namespace A { class X; }",
1004                      "inline namespace B { class X; }", Lang_CXX17, "X");
1005   EXPECT_TRUE(testStructuralMatch(Decls));
1006 }
1007 
1008 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContext) {
1009   auto Decls =
1010       makeNamedDecls("extern \"C\" { class X; }", "class X;", Lang_CXX03, "X");
1011   EXPECT_TRUE(testStructuralMatch(Decls));
1012 }
1013 
1014 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextNE) {
1015   auto Decls = makeNamedDecls("extern \"C\" { class X; }",
1016                               "namespace { class X; }", Lang_CXX03, "X");
1017   EXPECT_FALSE(testStructuralMatch(Decls));
1018 }
1019 
1020 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextInNamespace) {
1021   auto Decls = makeNamedDecls("extern \"C\" { namespace N { class X; } }",
1022                               "namespace N { extern \"C\" { class X; } }",
1023                               Lang_CXX03, "X");
1024   EXPECT_TRUE(testStructuralMatch(Decls));
1025 }
1026 
1027 TEST_F(StructuralEquivalenceRecordContextTest,
1028        ClassTemplateSpecializationContext) {
1029   std::string Code =
1030       R"(
1031       template <typename T> struct O {
1032         struct M {};
1033       };
1034       )";
1035   auto t = makeDecls<VarDecl>(Code + R"(
1036       typedef O<int>::M MT1;
1037       MT1 A;
1038       )",
1039                               Code + R"(
1040       namespace {
1041         struct I {};
1042       } // namespace
1043       typedef O<I>::M MT2;
1044       MT2 A;
1045       )",
1046                               Lang_CXX11, varDecl(hasName("A")));
1047   EXPECT_FALSE(testStructuralMatch(t));
1048 }
1049 
1050 TEST_F(StructuralEquivalenceTest, NamespaceOfRecordMember) {
1051   auto Decls = makeNamedDecls(
1052       R"(
1053       class X;
1054       class Y { X* x; };
1055       )",
1056       R"(
1057       namespace N { class X; }
1058       class Y { N::X* x; };
1059       )",
1060       Lang_CXX03, "Y");
1061   EXPECT_FALSE(testStructuralMatch(Decls));
1062 }
1063 
1064 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototype) {
1065   auto Decls =
1066       makeNamedDecls("struct Param { int a; }; void foo(struct Param *p);",
1067                      "void foo(struct Param { int a; } *p);", Lang_C89);
1068   EXPECT_TRUE(testStructuralMatch(Decls));
1069 }
1070 
1071 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototypeDifferentName) {
1072   auto Decls =
1073       makeNamedDecls("struct Param1 { int a; }; void foo(struct Param1 *p);",
1074                      "void foo(struct Param2 { int a; } *p);", Lang_C89);
1075   EXPECT_FALSE(testStructuralMatch(Decls));
1076 }
1077 
1078 TEST_F(StructuralEquivalenceRecordContextTest, RecordInsideFunction) {
1079   auto Decls = makeNamedDecls("struct Param { int a; };",
1080                               "void f() { struct Param { int a; }; }", Lang_C89,
1081                               "Param");
1082   EXPECT_TRUE(testStructuralMatch(Decls));
1083 }
1084 
1085 struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
1086 
1087 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
1088   auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
1089   EXPECT_TRUE(testStructuralMatch(t));
1090 }
1091 
1092 TEST_F(StructuralEquivalenceEnumTest,
1093        FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
1094   auto t =
1095       makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
1096   EXPECT_TRUE(testStructuralMatch(t));
1097 }
1098 
1099 TEST_F(StructuralEquivalenceEnumTest,
1100        EnumShouldBeEqualWithEnumWhichHasDefinition) {
1101   auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
1102                           Lang_CXX11);
1103   EXPECT_TRUE(testStructuralMatch(t));
1104 }
1105 
1106 TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
1107   auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
1108                           Lang_CXX11);
1109   EXPECT_FALSE(testStructuralMatch(t));
1110 }
1111 
1112 TEST_F(StructuralEquivalenceEnumTest, AnonymousEnumsWithSameConsts) {
1113   // field x is required to trigger comparison of the anonymous enum
1114   auto t = makeNamedDecls("struct foo { enum { A } x; };",
1115                           "struct foo { enum { A } x;};", Lang_CXX11);
1116   EXPECT_TRUE(testStructuralMatch(t));
1117 }
1118 
1119 TEST_F(StructuralEquivalenceEnumTest, AnonymousEnumsWithDiffConsts) {
1120   // field x is required to trigger comparison of the anonymous enum
1121   auto t = makeNamedDecls("struct foo { enum { A } x; };",
1122                           "struct foo { enum { B } x;};", Lang_CXX11);
1123   EXPECT_FALSE(testStructuralMatch(t));
1124 }
1125 
1126 struct StructuralEquivalenceEnumConstantTest : StructuralEquivalenceTest {};
1127 
1128 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithSameValues) {
1129   auto t = makeNamedDecls("enum foo { foo = 1 };", "enum foo { foo = 1 };",
1130                           Lang_C89);
1131   EXPECT_TRUE(testStructuralMatch(t));
1132 }
1133 
1134 TEST_F(StructuralEquivalenceEnumConstantTest,
1135        EnumConstantsWithDifferentValues) {
1136   auto t =
1137       makeNamedDecls("enum e { foo = 1 };", "enum e { foo = 2 };", Lang_C89);
1138   EXPECT_FALSE(testStructuralMatch(t));
1139 }
1140 
1141 TEST_F(StructuralEquivalenceEnumConstantTest,
1142        EnumConstantsWithDifferentExprsButSameValues) {
1143   auto t = makeNamedDecls("enum e { foo = 1 + 1 };", "enum e { foo = 2 };",
1144                           Lang_CXX11);
1145   EXPECT_FALSE(testStructuralMatch(t));
1146 }
1147 
1148 TEST_F(StructuralEquivalenceEnumConstantTest,
1149        EnumConstantsWithDifferentSignedness) {
1150   auto t = makeNamedDecls("enum e : unsigned { foo = 1 };",
1151                           "enum e : int { foo = 1 };", Lang_CXX11);
1152   EXPECT_FALSE(testStructuralMatch(t));
1153 }
1154 
1155 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentWidth) {
1156   auto t = makeNamedDecls("enum e : short { foo = 1 };",
1157                           "enum e : int { foo = 1 };", Lang_CXX11);
1158   EXPECT_FALSE(testStructuralMatch(t));
1159 }
1160 
1161 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentName) {
1162   auto t =
1163       makeDecls<EnumConstantDecl>("enum e { foo = 1 };", "enum e { bar = 1 };",
1164                                   Lang_CXX11, enumConstantDecl());
1165   EXPECT_FALSE(testStructuralMatch(t));
1166 }
1167 
1168 struct StructuralEquivalenceObjCCategoryTest : StructuralEquivalenceTest {};
1169 
1170 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchinCategoryNames) {
1171   auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1172                                        "@interface A @end @interface A(X) @end",
1173                                        Lang_OBJC, objcCategoryDecl());
1174   EXPECT_TRUE(testStructuralMatch(t));
1175 }
1176 
1177 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesForDifferentClasses) {
1178   auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1179                                        "@interface B @end @interface B(X) @end",
1180                                        Lang_OBJC, objcCategoryDecl());
1181   EXPECT_FALSE(testStructuralMatch(t));
1182 }
1183 
1184 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithDifferentNames) {
1185   auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1186                                        "@interface A @end @interface A(Y) @end",
1187                                        Lang_OBJC, objcCategoryDecl());
1188   EXPECT_FALSE(testStructuralMatch(t));
1189 }
1190 
1191 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithoutInterfaces) {
1192   auto t = makeDecls<ObjCCategoryDecl>("                  @interface A(X) @end",
1193                                        "@interface A @end @interface A(X) @end",
1194                                        Lang_OBJC, objcCategoryDecl());
1195   EXPECT_FALSE(testStructuralMatch(t));
1196 
1197   auto t2 = makeDecls<ObjCCategoryDecl>("@interface A(X) @end",
1198                                         "@interface A(X) @end",
1199                                         Lang_OBJC, objcCategoryDecl());
1200   EXPECT_TRUE(testStructuralMatch(t2));
1201 }
1202 
1203 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoryAndExtension) {
1204   auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1205                                        "@interface A @end @interface A() @end",
1206                                        Lang_OBJC, objcCategoryDecl());
1207   EXPECT_FALSE(testStructuralMatch(t));
1208 }
1209 
1210 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingProtocols) {
1211   auto t = makeDecls<ObjCCategoryDecl>(
1212       "@protocol P @end @interface A @end @interface A(X)<P> @end",
1213       "@protocol P @end @interface A @end @interface A(X)<P> @end", Lang_OBJC,
1214       objcCategoryDecl());
1215   EXPECT_TRUE(testStructuralMatch(t));
1216 }
1217 
1218 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocols) {
1219   auto t = makeDecls<ObjCCategoryDecl>(
1220       "@protocol P @end @interface A @end @interface A(X)<P> @end",
1221       "@protocol Q @end @interface A @end @interface A(X)<Q> @end", Lang_OBJC,
1222       objcCategoryDecl());
1223   EXPECT_FALSE(testStructuralMatch(t));
1224 }
1225 
1226 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocolsOrder) {
1227   auto t = makeDecls<ObjCCategoryDecl>(
1228       "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<P, "
1229       "Q> @end",
1230       "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<Q, "
1231       "P> @end",
1232       Lang_OBJC, objcCategoryDecl());
1233   EXPECT_FALSE(testStructuralMatch(t));
1234 }
1235 
1236 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingIvars) {
1237   auto t = makeDecls<ObjCCategoryDecl>(
1238       "@interface A @end @interface A() { int x; } @end",
1239       "@interface A @end @interface A() { int x; } @end", Lang_OBJC,
1240       objcCategoryDecl());
1241   EXPECT_TRUE(testStructuralMatch(t));
1242 }
1243 
1244 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarName) {
1245   auto t = makeDecls<ObjCCategoryDecl>(
1246       "@interface A @end @interface A() { int x; } @end",
1247       "@interface A @end @interface A() { int y; } @end", Lang_OBJC,
1248       objcCategoryDecl());
1249   EXPECT_FALSE(testStructuralMatch(t));
1250 }
1251 
1252 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarType) {
1253   auto t = makeDecls<ObjCCategoryDecl>(
1254       "@interface A @end @interface A() { int x; } @end",
1255       "@interface A @end @interface A() { float x; } @end", Lang_OBJC,
1256       objcCategoryDecl());
1257   EXPECT_FALSE(testStructuralMatch(t));
1258 }
1259 
1260 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarBitfieldWidth) {
1261   auto t = makeDecls<ObjCCategoryDecl>(
1262       "@interface A @end @interface A() { int x: 1; } @end",
1263       "@interface A @end @interface A() { int x: 2; } @end", Lang_OBJC,
1264       objcCategoryDecl());
1265   EXPECT_FALSE(testStructuralMatch(t));
1266 }
1267 
1268 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarVisibility) {
1269   auto t = makeDecls<ObjCCategoryDecl>(
1270       "@interface A @end @interface A() { @public int x; } @end",
1271       "@interface A @end @interface A() { @protected int x; } @end", Lang_OBJC,
1272       objcCategoryDecl());
1273   EXPECT_FALSE(testStructuralMatch(t));
1274 }
1275 
1276 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarNumber) {
1277   auto t = makeDecls<ObjCCategoryDecl>(
1278       "@interface A @end @interface A() { int x; } @end",
1279       "@interface A @end @interface A() {} @end", Lang_OBJC,
1280       objcCategoryDecl());
1281   EXPECT_FALSE(testStructuralMatch(t));
1282 }
1283 
1284 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarOrder) {
1285   auto t = makeDecls<ObjCCategoryDecl>(
1286       "@interface A @end @interface A() { int x; int y; } @end",
1287       "@interface A @end @interface A() { int y; int x; } @end", Lang_OBJC,
1288       objcCategoryDecl());
1289   EXPECT_FALSE(testStructuralMatch(t));
1290 }
1291 
1292 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingMethods) {
1293   auto t = makeDecls<ObjCCategoryDecl>(
1294       "@interface A @end @interface A(X) -(void)test; @end",
1295       "@interface A @end @interface A(X) -(void)test; @end", Lang_OBJC,
1296       objcCategoryDecl());
1297   EXPECT_TRUE(testStructuralMatch(t));
1298 }
1299 
1300 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodName) {
1301   auto t = makeDecls<ObjCCategoryDecl>(
1302       "@interface A @end @interface A(X) -(void)test; @end",
1303       "@interface A @end @interface A(X) -(void)wasd; @end", Lang_OBJC,
1304       objcCategoryDecl());
1305   EXPECT_FALSE(testStructuralMatch(t));
1306 
1307   auto t2 = makeDecls<ObjCCategoryDecl>(
1308       "@interface A @end @interface A(X) -(void)test:(int)x more:(int)y; @end",
1309       "@interface A @end @interface A(X) -(void)test:(int)x :(int)y; @end",
1310       Lang_OBJC, objcCategoryDecl());
1311   EXPECT_FALSE(testStructuralMatch(t2));
1312 }
1313 
1314 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodClassInstance) {
1315   auto t = makeDecls<ObjCCategoryDecl>(
1316       "@interface A @end @interface A(X) -(void)test; @end",
1317       "@interface A @end @interface A(X) +(void)test; @end", Lang_OBJC,
1318       objcCategoryDecl());
1319   EXPECT_FALSE(testStructuralMatch(t));
1320 }
1321 
1322 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodReturnType) {
1323   auto t = makeDecls<ObjCCategoryDecl>(
1324       "@interface A @end @interface A(X) -(void)test; @end",
1325       "@interface A @end @interface A(X) -(int)test; @end", Lang_OBJC,
1326       objcCategoryDecl());
1327   EXPECT_FALSE(testStructuralMatch(t));
1328 }
1329 
1330 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterType) {
1331   auto t = makeDecls<ObjCCategoryDecl>(
1332       "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1333       "@interface A @end @interface A(X) -(void)test:(float)x; @end", Lang_OBJC,
1334       objcCategoryDecl());
1335   EXPECT_FALSE(testStructuralMatch(t));
1336 }
1337 
1338 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterName) {
1339   auto t = makeDecls<ObjCCategoryDecl>(
1340       "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1341       "@interface A @end @interface A(X) -(void)test:(int)y; @end", Lang_OBJC,
1342       objcCategoryDecl());
1343   EXPECT_TRUE(testStructuralMatch(t));
1344 }
1345 
1346 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodNumber) {
1347   auto t = makeDecls<ObjCCategoryDecl>(
1348       "@interface A @end @interface A(X) -(void)test; @end",
1349       "@interface A @end @interface A(X) @end", Lang_OBJC, objcCategoryDecl());
1350   EXPECT_FALSE(testStructuralMatch(t));
1351 }
1352 
1353 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodOrder) {
1354   auto t = makeDecls<ObjCCategoryDecl>(
1355       "@interface A @end @interface A(X) -(void)u; -(void)v; @end",
1356       "@interface A @end @interface A(X) -(void)v; -(void)u; @end", Lang_OBJC,
1357       objcCategoryDecl());
1358   EXPECT_FALSE(testStructuralMatch(t));
1359 }
1360 
1361 struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
1362 
1363 TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
1364   auto t = makeNamedDecls("template <class T> struct foo;",
1365                           "template <class T> struct foo;", Lang_CXX03);
1366   EXPECT_TRUE(testStructuralMatch(t));
1367 }
1368 
1369 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
1370   auto t = makeNamedDecls("template <class T> struct foo;",
1371                           "template <class U> struct foo;", Lang_CXX03);
1372   EXPECT_TRUE(testStructuralMatch(t));
1373 }
1374 
1375 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
1376   auto t = makeNamedDecls("template <class T> struct foo;",
1377                           "template <int T> struct foo;", Lang_CXX03);
1378   EXPECT_FALSE(testStructuralMatch(t));
1379 }
1380 
1381 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDecl) {
1382   const char *Code = "class foo { int a : 2; };";
1383   auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1384   EXPECT_TRUE(testStructuralMatch(t));
1385 }
1386 
1387 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDeclDifferentWidth) {
1388   auto t = makeNamedDecls("class foo { int a : 2; };",
1389                           "class foo { int a : 4; };", Lang_CXX03);
1390   EXPECT_FALSE(testStructuralMatch(t));
1391 }
1392 
1393 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDecl) {
1394   const char *Code = "template <class T> class foo { int a : sizeof(T); };";
1395   auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1396   EXPECT_TRUE(testStructuralMatch(t));
1397 }
1398 
1399 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal) {
1400   auto t = makeNamedDecls(
1401       "template <class A, class B> class foo { int a : sizeof(A); };",
1402       "template <class A, class B> class foo { int a : sizeof(B); };",
1403       Lang_CXX03);
1404   EXPECT_FALSE(testStructuralMatch(t));
1405 }
1406 
1407 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal2) {
1408   auto t = makeNamedDecls(
1409       "template <class A> class foo { int a : sizeof(A); };",
1410       "template <class A> class foo { int a : sizeof(A) + 1; };", Lang_CXX03);
1411   EXPECT_FALSE(testStructuralMatch(t));
1412 }
1413 
1414 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
1415   auto Decls = makeNamedDecls(
1416       "template <bool b> struct foo {explicit(b) foo(int);};",
1417       "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX20);
1418   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1419       get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1420   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1421       get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1422   EXPECT_TRUE(testStructuralMatch(First, Second));
1423 }
1424 
1425 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
1426   auto Decls = makeNamedDecls(
1427       "template <bool b> struct foo {explicit(b) foo(int);};",
1428       "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX20);
1429   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1430       get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1431   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1432       get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1433   EXPECT_FALSE(testStructuralMatch(First, Second));
1434 }
1435 
1436 TEST_F(StructuralEquivalenceTemplateTest,
1437        TemplateVsSubstTemplateTemplateParmInArgEq) {
1438   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1439       R"(
1440 template <typename P1> class Arg { };
1441 template <template <typename PP1> class P1> class Primary { };
1442 
1443 void f() {
1444   // Make specialization with simple template.
1445   Primary <Arg> A;
1446 }
1447       )",
1448       R"(
1449 template <typename P1> class Arg { };
1450 template <template <typename PP1> class P1> class Primary { };
1451 
1452 template <template <typename PP1> class P1> class Templ {
1453   void f() {
1454     // Make specialization with substituted template template param.
1455     Primary <P1> A;
1456   };
1457 };
1458 
1459 // Instantiate with substitution Arg into P1.
1460 template class Templ <Arg>;
1461       )",
1462       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1463   EXPECT_TRUE(testStructuralMatch(t));
1464 }
1465 
1466 TEST_F(StructuralEquivalenceTemplateTest,
1467        TemplateVsSubstTemplateTemplateParmInArgNotEq) {
1468   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1469       R"(
1470 template <typename P1> class Arg { };
1471 template <template <typename PP1> class P1> class Primary { };
1472 
1473 void f() {
1474   // Make specialization with simple template.
1475   Primary <Arg> A;
1476 }
1477       )",
1478       R"(
1479 // Arg is different from the other, this should cause non-equivalence.
1480 template <typename P1> class Arg { int X; };
1481 template <template <typename PP1> class P1> class Primary { };
1482 
1483 template <template <typename PP1> class P1> class Templ {
1484   void f() {
1485     // Make specialization with substituted template template param.
1486     Primary <P1> A;
1487   };
1488 };
1489 
1490 // Instantiate with substitution Arg into P1.
1491 template class Templ <Arg>;
1492       )",
1493       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1494   EXPECT_FALSE(testStructuralMatch(t));
1495 }
1496 
1497 struct StructuralEquivalenceDependentTemplateArgsTest
1498     : StructuralEquivalenceTemplateTest {};
1499 
1500 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1501        SameStructsInDependentArgs) {
1502   std::string Code =
1503       R"(
1504       template <typename>
1505       struct S1;
1506 
1507       template <typename>
1508       struct enable_if;
1509 
1510       struct S
1511       {
1512         template <typename T, typename enable_if<S1<T>>::type>
1513         void f();
1514       };
1515       )";
1516   auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1517                                            functionTemplateDecl(hasName("f")));
1518   EXPECT_TRUE(testStructuralMatch(t));
1519 }
1520 
1521 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1522        DifferentStructsInDependentArgs) {
1523   std::string Code =
1524       R"(
1525       template <typename>
1526       struct S1;
1527 
1528       template <typename>
1529       struct S2;
1530 
1531       template <typename>
1532       struct enable_if;
1533       )";
1534   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1535       struct S
1536       {
1537         template <typename T, typename enable_if<S1<T>>::type>
1538         void f();
1539       };
1540       )",
1541                                            Code + R"(
1542       struct S
1543       {
1544         template <typename T, typename enable_if<S2<T>>::type>
1545         void f();
1546       };
1547       )",
1548                                            Lang_CXX11,
1549                                            functionTemplateDecl(hasName("f")));
1550   EXPECT_FALSE(testStructuralMatch(t));
1551 }
1552 
1553 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1554        SameStructsInDependentScopeDeclRefExpr) {
1555   std::string Code =
1556       R"(
1557       template <typename>
1558       struct S1;
1559 
1560       template <bool>
1561       struct enable_if;
1562 
1563       struct S
1564       {
1565         template <typename T, typename enable_if<S1<T>::value>::type>
1566         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1567       };
1568       )";
1569   auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1570                                            functionTemplateDecl(hasName("f")));
1571   EXPECT_TRUE(testStructuralMatch(t));
1572 }
1573 
1574 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1575        DifferentStructsInDependentScopeDeclRefExpr) {
1576   std::string Code =
1577       R"(
1578       template <typename>
1579       struct S1;
1580 
1581       template <typename>
1582       struct S2;
1583 
1584       template <bool>
1585       struct enable_if;
1586       )";
1587   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1588       struct S
1589       {
1590         template <typename T, typename enable_if<S1<T>::value>::type>
1591         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1592       };
1593       )",
1594                                            Code + R"(
1595       struct S
1596       {
1597         template <typename T, typename enable_if<S2<T>::value>::type>
1598         void f();
1599       };
1600       )",
1601                                            Lang_CXX03,
1602                                            functionTemplateDecl(hasName("f")));
1603   EXPECT_FALSE(testStructuralMatch(t));
1604 }
1605 
1606 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1607        DifferentValueInDependentScopeDeclRefExpr) {
1608   std::string Code =
1609       R"(
1610       template <typename>
1611       struct S1;
1612 
1613       template <bool>
1614       struct enable_if;
1615       )";
1616   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1617       struct S
1618       {
1619         template <typename T, typename enable_if<S1<T>::value1>::type>
1620         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1621       };
1622       )",
1623                                            Code + R"(
1624       struct S
1625       {
1626         template <typename T, typename enable_if<S1<T>::value2>::type>
1627         void f();
1628       };
1629       )",
1630                                            Lang_CXX03,
1631                                            functionTemplateDecl(hasName("f")));
1632   EXPECT_FALSE(testStructuralMatch(t));
1633 }
1634 
1635 TEST_F(
1636     StructuralEquivalenceTemplateTest,
1637     ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) {
1638   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1639       R"(
1640       template <class T> struct Primary {};
1641       namespace N {
1642         struct Arg;
1643       }
1644       // Explicit instantiation with qualified name.
1645       template struct Primary<N::Arg>;
1646       )",
1647       R"(
1648       template <class T> struct Primary {};
1649       namespace N {
1650         struct Arg;
1651       }
1652       using namespace N;
1653       // Explicit instantiation with UNqualified name.
1654       template struct Primary<Arg>;
1655       )",
1656       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1657   EXPECT_TRUE(testStructuralMatch(t));
1658 }
1659 
1660 TEST_F(
1661     StructuralEquivalenceTemplateTest,
1662     ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) {
1663   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1664       R"(
1665       template <class T> struct Primary {};
1666       namespace N {
1667         struct Arg { int a; };
1668       }
1669       // Explicit instantiation with qualified name.
1670       template struct Primary<N::Arg>;
1671       )",
1672       R"(
1673       template <class T> struct Primary {};
1674       namespace N {
1675         // This struct is not equivalent with the other in the prev TU.
1676         struct Arg { double b; }; // -- Field mismatch.
1677       }
1678       using namespace N;
1679       // Explicit instantiation with UNqualified name.
1680       template struct Primary<Arg>;
1681       )",
1682       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1683   EXPECT_FALSE(testStructuralMatch(t));
1684 }
1685 
1686 TEST_F(
1687     StructuralEquivalenceTemplateTest,
1688     ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) {
1689   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1690       R"(
1691       template <template <class> class T> struct Primary {};
1692       namespace N {
1693         template <class T> struct Arg;
1694       }
1695       // Explicit instantiation with qualified name.
1696       template struct Primary<N::Arg>;
1697       )",
1698       R"(
1699       template <template <class> class T> struct Primary {};
1700       namespace N {
1701         template <class T> struct Arg;
1702       }
1703       using namespace N;
1704       // Explicit instantiation with UNqualified name.
1705       template struct Primary<Arg>;
1706       )",
1707       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1708   EXPECT_TRUE(testStructuralMatch(t));
1709 }
1710 
1711 TEST_F(
1712     StructuralEquivalenceTemplateTest,
1713     ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) {
1714   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1715       R"(
1716       template <template <class> class T> struct Primary {};
1717       namespace N {
1718         template <class T> struct Arg { int a; };
1719       }
1720       // Explicit instantiation with qualified name.
1721       template struct Primary<N::Arg>;
1722       )",
1723       R"(
1724       template <template <class> class T> struct Primary {};
1725       namespace N {
1726         // This template is not equivalent with the other in the prev TU.
1727         template <class T> struct Arg { double b; }; // -- Field mismatch.
1728       }
1729       using namespace N;
1730       // Explicit instantiation with UNqualified name.
1731       template struct Primary<Arg>;
1732       )",
1733       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1734   EXPECT_FALSE(testStructuralMatch(t));
1735 }
1736 
1737 TEST_F(StructuralEquivalenceTemplateTest,
1738        IgnoreTemplateParmDepthAtTemplateTypeParmDecl) {
1739   auto Decls = makeDecls<ClassTemplateDecl>(
1740       R"(
1741         template<class> struct A;
1742       )",
1743       R"(
1744         template<class> struct S {
1745           template<class> friend struct A;
1746         };
1747       )",
1748       Lang_CXX03, classTemplateDecl(hasName("A")),
1749       classTemplateDecl(hasName("A")));
1750   EXPECT_TRUE(testStructuralMatch(Decls));
1751   EXPECT_TRUE(testStructuralMatch(Decls, true));
1752 }
1753 
1754 TEST_F(StructuralEquivalenceTemplateTest,
1755        IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) {
1756   auto Decls = makeDecls<ClassTemplateDecl>(
1757       R"(
1758         template<class T, T U> struct A;
1759       )",
1760       R"(
1761         template<class T> struct S {
1762           template<class P, P Q> friend struct A;
1763         };
1764       )",
1765       Lang_CXX03, classTemplateDecl(hasName("A")),
1766       classTemplateDecl(hasName("A")));
1767   EXPECT_FALSE(testStructuralMatch(Decls));
1768   EXPECT_TRUE(testStructuralMatch(Decls, /*IgnoreTemplateParmDepth=*/true));
1769 }
1770 
1771 TEST_F(
1772     StructuralEquivalenceTemplateTest,
1773     ClassTemplSpecWithInequivalentShadowedTemplArg) {
1774   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1775       R"(
1776       template <template <class> class T> struct Primary {};
1777       template <class T> struct Arg { int a; };
1778       // Explicit instantiation with ::Arg
1779       template struct Primary<Arg>;
1780       )",
1781       R"(
1782       template <template <class> class T> struct Primary {};
1783       template <class T> struct Arg { int a; };
1784       namespace N {
1785         // This template is not equivalent with the other in the global scope.
1786         template <class T> struct Arg { double b; }; // -- Field mismatch.
1787         // Explicit instantiation with N::Arg which shadows ::Arg
1788         template struct Primary<Arg>;
1789       }
1790       )",
1791       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1792   EXPECT_FALSE(testStructuralMatch(t));
1793 }
1794 struct StructuralEquivalenceCacheTest : public StructuralEquivalenceTest {
1795   StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls;
1796 
1797   template <typename NodeType, typename MatcherType>
1798   std::pair<NodeType *, NodeType *>
1799   findDeclPair(std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> TU,
1800                MatcherType M) {
1801     NodeType *D0 = FirstDeclMatcher<NodeType>().match(get<0>(TU), M);
1802     NodeType *D1 = FirstDeclMatcher<NodeType>().match(get<1>(TU), M);
1803     return {D0, D1};
1804   }
1805 
1806   template <typename NodeType>
1807   bool isInNonEqCache(std::pair<NodeType *, NodeType *> D,
1808                       bool IgnoreTemplateParmDepth = false) {
1809     return NonEquivalentDecls.count(
1810                std::make_tuple(D.first, D.second, IgnoreTemplateParmDepth)) > 0;
1811   }
1812 };
1813 
1814 TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) {
1815   auto TU = makeTuDecls(
1816       R"(
1817       class A {};
1818       class B {};
1819       void x(A, A);
1820       )",
1821       R"(
1822       class A {};
1823       class B {};
1824       void x(A, B);
1825       )",
1826       Lang_CXX03);
1827 
1828   StructuralEquivalenceContext Ctx(
1829       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1830       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1831 
1832   auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1833   EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
1834 
1835   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1836       TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1837   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1838       TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1839 }
1840 
1841 TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
1842   auto TU = makeTuDecls(
1843       R"(
1844       bool x() { return true; }
1845       )",
1846       R"(
1847       bool x() { return false; }
1848       )",
1849       Lang_CXX03);
1850 
1851   StructuralEquivalenceContext Ctx(
1852       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1853       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1854 
1855   auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1856   EXPECT_FALSE(Ctx.IsEquivalent(X.first->getBody(), X.second->getBody()));
1857 
1858 }
1859 
1860 TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
1861   auto TU = makeTuDecls(
1862       R"(
1863       int p;
1864       )",
1865       R"(
1866       int q;
1867       )",
1868       Lang_CXX03);
1869 
1870   StructuralEquivalenceContext Ctx(
1871       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1872       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1873 
1874   auto Var = findDeclPair<VarDecl>(TU, varDecl());
1875   EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1876 }
1877 
1878 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
1879   auto TU = makeTuDecls(
1880       R"(
1881       int p;
1882       )",
1883       R"(
1884       static int p;
1885       )",
1886       Lang_CXX03);
1887 
1888   StructuralEquivalenceContext Ctx(
1889       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1890       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1891 
1892   auto Var = findDeclPair<VarDecl>(TU, varDecl());
1893   EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1894 }
1895 
1896 TEST_F(StructuralEquivalenceCacheTest,
1897        NonTypeTemplateParmWithDifferentPositionNoEq) {
1898   auto TU = makeTuDecls(
1899       R"(
1900       template<int T>
1901       struct A {
1902         template<int U>
1903         void foo() {}
1904       };
1905       )",
1906       R"(
1907       template<int U>
1908       struct A {
1909         template<int V, int T>
1910         void foo() {}
1911       };
1912       )",
1913       Lang_CXX03);
1914 
1915   StructuralEquivalenceContext Ctx(
1916       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1917       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1918 
1919   auto NTTP = findDeclPair<NonTypeTemplateParmDecl>(
1920       TU, nonTypeTemplateParmDecl(hasName("T")));
1921   EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second));
1922 }
1923 
1924 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
1925   auto TU = makeTuDecls(
1926       R"(
1927       int p = 1;
1928       )",
1929       R"(
1930       int p = 2;
1931       )",
1932       Lang_CXX03);
1933 
1934   StructuralEquivalenceContext Ctx(
1935       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1936       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1937 
1938   auto Var = findDeclPair<VarDecl>(TU, varDecl());
1939   EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1940 }
1941 
1942 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
1943   auto TU = makeTuDecls(
1944       R"(
1945       class A {};
1946       class B { int i; };
1947       void x(A *);
1948       void y(A *);
1949       class C {
1950         friend void x(A *);
1951         friend void y(A *);
1952       };
1953       )",
1954       R"(
1955       class A {};
1956       class B { int i; };
1957       void x(A *);
1958       void y(B *);
1959       class C {
1960         friend void x(A *);
1961         friend void y(B *);
1962       };
1963       )",
1964       Lang_CXX03);
1965 
1966   StructuralEquivalenceContext Ctx(
1967       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1968       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1969 
1970   auto C = findDeclPair<CXXRecordDecl>(
1971       TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1972   EXPECT_FALSE(Ctx.IsEquivalent(C.first, C.second));
1973 
1974   EXPECT_FALSE(isInNonEqCache(C));
1975   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1976       TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1977   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1978       TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1979   EXPECT_FALSE(isInNonEqCache(
1980       findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
1981   EXPECT_FALSE(isInNonEqCache(
1982       findDeclPair<FunctionDecl>(TU, functionDecl(hasName("y")))));
1983 }
1984 
1985 TEST_F(StructuralEquivalenceCacheTest, Cycle) {
1986   auto TU = makeTuDecls(
1987       R"(
1988       class C;
1989       class A { C *c; };
1990       void x(A *);
1991       class C {
1992         friend void x(A *);
1993       };
1994       )",
1995       R"(
1996       class C;
1997       class A { C *c; };
1998       void x(A *);
1999       class C {
2000         friend void x(A *);
2001       };
2002       )",
2003       Lang_CXX03);
2004 
2005   StructuralEquivalenceContext Ctx(
2006       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
2007       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
2008 
2009   auto C = findDeclPair<CXXRecordDecl>(
2010       TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
2011   EXPECT_TRUE(Ctx.IsEquivalent(C.first, C.second));
2012 
2013   EXPECT_FALSE(isInNonEqCache(C));
2014   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
2015       TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
2016   EXPECT_FALSE(isInNonEqCache(
2017       findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
2018 }
2019 
2020 TEST_F(StructuralEquivalenceCacheTest, TemplateParmDepth) {
2021   // In 'friend struct Y' ClassTemplateDecl has the TU as parent context.
2022   // This declaration has template depth 1 (it is already inside a template).
2023   // It has not a previous declaration and is an "undeclared" friend.
2024   //
2025   // Second TU has a specialization of 'struct X'.
2026   // In this case 'friend struct Y' has the ClassTemplateSpecializationDecl as
2027   // parent. It has template depth 0 (it is in the specialization). It has the
2028   // first 'struct Y' declaration as previous declaration and canonical
2029   // declaration.
2030   //
2031   // When these two 'friend struct Y' are compared, only the template depth is
2032   // different.
2033   // FIXME: Structural equivalence checks the depth only in types, not in
2034   // TemplateParmDecl. For this reason the second 'A1' argument is needed (as a
2035   // type) in the template to make the check fail.
2036   auto TU = makeTuDecls(
2037       R"(
2038       template <class A1, A1>
2039       struct Y;
2040 
2041       template <class A>
2042       struct X {
2043         template <class A1, A1>
2044         friend struct Y;
2045       };
2046       )",
2047       R"(
2048       template <class A1, A1>
2049       struct Y;
2050 
2051       template <class A>
2052       struct X {
2053         template <class A1, A1>
2054         friend struct Y;
2055       };
2056 
2057       X<int> x;
2058       )",
2059       Lang_CXX03);
2060 
2061   auto *D0 = LastDeclMatcher<ClassTemplateDecl>().match(
2062       get<0>(TU), classTemplateDecl(hasName("Y"), unless(isImplicit())));
2063   auto *D1 = LastDeclMatcher<ClassTemplateDecl>().match(
2064       get<1>(TU), classTemplateDecl(hasName("Y"), unless(isImplicit())));
2065   ASSERT_EQ(D0->getTemplateDepth(), 1u);
2066   ASSERT_EQ(D1->getTemplateDepth(), 0u);
2067 
2068   StructuralEquivalenceContext Ctx_NoIgnoreTemplateParmDepth(
2069       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
2070       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false,
2071       false, false);
2072 
2073   EXPECT_FALSE(Ctx_NoIgnoreTemplateParmDepth.IsEquivalent(D0, D1));
2074 
2075   Decl *NonEqDecl0 =
2076       D0->getCanonicalDecl()->getTemplateParameters()->getParam(1);
2077   Decl *NonEqDecl1 =
2078       D1->getCanonicalDecl()->getTemplateParameters()->getParam(1);
2079   EXPECT_TRUE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), false));
2080   EXPECT_FALSE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), true));
2081 
2082   StructuralEquivalenceContext Ctx_IgnoreTemplateParmDepth(
2083       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
2084       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false,
2085       false, true);
2086 
2087   EXPECT_TRUE(Ctx_IgnoreTemplateParmDepth.IsEquivalent(D0, D1));
2088 
2089   EXPECT_FALSE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), true));
2090 }
2091 
2092 struct StructuralEquivalenceStmtTest : StructuralEquivalenceTest {};
2093 
2094 /// Fallback matcher to be used only when there is no specific matcher for a
2095 /// Expr subclass. Remove this once all Expr subclasses have their own matcher.
2096 static auto &fallbackExprMatcher = expr;
2097 
2098 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExpr) {
2099   auto t = makeWrappedStmts("lbl: &&lbl;", "lbl: &&lbl;", Lang_CXX03,
2100                             addrLabelExpr());
2101   EXPECT_TRUE(testStructuralMatch(t));
2102 }
2103 
2104 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExprDifferentLabel) {
2105   auto t = makeWrappedStmts("lbl1: lbl2: &&lbl1;", "lbl1: lbl2: &&lbl2;",
2106                             Lang_CXX03, addrLabelExpr());
2107   // FIXME: Should be false. LabelDecl are incorrectly matched.
2108   EXPECT_TRUE(testStructuralMatch(t));
2109 }
2110 
2111 static const std::string MemoryOrderSrc = R"(
2112 enum memory_order {
2113   memory_order_relaxed,
2114   memory_order_consume,
2115   memory_order_acquire,
2116   memory_order_release,
2117   memory_order_acq_rel,
2118   memory_order_seq_cst
2119 };
2120 )";
2121 
2122 TEST_F(StructuralEquivalenceStmtTest, AtomicExpr) {
2123   std::string Prefix = "char a, b; " + MemoryOrderSrc;
2124   auto t = makeStmts(
2125       Prefix +
2126           "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2127       Prefix +
2128           "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2129       Lang_CXX03, atomicExpr());
2130   EXPECT_TRUE(testStructuralMatch(t));
2131 }
2132 
2133 TEST_F(StructuralEquivalenceStmtTest, AtomicExprDifferentOp) {
2134   std::string Prefix = "char a, b; " + MemoryOrderSrc;
2135   auto t = makeStmts(
2136       Prefix +
2137           "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2138       Prefix +
2139           "void wrapped() { __atomic_store(&a, &b, memory_order_seq_cst); }",
2140       Lang_CXX03, atomicExpr());
2141   EXPECT_FALSE(testStructuralMatch(t));
2142 }
2143 
2144 TEST_F(StructuralEquivalenceStmtTest, BinaryOperator) {
2145   auto t = makeWrappedStmts("1 + 1", "1 + 1", Lang_CXX03, binaryOperator());
2146   EXPECT_TRUE(testStructuralMatch(t));
2147 }
2148 
2149 TEST_F(StructuralEquivalenceStmtTest, BinaryOperatorDifferentOps) {
2150   auto t = makeWrappedStmts("1 + 1", "1 - 1", Lang_CXX03, binaryOperator());
2151   EXPECT_FALSE(testStructuralMatch(t));
2152 }
2153 
2154 TEST_F(StructuralEquivalenceStmtTest, CallExpr) {
2155   std::string Src = "int call(); int wrapped() { call(); }";
2156   auto t = makeStmts(Src, Src, Lang_CXX03, callExpr());
2157   EXPECT_TRUE(testStructuralMatch(t));
2158 }
2159 
2160 TEST_F(StructuralEquivalenceStmtTest, CallExprDifferentCallee) {
2161   std::string FunctionSrc = "int func1(); int func2();\n";
2162   auto t = makeStmts(FunctionSrc + "void wrapper() { func1(); }",
2163                      FunctionSrc + "void wrapper() { func2(); }", Lang_CXX03,
2164                      callExpr());
2165   EXPECT_FALSE(testStructuralMatch(t));
2166 }
2167 
2168 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteral) {
2169   auto t = makeWrappedStmts("'a'", "'a'", Lang_CXX03, characterLiteral());
2170   EXPECT_TRUE(testStructuralMatch(t));
2171 }
2172 
2173 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteralDifferentValues) {
2174   auto t = makeWrappedStmts("'a'", "'b'", Lang_CXX03, characterLiteral());
2175   EXPECT_FALSE(testStructuralMatch(t));
2176 }
2177 
2178 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExpr) {
2179   auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_lvalue_expr(1)",
2180                             Lang_CXX03, fallbackExprMatcher());
2181   EXPECT_TRUE(testStructuralMatch(t));
2182 }
2183 
2184 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExprDifferentKind) {
2185   auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_rvalue_expr(1)",
2186                             Lang_CXX03, fallbackExprMatcher());
2187   EXPECT_FALSE(testStructuralMatch(t));
2188 }
2189 
2190 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteral) {
2191   auto t = makeWrappedStmts("1.0", "1.0", Lang_CXX03, fallbackExprMatcher());
2192   EXPECT_TRUE(testStructuralMatch(t));
2193 }
2194 
2195 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentSpelling) {
2196   auto t = makeWrappedStmts("0x10.1p0", "16.0625", Lang_CXX17,
2197                             fallbackExprMatcher());
2198   // Same value but with different spelling is equivalent.
2199   EXPECT_TRUE(testStructuralMatch(t));
2200 }
2201 
2202 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentType) {
2203   auto t = makeWrappedStmts("1.0", "1.0f", Lang_CXX03, fallbackExprMatcher());
2204   EXPECT_FALSE(testStructuralMatch(t));
2205 }
2206 
2207 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentValue) {
2208   auto t = makeWrappedStmts("1.01", "1.0", Lang_CXX03, fallbackExprMatcher());
2209   EXPECT_FALSE(testStructuralMatch(t));
2210 }
2211 
2212 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSame) {
2213   auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2214                             "_Generic(0u, unsigned int: 0, float: 1)", Lang_C99,
2215                             genericSelectionExpr());
2216   EXPECT_TRUE(testStructuralMatch(t));
2217 }
2218 
2219 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSignsDiffer) {
2220   auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2221                             "_Generic(0, int: 0, float: 1)", Lang_C99,
2222                             genericSelectionExpr());
2223   EXPECT_FALSE(testStructuralMatch(t));
2224 }
2225 
2226 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprOrderDiffers) {
2227   auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2228                             "_Generic(0u, float: 1, unsigned int: 0)", Lang_C99,
2229                             genericSelectionExpr());
2230   EXPECT_FALSE(testStructuralMatch(t));
2231 }
2232 
2233 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) {
2234   auto t = makeStmts(
2235       R"(
2236       template <typename T>
2237       void f() {
2238         T x;
2239         (void)_Generic(x, int: 0, float: 1);
2240       }
2241       void g() { f<int>(); }
2242       )",
2243       R"(
2244       template <typename T>
2245       void f() {
2246         T x;
2247         (void)_Generic(x, int: 0, float: 1);
2248       }
2249       void g() { f<int>(); }
2250       )",
2251       Lang_CXX03, genericSelectionExpr());
2252   EXPECT_TRUE(testStructuralMatch(t));
2253 }
2254 
2255 TEST_F(StructuralEquivalenceStmtTest,
2256        GenericSelectionExprDependentResultOrderDiffers) {
2257   auto t = makeStmts(
2258       R"(
2259       template <typename T>
2260       void f() {
2261         T x;
2262         (void)_Generic(x, float: 1, int: 0);
2263       }
2264       void g() { f<int>(); }
2265       )",
2266       R"(
2267       template <typename T>
2268       void f() {
2269         T x;
2270         (void)_Generic(x, int: 0, float: 1);
2271       }
2272       void g() { f<int>(); }
2273       )",
2274       Lang_CXX03, genericSelectionExpr());
2275 
2276   EXPECT_FALSE(testStructuralMatch(t));
2277 }
2278 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteral) {
2279   auto t = makeWrappedStmts("1", "1", Lang_CXX03, integerLiteral());
2280   EXPECT_TRUE(testStructuralMatch(t));
2281 }
2282 
2283 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentSpelling) {
2284   auto t = makeWrappedStmts("1", "0x1", Lang_CXX03, integerLiteral());
2285   // Same value but with different spelling is equivalent.
2286   EXPECT_TRUE(testStructuralMatch(t));
2287 }
2288 
2289 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentValue) {
2290   auto t = makeWrappedStmts("1", "2", Lang_CXX03, integerLiteral());
2291   EXPECT_FALSE(testStructuralMatch(t));
2292 }
2293 
2294 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentTypes) {
2295   auto t = makeWrappedStmts("1", "1L", Lang_CXX03, integerLiteral());
2296   EXPECT_FALSE(testStructuralMatch(t));
2297 }
2298 
2299 TEST_F(StructuralEquivalenceStmtTest, MemberExpr) {
2300   std::string ClassSrc = "struct C { int a; int b; };";
2301   auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2302                      ClassSrc + "int wrapper() { C c; return c.a; }",
2303                      Lang_CXX03, memberExpr());
2304   EXPECT_TRUE(testStructuralMatch(t));
2305 }
2306 
2307 TEST_F(StructuralEquivalenceStmtTest, MemberExprDifferentMember) {
2308   std::string ClassSrc = "struct C { int a; int b; };";
2309   auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2310                      ClassSrc + "int wrapper() { C c; return c.b; }",
2311                      Lang_CXX03, memberExpr());
2312   EXPECT_FALSE(testStructuralMatch(t));
2313 }
2314 
2315 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteral) {
2316   auto t =
2317       makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX, fallbackExprMatcher());
2318   EXPECT_TRUE(testStructuralMatch(t));
2319 }
2320 
2321 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteralDifferentContent) {
2322   auto t =
2323       makeWrappedStmts("@\"a\"", "@\"b\"", Lang_OBJCXX, fallbackExprMatcher());
2324   EXPECT_FALSE(testStructuralMatch(t));
2325 }
2326 
2327 TEST_F(StructuralEquivalenceStmtTest, StringLiteral) {
2328   auto t = makeWrappedStmts("\"a\"", "\"a\"", Lang_CXX03, stringLiteral());
2329   EXPECT_TRUE(testStructuralMatch(t));
2330 }
2331 
2332 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentContent) {
2333   auto t = makeWrappedStmts("\"a\"", "\"b\"", Lang_CXX03, stringLiteral());
2334   EXPECT_FALSE(testStructuralMatch(t));
2335 }
2336 
2337 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentLength) {
2338   auto t = makeWrappedStmts("\"a\"", "\"aa\"", Lang_CXX03, stringLiteral());
2339   EXPECT_FALSE(testStructuralMatch(t));
2340 }
2341 
2342 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExpr) {
2343   auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(int)", Lang_CXX03,
2344                             fallbackExprMatcher());
2345   EXPECT_TRUE(testStructuralMatch(t));
2346 }
2347 
2348 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentType) {
2349   auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(long)", Lang_CXX03,
2350                             fallbackExprMatcher());
2351   EXPECT_FALSE(testStructuralMatch(t));
2352 }
2353 
2354 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTrait) {
2355   auto t = makeWrappedStmts(
2356       "__is_pod(int)", "__is_trivially_constructible(int)", Lang_CXX03, expr());
2357   EXPECT_FALSE(testStructuralMatch(t));
2358 }
2359 
2360 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTraits) {
2361   auto t = makeWrappedStmts("__is_constructible(int)",
2362                             "__is_constructible(int, int)", Lang_CXX03, expr());
2363   EXPECT_FALSE(testStructuralMatch(t));
2364 }
2365 
2366 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExpr) {
2367   auto t = makeWrappedStmts("sizeof(int)", "sizeof(int)", Lang_CXX03,
2368                             unaryExprOrTypeTraitExpr());
2369   EXPECT_TRUE(testStructuralMatch(t));
2370 }
2371 
2372 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentKind) {
2373   auto t = makeWrappedStmts("sizeof(int)", "alignof(long)", Lang_CXX11,
2374                             unaryExprOrTypeTraitExpr());
2375   EXPECT_FALSE(testStructuralMatch(t));
2376 }
2377 
2378 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentType) {
2379   auto t = makeWrappedStmts("sizeof(int)", "sizeof(long)", Lang_CXX03,
2380                             unaryExprOrTypeTraitExpr());
2381   EXPECT_FALSE(testStructuralMatch(t));
2382 }
2383 
2384 TEST_F(StructuralEquivalenceStmtTest, UnaryOperator) {
2385   auto t = makeWrappedStmts("+1", "+1", Lang_CXX03, unaryOperator());
2386   EXPECT_TRUE(testStructuralMatch(t));
2387 }
2388 
2389 TEST_F(StructuralEquivalenceStmtTest, UnaryOperatorDifferentOps) {
2390   auto t = makeWrappedStmts("+1", "-1", Lang_CXX03, unaryOperator());
2391   EXPECT_FALSE(testStructuralMatch(t));
2392 }
2393 
2394 TEST_F(StructuralEquivalenceStmtTest,
2395        CXXOperatorCallExprVsUnaryBinaryOperator) {
2396   auto t = makeNamedDecls(
2397       R"(
2398       template <typename T, T x>
2399       class A;
2400       template <typename T, T x, T y>
2401       void foo(
2402         A<T, x + y>,
2403         A<T, x - y>,
2404         A<T, -x>,
2405         A<T, x * y>,
2406         A<T, *x>,
2407         A<T, x / y>,
2408         A<T, x % y>,
2409         A<T, x ^ y>,
2410         A<T, x & y>,
2411         A<T, &x>,
2412         A<T, x | y>,
2413         A<T, ~x>,
2414         A<T, !x>,
2415         A<T, x < y>,
2416         A<T, (x > y)>,
2417         A<T, x << y>,
2418         A<T, (x >> y)>,
2419         A<T, x == y>,
2420         A<T, x != y>,
2421         A<T, x <= y>,
2422         A<T, x >= y>,
2423         A<T, x <=> y>,
2424         A<T, x && y>,
2425         A<T, x || y>,
2426         A<T, ++x>,
2427         A<T, --x>,
2428         A<T, (x , y)>,
2429         A<T, x ->* y>,
2430         A<T, x -> y>
2431       );
2432       )",
2433       R"(
2434       struct Bar {
2435         Bar& operator=(Bar&);
2436         Bar& operator->();
2437       };
2438 
2439       Bar& operator+(Bar&, Bar&);
2440       Bar& operator+(Bar&);
2441       Bar& operator-(Bar&, Bar&);
2442       Bar& operator-(Bar&);
2443       Bar& operator*(Bar&, Bar&);
2444       Bar& operator*(Bar&);
2445       Bar& operator/(Bar&, Bar&);
2446       Bar& operator%(Bar&, Bar&);
2447       Bar& operator^(Bar&, Bar&);
2448       Bar& operator&(Bar&, Bar&);
2449       Bar& operator&(Bar&);
2450       Bar& operator|(Bar&, Bar&);
2451       Bar& operator~(Bar&);
2452       Bar& operator!(Bar&);
2453       Bar& operator<(Bar&, Bar&);
2454       Bar& operator>(Bar&, Bar&);
2455       Bar& operator+=(Bar&, Bar&);
2456       Bar& operator-=(Bar&, Bar&);
2457       Bar& operator*=(Bar&, Bar&);
2458       Bar& operator/=(Bar&, Bar&);
2459       Bar& operator%=(Bar&, Bar&);
2460       Bar& operator^=(Bar&, Bar&);
2461       Bar& operator&=(Bar&, Bar&);
2462       Bar& operator|=(Bar&, Bar&);
2463       Bar& operator<<(Bar&, Bar&);
2464       Bar& operator>>(Bar&, Bar&);
2465       Bar& operator<<=(Bar&, Bar&);
2466       Bar& operator>>=(Bar&, Bar&);
2467       Bar& operator==(Bar&, Bar&);
2468       Bar& operator!=(Bar&, Bar&);
2469       Bar& operator<=(Bar&, Bar&);
2470       Bar& operator>=(Bar&, Bar&);
2471       Bar& operator<=>(Bar&, Bar&);
2472       Bar& operator&&(Bar&, Bar&);
2473       Bar& operator||(Bar&, Bar&);
2474       Bar& operator++(Bar&);
2475       Bar& operator--(Bar&);
2476       Bar& operator,(Bar&, Bar&);
2477       Bar& operator->*(Bar&, Bar&);
2478 
2479       template <typename T, T x>
2480       class A;
2481       template <typename T, T x, T y>
2482       void foo(
2483         A<T, x + y>,
2484         A<T, x - y>,
2485         A<T, -x>,
2486         A<T, x * y>,
2487         A<T, *x>,
2488         A<T, x / y>,
2489         A<T, x % y>,
2490         A<T, x ^ y>,
2491         A<T, x & y>,
2492         A<T, &x>,
2493         A<T, x | y>,
2494         A<T, ~x>,
2495         A<T, !x>,
2496         A<T, x < y>,
2497         A<T, (x > y)>,
2498         A<T, x << y>,
2499         A<T, (x >> y)>,
2500         A<T, x == y>,
2501         A<T, x != y>,
2502         A<T, x <= y>,
2503         A<T, x >= y>,
2504         A<T, x <=> y>,
2505         A<T, x && y>,
2506         A<T, x || y>,
2507         A<T, ++x>,
2508         A<T, --x>,
2509         A<T, (x , y)>,
2510         A<T, x ->* y>,
2511         A<T, x -> y>
2512       );
2513       )",
2514       Lang_CXX20);
2515   EXPECT_TRUE(testStructuralMatch(t));
2516 }
2517 
2518 TEST_F(StructuralEquivalenceStmtTest,
2519        CXXOperatorCallExprVsUnaryBinaryOperatorNe) {
2520   auto t = makeNamedDecls(
2521       R"(
2522       template <typename T, T x>
2523       class A;
2524       template <typename T, T x, T y>
2525       void foo(
2526         A<T, x + y>
2527       );
2528       )",
2529       R"(
2530       struct Bar;
2531 
2532       Bar& operator-(Bar&, Bar&);
2533 
2534       template <typename T, T x>
2535       class A;
2536       template <typename T, T x, T y>
2537       void foo(
2538         A<T, x - y>
2539       );
2540       )",
2541       Lang_CXX11);
2542   EXPECT_FALSE(testStructuralMatch(t));
2543 }
2544 
2545 TEST_F(StructuralEquivalenceStmtTest, NonTypeTemplateParm) {
2546   auto t = makeNamedDecls(
2547       R"(
2548       template <typename T, T x>
2549       class A;
2550       template <typename T, T x, T y>
2551       void foo(A<T, x>);
2552       )",
2553       R"(
2554       template <typename T, T x>
2555       class A;
2556       template <typename T, T x, T y>
2557       void foo(A<T, y>);
2558       )",
2559       Lang_CXX11);
2560   EXPECT_FALSE(testStructuralMatch(t));
2561 }
2562 
2563 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
2564   auto t = makeStmts(
2565       R"(
2566       void f1(int);
2567       template <typename T>
2568       void f(T t) {
2569         f1(t);
2570       }
2571       void g() { f<int>(1); }
2572       )",
2573       R"(
2574       void f2(int);
2575       template <typename T>
2576       void f(T t) {
2577         f2(t);
2578       }
2579       void g() { f<int>(1); }
2580       )",
2581       Lang_CXX03, unresolvedLookupExpr());
2582   EXPECT_FALSE(testStructuralMatch(t));
2583 }
2584 
2585 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentQualifier) {
2586   auto t = makeStmts(
2587       R"(
2588       struct X {
2589         static void g(int);
2590         static void g(char);
2591       };
2592 
2593       template <typename T>
2594       void f(T t) {
2595         X::g(t);
2596       }
2597 
2598       void g() { f<int>(1); }
2599       )",
2600       R"(
2601       struct Y {
2602         static void g(int);
2603         static void g(char);
2604       };
2605 
2606       template <typename T>
2607       void f(T t) {
2608         Y::g(t);
2609       }
2610 
2611       void g() { f<int>(1); }
2612       )",
2613       Lang_CXX03, unresolvedLookupExpr());
2614   EXPECT_FALSE(testStructuralMatch(t));
2615 }
2616 
2617 TEST_F(StructuralEquivalenceStmtTest,
2618        UnresolvedLookupDifferentTemplateArgument) {
2619   auto t = makeStmts(
2620       R"(
2621       struct A {};
2622       template<typename T1, typename T2>
2623       void g() {}
2624 
2625       template <typename T>
2626       void f() {
2627         g<A, T>();
2628       }
2629 
2630       void h() { f<int>(); }
2631       )",
2632       R"(
2633       struct B {};
2634       template<typename T1, typename T2>
2635       void g() {}
2636 
2637       template <typename T>
2638       void f() {
2639         g<B, T>();
2640       }
2641 
2642       void h() { f<int>(); }
2643       )",
2644       Lang_CXX03, unresolvedLookupExpr());
2645   EXPECT_FALSE(testStructuralMatch(t));
2646 }
2647 
2648 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
2649   auto t = makeStmts(
2650       R"(
2651       struct A {};
2652       struct B {
2653         template<typename T1, typename T2>
2654         static void g(int) {};
2655         template<typename T1, typename T2>
2656         static void g(char) {};
2657       };
2658 
2659       template <typename T1, typename T2>
2660       void f(T2 x) {
2661         B::g<A, T1>(x);
2662       }
2663 
2664       void g() { f<char, int>(1); }
2665       )",
2666       R"(
2667       struct A {};
2668       struct B {
2669         template<typename T1, typename T2>
2670         static void g(int) {};
2671         template<typename T1, typename T2>
2672         static void g(char) {};
2673       };
2674 
2675       template <typename T1, typename T2>
2676       void f(T2 x) {
2677         B::g<A, T1>(x);
2678       }
2679 
2680       void g() { f<char, int>(1); }
2681       )",
2682       Lang_CXX03, unresolvedLookupExpr());
2683   EXPECT_TRUE(testStructuralMatch(t));
2684 }
2685 
2686 TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
2687   auto S = makeStmts(
2688       R"(
2689       void foo() {
2690         goto L1;
2691         L1: foo();
2692       }
2693       )",
2694       R"(
2695       void foo() {
2696         goto L2;
2697         L2: foo();
2698       }
2699       )",
2700       Lang_CXX03, gotoStmt());
2701   EXPECT_FALSE(testStructuralMatch(S));
2702 }
2703 
2704 TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
2705   std::string Prefix = "enum Test { AAA, BBB };";
2706   auto t = makeStmts(
2707       Prefix + "void foo(int i) {if (i > 0) {i = AAA;} else {i = BBB;}}",
2708       Prefix + "void foo(int i) {if (i > 0) {i = BBB;} else {i = AAA;}}",
2709       Lang_CXX03, ifStmt());
2710   EXPECT_FALSE(testStructuralMatch(t));
2711 }
2712 
2713 TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
2714   auto S = makeStmts(
2715       R"(
2716       template <class T>
2717       void foo() {
2718         (void)T().x;
2719       }
2720       struct A { int x; };
2721       void bar() {
2722         foo<A>();
2723       }
2724       )",
2725       R"(
2726       template <class T>
2727       void foo() {
2728         (void)T().y;
2729       }
2730       struct A { int y; };
2731       void bar() {
2732         foo<A>();
2733       }
2734       )",
2735       Lang_CXX11, cxxDependentScopeMemberExpr());
2736   EXPECT_FALSE(testStructuralMatch(S));
2737 }
2738 
2739 } // end namespace ast_matchers
2740 } // end namespace clang
2741