1 #include "clang/AST/ASTContext.h"
2 #include "clang/AST/ASTStructuralEquivalence.h"
3 #include "clang/ASTMatchers/ASTMatchers.h"
4 #include "clang/Frontend/ASTUnit.h"
5 #include "clang/Testing/CommandLineArgs.h"
6 #include "clang/Tooling/Tooling.h"
7 #include "llvm/Support/Host.h"
8 
9 #include "DeclMatcher.h"
10 
11 #include "gtest/gtest.h"
12 
13 namespace clang {
14 namespace ast_matchers {
15 
16 using std::get;
17 
18 struct StructuralEquivalenceTest : ::testing::Test {
19   std::unique_ptr<ASTUnit> AST0, AST1;
20   std::string Code0, Code1; // Buffers for SourceManager
21 
22   // Parses the source code in the specified language and sets the ASTs of
23   // the current test instance to the parse result.
makeASTUnitsclang::ast_matchers::StructuralEquivalenceTest24   void makeASTUnits(const std::string &SrcCode0, const std::string &SrcCode1,
25                     TestLanguage Lang) {
26     this->Code0 = SrcCode0;
27     this->Code1 = SrcCode1;
28     std::vector<std::string> Args = getCommandLineArgsForTesting(Lang);
29 
30     const char *const InputFileName = "input.cc";
31 
32     AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName);
33     AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName);
34   }
35 
36   // Get a pair of node pointers into the synthesized AST from the given code
37   // snippets. To determine the returned node, a separate matcher is specified
38   // for both snippets. The first matching node is returned.
39   template <typename NodeType, typename MatcherType>
40   std::tuple<NodeType *, NodeType *>
makeDeclsclang::ast_matchers::StructuralEquivalenceTest41   makeDecls(const std::string &SrcCode0, const std::string &SrcCode1,
42             TestLanguage Lang, const MatcherType &Matcher0,
43             const MatcherType &Matcher1) {
44     makeASTUnits(SrcCode0, SrcCode1, Lang);
45 
46     NodeType *D0 = FirstDeclMatcher<NodeType>().match(
47         AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
48     NodeType *D1 = FirstDeclMatcher<NodeType>().match(
49         AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
50 
51     return std::make_tuple(D0, D1);
52   }
53 
54   std::tuple<TranslationUnitDecl *, TranslationUnitDecl *>
makeTuDeclsclang::ast_matchers::StructuralEquivalenceTest55   makeTuDecls(const std::string &SrcCode0, const std::string &SrcCode1,
56               TestLanguage Lang) {
57     makeASTUnits(SrcCode0, SrcCode1, Lang);
58 
59     return std::make_tuple(AST0->getASTContext().getTranslationUnitDecl(),
60                            AST1->getASTContext().getTranslationUnitDecl());
61   }
62 
63   // Get a pair of node pointers into the synthesized AST from the given code
64   // snippets. The same matcher is used for both snippets.
65   template <typename NodeType, typename MatcherType>
66   std::tuple<NodeType *, NodeType *>
makeDeclsclang::ast_matchers::StructuralEquivalenceTest67   makeDecls(const std::string &SrcCode0, const std::string &SrcCode1,
68             TestLanguage Lang, const MatcherType &AMatcher) {
69     return makeDecls<NodeType, MatcherType>(
70           SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
71   }
72 
73   // Get a pair of Decl pointers to the synthesized declarations from the given
74   // code snippets. We search for the first NamedDecl with given name in both
75   // snippets.
76   std::tuple<NamedDecl *, NamedDecl *>
makeNamedDeclsclang::ast_matchers::StructuralEquivalenceTest77   makeNamedDecls(const std::string &SrcCode0, const std::string &SrcCode1,
78                  TestLanguage Lang, const char *const Identifier = "foo") {
79     auto Matcher = namedDecl(hasName(Identifier));
80     return makeDecls<NamedDecl>(SrcCode0, SrcCode1, Lang, Matcher);
81   }
82 
83   // Wraps a Stmt and the ASTContext that contains it.
84   struct StmtWithASTContext {
85     Stmt *S;
86     ASTContext *Context;
StmtWithASTContextclang::ast_matchers::StructuralEquivalenceTest::StmtWithASTContext87     explicit StmtWithASTContext(Stmt &S, ASTContext &Context)
88         : S(&S), Context(&Context) {}
StmtWithASTContextclang::ast_matchers::StructuralEquivalenceTest::StmtWithASTContext89     explicit StmtWithASTContext(FunctionDecl *FD)
90         : S(FD->getBody()), Context(&FD->getASTContext()) {}
91   };
92 
93   // Get a pair of node pointers into the synthesized AST from the given code
94   // snippets. To determine the returned node, a separate matcher is specified
95   // for both snippets. The first matching node is returned.
96   template <typename MatcherType>
97   std::tuple<StmtWithASTContext, StmtWithASTContext>
makeStmtsclang::ast_matchers::StructuralEquivalenceTest98   makeStmts(const std::string &SrcCode0, const std::string &SrcCode1,
99             TestLanguage Lang, const MatcherType &Matcher0,
100             const MatcherType &Matcher1) {
101     makeASTUnits(SrcCode0, SrcCode1, Lang);
102 
103     Stmt *S0 = FirstDeclMatcher<Stmt>().match(
104         AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
105     Stmt *S1 = FirstDeclMatcher<Stmt>().match(
106         AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
107 
108     return std::make_tuple(StmtWithASTContext(*S0, AST0->getASTContext()),
109                            StmtWithASTContext(*S1, AST1->getASTContext()));
110   }
111 
112   // Get a pair of node pointers into the synthesized AST from the given code
113   // snippets. The same matcher is used for both snippets.
114   template <typename MatcherType>
115   std::tuple<StmtWithASTContext, StmtWithASTContext>
makeStmtsclang::ast_matchers::StructuralEquivalenceTest116   makeStmts(const std::string &SrcCode0, const std::string &SrcCode1,
117             TestLanguage Lang, const MatcherType &AMatcher) {
118     return makeStmts(SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
119   }
120 
121   // Convenience function for makeStmts that wraps the code inside a function
122   // body.
123   template <typename MatcherType>
124   std::tuple<StmtWithASTContext, StmtWithASTContext>
makeWrappedStmtsclang::ast_matchers::StructuralEquivalenceTest125   makeWrappedStmts(const std::string &SrcCode0, const std::string &SrcCode1,
126                    TestLanguage Lang, const MatcherType &AMatcher) {
127     auto Wrap = [](const std::string &Src) {
128       return "void wrapped() {" + Src + ";}";
129     };
130     return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
131   }
132 
testStructuralMatchclang::ast_matchers::StructuralEquivalenceTest133   bool testStructuralMatch(Decl *D0, Decl *D1) {
134     llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
135     llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
136     StructuralEquivalenceContext Ctx01(
137         D0->getASTContext(), D1->getASTContext(),
138         NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
139     StructuralEquivalenceContext Ctx10(
140         D1->getASTContext(), D0->getASTContext(),
141         NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
142     bool Eq01 = Ctx01.IsEquivalent(D0, D1);
143     bool Eq10 = Ctx10.IsEquivalent(D1, D0);
144     EXPECT_EQ(Eq01, Eq10);
145     return Eq01;
146   }
147 
testStructuralMatchclang::ast_matchers::StructuralEquivalenceTest148   bool testStructuralMatch(StmtWithASTContext S0, StmtWithASTContext S1) {
149     llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
150     llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
151     StructuralEquivalenceContext Ctx01(
152         *S0.Context, *S1.Context, NonEquivalentDecls01,
153         StructuralEquivalenceKind::Default, false, false);
154     StructuralEquivalenceContext Ctx10(
155         *S1.Context, *S0.Context, NonEquivalentDecls10,
156         StructuralEquivalenceKind::Default, false, false);
157     bool Eq01 = Ctx01.IsEquivalent(S0.S, S1.S);
158     bool Eq10 = Ctx10.IsEquivalent(S1.S, S0.S);
159     EXPECT_EQ(Eq01, Eq10);
160     return Eq01;
161   }
162 
163   bool
testStructuralMatchclang::ast_matchers::StructuralEquivalenceTest164   testStructuralMatch(std::tuple<StmtWithASTContext, StmtWithASTContext> t) {
165     return testStructuralMatch(get<0>(t), get<1>(t));
166   }
167 
testStructuralMatchclang::ast_matchers::StructuralEquivalenceTest168   bool testStructuralMatch(std::tuple<Decl *, Decl *> t) {
169     return testStructuralMatch(get<0>(t), get<1>(t));
170   }
171 };
172 
TEST_F(StructuralEquivalenceTest,Int)173 TEST_F(StructuralEquivalenceTest, Int) {
174   auto Decls = makeNamedDecls("int foo;", "int foo;", Lang_CXX03);
175   EXPECT_TRUE(testStructuralMatch(Decls));
176 }
177 
TEST_F(StructuralEquivalenceTest,IntVsSignedInt)178 TEST_F(StructuralEquivalenceTest, IntVsSignedInt) {
179   auto Decls = makeNamedDecls("int foo;", "signed int foo;", Lang_CXX03);
180   EXPECT_TRUE(testStructuralMatch(Decls));
181 }
182 
TEST_F(StructuralEquivalenceTest,Char)183 TEST_F(StructuralEquivalenceTest, Char) {
184   auto Decls = makeNamedDecls("char foo;", "char foo;", Lang_CXX03);
185   EXPECT_TRUE(testStructuralMatch(Decls));
186 }
187 
188 // This test is disabled for now.
189 // FIXME Whether this is equivalent is dependendant on the target.
TEST_F(StructuralEquivalenceTest,DISABLED_CharVsSignedChar)190 TEST_F(StructuralEquivalenceTest, DISABLED_CharVsSignedChar) {
191   auto Decls = makeNamedDecls("char foo;", "signed char foo;", Lang_CXX03);
192   EXPECT_FALSE(testStructuralMatch(Decls));
193 }
194 
TEST_F(StructuralEquivalenceTest,ForwardRecordDecl)195 TEST_F(StructuralEquivalenceTest, ForwardRecordDecl) {
196   auto Decls = makeNamedDecls("struct foo;", "struct foo;", Lang_CXX03);
197   EXPECT_TRUE(testStructuralMatch(Decls));
198 }
199 
TEST_F(StructuralEquivalenceTest,IntVsSignedIntInStruct)200 TEST_F(StructuralEquivalenceTest, IntVsSignedIntInStruct) {
201   auto Decls = makeNamedDecls("struct foo { int x; };",
202                               "struct foo { signed int x; };", Lang_CXX03);
203   EXPECT_TRUE(testStructuralMatch(Decls));
204 }
205 
TEST_F(StructuralEquivalenceTest,CharVsSignedCharInStruct)206 TEST_F(StructuralEquivalenceTest, CharVsSignedCharInStruct) {
207   auto Decls = makeNamedDecls("struct foo { char x; };",
208                               "struct foo { signed char x; };", Lang_CXX03);
209   EXPECT_FALSE(testStructuralMatch(Decls));
210 }
211 
TEST_F(StructuralEquivalenceTest,IntVsSignedIntTemplateSpec)212 TEST_F(StructuralEquivalenceTest, IntVsSignedIntTemplateSpec) {
213   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
214       R"(template <class T> struct foo; template<> struct foo<int>{};)",
215       R"(template <class T> struct foo; template<> struct foo<signed int>{};)",
216       Lang_CXX03, classTemplateSpecializationDecl());
217   auto Spec0 = get<0>(Decls);
218   auto Spec1 = get<1>(Decls);
219   EXPECT_TRUE(testStructuralMatch(Spec0, Spec1));
220 }
221 
TEST_F(StructuralEquivalenceTest,CharVsSignedCharTemplateSpec)222 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpec) {
223   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
224       R"(template <class T> struct foo; template<> struct foo<char>{};)",
225       R"(template <class T> struct foo; template<> struct foo<signed char>{};)",
226       Lang_CXX03, classTemplateSpecializationDecl());
227   auto Spec0 = get<0>(Decls);
228   auto Spec1 = get<1>(Decls);
229   EXPECT_FALSE(testStructuralMatch(Spec0, Spec1));
230 }
231 
TEST_F(StructuralEquivalenceTest,CharVsSignedCharTemplateSpecWithInheritance)232 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpecWithInheritance) {
233   auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
234       R"(
235       struct true_type{};
236       template <class T> struct foo;
237       template<> struct foo<char> : true_type {};
238       )",
239       R"(
240       struct true_type{};
241       template <class T> struct foo;
242       template<> struct foo<signed char> : true_type {};
243       )",
244       Lang_CXX03, classTemplateSpecializationDecl());
245   EXPECT_FALSE(testStructuralMatch(Decls));
246 }
247 
248 // This test is disabled for now.
249 // FIXME Enable it, once the check is implemented.
TEST_F(StructuralEquivalenceTest,DISABLED_WrongOrderInNamespace)250 TEST_F(StructuralEquivalenceTest, DISABLED_WrongOrderInNamespace) {
251   auto Code =
252       R"(
253       namespace NS {
254       template <class T> class Base {
255           int a;
256       };
257       class Derived : Base<Derived> {
258       };
259       }
260       void foo(NS::Derived &);
261       )";
262   auto Decls = makeNamedDecls(Code, Code, Lang_CXX03);
263 
264   NamespaceDecl *NS =
265       LastDeclMatcher<NamespaceDecl>().match(get<1>(Decls), namespaceDecl());
266   ClassTemplateDecl *TD = LastDeclMatcher<ClassTemplateDecl>().match(
267       get<1>(Decls), classTemplateDecl(hasName("Base")));
268 
269   // Reorder the decls, move the TD to the last place in the DC.
270   NS->removeDecl(TD);
271   NS->addDeclInternal(TD);
272 
273   EXPECT_FALSE(testStructuralMatch(Decls));
274 }
275 
TEST_F(StructuralEquivalenceTest,WrongOrderOfFieldsInClass)276 TEST_F(StructuralEquivalenceTest, WrongOrderOfFieldsInClass) {
277   auto Code = "class X { int a; int b; };";
278   auto Decls = makeNamedDecls(Code, Code, Lang_CXX03, "X");
279 
280   CXXRecordDecl *RD = FirstDeclMatcher<CXXRecordDecl>().match(
281       get<1>(Decls), cxxRecordDecl(hasName("X")));
282   FieldDecl *FD =
283       FirstDeclMatcher<FieldDecl>().match(get<1>(Decls), fieldDecl(hasName("a")));
284 
285   // Reorder the FieldDecls
286   RD->removeDecl(FD);
287   RD->addDeclInternal(FD);
288 
289   EXPECT_FALSE(testStructuralMatch(Decls));
290 }
291 
292 struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
293 };
294 
TEST_F(StructuralEquivalenceFunctionTest,TemplateVsNonTemplate)295 TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
296   auto t = makeNamedDecls("void foo();", "template<class T> void foo();",
297                           Lang_CXX03);
298   EXPECT_FALSE(testStructuralMatch(t));
299 }
300 
TEST_F(StructuralEquivalenceFunctionTest,DifferentOperators)301 TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
302   auto t = makeDecls<FunctionDecl>(
303       "struct X{}; bool operator<(X, X);", "struct X{}; bool operator==(X, X);",
304       Lang_CXX03, functionDecl(hasOverloadedOperatorName("<")),
305       functionDecl(hasOverloadedOperatorName("==")));
306   EXPECT_FALSE(testStructuralMatch(t));
307 }
308 
TEST_F(StructuralEquivalenceFunctionTest,SameOperators)309 TEST_F(StructuralEquivalenceFunctionTest, SameOperators) {
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_TRUE(testStructuralMatch(t));
315 }
316 
TEST_F(StructuralEquivalenceFunctionTest,CtorVsDtor)317 TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) {
318   auto t = makeDecls<FunctionDecl>("struct X{ X(); };", "struct X{ ~X(); };",
319                                    Lang_CXX03, cxxConstructorDecl(),
320                                    cxxDestructorDecl());
321   EXPECT_FALSE(testStructuralMatch(t));
322 }
323 
TEST_F(StructuralEquivalenceFunctionTest,ParamConstWithRef)324 TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
325   auto t =
326       makeNamedDecls("void foo(int&);", "void foo(const int&);", Lang_CXX03);
327   EXPECT_FALSE(testStructuralMatch(t));
328 }
329 
TEST_F(StructuralEquivalenceFunctionTest,ParamConstSimple)330 TEST_F(StructuralEquivalenceFunctionTest, ParamConstSimple) {
331   auto t = makeNamedDecls("void foo(int);", "void foo(const int);", Lang_CXX03);
332   EXPECT_TRUE(testStructuralMatch(t));
333   // consider this OK
334 }
335 
TEST_F(StructuralEquivalenceFunctionTest,Throw)336 TEST_F(StructuralEquivalenceFunctionTest, Throw) {
337   auto t = makeNamedDecls("void foo();", "void foo() throw();", Lang_CXX03);
338   EXPECT_FALSE(testStructuralMatch(t));
339 }
340 
TEST_F(StructuralEquivalenceFunctionTest,Noexcept)341 TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
342   auto t = makeNamedDecls("void foo();",
343                           "void foo() noexcept;", Lang_CXX11);
344   EXPECT_FALSE(testStructuralMatch(t));
345 }
346 
TEST_F(StructuralEquivalenceFunctionTest,ThrowVsNoexcept)347 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexcept) {
348   auto t = makeNamedDecls("void foo() throw();",
349                           "void foo() noexcept;", Lang_CXX11);
350   EXPECT_FALSE(testStructuralMatch(t));
351 }
352 
TEST_F(StructuralEquivalenceFunctionTest,ThrowVsNoexceptFalse)353 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptFalse) {
354   auto t = makeNamedDecls("void foo() throw();",
355                           "void foo() noexcept(false);", Lang_CXX11);
356   EXPECT_FALSE(testStructuralMatch(t));
357 }
358 
TEST_F(StructuralEquivalenceFunctionTest,ThrowVsNoexceptTrue)359 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptTrue) {
360   auto t = makeNamedDecls("void foo() throw();",
361                           "void foo() noexcept(true);", Lang_CXX11);
362   EXPECT_FALSE(testStructuralMatch(t));
363 }
364 
TEST_F(StructuralEquivalenceFunctionTest,NoexceptNonMatch)365 TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
366   auto t = makeNamedDecls("void foo() noexcept(false);",
367                           "void foo() noexcept(true);", Lang_CXX11);
368   EXPECT_FALSE(testStructuralMatch(t));
369 }
370 
TEST_F(StructuralEquivalenceFunctionTest,NoexceptMatch)371 TEST_F(StructuralEquivalenceFunctionTest, NoexceptMatch) {
372   auto t = makeNamedDecls("void foo() noexcept(false);",
373                           "void foo() noexcept(false);", Lang_CXX11);
374   EXPECT_TRUE(testStructuralMatch(t));
375 }
376 
TEST_F(StructuralEquivalenceFunctionTest,NoexceptVsNoexceptFalse)377 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptFalse) {
378   auto t = makeNamedDecls("void foo() noexcept;",
379                           "void foo() noexcept(false);", Lang_CXX11);
380   EXPECT_FALSE(testStructuralMatch(t));
381 }
382 
TEST_F(StructuralEquivalenceFunctionTest,NoexceptVsNoexceptTrue)383 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptTrue) {
384   auto t = makeNamedDecls("void foo() noexcept;",
385                           "void foo() noexcept(true);", Lang_CXX11);
386   EXPECT_FALSE(testStructuralMatch(t));
387 }
388 
TEST_F(StructuralEquivalenceFunctionTest,ReturnType)389 TEST_F(StructuralEquivalenceFunctionTest, ReturnType) {
390   auto t = makeNamedDecls("char foo();", "int foo();", Lang_CXX03);
391   EXPECT_FALSE(testStructuralMatch(t));
392 }
393 
TEST_F(StructuralEquivalenceFunctionTest,ReturnConst)394 TEST_F(StructuralEquivalenceFunctionTest, ReturnConst) {
395   auto t = makeNamedDecls("char foo();", "const char foo();", Lang_CXX03);
396   EXPECT_FALSE(testStructuralMatch(t));
397 }
398 
TEST_F(StructuralEquivalenceFunctionTest,ReturnRef)399 TEST_F(StructuralEquivalenceFunctionTest, ReturnRef) {
400   auto t = makeNamedDecls("char &foo();",
401                           "char &&foo();", Lang_CXX11);
402   EXPECT_FALSE(testStructuralMatch(t));
403 }
404 
TEST_F(StructuralEquivalenceFunctionTest,ParamCount)405 TEST_F(StructuralEquivalenceFunctionTest, ParamCount) {
406   auto t = makeNamedDecls("void foo(int);", "void foo(int, int);", Lang_CXX03);
407   EXPECT_FALSE(testStructuralMatch(t));
408 }
409 
TEST_F(StructuralEquivalenceFunctionTest,ParamType)410 TEST_F(StructuralEquivalenceFunctionTest, ParamType) {
411   auto t = makeNamedDecls("void foo(int);", "void foo(char);", Lang_CXX03);
412   EXPECT_FALSE(testStructuralMatch(t));
413 }
414 
TEST_F(StructuralEquivalenceFunctionTest,ParamName)415 TEST_F(StructuralEquivalenceFunctionTest, ParamName) {
416   auto t = makeNamedDecls("void foo(int a);", "void foo(int b);", Lang_CXX03);
417   EXPECT_TRUE(testStructuralMatch(t));
418 }
419 
TEST_F(StructuralEquivalenceFunctionTest,Variadic)420 TEST_F(StructuralEquivalenceFunctionTest, Variadic) {
421   auto t =
422       makeNamedDecls("void foo(int x...);", "void foo(int x);", Lang_CXX03);
423   EXPECT_FALSE(testStructuralMatch(t));
424 }
425 
TEST_F(StructuralEquivalenceFunctionTest,ParamPtr)426 TEST_F(StructuralEquivalenceFunctionTest, ParamPtr) {
427   auto t = makeNamedDecls("void foo(int *);", "void foo(int);", Lang_CXX03);
428   EXPECT_FALSE(testStructuralMatch(t));
429 }
430 
TEST_F(StructuralEquivalenceFunctionTest,NameInParen)431 TEST_F(StructuralEquivalenceFunctionTest, NameInParen) {
432   auto t = makeNamedDecls("void ((foo))();", "void foo();", Lang_CXX03);
433   EXPECT_TRUE(testStructuralMatch(t));
434 }
435 
TEST_F(StructuralEquivalenceFunctionTest,NameInParenWithExceptionSpec)436 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithExceptionSpec) {
437   auto t = makeNamedDecls(
438       "void (foo)() throw(int);",
439       "void (foo)() noexcept;",
440       Lang_CXX11);
441   EXPECT_FALSE(testStructuralMatch(t));
442 }
443 
TEST_F(StructuralEquivalenceFunctionTest,NameInParenWithConst)444 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) {
445   auto t = makeNamedDecls(
446       "struct A { void (foo)() const; };",
447       "struct A { void (foo)(); };",
448       Lang_CXX11);
449   EXPECT_FALSE(testStructuralMatch(t));
450 }
451 
TEST_F(StructuralEquivalenceFunctionTest,FunctionsWithDifferentNoreturnAttr)452 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
453   auto t = makeNamedDecls("__attribute__((noreturn)) void foo();",
454                           "                          void foo();", Lang_C99);
455   EXPECT_TRUE(testStructuralMatch(t));
456 }
457 
TEST_F(StructuralEquivalenceFunctionTest,FunctionsWithDifferentCallingConventions)458 TEST_F(StructuralEquivalenceFunctionTest,
459     FunctionsWithDifferentCallingConventions) {
460   // These attributes may not be available on certain platforms.
461   if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
462       llvm::Triple::x86_64)
463     return;
464   auto t = makeNamedDecls("__attribute__((preserve_all)) void foo();",
465                           "__attribute__((ms_abi))   void foo();", Lang_C99);
466   EXPECT_FALSE(testStructuralMatch(t));
467 }
468 
TEST_F(StructuralEquivalenceFunctionTest,FunctionsWithDifferentSavedRegsAttr)469 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) {
470   if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
471       llvm::Triple::x86_64)
472     return;
473   auto t = makeNamedDecls(
474       "__attribute__((no_caller_saved_registers)) void foo();",
475       "                                           void foo();", Lang_C99);
476   EXPECT_FALSE(testStructuralMatch(t));
477 }
478 
479 struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
480 };
481 
TEST_F(StructuralEquivalenceCXXMethodTest,Virtual)482 TEST_F(StructuralEquivalenceCXXMethodTest, Virtual) {
483   auto t = makeDecls<CXXMethodDecl>("struct X { void foo(); };",
484                                     "struct X { virtual void foo(); };",
485                                     Lang_CXX03, cxxMethodDecl(hasName("foo")));
486   EXPECT_FALSE(testStructuralMatch(t));
487 }
488 
TEST_F(StructuralEquivalenceCXXMethodTest,Pure)489 TEST_F(StructuralEquivalenceCXXMethodTest, Pure) {
490   auto t = makeNamedDecls("struct X { virtual void foo(); };",
491                           "struct X { virtual void foo() = 0; };", Lang_CXX03);
492   EXPECT_FALSE(testStructuralMatch(t));
493 }
494 
TEST_F(StructuralEquivalenceCXXMethodTest,DISABLED_Final)495 TEST_F(StructuralEquivalenceCXXMethodTest, DISABLED_Final) {
496   // The final-ness is not checked yet.
497   auto t =
498       makeNamedDecls("struct X { virtual void foo(); };",
499                      "struct X { virtual void foo() final; };", Lang_CXX03);
500   EXPECT_FALSE(testStructuralMatch(t));
501 }
502 
TEST_F(StructuralEquivalenceCXXMethodTest,Const)503 TEST_F(StructuralEquivalenceCXXMethodTest, Const) {
504   auto t = makeNamedDecls("struct X { void foo(); };",
505                           "struct X { void foo() const; };", Lang_CXX03);
506   EXPECT_FALSE(testStructuralMatch(t));
507 }
508 
TEST_F(StructuralEquivalenceCXXMethodTest,Static)509 TEST_F(StructuralEquivalenceCXXMethodTest, Static) {
510   auto t = makeNamedDecls("struct X { void foo(); };",
511                           "struct X { static void foo(); };", Lang_CXX03);
512   EXPECT_FALSE(testStructuralMatch(t));
513 }
514 
TEST_F(StructuralEquivalenceCXXMethodTest,Ref1)515 TEST_F(StructuralEquivalenceCXXMethodTest, Ref1) {
516   auto t = makeNamedDecls("struct X { void foo(); };",
517                           "struct X { void foo() &&; };", Lang_CXX11);
518   EXPECT_FALSE(testStructuralMatch(t));
519 }
520 
TEST_F(StructuralEquivalenceCXXMethodTest,Ref2)521 TEST_F(StructuralEquivalenceCXXMethodTest, Ref2) {
522   auto t = makeNamedDecls("struct X { void foo() &; };",
523                           "struct X { void foo() &&; };", Lang_CXX11);
524   EXPECT_FALSE(testStructuralMatch(t));
525 }
526 
TEST_F(StructuralEquivalenceCXXMethodTest,AccessSpecifier)527 TEST_F(StructuralEquivalenceCXXMethodTest, AccessSpecifier) {
528   auto t = makeDecls<CXXMethodDecl>("struct X { public: void foo(); };",
529                                     "struct X { private: void foo(); };",
530                                     Lang_CXX03, cxxMethodDecl(hasName("foo")));
531   EXPECT_FALSE(testStructuralMatch(t));
532 }
533 
TEST_F(StructuralEquivalenceCXXMethodTest,Delete)534 TEST_F(StructuralEquivalenceCXXMethodTest, Delete) {
535   auto t = makeNamedDecls("struct X { void foo(); };",
536                           "struct X { void foo() = delete; };", Lang_CXX11);
537   EXPECT_FALSE(testStructuralMatch(t));
538 }
539 
TEST_F(StructuralEquivalenceCXXMethodTest,Constructor)540 TEST_F(StructuralEquivalenceCXXMethodTest, Constructor) {
541   auto t = makeDecls<FunctionDecl>("void foo();", "struct foo { foo(); };",
542                                    Lang_CXX03, functionDecl(hasName("foo")),
543                                    cxxConstructorDecl(hasName("foo")));
544   EXPECT_FALSE(testStructuralMatch(t));
545 }
546 
TEST_F(StructuralEquivalenceCXXMethodTest,ConstructorParam)547 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorParam) {
548   auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
549                                          "struct X { X(int); };", Lang_CXX03,
550                                          cxxConstructorDecl(hasName("X")));
551   EXPECT_FALSE(testStructuralMatch(t));
552 }
553 
TEST_F(StructuralEquivalenceCXXMethodTest,ConstructorExplicit)554 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorExplicit) {
555   auto t = makeDecls<CXXConstructorDecl>("struct X { X(int); };",
556                                          "struct X { explicit X(int); };",
557                                          Lang_CXX11,
558                                          cxxConstructorDecl(hasName("X")));
559   EXPECT_FALSE(testStructuralMatch(t));
560 }
561 
TEST_F(StructuralEquivalenceCXXMethodTest,ConstructorDefault)562 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorDefault) {
563   auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
564                                          "struct X { X() = default; };",
565                                          Lang_CXX11,
566                                          cxxConstructorDecl(hasName("X")));
567   EXPECT_FALSE(testStructuralMatch(t));
568 }
569 
TEST_F(StructuralEquivalenceCXXMethodTest,Conversion)570 TEST_F(StructuralEquivalenceCXXMethodTest, Conversion) {
571   auto t = makeDecls<CXXConversionDecl>("struct X { operator bool(); };",
572                                         "struct X { operator char(); };",
573                                          Lang_CXX11,
574                                          cxxConversionDecl());
575   EXPECT_FALSE(testStructuralMatch(t));
576 }
577 
TEST_F(StructuralEquivalenceCXXMethodTest,Operator)578 TEST_F(StructuralEquivalenceCXXMethodTest, Operator) {
579   auto t =
580       makeDecls<FunctionDecl>("struct X { int operator +(int); };",
581                               "struct X { int operator -(int); };", Lang_CXX03,
582                               functionDecl(hasOverloadedOperatorName("+")),
583                               functionDecl(hasOverloadedOperatorName("-")));
584   EXPECT_FALSE(testStructuralMatch(t));
585 }
586 
TEST_F(StructuralEquivalenceCXXMethodTest,OutOfClass1)587 TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass1) {
588   auto t = makeDecls<FunctionDecl>(
589       "struct X { virtual void f(); }; void X::f() { }",
590       "struct X { virtual void f() { }; };", Lang_CXX03,
591       functionDecl(allOf(hasName("f"), isDefinition())));
592   EXPECT_TRUE(testStructuralMatch(t));
593 }
594 
TEST_F(StructuralEquivalenceCXXMethodTest,OutOfClass2)595 TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass2) {
596   auto t = makeDecls<FunctionDecl>(
597       "struct X { virtual void f(); }; void X::f() { }",
598       "struct X { void f(); }; void X::f() { }", Lang_CXX03,
599       functionDecl(allOf(hasName("f"), isDefinition())));
600   EXPECT_FALSE(testStructuralMatch(t));
601 }
602 
603 struct StructuralEquivalenceRecordTest : StructuralEquivalenceTest {
604   // FIXME Use a common getRecordDecl with ASTImporterTest.cpp!
getRecordDeclclang::ast_matchers::StructuralEquivalenceRecordTest605   RecordDecl *getRecordDecl(FieldDecl *FD) {
606     auto *ET = cast<ElaboratedType>(FD->getType().getTypePtr());
607     return cast<RecordType>(ET->getNamedType().getTypePtr())->getDecl();
608   };
609 };
610 
TEST_F(StructuralEquivalenceRecordTest,Name)611 TEST_F(StructuralEquivalenceRecordTest, Name) {
612   auto t = makeDecls<CXXRecordDecl>("struct A{ };", "struct B{ };", Lang_CXX03,
613                                     cxxRecordDecl(hasName("A")),
614                                     cxxRecordDecl(hasName("B")));
615   EXPECT_FALSE(testStructuralMatch(t));
616 }
617 
TEST_F(StructuralEquivalenceRecordTest,Fields)618 TEST_F(StructuralEquivalenceRecordTest, Fields) {
619   auto t = makeNamedDecls("struct foo{ int x; };", "struct foo{ char x; };",
620                           Lang_CXX03);
621   EXPECT_FALSE(testStructuralMatch(t));
622 }
623 
TEST_F(StructuralEquivalenceRecordTest,DISABLED_Methods)624 TEST_F(StructuralEquivalenceRecordTest, DISABLED_Methods) {
625   // Currently, methods of a class are not checked at class equivalence.
626   auto t = makeNamedDecls("struct foo{ int x(); };", "struct foo{ char x(); };",
627                           Lang_CXX03);
628   EXPECT_FALSE(testStructuralMatch(t));
629 }
630 
TEST_F(StructuralEquivalenceRecordTest,Bases)631 TEST_F(StructuralEquivalenceRecordTest, Bases) {
632   auto t = makeNamedDecls("struct A{ }; struct foo: A { };",
633                           "struct B{ }; struct foo: B { };", Lang_CXX03);
634   EXPECT_FALSE(testStructuralMatch(t));
635 }
636 
TEST_F(StructuralEquivalenceRecordTest,InheritanceVirtual)637 TEST_F(StructuralEquivalenceRecordTest, InheritanceVirtual) {
638   auto t =
639       makeNamedDecls("struct A{ }; struct foo: A { };",
640                      "struct A{ }; struct foo: virtual A { };", Lang_CXX03);
641   EXPECT_FALSE(testStructuralMatch(t));
642 }
643 
TEST_F(StructuralEquivalenceRecordTest,DISABLED_InheritanceType)644 TEST_F(StructuralEquivalenceRecordTest, DISABLED_InheritanceType) {
645   // Access specifier in inheritance is not checked yet.
646   auto t =
647       makeNamedDecls("struct A{ }; struct foo: public A { };",
648                      "struct A{ }; struct foo: private A { };", Lang_CXX03);
649   EXPECT_FALSE(testStructuralMatch(t));
650 }
651 
TEST_F(StructuralEquivalenceRecordTest,Match)652 TEST_F(StructuralEquivalenceRecordTest, Match) {
653   auto Code = R"(
654       struct A{ };
655       struct B{ };
656       struct foo: A, virtual B {
657         void x();
658         int a;
659       };
660       )";
661   auto t = makeNamedDecls(Code, Code, Lang_CXX03);
662   EXPECT_TRUE(testStructuralMatch(t));
663 }
664 
TEST_F(StructuralEquivalenceRecordTest,UnnamedRecordsShouldBeInequivalent)665 TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) {
666   auto t = makeTuDecls(
667       R"(
668       struct A {
669         struct {
670           struct A *next;
671         } entry0;
672         struct {
673           struct A *next;
674         } entry1;
675       };
676       )",
677       "", Lang_C99);
678   auto *TU = get<0>(t);
679   auto *Entry0 =
680       FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry0")));
681   auto *Entry1 =
682       FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry1")));
683   auto *R0 = getRecordDecl(Entry0);
684   auto *R1 = getRecordDecl(Entry1);
685 
686   ASSERT_NE(R0, R1);
687   EXPECT_TRUE(testStructuralMatch(R0, R0));
688   EXPECT_TRUE(testStructuralMatch(R1, R1));
689   EXPECT_FALSE(testStructuralMatch(R0, R1));
690 }
691 
TEST_F(StructuralEquivalenceRecordTest,AnonymousRecordsShouldBeInequivalent)692 TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
693   auto t = makeTuDecls(
694       R"(
695       struct X {
696         struct {
697           int a;
698         };
699         struct {
700           int b;
701         };
702       };
703       )",
704       "", Lang_C99);
705   auto *TU = get<0>(t);
706   auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
707       TU, indirectFieldDecl(hasName("a")));
708   auto *FA = cast<FieldDecl>(A->chain().front());
709   RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
710   auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
711       TU, indirectFieldDecl(hasName("b")));
712   auto *FB = cast<FieldDecl>(B->chain().front());
713   RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
714 
715   ASSERT_NE(RA, RB);
716   EXPECT_TRUE(testStructuralMatch(RA, RA));
717   EXPECT_TRUE(testStructuralMatch(RB, RB));
718   EXPECT_FALSE(testStructuralMatch(RA, RB));
719 }
720 
TEST_F(StructuralEquivalenceRecordTest,RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent)721 TEST_F(StructuralEquivalenceRecordTest,
722        RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) {
723   auto t = makeTuDecls(
724       R"(
725       struct X {
726         struct { int a; };
727         struct { int b; };
728       };
729       )",
730       R"(
731       struct X { // The order is reversed.
732         struct { int b; };
733         struct { int a; };
734       };
735       )",
736       Lang_C99);
737 
738   auto *TU = get<0>(t);
739   auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
740       TU, indirectFieldDecl(hasName("a")));
741   auto *FA = cast<FieldDecl>(A->chain().front());
742   RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
743 
744   auto *TU1 = get<1>(t);
745   auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
746       TU1, indirectFieldDecl(hasName("a")));
747   auto *FA1 = cast<FieldDecl>(A1->chain().front());
748   RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
749 
750   RecordDecl *X =
751       FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
752   RecordDecl *X1 =
753       FirstDeclMatcher<RecordDecl>().match(TU1, recordDecl(hasName("X")));
754   ASSERT_NE(X, X1);
755   EXPECT_FALSE(testStructuralMatch(X, X1));
756 
757   ASSERT_NE(RA, RA1);
758   EXPECT_TRUE(testStructuralMatch(RA, RA));
759   EXPECT_TRUE(testStructuralMatch(RA1, RA1));
760   EXPECT_FALSE(testStructuralMatch(RA1, RA));
761 }
762 
TEST_F(StructuralEquivalenceRecordTest,UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined)763 TEST_F(StructuralEquivalenceRecordTest,
764        UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) {
765   auto Code =
766       R"(
767       struct A {
768         struct {
769           struct A *next;
770         } entry0;
771         struct {
772           struct A *next;
773         } entry1;
774       };
775       )";
776   auto t = makeTuDecls(Code, Code, Lang_C99);
777 
778   auto *FromTU = get<0>(t);
779   auto *Entry1 =
780       FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("entry1")));
781 
782   auto *ToTU = get<1>(t);
783   auto *Entry0 =
784       FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
785   auto *A =
786       FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
787   A->startDefinition(); // Set isBeingDefined, getDefinition() will return a
788                         // nullptr. This may be the case during ASTImport.
789 
790   auto *R0 = getRecordDecl(Entry0);
791   auto *R1 = getRecordDecl(Entry1);
792 
793   ASSERT_NE(R0, R1);
794   EXPECT_TRUE(testStructuralMatch(R0, R0));
795   EXPECT_TRUE(testStructuralMatch(R1, R1));
796   EXPECT_FALSE(testStructuralMatch(R0, R1));
797 }
798 
TEST_F(StructuralEquivalenceRecordTest,TemplateVsNonTemplate)799 TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
800   auto t = makeDecls<CXXRecordDecl>("struct A { };",
801                                     "template<class T> struct A { };",
802                                     Lang_CXX03, cxxRecordDecl(hasName("A")));
803   EXPECT_FALSE(testStructuralMatch(t));
804 }
805 
TEST_F(StructuralEquivalenceRecordTest,FwdDeclRecordShouldBeEqualWithFwdDeclRecord)806 TEST_F(StructuralEquivalenceRecordTest,
807     FwdDeclRecordShouldBeEqualWithFwdDeclRecord) {
808   auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11);
809   EXPECT_TRUE(testStructuralMatch(t));
810 }
811 
TEST_F(StructuralEquivalenceRecordTest,FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition)812 TEST_F(StructuralEquivalenceRecordTest,
813        FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) {
814   auto t =
815       makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11);
816   EXPECT_TRUE(testStructuralMatch(t));
817 }
818 
TEST_F(StructuralEquivalenceRecordTest,RecordShouldBeEqualWithRecordWhichHasDefinition)819 TEST_F(StructuralEquivalenceRecordTest,
820        RecordShouldBeEqualWithRecordWhichHasDefinition) {
821   auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };",
822                           Lang_CXX11);
823   EXPECT_TRUE(testStructuralMatch(t));
824 }
825 
TEST_F(StructuralEquivalenceRecordTest,RecordsWithDifferentBody)826 TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) {
827   auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };",
828                           Lang_CXX11);
829   EXPECT_FALSE(testStructuralMatch(t));
830 }
831 
TEST_F(StructuralEquivalenceRecordTest,SameFriendMultipleTimes)832 TEST_F(StructuralEquivalenceRecordTest, SameFriendMultipleTimes) {
833   auto t = makeNamedDecls("struct foo { friend class X; };",
834                           "struct foo { friend class X; friend class X; };",
835                           Lang_CXX11);
836   EXPECT_FALSE(testStructuralMatch(t));
837 }
838 
TEST_F(StructuralEquivalenceRecordTest,SameFriendsDifferentOrder)839 TEST_F(StructuralEquivalenceRecordTest, SameFriendsDifferentOrder) {
840   auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };",
841                           "struct foo { friend class Y; friend class X; };",
842                           Lang_CXX11);
843   EXPECT_FALSE(testStructuralMatch(t));
844 }
845 
TEST_F(StructuralEquivalenceRecordTest,SameFriendsSameOrder)846 TEST_F(StructuralEquivalenceRecordTest, SameFriendsSameOrder) {
847   auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };",
848                           "struct foo { friend class X; friend class Y; };",
849                           Lang_CXX11);
850   EXPECT_TRUE(testStructuralMatch(t));
851 }
852 
853 struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {};
854 
TEST_F(StructuralEquivalenceLambdaTest,LambdaClassesWithDifferentMethods)855 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) {
856   // Get the LambdaExprs, unfortunately we can't match directly the underlying
857   // implicit CXXRecordDecl of the Lambda classes.
858   auto t = makeDecls<LambdaExpr>(
859       "void f() { auto L0 = [](int){}; }",
860       "void f() { auto L1 = [](){}; }",
861       Lang_CXX11,
862       lambdaExpr(),
863       lambdaExpr());
864   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
865   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
866   EXPECT_FALSE(testStructuralMatch(L0, L1));
867 }
868 
TEST_F(StructuralEquivalenceLambdaTest,LambdaClassesWithEqMethods)869 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqMethods) {
870   auto t = makeDecls<LambdaExpr>(
871       "void f() { auto L0 = [](int){}; }",
872       "void f() { auto L1 = [](int){}; }",
873       Lang_CXX11,
874       lambdaExpr(),
875       lambdaExpr());
876   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
877   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
878   EXPECT_TRUE(testStructuralMatch(L0, L1));
879 }
880 
TEST_F(StructuralEquivalenceLambdaTest,LambdaClassesWithDifferentFields)881 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentFields) {
882   auto t = makeDecls<LambdaExpr>(
883       "void f() { char* X; auto L0 = [X](){}; }",
884       "void f() { float X; auto L1 = [X](){}; }",
885       Lang_CXX11,
886       lambdaExpr(),
887       lambdaExpr());
888   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
889   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
890   EXPECT_FALSE(testStructuralMatch(L0, L1));
891 }
892 
TEST_F(StructuralEquivalenceLambdaTest,LambdaClassesWithEqFields)893 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqFields) {
894   auto t = makeDecls<LambdaExpr>(
895       "void f() { float X; auto L0 = [X](){}; }",
896       "void f() { float X; auto L1 = [X](){}; }",
897       Lang_CXX11,
898       lambdaExpr(),
899       lambdaExpr());
900   CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
901   CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
902   EXPECT_TRUE(testStructuralMatch(L0, L1));
903 }
904 
TEST_F(StructuralEquivalenceTest,CompareSameDeclWithMultiple)905 TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
906   auto t = makeNamedDecls("struct A{ }; struct B{ }; void foo(A a, A b);",
907                           "struct A{ }; struct B{ }; void foo(A a, B b);",
908                           Lang_CXX03);
909   EXPECT_FALSE(testStructuralMatch(t));
910 }
911 
TEST_F(StructuralEquivalenceTest,ExplicitBoolDifferent)912 TEST_F(StructuralEquivalenceTest, ExplicitBoolDifferent) {
913   auto Decls = makeNamedDecls("struct foo {explicit(false) foo(int);};",
914                               "struct foo {explicit(true) foo(int);};", Lang_CXX20);
915   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
916       get<0>(Decls), cxxConstructorDecl(hasName("foo")));
917   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
918       get<1>(Decls), cxxConstructorDecl(hasName("foo")));
919   EXPECT_FALSE(testStructuralMatch(First, Second));
920 }
921 
TEST_F(StructuralEquivalenceTest,ExplicitBoolSame)922 TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
923   auto Decls = makeNamedDecls("struct foo {explicit(true) foo(int);};",
924                               "struct foo {explicit(true) foo(int);};", Lang_CXX20);
925   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
926       get<0>(Decls), cxxConstructorDecl(hasName("foo")));
927   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
928       get<1>(Decls), cxxConstructorDecl(hasName("foo")));
929   EXPECT_TRUE(testStructuralMatch(First, Second));
930 }
931 
932 struct StructuralEquivalenceRecordContextTest : StructuralEquivalenceTest {};
933 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceNoVsNamed)934 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsNamed) {
935   auto Decls =
936       makeNamedDecls("class X;", "namespace N { class X; }", Lang_CXX03, "X");
937   EXPECT_FALSE(testStructuralMatch(Decls));
938 }
939 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceNamedVsNamed)940 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsNamed) {
941   auto Decls = makeNamedDecls("namespace A { class X; }",
942                               "namespace B { class X; }", Lang_CXX03, "X");
943   EXPECT_FALSE(testStructuralMatch(Decls));
944 }
945 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceAnonVsNamed)946 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsNamed) {
947   auto Decls = makeNamedDecls("namespace { class X; }",
948                               "namespace N { class X; }", Lang_CXX03, "X");
949   EXPECT_FALSE(testStructuralMatch(Decls));
950 }
951 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceNoVsAnon)952 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsAnon) {
953   auto Decls =
954       makeNamedDecls("class X;", "namespace { class X; }", Lang_CXX03, "X");
955   EXPECT_FALSE(testStructuralMatch(Decls));
956 }
957 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceAnonVsAnon)958 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnon) {
959   auto Decls = makeNamedDecls("namespace { class X; }",
960                               "namespace { class X; }", Lang_CXX03, "X");
961   EXPECT_TRUE(testStructuralMatch(Decls));
962 }
963 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceAnonVsAnonAnon)964 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnonAnon) {
965   auto Decls =
966       makeNamedDecls("namespace { class X; }",
967                      "namespace { namespace { class X; } }", Lang_CXX03, "X");
968   EXPECT_FALSE(testStructuralMatch(Decls));
969 }
970 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceNamedNamedVsNamedNamed)971 TEST_F(StructuralEquivalenceRecordContextTest,
972        NamespaceNamedNamedVsNamedNamed) {
973   auto Decls = makeNamedDecls("namespace A { namespace N { class X; } }",
974                               "namespace B { namespace N { class X; } }",
975                               Lang_CXX03, "X");
976   EXPECT_FALSE(testStructuralMatch(Decls));
977 }
978 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceNamedVsInline)979 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsInline) {
980   auto Decls = makeNamedDecls("namespace A { namespace A { class X; } }",
981                               "namespace A { inline namespace A { class X; } }",
982                               Lang_CXX17, "X");
983   EXPECT_FALSE(testStructuralMatch(Decls));
984 }
985 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceInlineVsInline)986 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineVsInline) {
987   auto Decls = makeNamedDecls("namespace A { inline namespace A { class X; } }",
988                               "namespace A { inline namespace B { class X; } }",
989                               Lang_CXX17, "X");
990   EXPECT_TRUE(testStructuralMatch(Decls));
991 }
992 
TEST_F(StructuralEquivalenceRecordContextTest,NamespaceInlineTopLevel)993 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineTopLevel) {
994   auto Decls =
995       makeNamedDecls("inline namespace A { class X; } }",
996                      "inline namespace B { class X; } }", Lang_CXX17, "X");
997   EXPECT_TRUE(testStructuralMatch(Decls));
998 }
999 
TEST_F(StructuralEquivalenceRecordContextTest,TransparentContext)1000 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContext) {
1001   auto Decls =
1002       makeNamedDecls("extern \"C\" { class X; }", "class X;", Lang_CXX03, "X");
1003   EXPECT_TRUE(testStructuralMatch(Decls));
1004 }
1005 
TEST_F(StructuralEquivalenceRecordContextTest,TransparentContextNE)1006 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextNE) {
1007   auto Decls = makeNamedDecls("extern \"C\" { class X; }",
1008                               "namespace { class X; }", Lang_CXX03, "X");
1009   EXPECT_FALSE(testStructuralMatch(Decls));
1010 }
1011 
TEST_F(StructuralEquivalenceRecordContextTest,TransparentContextInNamespace)1012 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextInNamespace) {
1013   auto Decls = makeNamedDecls("extern \"C\" { namespace N { class X; } }",
1014                               "namespace N { extern \"C\" { class X; } }",
1015                               Lang_CXX03, "X");
1016   EXPECT_TRUE(testStructuralMatch(Decls));
1017 }
1018 
TEST_F(StructuralEquivalenceTest,NamespaceOfRecordMember)1019 TEST_F(StructuralEquivalenceTest, NamespaceOfRecordMember) {
1020   auto Decls = makeNamedDecls(
1021       R"(
1022       class X;
1023       class Y { X* x; };
1024       )",
1025       R"(
1026       namespace N { class X; }
1027       class Y { N::X* x; };
1028       )",
1029       Lang_CXX03, "Y");
1030   EXPECT_FALSE(testStructuralMatch(Decls));
1031 }
1032 
TEST_F(StructuralEquivalenceTest,StructDefinitionInPrototype)1033 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototype) {
1034   auto Decls =
1035       makeNamedDecls("struct Param { int a; }; void foo(struct Param *p);",
1036                      "void foo(struct Param { int a; } *p);", Lang_C89);
1037   EXPECT_TRUE(testStructuralMatch(Decls));
1038 }
1039 
TEST_F(StructuralEquivalenceTest,StructDefinitionInPrototypeDifferentName)1040 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototypeDifferentName) {
1041   auto Decls =
1042       makeNamedDecls("struct Param1 { int a; }; void foo(struct Param1 *p);",
1043                      "void foo(struct Param2 { int a; } *p);", Lang_C89);
1044   EXPECT_FALSE(testStructuralMatch(Decls));
1045 }
1046 
TEST_F(StructuralEquivalenceRecordContextTest,RecordInsideFunction)1047 TEST_F(StructuralEquivalenceRecordContextTest, RecordInsideFunction) {
1048   auto Decls = makeNamedDecls("struct Param { int a; };",
1049                               "void f() { struct Param { int a; }; }", Lang_C89,
1050                               "Param");
1051   EXPECT_TRUE(testStructuralMatch(Decls));
1052 }
1053 
1054 struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
1055 
TEST_F(StructuralEquivalenceEnumTest,FwdDeclEnumShouldBeEqualWithFwdDeclEnum)1056 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
1057   auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
1058   EXPECT_TRUE(testStructuralMatch(t));
1059 }
1060 
TEST_F(StructuralEquivalenceEnumTest,FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition)1061 TEST_F(StructuralEquivalenceEnumTest,
1062        FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
1063   auto t =
1064       makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
1065   EXPECT_TRUE(testStructuralMatch(t));
1066 }
1067 
TEST_F(StructuralEquivalenceEnumTest,EnumShouldBeEqualWithEnumWhichHasDefinition)1068 TEST_F(StructuralEquivalenceEnumTest,
1069        EnumShouldBeEqualWithEnumWhichHasDefinition) {
1070   auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
1071                           Lang_CXX11);
1072   EXPECT_TRUE(testStructuralMatch(t));
1073 }
1074 
TEST_F(StructuralEquivalenceEnumTest,EnumsWithDifferentBody)1075 TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
1076   auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
1077                           Lang_CXX11);
1078   EXPECT_FALSE(testStructuralMatch(t));
1079 }
1080 
1081 struct StructuralEquivalenceEnumConstantTest : StructuralEquivalenceTest {};
1082 
TEST_F(StructuralEquivalenceEnumConstantTest,EnumConstantsWithSameValues)1083 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithSameValues) {
1084   auto t = makeNamedDecls("enum foo { foo = 1 };", "enum foo { foo = 1 };",
1085                           Lang_C89);
1086   EXPECT_TRUE(testStructuralMatch(t));
1087 }
1088 
TEST_F(StructuralEquivalenceEnumConstantTest,EnumConstantsWithDifferentValues)1089 TEST_F(StructuralEquivalenceEnumConstantTest,
1090        EnumConstantsWithDifferentValues) {
1091   auto t =
1092       makeNamedDecls("enum e { foo = 1 };", "enum e { foo = 2 };", Lang_C89);
1093   EXPECT_FALSE(testStructuralMatch(t));
1094 }
1095 
TEST_F(StructuralEquivalenceEnumConstantTest,EnumConstantsWithDifferentExprsButSameValues)1096 TEST_F(StructuralEquivalenceEnumConstantTest,
1097        EnumConstantsWithDifferentExprsButSameValues) {
1098   auto t = makeNamedDecls("enum e { foo = 1 + 1 };", "enum e { foo = 2 };",
1099                           Lang_CXX11);
1100   EXPECT_FALSE(testStructuralMatch(t));
1101 }
1102 
TEST_F(StructuralEquivalenceEnumConstantTest,EnumConstantsWithDifferentSignedness)1103 TEST_F(StructuralEquivalenceEnumConstantTest,
1104        EnumConstantsWithDifferentSignedness) {
1105   auto t = makeNamedDecls("enum e : unsigned { foo = 1 };",
1106                           "enum e : int { foo = 1 };", Lang_CXX11);
1107   EXPECT_FALSE(testStructuralMatch(t));
1108 }
1109 
TEST_F(StructuralEquivalenceEnumConstantTest,EnumConstantsWithDifferentWidth)1110 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentWidth) {
1111   auto t = makeNamedDecls("enum e : short { foo = 1 };",
1112                           "enum e : int { foo = 1 };", Lang_CXX11);
1113   EXPECT_FALSE(testStructuralMatch(t));
1114 }
1115 
TEST_F(StructuralEquivalenceEnumConstantTest,EnumConstantsWithDifferentName)1116 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentName) {
1117   auto t =
1118       makeDecls<EnumConstantDecl>("enum e { foo = 1 };", "enum e { bar = 1 };",
1119                                   Lang_CXX11, enumConstantDecl());
1120   EXPECT_FALSE(testStructuralMatch(t));
1121 }
1122 
1123 struct StructuralEquivalenceObjCCategoryTest : StructuralEquivalenceTest {};
1124 
TEST_F(StructuralEquivalenceObjCCategoryTest,MatchinCategoryNames)1125 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchinCategoryNames) {
1126   auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1127                                        "@interface A @end @interface A(X) @end",
1128                                        Lang_OBJC, objcCategoryDecl());
1129   EXPECT_TRUE(testStructuralMatch(t));
1130 }
1131 
TEST_F(StructuralEquivalenceObjCCategoryTest,CategoriesForDifferentClasses)1132 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesForDifferentClasses) {
1133   auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1134                                        "@interface B @end @interface B(X) @end",
1135                                        Lang_OBJC, objcCategoryDecl());
1136   EXPECT_FALSE(testStructuralMatch(t));
1137 }
1138 
TEST_F(StructuralEquivalenceObjCCategoryTest,CategoriesWithDifferentNames)1139 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithDifferentNames) {
1140   auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1141                                        "@interface A @end @interface A(Y) @end",
1142                                        Lang_OBJC, objcCategoryDecl());
1143   EXPECT_FALSE(testStructuralMatch(t));
1144 }
1145 
TEST_F(StructuralEquivalenceObjCCategoryTest,CategoryAndExtension)1146 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoryAndExtension) {
1147   auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1148                                        "@interface A @end @interface A() @end",
1149                                        Lang_OBJC, objcCategoryDecl());
1150   EXPECT_FALSE(testStructuralMatch(t));
1151 }
1152 
TEST_F(StructuralEquivalenceObjCCategoryTest,MatchingProtocols)1153 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingProtocols) {
1154   auto t = makeDecls<ObjCCategoryDecl>(
1155       "@protocol P @end @interface A @end @interface A(X)<P> @end",
1156       "@protocol P @end @interface A @end @interface A(X)<P> @end", Lang_OBJC,
1157       objcCategoryDecl());
1158   EXPECT_TRUE(testStructuralMatch(t));
1159 }
1160 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentProtocols)1161 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocols) {
1162   auto t = makeDecls<ObjCCategoryDecl>(
1163       "@protocol P @end @interface A @end @interface A(X)<P> @end",
1164       "@protocol Q @end @interface A @end @interface A(X)<Q> @end", Lang_OBJC,
1165       objcCategoryDecl());
1166   EXPECT_FALSE(testStructuralMatch(t));
1167 }
1168 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentProtocolsOrder)1169 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocolsOrder) {
1170   auto t = makeDecls<ObjCCategoryDecl>(
1171       "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<P, "
1172       "Q> @end",
1173       "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<Q, "
1174       "P> @end",
1175       Lang_OBJC, objcCategoryDecl());
1176   EXPECT_FALSE(testStructuralMatch(t));
1177 }
1178 
TEST_F(StructuralEquivalenceObjCCategoryTest,MatchingIvars)1179 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingIvars) {
1180   auto t = makeDecls<ObjCCategoryDecl>(
1181       "@interface A @end @interface A() { int x; } @end",
1182       "@interface A @end @interface A() { int x; } @end", Lang_OBJC,
1183       objcCategoryDecl());
1184   EXPECT_TRUE(testStructuralMatch(t));
1185 }
1186 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentIvarName)1187 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarName) {
1188   auto t = makeDecls<ObjCCategoryDecl>(
1189       "@interface A @end @interface A() { int x; } @end",
1190       "@interface A @end @interface A() { int y; } @end", Lang_OBJC,
1191       objcCategoryDecl());
1192   EXPECT_FALSE(testStructuralMatch(t));
1193 }
1194 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentIvarType)1195 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarType) {
1196   auto t = makeDecls<ObjCCategoryDecl>(
1197       "@interface A @end @interface A() { int x; } @end",
1198       "@interface A @end @interface A() { float x; } @end", Lang_OBJC,
1199       objcCategoryDecl());
1200   EXPECT_FALSE(testStructuralMatch(t));
1201 }
1202 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentIvarBitfieldWidth)1203 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarBitfieldWidth) {
1204   auto t = makeDecls<ObjCCategoryDecl>(
1205       "@interface A @end @interface A() { int x: 1; } @end",
1206       "@interface A @end @interface A() { int x: 2; } @end", Lang_OBJC,
1207       objcCategoryDecl());
1208   EXPECT_FALSE(testStructuralMatch(t));
1209 }
1210 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentIvarVisibility)1211 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarVisibility) {
1212   auto t = makeDecls<ObjCCategoryDecl>(
1213       "@interface A @end @interface A() { @public int x; } @end",
1214       "@interface A @end @interface A() { @protected int x; } @end", Lang_OBJC,
1215       objcCategoryDecl());
1216   EXPECT_FALSE(testStructuralMatch(t));
1217 }
1218 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentIvarNumber)1219 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarNumber) {
1220   auto t = makeDecls<ObjCCategoryDecl>(
1221       "@interface A @end @interface A() { int x; } @end",
1222       "@interface A @end @interface A() {} @end", Lang_OBJC,
1223       objcCategoryDecl());
1224   EXPECT_FALSE(testStructuralMatch(t));
1225 }
1226 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentIvarOrder)1227 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarOrder) {
1228   auto t = makeDecls<ObjCCategoryDecl>(
1229       "@interface A @end @interface A() { int x; int y; } @end",
1230       "@interface A @end @interface A() { int y; int x; } @end", Lang_OBJC,
1231       objcCategoryDecl());
1232   EXPECT_FALSE(testStructuralMatch(t));
1233 }
1234 
TEST_F(StructuralEquivalenceObjCCategoryTest,MatchingMethods)1235 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingMethods) {
1236   auto t = makeDecls<ObjCCategoryDecl>(
1237       "@interface A @end @interface A(X) -(void)test; @end",
1238       "@interface A @end @interface A(X) -(void)test; @end", Lang_OBJC,
1239       objcCategoryDecl());
1240   EXPECT_TRUE(testStructuralMatch(t));
1241 }
1242 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentMethodName)1243 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodName) {
1244   auto t = makeDecls<ObjCCategoryDecl>(
1245       "@interface A @end @interface A(X) -(void)test; @end",
1246       "@interface A @end @interface A(X) -(void)wasd; @end", Lang_OBJC,
1247       objcCategoryDecl());
1248   EXPECT_FALSE(testStructuralMatch(t));
1249 
1250   auto t2 = makeDecls<ObjCCategoryDecl>(
1251       "@interface A @end @interface A(X) -(void)test:(int)x more:(int)y; @end",
1252       "@interface A @end @interface A(X) -(void)test:(int)x :(int)y; @end",
1253       Lang_OBJC, objcCategoryDecl());
1254   EXPECT_FALSE(testStructuralMatch(t2));
1255 }
1256 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentMethodClassInstance)1257 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodClassInstance) {
1258   auto t = makeDecls<ObjCCategoryDecl>(
1259       "@interface A @end @interface A(X) -(void)test; @end",
1260       "@interface A @end @interface A(X) +(void)test; @end", Lang_OBJC,
1261       objcCategoryDecl());
1262   EXPECT_FALSE(testStructuralMatch(t));
1263 }
1264 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentMethodReturnType)1265 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodReturnType) {
1266   auto t = makeDecls<ObjCCategoryDecl>(
1267       "@interface A @end @interface A(X) -(void)test; @end",
1268       "@interface A @end @interface A(X) -(int)test; @end", Lang_OBJC,
1269       objcCategoryDecl());
1270   EXPECT_FALSE(testStructuralMatch(t));
1271 }
1272 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentMethodParameterType)1273 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterType) {
1274   auto t = makeDecls<ObjCCategoryDecl>(
1275       "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1276       "@interface A @end @interface A(X) -(void)test:(float)x; @end", Lang_OBJC,
1277       objcCategoryDecl());
1278   EXPECT_FALSE(testStructuralMatch(t));
1279 }
1280 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentMethodParameterName)1281 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterName) {
1282   auto t = makeDecls<ObjCCategoryDecl>(
1283       "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1284       "@interface A @end @interface A(X) -(void)test:(int)y; @end", Lang_OBJC,
1285       objcCategoryDecl());
1286   EXPECT_TRUE(testStructuralMatch(t));
1287 }
1288 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentMethodNumber)1289 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodNumber) {
1290   auto t = makeDecls<ObjCCategoryDecl>(
1291       "@interface A @end @interface A(X) -(void)test; @end",
1292       "@interface A @end @interface A(X) @end", Lang_OBJC, objcCategoryDecl());
1293   EXPECT_FALSE(testStructuralMatch(t));
1294 }
1295 
TEST_F(StructuralEquivalenceObjCCategoryTest,DifferentMethodOrder)1296 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodOrder) {
1297   auto t = makeDecls<ObjCCategoryDecl>(
1298       "@interface A @end @interface A(X) -(void)u; -(void)v; @end",
1299       "@interface A @end @interface A(X) -(void)v; -(void)u; @end", Lang_OBJC,
1300       objcCategoryDecl());
1301   EXPECT_FALSE(testStructuralMatch(t));
1302 }
1303 
1304 struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
1305 
TEST_F(StructuralEquivalenceTemplateTest,ExactlySameTemplates)1306 TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
1307   auto t = makeNamedDecls("template <class T> struct foo;",
1308                           "template <class T> struct foo;", Lang_CXX03);
1309   EXPECT_TRUE(testStructuralMatch(t));
1310 }
1311 
TEST_F(StructuralEquivalenceTemplateTest,DifferentTemplateArgName)1312 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
1313   auto t = makeNamedDecls("template <class T> struct foo;",
1314                           "template <class U> struct foo;", Lang_CXX03);
1315   EXPECT_TRUE(testStructuralMatch(t));
1316 }
1317 
TEST_F(StructuralEquivalenceTemplateTest,DifferentTemplateArgKind)1318 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
1319   auto t = makeNamedDecls("template <class T> struct foo;",
1320                           "template <int T> struct foo;", Lang_CXX03);
1321   EXPECT_FALSE(testStructuralMatch(t));
1322 }
1323 
TEST_F(StructuralEquivalenceTemplateTest,BitFieldDecl)1324 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDecl) {
1325   const char *Code = "class foo { int a : 2; };";
1326   auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1327   EXPECT_TRUE(testStructuralMatch(t));
1328 }
1329 
TEST_F(StructuralEquivalenceTemplateTest,BitFieldDeclDifferentWidth)1330 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDeclDifferentWidth) {
1331   auto t = makeNamedDecls("class foo { int a : 2; };",
1332                           "class foo { int a : 4; };", Lang_CXX03);
1333   EXPECT_FALSE(testStructuralMatch(t));
1334 }
1335 
TEST_F(StructuralEquivalenceTemplateTest,DependentBitFieldDecl)1336 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDecl) {
1337   const char *Code = "template <class T> class foo { int a : sizeof(T); };";
1338   auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1339   EXPECT_TRUE(testStructuralMatch(t));
1340 }
1341 
TEST_F(StructuralEquivalenceTemplateTest,DependentBitFieldDeclDifferentVal)1342 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal) {
1343   auto t = makeNamedDecls(
1344       "template <class A, class B> class foo { int a : sizeof(A); };",
1345       "template <class A, class B> class foo { int a : sizeof(B); };",
1346       Lang_CXX03);
1347   EXPECT_FALSE(testStructuralMatch(t));
1348 }
1349 
TEST_F(StructuralEquivalenceTemplateTest,DependentBitFieldDeclDifferentVal2)1350 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal2) {
1351   auto t = makeNamedDecls(
1352       "template <class A> class foo { int a : sizeof(A); };",
1353       "template <class A> class foo { int a : sizeof(A) + 1; };", Lang_CXX03);
1354   EXPECT_FALSE(testStructuralMatch(t));
1355 }
1356 
TEST_F(StructuralEquivalenceTemplateTest,ExplicitBoolSame)1357 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
1358   auto Decls = makeNamedDecls(
1359       "template <bool b> struct foo {explicit(b) foo(int);};",
1360       "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX20);
1361   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1362       get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1363   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1364       get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1365   EXPECT_TRUE(testStructuralMatch(First, Second));
1366 }
1367 
TEST_F(StructuralEquivalenceTemplateTest,ExplicitBoolDifference)1368 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
1369   auto Decls = makeNamedDecls(
1370       "template <bool b> struct foo {explicit(b) foo(int);};",
1371       "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX20);
1372   CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1373       get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1374   CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1375       get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1376   EXPECT_FALSE(testStructuralMatch(First, Second));
1377 }
1378 
TEST_F(StructuralEquivalenceTemplateTest,TemplateVsSubstTemplateTemplateParmInArgEq)1379 TEST_F(StructuralEquivalenceTemplateTest,
1380        TemplateVsSubstTemplateTemplateParmInArgEq) {
1381   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1382       R"(
1383 template <typename P1> class Arg { };
1384 template <template <typename PP1> class P1> class Primary { };
1385 
1386 void f() {
1387   // Make specialization with simple template.
1388   Primary <Arg> A;
1389 }
1390       )",
1391       R"(
1392 template <typename P1> class Arg { };
1393 template <template <typename PP1> class P1> class Primary { };
1394 
1395 template <template <typename PP1> class P1> class Templ {
1396   void f() {
1397     // Make specialization with substituted template template param.
1398     Primary <P1> A;
1399   };
1400 };
1401 
1402 // Instantiate with substitution Arg into P1.
1403 template class Templ <Arg>;
1404       )",
1405       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1406   EXPECT_TRUE(testStructuralMatch(t));
1407 }
1408 
TEST_F(StructuralEquivalenceTemplateTest,TemplateVsSubstTemplateTemplateParmInArgNotEq)1409 TEST_F(StructuralEquivalenceTemplateTest,
1410        TemplateVsSubstTemplateTemplateParmInArgNotEq) {
1411   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1412       R"(
1413 template <typename P1> class Arg { };
1414 template <template <typename PP1> class P1> class Primary { };
1415 
1416 void f() {
1417   // Make specialization with simple template.
1418   Primary <Arg> A;
1419 }
1420       )",
1421       R"(
1422 // Arg is different from the other, this should cause non-equivalence.
1423 template <typename P1> class Arg { int X; };
1424 template <template <typename PP1> class P1> class Primary { };
1425 
1426 template <template <typename PP1> class P1> class Templ {
1427   void f() {
1428     // Make specialization with substituted template template param.
1429     Primary <P1> A;
1430   };
1431 };
1432 
1433 // Instantiate with substitution Arg into P1.
1434 template class Templ <Arg>;
1435       )",
1436       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1437   EXPECT_FALSE(testStructuralMatch(t));
1438 }
1439 
1440 struct StructuralEquivalenceDependentTemplateArgsTest
1441     : StructuralEquivalenceTemplateTest {};
1442 
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,SameStructsInDependentArgs)1443 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1444        SameStructsInDependentArgs) {
1445   std::string Code =
1446       R"(
1447       template <typename>
1448       struct S1;
1449 
1450       template <typename>
1451       struct enable_if;
1452 
1453       struct S
1454       {
1455         template <typename T, typename enable_if<S1<T>>::type>
1456         void f();
1457       };
1458       )";
1459   auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1460                                            functionTemplateDecl(hasName("f")));
1461   EXPECT_TRUE(testStructuralMatch(t));
1462 }
1463 
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,DifferentStructsInDependentArgs)1464 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1465        DifferentStructsInDependentArgs) {
1466   std::string Code =
1467       R"(
1468       template <typename>
1469       struct S1;
1470 
1471       template <typename>
1472       struct S2;
1473 
1474       template <typename>
1475       struct enable_if;
1476       )";
1477   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1478       struct S
1479       {
1480         template <typename T, typename enable_if<S1<T>>::type>
1481         void f();
1482       };
1483       )",
1484                                            Code + R"(
1485       struct S
1486       {
1487         template <typename T, typename enable_if<S2<T>>::type>
1488         void f();
1489       };
1490       )",
1491                                            Lang_CXX11,
1492                                            functionTemplateDecl(hasName("f")));
1493   EXPECT_FALSE(testStructuralMatch(t));
1494 }
1495 
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,SameStructsInDependentScopeDeclRefExpr)1496 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1497        SameStructsInDependentScopeDeclRefExpr) {
1498   std::string Code =
1499       R"(
1500       template <typename>
1501       struct S1;
1502 
1503       template <bool>
1504       struct enable_if;
1505 
1506       struct S
1507       {
1508         template <typename T, typename enable_if<S1<T>::value>::type>
1509         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1510       };
1511       )";
1512   auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1513                                            functionTemplateDecl(hasName("f")));
1514   EXPECT_TRUE(testStructuralMatch(t));
1515 }
1516 
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,DifferentStructsInDependentScopeDeclRefExpr)1517 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1518        DifferentStructsInDependentScopeDeclRefExpr) {
1519   std::string Code =
1520       R"(
1521       template <typename>
1522       struct S1;
1523 
1524       template <typename>
1525       struct S2;
1526 
1527       template <bool>
1528       struct enable_if;
1529       )";
1530   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1531       struct S
1532       {
1533         template <typename T, typename enable_if<S1<T>::value>::type>
1534         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1535       };
1536       )",
1537                                            Code + R"(
1538       struct S
1539       {
1540         template <typename T, typename enable_if<S2<T>::value>::type>
1541         void f();
1542       };
1543       )",
1544                                            Lang_CXX03,
1545                                            functionTemplateDecl(hasName("f")));
1546   EXPECT_FALSE(testStructuralMatch(t));
1547 }
1548 
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,DifferentValueInDependentScopeDeclRefExpr)1549 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1550        DifferentValueInDependentScopeDeclRefExpr) {
1551   std::string Code =
1552       R"(
1553       template <typename>
1554       struct S1;
1555 
1556       template <bool>
1557       struct enable_if;
1558       )";
1559   auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1560       struct S
1561       {
1562         template <typename T, typename enable_if<S1<T>::value1>::type>
1563         void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1564       };
1565       )",
1566                                            Code + R"(
1567       struct S
1568       {
1569         template <typename T, typename enable_if<S1<T>::value2>::type>
1570         void f();
1571       };
1572       )",
1573                                            Lang_CXX03,
1574                                            functionTemplateDecl(hasName("f")));
1575   EXPECT_FALSE(testStructuralMatch(t));
1576 }
1577 
TEST_F(StructuralEquivalenceTemplateTest,ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual)1578 TEST_F(
1579     StructuralEquivalenceTemplateTest,
1580     ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) {
1581   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1582       R"(
1583       template <class T> struct Primary {};
1584       namespace N {
1585         struct Arg;
1586       }
1587       // Explicit instantiation with qualified name.
1588       template struct Primary<N::Arg>;
1589       )",
1590       R"(
1591       template <class T> struct Primary {};
1592       namespace N {
1593         struct Arg;
1594       }
1595       using namespace N;
1596       // Explicit instantiation with UNqualified name.
1597       template struct Primary<Arg>;
1598       )",
1599       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1600   EXPECT_TRUE(testStructuralMatch(t));
1601 }
1602 
TEST_F(StructuralEquivalenceTemplateTest,ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs)1603 TEST_F(
1604     StructuralEquivalenceTemplateTest,
1605     ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) {
1606   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1607       R"(
1608       template <class T> struct Primary {};
1609       namespace N {
1610         struct Arg { int a; };
1611       }
1612       // Explicit instantiation with qualified name.
1613       template struct Primary<N::Arg>;
1614       )",
1615       R"(
1616       template <class T> struct Primary {};
1617       namespace N {
1618         // This struct is not equivalent with the other in the prev TU.
1619         struct Arg { double b; }; // -- Field mismatch.
1620       }
1621       using namespace N;
1622       // Explicit instantiation with UNqualified name.
1623       template struct Primary<Arg>;
1624       )",
1625       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1626   EXPECT_FALSE(testStructuralMatch(t));
1627 }
1628 
TEST_F(StructuralEquivalenceTemplateTest,ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual)1629 TEST_F(
1630     StructuralEquivalenceTemplateTest,
1631     ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) {
1632   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1633       R"(
1634       template <template <class> class T> struct Primary {};
1635       namespace N {
1636         template <class T> struct Arg;
1637       }
1638       // Explicit instantiation with qualified name.
1639       template struct Primary<N::Arg>;
1640       )",
1641       R"(
1642       template <template <class> class T> struct Primary {};
1643       namespace N {
1644         template <class T> struct Arg;
1645       }
1646       using namespace N;
1647       // Explicit instantiation with UNqualified name.
1648       template struct Primary<Arg>;
1649       )",
1650       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1651   EXPECT_TRUE(testStructuralMatch(t));
1652 }
1653 
TEST_F(StructuralEquivalenceTemplateTest,ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs)1654 TEST_F(
1655     StructuralEquivalenceTemplateTest,
1656     ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) {
1657   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1658       R"(
1659       template <template <class> class T> struct Primary {};
1660       namespace N {
1661         template <class T> struct Arg { int a; };
1662       }
1663       // Explicit instantiation with qualified name.
1664       template struct Primary<N::Arg>;
1665       )",
1666       R"(
1667       template <template <class> class T> struct Primary {};
1668       namespace N {
1669         // This template is not equivalent with the other in the prev TU.
1670         template <class T> struct Arg { double b; }; // -- Field mismatch.
1671       }
1672       using namespace N;
1673       // Explicit instantiation with UNqualified name.
1674       template struct Primary<Arg>;
1675       )",
1676       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1677   EXPECT_FALSE(testStructuralMatch(t));
1678 }
1679 
TEST_F(StructuralEquivalenceTemplateTest,ClassTemplSpecWithInequivalentShadowedTemplArg)1680 TEST_F(
1681     StructuralEquivalenceTemplateTest,
1682     ClassTemplSpecWithInequivalentShadowedTemplArg) {
1683   auto t = makeDecls<ClassTemplateSpecializationDecl>(
1684       R"(
1685       template <template <class> class T> struct Primary {};
1686       template <class T> struct Arg { int a; };
1687       // Explicit instantiation with ::Arg
1688       template struct Primary<Arg>;
1689       )",
1690       R"(
1691       template <template <class> class T> struct Primary {};
1692       template <class T> struct Arg { int a; };
1693       namespace N {
1694         // This template is not equivalent with the other in the global scope.
1695         template <class T> struct Arg { double b; }; // -- Field mismatch.
1696         // Explicit instantiation with N::Arg which shadows ::Arg
1697         template struct Primary<Arg>;
1698       }
1699       )",
1700       Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1701   EXPECT_FALSE(testStructuralMatch(t));
1702 }
1703 struct StructuralEquivalenceCacheTest : public StructuralEquivalenceTest {
1704   llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls;
1705 
1706   template <typename NodeType, typename MatcherType>
1707   std::pair<NodeType *, NodeType *>
findDeclPairclang::ast_matchers::StructuralEquivalenceCacheTest1708   findDeclPair(std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> TU,
1709                MatcherType M) {
1710     NodeType *D0 = FirstDeclMatcher<NodeType>().match(get<0>(TU), M);
1711     NodeType *D1 = FirstDeclMatcher<NodeType>().match(get<1>(TU), M);
1712     return {D0, D1};
1713   }
1714 
1715   template <typename NodeType>
isInNonEqCacheclang::ast_matchers::StructuralEquivalenceCacheTest1716   bool isInNonEqCache(std::pair<NodeType *, NodeType *> D) {
1717     return NonEquivalentDecls.count(D) > 0;
1718   }
1719 };
1720 
TEST_F(StructuralEquivalenceCacheTest,SimpleNonEq)1721 TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) {
1722   auto TU = makeTuDecls(
1723       R"(
1724       class A {};
1725       class B {};
1726       void x(A, A);
1727       )",
1728       R"(
1729       class A {};
1730       class B {};
1731       void x(A, B);
1732       )",
1733       Lang_CXX03);
1734 
1735   StructuralEquivalenceContext Ctx(
1736       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1737       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1738 
1739   auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1740   EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
1741 
1742   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1743       TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1744   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1745       TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1746 }
1747 
TEST_F(StructuralEquivalenceCacheTest,SpecialNonEq)1748 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
1749   auto TU = makeTuDecls(
1750       R"(
1751       class A {};
1752       class B { int i; };
1753       void x(A *);
1754       void y(A *);
1755       class C {
1756         friend void x(A *);
1757         friend void y(A *);
1758       };
1759       )",
1760       R"(
1761       class A {};
1762       class B { int i; };
1763       void x(A *);
1764       void y(B *);
1765       class C {
1766         friend void x(A *);
1767         friend void y(B *);
1768       };
1769       )",
1770       Lang_CXX03);
1771 
1772   StructuralEquivalenceContext Ctx(
1773       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1774       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1775 
1776   auto C = findDeclPair<CXXRecordDecl>(
1777       TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1778   EXPECT_FALSE(Ctx.IsEquivalent(C.first, C.second));
1779 
1780   EXPECT_FALSE(isInNonEqCache(C));
1781   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1782       TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1783   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1784       TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1785   EXPECT_FALSE(isInNonEqCache(
1786       findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
1787   EXPECT_FALSE(isInNonEqCache(
1788       findDeclPair<FunctionDecl>(TU, functionDecl(hasName("y")))));
1789 }
1790 
TEST_F(StructuralEquivalenceCacheTest,Cycle)1791 TEST_F(StructuralEquivalenceCacheTest, Cycle) {
1792   auto TU = makeTuDecls(
1793       R"(
1794       class C;
1795       class A { C *c; };
1796       void x(A *);
1797       class C {
1798         friend void x(A *);
1799       };
1800       )",
1801       R"(
1802       class C;
1803       class A { C *c; };
1804       void x(A *);
1805       class C {
1806         friend void x(A *);
1807       };
1808       )",
1809       Lang_CXX03);
1810 
1811   StructuralEquivalenceContext Ctx(
1812       get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1813       NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1814 
1815   auto C = findDeclPair<CXXRecordDecl>(
1816       TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1817   EXPECT_TRUE(Ctx.IsEquivalent(C.first, C.second));
1818 
1819   EXPECT_FALSE(isInNonEqCache(C));
1820   EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1821       TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1822   EXPECT_FALSE(isInNonEqCache(
1823       findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
1824 }
1825 
1826 struct StructuralEquivalenceStmtTest : StructuralEquivalenceTest {};
1827 
1828 /// Fallback matcher to be used only when there is no specific matcher for a
1829 /// Expr subclass. Remove this once all Expr subclasses have their own matcher.
1830 static auto &fallbackExprMatcher = expr;
1831 
TEST_F(StructuralEquivalenceStmtTest,AddrLabelExpr)1832 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExpr) {
1833   auto t = makeWrappedStmts("lbl: &&lbl;", "lbl: &&lbl;", Lang_CXX03,
1834                             addrLabelExpr());
1835   EXPECT_TRUE(testStructuralMatch(t));
1836 }
1837 
TEST_F(StructuralEquivalenceStmtTest,AddrLabelExprDifferentLabel)1838 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExprDifferentLabel) {
1839   auto t = makeWrappedStmts("lbl1: lbl2: &&lbl1;", "lbl1: lbl2: &&lbl2;",
1840                             Lang_CXX03, addrLabelExpr());
1841   // FIXME: Should be false. LabelDecl are incorrectly matched.
1842   EXPECT_TRUE(testStructuralMatch(t));
1843 }
1844 
1845 static const std::string MemoryOrderSrc = R"(
1846 enum memory_order {
1847   memory_order_relaxed,
1848   memory_order_consume,
1849   memory_order_acquire,
1850   memory_order_release,
1851   memory_order_acq_rel,
1852   memory_order_seq_cst
1853 };
1854 )";
1855 
TEST_F(StructuralEquivalenceStmtTest,AtomicExpr)1856 TEST_F(StructuralEquivalenceStmtTest, AtomicExpr) {
1857   std::string Prefix = "char a, b; " + MemoryOrderSrc;
1858   auto t = makeStmts(
1859       Prefix +
1860           "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
1861       Prefix +
1862           "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
1863       Lang_CXX03, atomicExpr());
1864   EXPECT_TRUE(testStructuralMatch(t));
1865 }
1866 
TEST_F(StructuralEquivalenceStmtTest,AtomicExprDifferentOp)1867 TEST_F(StructuralEquivalenceStmtTest, AtomicExprDifferentOp) {
1868   std::string Prefix = "char a, b; " + MemoryOrderSrc;
1869   auto t = makeStmts(
1870       Prefix +
1871           "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
1872       Prefix +
1873           "void wrapped() { __atomic_store(&a, &b, memory_order_seq_cst); }",
1874       Lang_CXX03, atomicExpr());
1875   EXPECT_FALSE(testStructuralMatch(t));
1876 }
1877 
TEST_F(StructuralEquivalenceStmtTest,BinaryOperator)1878 TEST_F(StructuralEquivalenceStmtTest, BinaryOperator) {
1879   auto t = makeWrappedStmts("1 + 1", "1 + 1", Lang_CXX03, binaryOperator());
1880   EXPECT_TRUE(testStructuralMatch(t));
1881 }
1882 
TEST_F(StructuralEquivalenceStmtTest,BinaryOperatorDifferentOps)1883 TEST_F(StructuralEquivalenceStmtTest, BinaryOperatorDifferentOps) {
1884   auto t = makeWrappedStmts("1 + 1", "1 - 1", Lang_CXX03, binaryOperator());
1885   EXPECT_FALSE(testStructuralMatch(t));
1886 }
1887 
TEST_F(StructuralEquivalenceStmtTest,CallExpr)1888 TEST_F(StructuralEquivalenceStmtTest, CallExpr) {
1889   std::string Src = "int call(); int wrapped() { call(); }";
1890   auto t = makeStmts(Src, Src, Lang_CXX03, callExpr());
1891   EXPECT_TRUE(testStructuralMatch(t));
1892 }
1893 
TEST_F(StructuralEquivalenceStmtTest,CallExprDifferentCallee)1894 TEST_F(StructuralEquivalenceStmtTest, CallExprDifferentCallee) {
1895   std::string FunctionSrc = "int func1(); int func2();\n";
1896   auto t = makeStmts(FunctionSrc + "void wrapper() { func1(); }",
1897                      FunctionSrc + "void wrapper() { func2(); }", Lang_CXX03,
1898                      callExpr());
1899   EXPECT_FALSE(testStructuralMatch(t));
1900 }
1901 
TEST_F(StructuralEquivalenceStmtTest,CharacterLiteral)1902 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteral) {
1903   auto t = makeWrappedStmts("'a'", "'a'", Lang_CXX03, characterLiteral());
1904   EXPECT_TRUE(testStructuralMatch(t));
1905 }
1906 
TEST_F(StructuralEquivalenceStmtTest,CharacterLiteralDifferentValues)1907 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteralDifferentValues) {
1908   auto t = makeWrappedStmts("'a'", "'b'", Lang_CXX03, characterLiteral());
1909   EXPECT_FALSE(testStructuralMatch(t));
1910 }
1911 
TEST_F(StructuralEquivalenceStmtTest,ExpressionTraitExpr)1912 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExpr) {
1913   auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_lvalue_expr(1)",
1914                             Lang_CXX03, fallbackExprMatcher());
1915   EXPECT_TRUE(testStructuralMatch(t));
1916 }
1917 
TEST_F(StructuralEquivalenceStmtTest,ExpressionTraitExprDifferentKind)1918 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExprDifferentKind) {
1919   auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_rvalue_expr(1)",
1920                             Lang_CXX03, fallbackExprMatcher());
1921   EXPECT_FALSE(testStructuralMatch(t));
1922 }
1923 
TEST_F(StructuralEquivalenceStmtTest,FloatingLiteral)1924 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteral) {
1925   auto t = makeWrappedStmts("1.0", "1.0", Lang_CXX03, fallbackExprMatcher());
1926   EXPECT_TRUE(testStructuralMatch(t));
1927 }
1928 
TEST_F(StructuralEquivalenceStmtTest,FloatingLiteralDifferentSpelling)1929 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentSpelling) {
1930   auto t = makeWrappedStmts("0x10.1p0", "16.0625", Lang_CXX17,
1931                             fallbackExprMatcher());
1932   // Same value but with different spelling is equivalent.
1933   EXPECT_TRUE(testStructuralMatch(t));
1934 }
1935 
TEST_F(StructuralEquivalenceStmtTest,FloatingLiteralDifferentType)1936 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentType) {
1937   auto t = makeWrappedStmts("1.0", "1.0f", Lang_CXX03, fallbackExprMatcher());
1938   EXPECT_FALSE(testStructuralMatch(t));
1939 }
1940 
TEST_F(StructuralEquivalenceStmtTest,FloatingLiteralDifferentValue)1941 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentValue) {
1942   auto t = makeWrappedStmts("1.01", "1.0", Lang_CXX03, fallbackExprMatcher());
1943   EXPECT_FALSE(testStructuralMatch(t));
1944 }
1945 
TEST_F(StructuralEquivalenceStmtTest,GenericSelectionExprSame)1946 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSame) {
1947   auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
1948                             "_Generic(0u, unsigned int: 0, float: 1)", Lang_C99,
1949                             genericSelectionExpr());
1950   EXPECT_TRUE(testStructuralMatch(t));
1951 }
1952 
TEST_F(StructuralEquivalenceStmtTest,GenericSelectionExprSignsDiffer)1953 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSignsDiffer) {
1954   auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
1955                             "_Generic(0, int: 0, float: 1)", Lang_C99,
1956                             genericSelectionExpr());
1957   EXPECT_FALSE(testStructuralMatch(t));
1958 }
1959 
TEST_F(StructuralEquivalenceStmtTest,GenericSelectionExprOrderDiffers)1960 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprOrderDiffers) {
1961   auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
1962                             "_Generic(0u, float: 1, unsigned int: 0)", Lang_C99,
1963                             genericSelectionExpr());
1964   EXPECT_FALSE(testStructuralMatch(t));
1965 }
1966 
TEST_F(StructuralEquivalenceStmtTest,GenericSelectionExprDependentResultSame)1967 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) {
1968   auto t = makeStmts(
1969       R"(
1970       template <typename T>
1971       void f() {
1972         T x;
1973         (void)_Generic(x, int: 0, float: 1);
1974       }
1975       void g() { f<int>(); }
1976       )",
1977       R"(
1978       template <typename T>
1979       void f() {
1980         T x;
1981         (void)_Generic(x, int: 0, float: 1);
1982       }
1983       void g() { f<int>(); }
1984       )",
1985       Lang_CXX03, genericSelectionExpr());
1986   EXPECT_TRUE(testStructuralMatch(t));
1987 }
1988 
TEST_F(StructuralEquivalenceStmtTest,GenericSelectionExprDependentResultOrderDiffers)1989 TEST_F(StructuralEquivalenceStmtTest,
1990        GenericSelectionExprDependentResultOrderDiffers) {
1991   auto t = makeStmts(
1992       R"(
1993       template <typename T>
1994       void f() {
1995         T x;
1996         (void)_Generic(x, float: 1, int: 0);
1997       }
1998       void g() { f<int>(); }
1999       )",
2000       R"(
2001       template <typename T>
2002       void f() {
2003         T x;
2004         (void)_Generic(x, int: 0, float: 1);
2005       }
2006       void g() { f<int>(); }
2007       )",
2008       Lang_CXX03, genericSelectionExpr());
2009 
2010   EXPECT_FALSE(testStructuralMatch(t));
2011 }
TEST_F(StructuralEquivalenceStmtTest,IntegerLiteral)2012 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteral) {
2013   auto t = makeWrappedStmts("1", "1", Lang_CXX03, integerLiteral());
2014   EXPECT_TRUE(testStructuralMatch(t));
2015 }
2016 
TEST_F(StructuralEquivalenceStmtTest,IntegerLiteralDifferentSpelling)2017 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentSpelling) {
2018   auto t = makeWrappedStmts("1", "0x1", Lang_CXX03, integerLiteral());
2019   // Same value but with different spelling is equivalent.
2020   EXPECT_TRUE(testStructuralMatch(t));
2021 }
2022 
TEST_F(StructuralEquivalenceStmtTest,IntegerLiteralDifferentValue)2023 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentValue) {
2024   auto t = makeWrappedStmts("1", "2", Lang_CXX03, integerLiteral());
2025   EXPECT_FALSE(testStructuralMatch(t));
2026 }
2027 
TEST_F(StructuralEquivalenceStmtTest,IntegerLiteralDifferentTypes)2028 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentTypes) {
2029   auto t = makeWrappedStmts("1", "1L", Lang_CXX03, integerLiteral());
2030   EXPECT_FALSE(testStructuralMatch(t));
2031 }
2032 
TEST_F(StructuralEquivalenceStmtTest,MemberExpr)2033 TEST_F(StructuralEquivalenceStmtTest, MemberExpr) {
2034   std::string ClassSrc = "struct C { int a; int b; };";
2035   auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2036                      ClassSrc + "int wrapper() { C c; return c.a; }",
2037                      Lang_CXX03, memberExpr());
2038   EXPECT_TRUE(testStructuralMatch(t));
2039 }
2040 
TEST_F(StructuralEquivalenceStmtTest,MemberExprDifferentMember)2041 TEST_F(StructuralEquivalenceStmtTest, MemberExprDifferentMember) {
2042   std::string ClassSrc = "struct C { int a; int b; };";
2043   auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2044                      ClassSrc + "int wrapper() { C c; return c.b; }",
2045                      Lang_CXX03, memberExpr());
2046   EXPECT_FALSE(testStructuralMatch(t));
2047 }
2048 
TEST_F(StructuralEquivalenceStmtTest,ObjCStringLiteral)2049 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteral) {
2050   auto t =
2051       makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX, fallbackExprMatcher());
2052   EXPECT_TRUE(testStructuralMatch(t));
2053 }
2054 
TEST_F(StructuralEquivalenceStmtTest,ObjCStringLiteralDifferentContent)2055 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteralDifferentContent) {
2056   auto t =
2057       makeWrappedStmts("@\"a\"", "@\"b\"", Lang_OBJCXX, fallbackExprMatcher());
2058   EXPECT_FALSE(testStructuralMatch(t));
2059 }
2060 
TEST_F(StructuralEquivalenceStmtTest,StringLiteral)2061 TEST_F(StructuralEquivalenceStmtTest, StringLiteral) {
2062   auto t = makeWrappedStmts("\"a\"", "\"a\"", Lang_CXX03, stringLiteral());
2063   EXPECT_TRUE(testStructuralMatch(t));
2064 }
2065 
TEST_F(StructuralEquivalenceStmtTest,StringLiteralDifferentContent)2066 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentContent) {
2067   auto t = makeWrappedStmts("\"a\"", "\"b\"", Lang_CXX03, stringLiteral());
2068   EXPECT_FALSE(testStructuralMatch(t));
2069 }
2070 
TEST_F(StructuralEquivalenceStmtTest,StringLiteralDifferentLength)2071 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentLength) {
2072   auto t = makeWrappedStmts("\"a\"", "\"aa\"", Lang_CXX03, stringLiteral());
2073   EXPECT_FALSE(testStructuralMatch(t));
2074 }
2075 
TEST_F(StructuralEquivalenceStmtTest,TypeTraitExpr)2076 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExpr) {
2077   auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(int)", Lang_CXX03,
2078                             fallbackExprMatcher());
2079   EXPECT_TRUE(testStructuralMatch(t));
2080 }
2081 
TEST_F(StructuralEquivalenceStmtTest,TypeTraitExprDifferentType)2082 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentType) {
2083   auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(long)", Lang_CXX03,
2084                             fallbackExprMatcher());
2085   EXPECT_FALSE(testStructuralMatch(t));
2086 }
2087 
TEST_F(StructuralEquivalenceStmtTest,TypeTraitExprDifferentTrait)2088 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTrait) {
2089   auto t = makeWrappedStmts(
2090       "__is_pod(int)", "__is_trivially_constructible(int)", Lang_CXX03, expr());
2091   EXPECT_FALSE(testStructuralMatch(t));
2092 }
2093 
TEST_F(StructuralEquivalenceStmtTest,TypeTraitExprDifferentTraits)2094 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTraits) {
2095   auto t = makeWrappedStmts("__is_constructible(int)",
2096                             "__is_constructible(int, int)", Lang_CXX03, expr());
2097   EXPECT_FALSE(testStructuralMatch(t));
2098 }
2099 
TEST_F(StructuralEquivalenceStmtTest,UnaryExprOrTypeTraitExpr)2100 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExpr) {
2101   auto t = makeWrappedStmts("sizeof(int)", "sizeof(int)", Lang_CXX03,
2102                             unaryExprOrTypeTraitExpr());
2103   EXPECT_TRUE(testStructuralMatch(t));
2104 }
2105 
TEST_F(StructuralEquivalenceStmtTest,UnaryExprOrTypeTraitExprDifferentKind)2106 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentKind) {
2107   auto t = makeWrappedStmts("sizeof(int)", "alignof(long)", Lang_CXX11,
2108                             unaryExprOrTypeTraitExpr());
2109   EXPECT_FALSE(testStructuralMatch(t));
2110 }
2111 
TEST_F(StructuralEquivalenceStmtTest,UnaryExprOrTypeTraitExprDifferentType)2112 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentType) {
2113   auto t = makeWrappedStmts("sizeof(int)", "sizeof(long)", Lang_CXX03,
2114                             unaryExprOrTypeTraitExpr());
2115   EXPECT_FALSE(testStructuralMatch(t));
2116 }
2117 
TEST_F(StructuralEquivalenceStmtTest,UnaryOperator)2118 TEST_F(StructuralEquivalenceStmtTest, UnaryOperator) {
2119   auto t = makeWrappedStmts("+1", "+1", Lang_CXX03, unaryOperator());
2120   EXPECT_TRUE(testStructuralMatch(t));
2121 }
2122 
TEST_F(StructuralEquivalenceStmtTest,UnaryOperatorDifferentOps)2123 TEST_F(StructuralEquivalenceStmtTest, UnaryOperatorDifferentOps) {
2124   auto t = makeWrappedStmts("+1", "-1", Lang_CXX03, unaryOperator());
2125   EXPECT_FALSE(testStructuralMatch(t));
2126 }
2127 
2128 } // end namespace ast_matchers
2129 } // end namespace clang
2130