Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / AST / StructuralEquivalenceTest.cpp
blob44d950cfe758f1482e1ab5a102b60ec0d1a282c1
1 #include "clang/AST/ASTContext.h"
2 #include "clang/AST/ASTStructuralEquivalence.h"
3 #include "clang/AST/Decl.h"
4 #include "clang/AST/DeclTemplate.h"
5 #include "clang/ASTMatchers/ASTMatchers.h"
6 #include "clang/Frontend/ASTUnit.h"
7 #include "clang/Testing/CommandLineArgs.h"
8 #include "clang/Tooling/Tooling.h"
9 #include "llvm/TargetParser/Host.h"
11 #include "DeclMatcher.h"
13 #include "gtest/gtest.h"
15 namespace clang {
16 namespace ast_matchers {
18 using std::get;
20 struct StructuralEquivalenceTest : ::testing::Test {
21 std::unique_ptr<ASTUnit> AST0, AST1;
22 std::string Code0, Code1; // Buffers for SourceManager
24 // Parses the source code in the specified language and sets the ASTs of
25 // the current test instance to the parse result.
26 void makeASTUnits(const std::string &SrcCode0, const std::string &SrcCode1,
27 TestLanguage Lang) {
28 this->Code0 = SrcCode0;
29 this->Code1 = SrcCode1;
30 std::vector<std::string> Args = getCommandLineArgsForTesting(Lang);
32 const char *const InputFileName = "input.cc";
34 AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName);
35 AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName);
38 // Get a pair of node pointers into the synthesized AST from the given code
39 // snippets. To determine the returned node, a separate matcher is specified
40 // for both snippets. The first matching node is returned.
41 template <typename NodeType, typename MatcherType>
42 std::tuple<NodeType *, NodeType *>
43 makeDecls(const std::string &SrcCode0, const std::string &SrcCode1,
44 TestLanguage Lang, const MatcherType &Matcher0,
45 const MatcherType &Matcher1) {
46 makeASTUnits(SrcCode0, SrcCode1, Lang);
48 NodeType *D0 = FirstDeclMatcher<NodeType>().match(
49 AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
50 NodeType *D1 = FirstDeclMatcher<NodeType>().match(
51 AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
53 return std::make_tuple(D0, D1);
56 std::tuple<TranslationUnitDecl *, TranslationUnitDecl *>
57 makeTuDecls(const std::string &SrcCode0, const std::string &SrcCode1,
58 TestLanguage Lang) {
59 makeASTUnits(SrcCode0, SrcCode1, Lang);
61 return std::make_tuple(AST0->getASTContext().getTranslationUnitDecl(),
62 AST1->getASTContext().getTranslationUnitDecl());
65 // Get a pair of node pointers into the synthesized AST from the given code
66 // snippets. The same matcher is used for both snippets.
67 template <typename NodeType, typename MatcherType>
68 std::tuple<NodeType *, NodeType *>
69 makeDecls(const std::string &SrcCode0, const std::string &SrcCode1,
70 TestLanguage Lang, const MatcherType &AMatcher) {
71 return makeDecls<NodeType, MatcherType>(
72 SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
75 // Get a pair of Decl pointers to the synthesized declarations from the given
76 // code snippets. We search for the first NamedDecl with given name in both
77 // snippets.
78 std::tuple<NamedDecl *, NamedDecl *>
79 makeNamedDecls(const std::string &SrcCode0, const std::string &SrcCode1,
80 TestLanguage Lang, const char *const Identifier = "foo") {
81 auto Matcher = namedDecl(hasName(Identifier));
82 return makeDecls<NamedDecl>(SrcCode0, SrcCode1, Lang, Matcher);
85 // Wraps a Stmt and the ASTContext that contains it.
86 struct StmtWithASTContext {
87 Stmt *S;
88 ASTContext *Context;
89 explicit StmtWithASTContext(Stmt &S, ASTContext &Context)
90 : S(&S), Context(&Context) {}
91 explicit StmtWithASTContext(FunctionDecl *FD)
92 : S(FD->getBody()), Context(&FD->getASTContext()) {}
95 // Get a pair of node pointers into the synthesized AST from the given code
96 // snippets. To determine the returned node, a separate matcher is specified
97 // for both snippets. The first matching node is returned.
98 template <typename MatcherType>
99 std::tuple<StmtWithASTContext, StmtWithASTContext>
100 makeStmts(const std::string &SrcCode0, const std::string &SrcCode1,
101 TestLanguage Lang, const MatcherType &Matcher0,
102 const MatcherType &Matcher1) {
103 makeASTUnits(SrcCode0, SrcCode1, Lang);
105 Stmt *S0 = FirstDeclMatcher<Stmt>().match(
106 AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
107 Stmt *S1 = FirstDeclMatcher<Stmt>().match(
108 AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
110 return std::make_tuple(StmtWithASTContext(*S0, AST0->getASTContext()),
111 StmtWithASTContext(*S1, AST1->getASTContext()));
114 // Get a pair of node pointers into the synthesized AST from the given code
115 // snippets. The same matcher is used for both snippets.
116 template <typename MatcherType>
117 std::tuple<StmtWithASTContext, StmtWithASTContext>
118 makeStmts(const std::string &SrcCode0, const std::string &SrcCode1,
119 TestLanguage Lang, const MatcherType &AMatcher) {
120 return makeStmts(SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
123 // Convenience function for makeStmts that wraps the code inside a function
124 // body.
125 template <typename MatcherType>
126 std::tuple<StmtWithASTContext, StmtWithASTContext>
127 makeWrappedStmts(const std::string &SrcCode0, const std::string &SrcCode1,
128 TestLanguage Lang, const MatcherType &AMatcher) {
129 auto Wrap = [](const std::string &Src) {
130 return "void wrapped() {" + Src + ";}";
132 return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
135 bool testStructuralMatch(Decl *D0, Decl *D1,
136 bool IgnoreTemplateParmDepth = false) {
137 llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
138 llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
139 StructuralEquivalenceContext Ctx01(
140 D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
141 StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
142 /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
143 IgnoreTemplateParmDepth);
144 StructuralEquivalenceContext Ctx10(
145 D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
146 StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
147 /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
148 IgnoreTemplateParmDepth);
149 bool Eq01 = Ctx01.IsEquivalent(D0, D1);
150 bool Eq10 = Ctx10.IsEquivalent(D1, D0);
151 EXPECT_EQ(Eq01, Eq10);
152 return Eq01;
155 bool testStructuralMatch(StmtWithASTContext S0, StmtWithASTContext S1) {
156 llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
157 llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
158 StructuralEquivalenceContext Ctx01(
159 *S0.Context, *S1.Context, NonEquivalentDecls01,
160 StructuralEquivalenceKind::Default, false, false);
161 StructuralEquivalenceContext Ctx10(
162 *S1.Context, *S0.Context, NonEquivalentDecls10,
163 StructuralEquivalenceKind::Default, false, false);
164 bool Eq01 = Ctx01.IsEquivalent(S0.S, S1.S);
165 bool Eq10 = Ctx10.IsEquivalent(S1.S, S0.S);
166 EXPECT_EQ(Eq01, Eq10);
167 return Eq01;
170 bool
171 testStructuralMatch(std::tuple<StmtWithASTContext, StmtWithASTContext> t) {
172 return testStructuralMatch(get<0>(t), get<1>(t));
175 bool testStructuralMatch(std::tuple<Decl *, Decl *> t,
176 bool IgnoreTemplateParmDepth = false) {
177 return testStructuralMatch(get<0>(t), get<1>(t), IgnoreTemplateParmDepth);
181 TEST_F(StructuralEquivalenceTest, Int) {
182 auto Decls = makeNamedDecls("int foo;", "int foo;", Lang_CXX03);
183 EXPECT_TRUE(testStructuralMatch(Decls));
186 TEST_F(StructuralEquivalenceTest, IntVsSignedInt) {
187 auto Decls = makeNamedDecls("int foo;", "signed int foo;", Lang_CXX03);
188 EXPECT_TRUE(testStructuralMatch(Decls));
191 TEST_F(StructuralEquivalenceTest, Char) {
192 auto Decls = makeNamedDecls("char foo;", "char foo;", Lang_CXX03);
193 EXPECT_TRUE(testStructuralMatch(Decls));
196 // This test is disabled for now.
197 // FIXME Whether this is equivalent is dependent on the target.
198 TEST_F(StructuralEquivalenceTest, DISABLED_CharVsSignedChar) {
199 auto Decls = makeNamedDecls("char foo;", "signed char foo;", Lang_CXX03);
200 EXPECT_FALSE(testStructuralMatch(Decls));
203 TEST_F(StructuralEquivalenceTest, ForwardRecordDecl) {
204 auto Decls = makeNamedDecls("struct foo;", "struct foo;", Lang_CXX03);
205 EXPECT_TRUE(testStructuralMatch(Decls));
208 TEST_F(StructuralEquivalenceTest, IntVsSignedIntInStruct) {
209 auto Decls = makeNamedDecls("struct foo { int x; };",
210 "struct foo { signed int x; };", Lang_CXX03);
211 EXPECT_TRUE(testStructuralMatch(Decls));
214 TEST_F(StructuralEquivalenceTest, CharVsSignedCharInStruct) {
215 auto Decls = makeNamedDecls("struct foo { char x; };",
216 "struct foo { signed char x; };", Lang_CXX03);
217 EXPECT_FALSE(testStructuralMatch(Decls));
220 TEST_F(StructuralEquivalenceTest, IntVsSignedIntTemplateSpec) {
221 auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
222 R"(template <class T> struct foo; template<> struct foo<int>{};)",
223 R"(template <class T> struct foo; template<> struct foo<signed int>{};)",
224 Lang_CXX03, classTemplateSpecializationDecl());
225 auto Spec0 = get<0>(Decls);
226 auto Spec1 = get<1>(Decls);
227 EXPECT_TRUE(testStructuralMatch(Spec0, Spec1));
230 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpec) {
231 auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
232 R"(template <class T> struct foo; template<> struct foo<char>{};)",
233 R"(template <class T> struct foo; template<> struct foo<signed char>{};)",
234 Lang_CXX03, classTemplateSpecializationDecl());
235 auto Spec0 = get<0>(Decls);
236 auto Spec1 = get<1>(Decls);
237 EXPECT_FALSE(testStructuralMatch(Spec0, Spec1));
240 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpecWithInheritance) {
241 auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
243 struct true_type{};
244 template <class T> struct foo;
245 template<> struct foo<char> : true_type {};
248 struct true_type{};
249 template <class T> struct foo;
250 template<> struct foo<signed char> : true_type {};
252 Lang_CXX03, classTemplateSpecializationDecl());
253 EXPECT_FALSE(testStructuralMatch(Decls));
256 // This test is disabled for now.
257 // FIXME Enable it, once the check is implemented.
258 TEST_F(StructuralEquivalenceTest, DISABLED_WrongOrderInNamespace) {
259 auto Code =
261 namespace NS {
262 template <class T> class Base {
263 int a;
265 class Derived : Base<Derived> {
268 void foo(NS::Derived &);
270 auto Decls = makeNamedDecls(Code, Code, Lang_CXX03);
272 NamespaceDecl *NS =
273 LastDeclMatcher<NamespaceDecl>().match(get<1>(Decls), namespaceDecl());
274 ClassTemplateDecl *TD = LastDeclMatcher<ClassTemplateDecl>().match(
275 get<1>(Decls), classTemplateDecl(hasName("Base")));
277 // Reorder the decls, move the TD to the last place in the DC.
278 NS->removeDecl(TD);
279 NS->addDeclInternal(TD);
281 EXPECT_FALSE(testStructuralMatch(Decls));
284 TEST_F(StructuralEquivalenceTest, WrongOrderOfFieldsInClass) {
285 auto Code = "class X { int a; int b; };";
286 auto Decls = makeNamedDecls(Code, Code, Lang_CXX03, "X");
288 CXXRecordDecl *RD = FirstDeclMatcher<CXXRecordDecl>().match(
289 get<1>(Decls), cxxRecordDecl(hasName("X")));
290 FieldDecl *FD =
291 FirstDeclMatcher<FieldDecl>().match(get<1>(Decls), fieldDecl(hasName("a")));
293 // Reorder the FieldDecls
294 RD->removeDecl(FD);
295 RD->addDeclInternal(FD);
297 EXPECT_FALSE(testStructuralMatch(Decls));
300 struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
303 TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
304 auto t = makeNamedDecls("void foo();", "template<class T> void foo();",
305 Lang_CXX03);
306 EXPECT_FALSE(testStructuralMatch(t));
309 TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
310 auto t = makeDecls<FunctionDecl>(
311 "struct X{}; bool operator<(X, X);", "struct X{}; bool operator==(X, X);",
312 Lang_CXX03, functionDecl(hasOverloadedOperatorName("<")),
313 functionDecl(hasOverloadedOperatorName("==")));
314 EXPECT_FALSE(testStructuralMatch(t));
317 TEST_F(StructuralEquivalenceFunctionTest, SameOperators) {
318 auto t = makeDecls<FunctionDecl>(
319 "struct X{}; bool operator<(X, X);", "struct X{}; bool operator<(X, X);",
320 Lang_CXX03, functionDecl(hasOverloadedOperatorName("<")),
321 functionDecl(hasOverloadedOperatorName("<")));
322 EXPECT_TRUE(testStructuralMatch(t));
325 TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) {
326 auto t = makeDecls<FunctionDecl>("struct X{ X(); };", "struct X{ ~X(); };",
327 Lang_CXX03, cxxConstructorDecl(),
328 cxxDestructorDecl());
329 EXPECT_FALSE(testStructuralMatch(t));
332 TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
333 auto t =
334 makeNamedDecls("void foo(int&);", "void foo(const int&);", Lang_CXX03);
335 EXPECT_FALSE(testStructuralMatch(t));
338 TEST_F(StructuralEquivalenceFunctionTest, ParamConstSimple) {
339 auto t = makeNamedDecls("void foo(int);", "void foo(const int);", Lang_CXX03);
340 EXPECT_TRUE(testStructuralMatch(t));
341 // consider this OK
344 TEST_F(StructuralEquivalenceFunctionTest, Throw) {
345 auto t = makeNamedDecls("void foo();", "void foo() throw();", Lang_CXX03);
346 EXPECT_FALSE(testStructuralMatch(t));
349 TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
350 auto t = makeNamedDecls("void foo();",
351 "void foo() noexcept;", Lang_CXX11);
352 EXPECT_FALSE(testStructuralMatch(t));
355 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexcept) {
356 auto t = makeNamedDecls("void foo() throw();",
357 "void foo() noexcept;", Lang_CXX11);
358 EXPECT_FALSE(testStructuralMatch(t));
361 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptFalse) {
362 auto t = makeNamedDecls("void foo() throw();",
363 "void foo() noexcept(false);", Lang_CXX11);
364 EXPECT_FALSE(testStructuralMatch(t));
367 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptTrue) {
368 auto t = makeNamedDecls("void foo() throw();",
369 "void foo() noexcept(true);", Lang_CXX11);
370 EXPECT_FALSE(testStructuralMatch(t));
373 TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
374 auto t = makeNamedDecls("void foo() noexcept(false);",
375 "void foo() noexcept(true);", Lang_CXX11);
376 EXPECT_FALSE(testStructuralMatch(t));
379 TEST_F(StructuralEquivalenceFunctionTest, NoexceptMatch) {
380 auto t = makeNamedDecls("void foo() noexcept(false);",
381 "void foo() noexcept(false);", Lang_CXX11);
382 EXPECT_TRUE(testStructuralMatch(t));
385 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptFalse) {
386 auto t = makeNamedDecls("void foo() noexcept;",
387 "void foo() noexcept(false);", Lang_CXX11);
388 EXPECT_FALSE(testStructuralMatch(t));
391 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptTrue) {
392 auto t = makeNamedDecls("void foo() noexcept;",
393 "void foo() noexcept(true);", Lang_CXX11);
394 EXPECT_FALSE(testStructuralMatch(t));
397 TEST_F(StructuralEquivalenceFunctionTest, ReturnType) {
398 auto t = makeNamedDecls("char foo();", "int foo();", Lang_CXX03);
399 EXPECT_FALSE(testStructuralMatch(t));
402 TEST_F(StructuralEquivalenceFunctionTest, ReturnConst) {
403 auto t = makeNamedDecls("char foo();", "const char foo();", Lang_CXX03);
404 EXPECT_FALSE(testStructuralMatch(t));
407 TEST_F(StructuralEquivalenceFunctionTest, ReturnRef) {
408 auto t = makeNamedDecls("char &foo();",
409 "char &&foo();", Lang_CXX11);
410 EXPECT_FALSE(testStructuralMatch(t));
413 TEST_F(StructuralEquivalenceFunctionTest, ParamCount) {
414 auto t = makeNamedDecls("void foo(int);", "void foo(int, int);", Lang_CXX03);
415 EXPECT_FALSE(testStructuralMatch(t));
418 TEST_F(StructuralEquivalenceFunctionTest, ParamType) {
419 auto t = makeNamedDecls("void foo(int);", "void foo(char);", Lang_CXX03);
420 EXPECT_FALSE(testStructuralMatch(t));
423 TEST_F(StructuralEquivalenceFunctionTest, ParamName) {
424 auto t = makeNamedDecls("void foo(int a);", "void foo(int b);", Lang_CXX03);
425 EXPECT_TRUE(testStructuralMatch(t));
428 TEST_F(StructuralEquivalenceFunctionTest, Variadic) {
429 auto t =
430 makeNamedDecls("void foo(int x...);", "void foo(int x);", Lang_CXX03);
431 EXPECT_FALSE(testStructuralMatch(t));
434 TEST_F(StructuralEquivalenceFunctionTest, ParamPtr) {
435 auto t = makeNamedDecls("void foo(int *);", "void foo(int);", Lang_CXX03);
436 EXPECT_FALSE(testStructuralMatch(t));
439 TEST_F(StructuralEquivalenceFunctionTest, NameInParen) {
440 auto t = makeNamedDecls("void ((foo))();", "void foo();", Lang_CXX03);
441 EXPECT_TRUE(testStructuralMatch(t));
444 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithExceptionSpec) {
445 auto t = makeNamedDecls(
446 "void (foo)() throw(int);",
447 "void (foo)() noexcept;",
448 Lang_CXX11);
449 EXPECT_FALSE(testStructuralMatch(t));
452 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) {
453 auto t = makeNamedDecls(
454 "struct A { void (foo)() const; };",
455 "struct A { void (foo)(); };",
456 Lang_CXX11);
457 EXPECT_FALSE(testStructuralMatch(t));
460 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
461 auto t = makeNamedDecls("__attribute__((noreturn)) void foo();",
462 " void foo();", Lang_C99);
463 EXPECT_TRUE(testStructuralMatch(t));
466 TEST_F(StructuralEquivalenceFunctionTest,
467 FunctionsWithDifferentCallingConventions) {
468 // These attributes may not be available on certain platforms.
469 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
470 llvm::Triple::x86_64)
471 GTEST_SKIP();
472 auto t = makeNamedDecls("__attribute__((preserve_all)) void foo();",
473 "__attribute__((ms_abi)) void foo();", Lang_C99);
474 EXPECT_FALSE(testStructuralMatch(t));
477 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) {
478 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
479 llvm::Triple::x86_64)
480 GTEST_SKIP();
481 auto t = makeNamedDecls(
482 "__attribute__((no_caller_saved_registers)) void foo();",
483 " void foo();", Lang_C99);
484 EXPECT_FALSE(testStructuralMatch(t));
487 struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
490 TEST_F(StructuralEquivalenceCXXMethodTest, Virtual) {
491 auto t = makeDecls<CXXMethodDecl>("struct X { void foo(); };",
492 "struct X { virtual void foo(); };",
493 Lang_CXX03, cxxMethodDecl(hasName("foo")));
494 EXPECT_FALSE(testStructuralMatch(t));
497 TEST_F(StructuralEquivalenceCXXMethodTest, Pure) {
498 auto t = makeNamedDecls("struct X { virtual void foo(); };",
499 "struct X { virtual void foo() = 0; };", Lang_CXX03);
500 EXPECT_FALSE(testStructuralMatch(t));
503 TEST_F(StructuralEquivalenceCXXMethodTest, DISABLED_Final) {
504 // The final-ness is not checked yet.
505 auto t =
506 makeNamedDecls("struct X { virtual void foo(); };",
507 "struct X { virtual void foo() final; };", Lang_CXX03);
508 EXPECT_FALSE(testStructuralMatch(t));
511 TEST_F(StructuralEquivalenceCXXMethodTest, Const) {
512 auto t = makeNamedDecls("struct X { void foo(); };",
513 "struct X { void foo() const; };", Lang_CXX03);
514 EXPECT_FALSE(testStructuralMatch(t));
517 TEST_F(StructuralEquivalenceCXXMethodTest, Static) {
518 auto t = makeNamedDecls("struct X { void foo(); };",
519 "struct X { static void foo(); };", Lang_CXX03);
520 EXPECT_FALSE(testStructuralMatch(t));
523 TEST_F(StructuralEquivalenceCXXMethodTest, Ref1) {
524 auto t = makeNamedDecls("struct X { void foo(); };",
525 "struct X { void foo() &&; };", Lang_CXX11);
526 EXPECT_FALSE(testStructuralMatch(t));
529 TEST_F(StructuralEquivalenceCXXMethodTest, Ref2) {
530 auto t = makeNamedDecls("struct X { void foo() &; };",
531 "struct X { void foo() &&; };", Lang_CXX11);
532 EXPECT_FALSE(testStructuralMatch(t));
535 TEST_F(StructuralEquivalenceCXXMethodTest, AccessSpecifier) {
536 auto t = makeDecls<CXXMethodDecl>("struct X { public: void foo(); };",
537 "struct X { private: void foo(); };",
538 Lang_CXX03, cxxMethodDecl(hasName("foo")));
539 EXPECT_FALSE(testStructuralMatch(t));
542 TEST_F(StructuralEquivalenceCXXMethodTest, Delete) {
543 auto t = makeNamedDecls("struct X { void foo(); };",
544 "struct X { void foo() = delete; };", Lang_CXX11);
545 EXPECT_FALSE(testStructuralMatch(t));
548 TEST_F(StructuralEquivalenceCXXMethodTest, Constructor) {
549 auto t = makeDecls<FunctionDecl>("void foo();", "struct foo { foo(); };",
550 Lang_CXX03, functionDecl(hasName("foo")),
551 cxxConstructorDecl(hasName("foo")));
552 EXPECT_FALSE(testStructuralMatch(t));
555 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorParam) {
556 auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
557 "struct X { X(int); };", Lang_CXX03,
558 cxxConstructorDecl(hasName("X")));
559 EXPECT_FALSE(testStructuralMatch(t));
562 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorExplicit) {
563 auto t = makeDecls<CXXConstructorDecl>("struct X { X(int); };",
564 "struct X { explicit X(int); };",
565 Lang_CXX11,
566 cxxConstructorDecl(hasName("X")));
567 EXPECT_FALSE(testStructuralMatch(t));
570 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorDefault) {
571 auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
572 "struct X { X() = default; };",
573 Lang_CXX11,
574 cxxConstructorDecl(hasName("X")));
575 EXPECT_FALSE(testStructuralMatch(t));
578 TEST_F(StructuralEquivalenceCXXMethodTest, Conversion) {
579 auto t = makeDecls<CXXConversionDecl>("struct X { operator bool(); };",
580 "struct X { operator char(); };",
581 Lang_CXX11,
582 cxxConversionDecl());
583 EXPECT_FALSE(testStructuralMatch(t));
586 TEST_F(StructuralEquivalenceCXXMethodTest, Operator) {
587 auto t =
588 makeDecls<FunctionDecl>("struct X { int operator +(int); };",
589 "struct X { int operator -(int); };", Lang_CXX03,
590 functionDecl(hasOverloadedOperatorName("+")),
591 functionDecl(hasOverloadedOperatorName("-")));
592 EXPECT_FALSE(testStructuralMatch(t));
595 TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass1) {
596 auto t = makeDecls<FunctionDecl>(
597 "struct X { virtual void f(); }; void X::f() { }",
598 "struct X { virtual void f() { }; };", Lang_CXX03,
599 functionDecl(allOf(hasName("f"), isDefinition())));
600 EXPECT_TRUE(testStructuralMatch(t));
603 TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass2) {
604 auto t = makeDecls<FunctionDecl>(
605 "struct X { virtual void f(); }; void X::f() { }",
606 "struct X { void f(); }; void X::f() { }", Lang_CXX03,
607 functionDecl(allOf(hasName("f"), isDefinition())));
608 EXPECT_FALSE(testStructuralMatch(t));
611 struct StructuralEquivalenceRecordTest : StructuralEquivalenceTest {
612 // FIXME Use a common getRecordDecl with ASTImporterTest.cpp!
613 RecordDecl *getRecordDecl(FieldDecl *FD) {
614 auto *ET = cast<ElaboratedType>(FD->getType().getTypePtr());
615 return cast<RecordType>(ET->getNamedType().getTypePtr())->getDecl();
619 TEST_F(StructuralEquivalenceRecordTest, Name) {
620 auto t = makeDecls<CXXRecordDecl>("struct A{ };", "struct B{ };", Lang_CXX03,
621 cxxRecordDecl(hasName("A")),
622 cxxRecordDecl(hasName("B")));
623 EXPECT_FALSE(testStructuralMatch(t));
626 TEST_F(StructuralEquivalenceRecordTest, Fields) {
627 auto t = makeNamedDecls("struct foo{ int x; };", "struct foo{ char x; };",
628 Lang_CXX03);
629 EXPECT_FALSE(testStructuralMatch(t));
632 TEST_F(StructuralEquivalenceRecordTest, DISABLED_Methods) {
633 // Currently, methods of a class are not checked at class equivalence.
634 auto t = makeNamedDecls("struct foo{ int x(); };", "struct foo{ char x(); };",
635 Lang_CXX03);
636 EXPECT_FALSE(testStructuralMatch(t));
639 TEST_F(StructuralEquivalenceRecordTest, Bases) {
640 auto t = makeNamedDecls("struct A{ }; struct foo: A { };",
641 "struct B{ }; struct foo: B { };", Lang_CXX03);
642 EXPECT_FALSE(testStructuralMatch(t));
645 TEST_F(StructuralEquivalenceRecordTest, InheritanceVirtual) {
646 auto t =
647 makeNamedDecls("struct A{ }; struct foo: A { };",
648 "struct A{ }; struct foo: virtual A { };", Lang_CXX03);
649 EXPECT_FALSE(testStructuralMatch(t));
652 TEST_F(StructuralEquivalenceRecordTest, DISABLED_InheritanceType) {
653 // Access specifier in inheritance is not checked yet.
654 auto t =
655 makeNamedDecls("struct A{ }; struct foo: public A { };",
656 "struct A{ }; struct foo: private A { };", Lang_CXX03);
657 EXPECT_FALSE(testStructuralMatch(t));
660 TEST_F(StructuralEquivalenceRecordTest, Match) {
661 auto Code = R"(
662 struct A{ };
663 struct B{ };
664 struct foo: A, virtual B {
665 void x();
666 int a;
669 auto t = makeNamedDecls(Code, Code, Lang_CXX03);
670 EXPECT_TRUE(testStructuralMatch(t));
673 TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) {
674 auto t = makeTuDecls(
676 struct A {
677 struct {
678 struct A *next;
679 } entry0;
680 struct {
681 struct A *next;
682 } entry1;
685 "", Lang_C99);
686 auto *TU = get<0>(t);
687 auto *Entry0 =
688 FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry0")));
689 auto *Entry1 =
690 FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry1")));
691 auto *R0 = getRecordDecl(Entry0);
692 auto *R1 = getRecordDecl(Entry1);
694 ASSERT_NE(R0, R1);
695 EXPECT_TRUE(testStructuralMatch(R0, R0));
696 EXPECT_TRUE(testStructuralMatch(R1, R1));
697 EXPECT_FALSE(testStructuralMatch(R0, R1));
700 TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
701 auto t = makeTuDecls(
703 struct X {
704 struct {
705 int a;
707 struct {
708 int b;
712 "", Lang_C99);
713 auto *TU = get<0>(t);
714 auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
715 TU, indirectFieldDecl(hasName("a")));
716 auto *FA = cast<FieldDecl>(A->chain().front());
717 RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
718 auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
719 TU, indirectFieldDecl(hasName("b")));
720 auto *FB = cast<FieldDecl>(B->chain().front());
721 RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
723 ASSERT_NE(RA, RB);
724 EXPECT_TRUE(testStructuralMatch(RA, RA));
725 EXPECT_TRUE(testStructuralMatch(RB, RB));
726 EXPECT_FALSE(testStructuralMatch(RA, RB));
729 TEST_F(StructuralEquivalenceRecordTest,
730 RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) {
731 auto t = makeTuDecls(
733 struct X {
734 struct { int a; };
735 struct { int b; };
739 struct X { // The order is reversed.
740 struct { int b; };
741 struct { int a; };
744 Lang_C99);
746 auto *TU = get<0>(t);
747 auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
748 TU, indirectFieldDecl(hasName("a")));
749 auto *FA = cast<FieldDecl>(A->chain().front());
750 RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
752 auto *TU1 = get<1>(t);
753 auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
754 TU1, indirectFieldDecl(hasName("a")));
755 auto *FA1 = cast<FieldDecl>(A1->chain().front());
756 RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
758 RecordDecl *X =
759 FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
760 RecordDecl *X1 =
761 FirstDeclMatcher<RecordDecl>().match(TU1, recordDecl(hasName("X")));
762 ASSERT_NE(X, X1);
763 EXPECT_FALSE(testStructuralMatch(X, X1));
765 ASSERT_NE(RA, RA1);
766 EXPECT_TRUE(testStructuralMatch(RA, RA));
767 EXPECT_TRUE(testStructuralMatch(RA1, RA1));
768 EXPECT_FALSE(testStructuralMatch(RA1, RA));
771 TEST_F(StructuralEquivalenceRecordTest,
772 UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) {
773 auto Code =
775 struct A {
776 struct {
777 struct A *next;
778 } entry0;
779 struct {
780 struct A *next;
781 } entry1;
784 auto t = makeTuDecls(Code, Code, Lang_C99);
786 auto *FromTU = get<0>(t);
787 auto *Entry1 =
788 FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("entry1")));
790 auto *ToTU = get<1>(t);
791 auto *Entry0 =
792 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
793 auto *A =
794 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
795 A->startDefinition(); // Set isBeingDefined, getDefinition() will return a
796 // nullptr. This may be the case during ASTImport.
798 auto *R0 = getRecordDecl(Entry0);
799 auto *R1 = getRecordDecl(Entry1);
801 ASSERT_NE(R0, R1);
802 EXPECT_TRUE(testStructuralMatch(R0, R0));
803 EXPECT_TRUE(testStructuralMatch(R1, R1));
804 EXPECT_FALSE(testStructuralMatch(R0, R1));
807 TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
808 auto t = makeDecls<CXXRecordDecl>("struct A { };",
809 "template<class T> struct A { };",
810 Lang_CXX03, cxxRecordDecl(hasName("A")));
811 EXPECT_FALSE(testStructuralMatch(t));
814 TEST_F(StructuralEquivalenceRecordTest,
815 FwdDeclRecordShouldBeEqualWithFwdDeclRecord) {
816 auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11);
817 EXPECT_TRUE(testStructuralMatch(t));
820 TEST_F(StructuralEquivalenceRecordTest,
821 FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) {
822 auto t =
823 makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11);
824 EXPECT_TRUE(testStructuralMatch(t));
827 TEST_F(StructuralEquivalenceRecordTest,
828 RecordShouldBeEqualWithRecordWhichHasDefinition) {
829 auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };",
830 Lang_CXX11);
831 EXPECT_TRUE(testStructuralMatch(t));
834 TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) {
835 auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };",
836 Lang_CXX11);
837 EXPECT_FALSE(testStructuralMatch(t));
840 TEST_F(StructuralEquivalenceRecordTest, SameFriendMultipleTimes) {
841 auto t = makeNamedDecls("struct foo { friend class X; };",
842 "struct foo { friend class X; friend class X; };",
843 Lang_CXX11);
844 EXPECT_FALSE(testStructuralMatch(t));
847 TEST_F(StructuralEquivalenceRecordTest, SameFriendsDifferentOrder) {
848 auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };",
849 "struct foo { friend class Y; friend class X; };",
850 Lang_CXX11);
851 EXPECT_FALSE(testStructuralMatch(t));
854 TEST_F(StructuralEquivalenceRecordTest, SameFriendsSameOrder) {
855 auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };",
856 "struct foo { friend class X; friend class Y; };",
857 Lang_CXX11);
858 EXPECT_TRUE(testStructuralMatch(t));
861 struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {};
863 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) {
864 // Get the LambdaExprs, unfortunately we can't match directly the underlying
865 // implicit CXXRecordDecl of the Lambda classes.
866 auto t = makeDecls<LambdaExpr>(
867 "void f() { auto L0 = [](int){}; }",
868 "void f() { auto L1 = [](){}; }",
869 Lang_CXX11,
870 lambdaExpr(),
871 lambdaExpr());
872 CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
873 CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
874 EXPECT_FALSE(testStructuralMatch(L0, L1));
877 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqMethods) {
878 auto t = makeDecls<LambdaExpr>(
879 "void f() { auto L0 = [](int){}; }",
880 "void f() { auto L1 = [](int){}; }",
881 Lang_CXX11,
882 lambdaExpr(),
883 lambdaExpr());
884 CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
885 CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
886 EXPECT_TRUE(testStructuralMatch(L0, L1));
889 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentFields) {
890 auto t = makeDecls<LambdaExpr>(
891 "void f() { char* X; auto L0 = [X](){}; }",
892 "void f() { float X; auto L1 = [X](){}; }",
893 Lang_CXX11,
894 lambdaExpr(),
895 lambdaExpr());
896 CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
897 CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
898 EXPECT_FALSE(testStructuralMatch(L0, L1));
901 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqFields) {
902 auto t = makeDecls<LambdaExpr>(
903 "void f() { float X; auto L0 = [X](){}; }",
904 "void f() { float X; auto L1 = [X](){}; }",
905 Lang_CXX11,
906 lambdaExpr(),
907 lambdaExpr());
908 CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
909 CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
910 EXPECT_TRUE(testStructuralMatch(L0, L1));
913 TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
914 auto t = makeNamedDecls("struct A{ }; struct B{ }; void foo(A a, A b);",
915 "struct A{ }; struct B{ }; void foo(A a, B b);",
916 Lang_CXX03);
917 EXPECT_FALSE(testStructuralMatch(t));
920 TEST_F(StructuralEquivalenceTest, ExplicitBoolDifferent) {
921 auto Decls = makeNamedDecls("struct foo {explicit(false) foo(int);};",
922 "struct foo {explicit(true) foo(int);};", Lang_CXX20);
923 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
924 get<0>(Decls), cxxConstructorDecl(hasName("foo")));
925 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
926 get<1>(Decls), cxxConstructorDecl(hasName("foo")));
927 EXPECT_FALSE(testStructuralMatch(First, Second));
930 TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
931 auto Decls = makeNamedDecls("struct foo {explicit(true) foo(int);};",
932 "struct foo {explicit(true) foo(int);};", Lang_CXX20);
933 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
934 get<0>(Decls), cxxConstructorDecl(hasName("foo")));
935 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
936 get<1>(Decls), cxxConstructorDecl(hasName("foo")));
937 EXPECT_TRUE(testStructuralMatch(First, Second));
940 struct StructuralEquivalenceRecordContextTest : StructuralEquivalenceTest {};
942 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsNamed) {
943 auto Decls =
944 makeNamedDecls("class X;", "namespace N { class X; }", Lang_CXX03, "X");
945 EXPECT_FALSE(testStructuralMatch(Decls));
948 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsNamed) {
949 auto Decls = makeNamedDecls("namespace A { class X; }",
950 "namespace B { class X; }", Lang_CXX03, "X");
951 EXPECT_FALSE(testStructuralMatch(Decls));
954 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsNamed) {
955 auto Decls = makeNamedDecls("namespace { class X; }",
956 "namespace N { class X; }", Lang_CXX03, "X");
957 EXPECT_FALSE(testStructuralMatch(Decls));
960 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsAnon) {
961 auto Decls =
962 makeNamedDecls("class X;", "namespace { class X; }", Lang_CXX03, "X");
963 EXPECT_FALSE(testStructuralMatch(Decls));
966 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnon) {
967 auto Decls = makeNamedDecls("namespace { class X; }",
968 "namespace { class X; }", Lang_CXX03, "X");
969 EXPECT_TRUE(testStructuralMatch(Decls));
972 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnonAnon) {
973 auto Decls =
974 makeNamedDecls("namespace { class X; }",
975 "namespace { namespace { class X; } }", Lang_CXX03, "X");
976 EXPECT_FALSE(testStructuralMatch(Decls));
979 TEST_F(StructuralEquivalenceRecordContextTest,
980 NamespaceNamedNamedVsNamedNamed) {
981 auto Decls = makeNamedDecls("namespace A { namespace N { class X; } }",
982 "namespace B { namespace N { class X; } }",
983 Lang_CXX03, "X");
984 EXPECT_FALSE(testStructuralMatch(Decls));
987 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsInline) {
988 auto Decls = makeNamedDecls("namespace A { namespace A { class X; } }",
989 "namespace A { inline namespace A { class X; } }",
990 Lang_CXX17, "X");
991 EXPECT_FALSE(testStructuralMatch(Decls));
994 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineVsInline) {
995 auto Decls = makeNamedDecls("namespace A { inline namespace A { class X; } }",
996 "namespace A { inline namespace B { class X; } }",
997 Lang_CXX17, "X");
998 EXPECT_TRUE(testStructuralMatch(Decls));
1001 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineTopLevel) {
1002 auto Decls =
1003 makeNamedDecls("inline namespace A { class X; }",
1004 "inline namespace B { class X; }", Lang_CXX17, "X");
1005 EXPECT_TRUE(testStructuralMatch(Decls));
1008 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContext) {
1009 auto Decls =
1010 makeNamedDecls("extern \"C\" { class X; }", "class X;", Lang_CXX03, "X");
1011 EXPECT_TRUE(testStructuralMatch(Decls));
1014 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextNE) {
1015 auto Decls = makeNamedDecls("extern \"C\" { class X; }",
1016 "namespace { class X; }", Lang_CXX03, "X");
1017 EXPECT_FALSE(testStructuralMatch(Decls));
1020 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextInNamespace) {
1021 auto Decls = makeNamedDecls("extern \"C\" { namespace N { class X; } }",
1022 "namespace N { extern \"C\" { class X; } }",
1023 Lang_CXX03, "X");
1024 EXPECT_TRUE(testStructuralMatch(Decls));
1027 TEST_F(StructuralEquivalenceTest, NamespaceOfRecordMember) {
1028 auto Decls = makeNamedDecls(
1030 class X;
1031 class Y { X* x; };
1034 namespace N { class X; }
1035 class Y { N::X* x; };
1037 Lang_CXX03, "Y");
1038 EXPECT_FALSE(testStructuralMatch(Decls));
1041 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototype) {
1042 auto Decls =
1043 makeNamedDecls("struct Param { int a; }; void foo(struct Param *p);",
1044 "void foo(struct Param { int a; } *p);", Lang_C89);
1045 EXPECT_TRUE(testStructuralMatch(Decls));
1048 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototypeDifferentName) {
1049 auto Decls =
1050 makeNamedDecls("struct Param1 { int a; }; void foo(struct Param1 *p);",
1051 "void foo(struct Param2 { int a; } *p);", Lang_C89);
1052 EXPECT_FALSE(testStructuralMatch(Decls));
1055 TEST_F(StructuralEquivalenceRecordContextTest, RecordInsideFunction) {
1056 auto Decls = makeNamedDecls("struct Param { int a; };",
1057 "void f() { struct Param { int a; }; }", Lang_C89,
1058 "Param");
1059 EXPECT_TRUE(testStructuralMatch(Decls));
1062 struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
1064 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
1065 auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
1066 EXPECT_TRUE(testStructuralMatch(t));
1069 TEST_F(StructuralEquivalenceEnumTest,
1070 FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
1071 auto t =
1072 makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
1073 EXPECT_TRUE(testStructuralMatch(t));
1076 TEST_F(StructuralEquivalenceEnumTest,
1077 EnumShouldBeEqualWithEnumWhichHasDefinition) {
1078 auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
1079 Lang_CXX11);
1080 EXPECT_TRUE(testStructuralMatch(t));
1083 TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
1084 auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
1085 Lang_CXX11);
1086 EXPECT_FALSE(testStructuralMatch(t));
1089 struct StructuralEquivalenceEnumConstantTest : StructuralEquivalenceTest {};
1091 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithSameValues) {
1092 auto t = makeNamedDecls("enum foo { foo = 1 };", "enum foo { foo = 1 };",
1093 Lang_C89);
1094 EXPECT_TRUE(testStructuralMatch(t));
1097 TEST_F(StructuralEquivalenceEnumConstantTest,
1098 EnumConstantsWithDifferentValues) {
1099 auto t =
1100 makeNamedDecls("enum e { foo = 1 };", "enum e { foo = 2 };", Lang_C89);
1101 EXPECT_FALSE(testStructuralMatch(t));
1104 TEST_F(StructuralEquivalenceEnumConstantTest,
1105 EnumConstantsWithDifferentExprsButSameValues) {
1106 auto t = makeNamedDecls("enum e { foo = 1 + 1 };", "enum e { foo = 2 };",
1107 Lang_CXX11);
1108 EXPECT_FALSE(testStructuralMatch(t));
1111 TEST_F(StructuralEquivalenceEnumConstantTest,
1112 EnumConstantsWithDifferentSignedness) {
1113 auto t = makeNamedDecls("enum e : unsigned { foo = 1 };",
1114 "enum e : int { foo = 1 };", Lang_CXX11);
1115 EXPECT_FALSE(testStructuralMatch(t));
1118 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentWidth) {
1119 auto t = makeNamedDecls("enum e : short { foo = 1 };",
1120 "enum e : int { foo = 1 };", Lang_CXX11);
1121 EXPECT_FALSE(testStructuralMatch(t));
1124 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentName) {
1125 auto t =
1126 makeDecls<EnumConstantDecl>("enum e { foo = 1 };", "enum e { bar = 1 };",
1127 Lang_CXX11, enumConstantDecl());
1128 EXPECT_FALSE(testStructuralMatch(t));
1131 struct StructuralEquivalenceObjCCategoryTest : StructuralEquivalenceTest {};
1133 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchinCategoryNames) {
1134 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1135 "@interface A @end @interface A(X) @end",
1136 Lang_OBJC, objcCategoryDecl());
1137 EXPECT_TRUE(testStructuralMatch(t));
1140 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesForDifferentClasses) {
1141 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1142 "@interface B @end @interface B(X) @end",
1143 Lang_OBJC, objcCategoryDecl());
1144 EXPECT_FALSE(testStructuralMatch(t));
1147 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithDifferentNames) {
1148 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1149 "@interface A @end @interface A(Y) @end",
1150 Lang_OBJC, objcCategoryDecl());
1151 EXPECT_FALSE(testStructuralMatch(t));
1154 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithoutInterfaces) {
1155 auto t = makeDecls<ObjCCategoryDecl>(" @interface A(X) @end",
1156 "@interface A @end @interface A(X) @end",
1157 Lang_OBJC, objcCategoryDecl());
1158 EXPECT_FALSE(testStructuralMatch(t));
1160 auto t2 = makeDecls<ObjCCategoryDecl>("@interface A(X) @end",
1161 "@interface A(X) @end",
1162 Lang_OBJC, objcCategoryDecl());
1163 EXPECT_TRUE(testStructuralMatch(t2));
1166 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoryAndExtension) {
1167 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1168 "@interface A @end @interface A() @end",
1169 Lang_OBJC, objcCategoryDecl());
1170 EXPECT_FALSE(testStructuralMatch(t));
1173 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingProtocols) {
1174 auto t = makeDecls<ObjCCategoryDecl>(
1175 "@protocol P @end @interface A @end @interface A(X)<P> @end",
1176 "@protocol P @end @interface A @end @interface A(X)<P> @end", Lang_OBJC,
1177 objcCategoryDecl());
1178 EXPECT_TRUE(testStructuralMatch(t));
1181 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocols) {
1182 auto t = makeDecls<ObjCCategoryDecl>(
1183 "@protocol P @end @interface A @end @interface A(X)<P> @end",
1184 "@protocol Q @end @interface A @end @interface A(X)<Q> @end", Lang_OBJC,
1185 objcCategoryDecl());
1186 EXPECT_FALSE(testStructuralMatch(t));
1189 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocolsOrder) {
1190 auto t = makeDecls<ObjCCategoryDecl>(
1191 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<P, "
1192 "Q> @end",
1193 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<Q, "
1194 "P> @end",
1195 Lang_OBJC, objcCategoryDecl());
1196 EXPECT_FALSE(testStructuralMatch(t));
1199 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingIvars) {
1200 auto t = makeDecls<ObjCCategoryDecl>(
1201 "@interface A @end @interface A() { int x; } @end",
1202 "@interface A @end @interface A() { int x; } @end", Lang_OBJC,
1203 objcCategoryDecl());
1204 EXPECT_TRUE(testStructuralMatch(t));
1207 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarName) {
1208 auto t = makeDecls<ObjCCategoryDecl>(
1209 "@interface A @end @interface A() { int x; } @end",
1210 "@interface A @end @interface A() { int y; } @end", Lang_OBJC,
1211 objcCategoryDecl());
1212 EXPECT_FALSE(testStructuralMatch(t));
1215 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarType) {
1216 auto t = makeDecls<ObjCCategoryDecl>(
1217 "@interface A @end @interface A() { int x; } @end",
1218 "@interface A @end @interface A() { float x; } @end", Lang_OBJC,
1219 objcCategoryDecl());
1220 EXPECT_FALSE(testStructuralMatch(t));
1223 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarBitfieldWidth) {
1224 auto t = makeDecls<ObjCCategoryDecl>(
1225 "@interface A @end @interface A() { int x: 1; } @end",
1226 "@interface A @end @interface A() { int x: 2; } @end", Lang_OBJC,
1227 objcCategoryDecl());
1228 EXPECT_FALSE(testStructuralMatch(t));
1231 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarVisibility) {
1232 auto t = makeDecls<ObjCCategoryDecl>(
1233 "@interface A @end @interface A() { @public int x; } @end",
1234 "@interface A @end @interface A() { @protected int x; } @end", Lang_OBJC,
1235 objcCategoryDecl());
1236 EXPECT_FALSE(testStructuralMatch(t));
1239 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarNumber) {
1240 auto t = makeDecls<ObjCCategoryDecl>(
1241 "@interface A @end @interface A() { int x; } @end",
1242 "@interface A @end @interface A() {} @end", Lang_OBJC,
1243 objcCategoryDecl());
1244 EXPECT_FALSE(testStructuralMatch(t));
1247 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarOrder) {
1248 auto t = makeDecls<ObjCCategoryDecl>(
1249 "@interface A @end @interface A() { int x; int y; } @end",
1250 "@interface A @end @interface A() { int y; int x; } @end", Lang_OBJC,
1251 objcCategoryDecl());
1252 EXPECT_FALSE(testStructuralMatch(t));
1255 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingMethods) {
1256 auto t = makeDecls<ObjCCategoryDecl>(
1257 "@interface A @end @interface A(X) -(void)test; @end",
1258 "@interface A @end @interface A(X) -(void)test; @end", Lang_OBJC,
1259 objcCategoryDecl());
1260 EXPECT_TRUE(testStructuralMatch(t));
1263 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodName) {
1264 auto t = makeDecls<ObjCCategoryDecl>(
1265 "@interface A @end @interface A(X) -(void)test; @end",
1266 "@interface A @end @interface A(X) -(void)wasd; @end", Lang_OBJC,
1267 objcCategoryDecl());
1268 EXPECT_FALSE(testStructuralMatch(t));
1270 auto t2 = makeDecls<ObjCCategoryDecl>(
1271 "@interface A @end @interface A(X) -(void)test:(int)x more:(int)y; @end",
1272 "@interface A @end @interface A(X) -(void)test:(int)x :(int)y; @end",
1273 Lang_OBJC, objcCategoryDecl());
1274 EXPECT_FALSE(testStructuralMatch(t2));
1277 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodClassInstance) {
1278 auto t = makeDecls<ObjCCategoryDecl>(
1279 "@interface A @end @interface A(X) -(void)test; @end",
1280 "@interface A @end @interface A(X) +(void)test; @end", Lang_OBJC,
1281 objcCategoryDecl());
1282 EXPECT_FALSE(testStructuralMatch(t));
1285 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodReturnType) {
1286 auto t = makeDecls<ObjCCategoryDecl>(
1287 "@interface A @end @interface A(X) -(void)test; @end",
1288 "@interface A @end @interface A(X) -(int)test; @end", Lang_OBJC,
1289 objcCategoryDecl());
1290 EXPECT_FALSE(testStructuralMatch(t));
1293 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterType) {
1294 auto t = makeDecls<ObjCCategoryDecl>(
1295 "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1296 "@interface A @end @interface A(X) -(void)test:(float)x; @end", Lang_OBJC,
1297 objcCategoryDecl());
1298 EXPECT_FALSE(testStructuralMatch(t));
1301 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterName) {
1302 auto t = makeDecls<ObjCCategoryDecl>(
1303 "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1304 "@interface A @end @interface A(X) -(void)test:(int)y; @end", Lang_OBJC,
1305 objcCategoryDecl());
1306 EXPECT_TRUE(testStructuralMatch(t));
1309 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodNumber) {
1310 auto t = makeDecls<ObjCCategoryDecl>(
1311 "@interface A @end @interface A(X) -(void)test; @end",
1312 "@interface A @end @interface A(X) @end", Lang_OBJC, objcCategoryDecl());
1313 EXPECT_FALSE(testStructuralMatch(t));
1316 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodOrder) {
1317 auto t = makeDecls<ObjCCategoryDecl>(
1318 "@interface A @end @interface A(X) -(void)u; -(void)v; @end",
1319 "@interface A @end @interface A(X) -(void)v; -(void)u; @end", Lang_OBJC,
1320 objcCategoryDecl());
1321 EXPECT_FALSE(testStructuralMatch(t));
1324 struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
1326 TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
1327 auto t = makeNamedDecls("template <class T> struct foo;",
1328 "template <class T> struct foo;", Lang_CXX03);
1329 EXPECT_TRUE(testStructuralMatch(t));
1332 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
1333 auto t = makeNamedDecls("template <class T> struct foo;",
1334 "template <class U> struct foo;", Lang_CXX03);
1335 EXPECT_TRUE(testStructuralMatch(t));
1338 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
1339 auto t = makeNamedDecls("template <class T> struct foo;",
1340 "template <int T> struct foo;", Lang_CXX03);
1341 EXPECT_FALSE(testStructuralMatch(t));
1344 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDecl) {
1345 const char *Code = "class foo { int a : 2; };";
1346 auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1347 EXPECT_TRUE(testStructuralMatch(t));
1350 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDeclDifferentWidth) {
1351 auto t = makeNamedDecls("class foo { int a : 2; };",
1352 "class foo { int a : 4; };", Lang_CXX03);
1353 EXPECT_FALSE(testStructuralMatch(t));
1356 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDecl) {
1357 const char *Code = "template <class T> class foo { int a : sizeof(T); };";
1358 auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1359 EXPECT_TRUE(testStructuralMatch(t));
1362 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal) {
1363 auto t = makeNamedDecls(
1364 "template <class A, class B> class foo { int a : sizeof(A); };",
1365 "template <class A, class B> class foo { int a : sizeof(B); };",
1366 Lang_CXX03);
1367 EXPECT_FALSE(testStructuralMatch(t));
1370 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal2) {
1371 auto t = makeNamedDecls(
1372 "template <class A> class foo { int a : sizeof(A); };",
1373 "template <class A> class foo { int a : sizeof(A) + 1; };", Lang_CXX03);
1374 EXPECT_FALSE(testStructuralMatch(t));
1377 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
1378 auto Decls = makeNamedDecls(
1379 "template <bool b> struct foo {explicit(b) foo(int);};",
1380 "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX20);
1381 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1382 get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1383 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1384 get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1385 EXPECT_TRUE(testStructuralMatch(First, Second));
1388 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
1389 auto Decls = makeNamedDecls(
1390 "template <bool b> struct foo {explicit(b) foo(int);};",
1391 "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX20);
1392 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1393 get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1394 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1395 get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1396 EXPECT_FALSE(testStructuralMatch(First, Second));
1399 TEST_F(StructuralEquivalenceTemplateTest,
1400 TemplateVsSubstTemplateTemplateParmInArgEq) {
1401 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1403 template <typename P1> class Arg { };
1404 template <template <typename PP1> class P1> class Primary { };
1406 void f() {
1407 // Make specialization with simple template.
1408 Primary <Arg> A;
1412 template <typename P1> class Arg { };
1413 template <template <typename PP1> class P1> class Primary { };
1415 template <template <typename PP1> class P1> class Templ {
1416 void f() {
1417 // Make specialization with substituted template template param.
1418 Primary <P1> A;
1422 // Instantiate with substitution Arg into P1.
1423 template class Templ <Arg>;
1425 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1426 EXPECT_TRUE(testStructuralMatch(t));
1429 TEST_F(StructuralEquivalenceTemplateTest,
1430 TemplateVsSubstTemplateTemplateParmInArgNotEq) {
1431 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1433 template <typename P1> class Arg { };
1434 template <template <typename PP1> class P1> class Primary { };
1436 void f() {
1437 // Make specialization with simple template.
1438 Primary <Arg> A;
1442 // Arg is different from the other, this should cause non-equivalence.
1443 template <typename P1> class Arg { int X; };
1444 template <template <typename PP1> class P1> class Primary { };
1446 template <template <typename PP1> class P1> class Templ {
1447 void f() {
1448 // Make specialization with substituted template template param.
1449 Primary <P1> A;
1453 // Instantiate with substitution Arg into P1.
1454 template class Templ <Arg>;
1456 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1457 EXPECT_FALSE(testStructuralMatch(t));
1460 struct StructuralEquivalenceDependentTemplateArgsTest
1461 : StructuralEquivalenceTemplateTest {};
1463 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1464 SameStructsInDependentArgs) {
1465 std::string Code =
1467 template <typename>
1468 struct S1;
1470 template <typename>
1471 struct enable_if;
1473 struct S
1475 template <typename T, typename enable_if<S1<T>>::type>
1476 void f();
1479 auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1480 functionTemplateDecl(hasName("f")));
1481 EXPECT_TRUE(testStructuralMatch(t));
1484 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1485 DifferentStructsInDependentArgs) {
1486 std::string Code =
1488 template <typename>
1489 struct S1;
1491 template <typename>
1492 struct S2;
1494 template <typename>
1495 struct enable_if;
1497 auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1498 struct S
1500 template <typename T, typename enable_if<S1<T>>::type>
1501 void f();
1504 Code + R"(
1505 struct S
1507 template <typename T, typename enable_if<S2<T>>::type>
1508 void f();
1511 Lang_CXX11,
1512 functionTemplateDecl(hasName("f")));
1513 EXPECT_FALSE(testStructuralMatch(t));
1516 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1517 SameStructsInDependentScopeDeclRefExpr) {
1518 std::string Code =
1520 template <typename>
1521 struct S1;
1523 template <bool>
1524 struct enable_if;
1526 struct S
1528 template <typename T, typename enable_if<S1<T>::value>::type>
1529 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1532 auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1533 functionTemplateDecl(hasName("f")));
1534 EXPECT_TRUE(testStructuralMatch(t));
1537 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1538 DifferentStructsInDependentScopeDeclRefExpr) {
1539 std::string Code =
1541 template <typename>
1542 struct S1;
1544 template <typename>
1545 struct S2;
1547 template <bool>
1548 struct enable_if;
1550 auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1551 struct S
1553 template <typename T, typename enable_if<S1<T>::value>::type>
1554 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1557 Code + R"(
1558 struct S
1560 template <typename T, typename enable_if<S2<T>::value>::type>
1561 void f();
1564 Lang_CXX03,
1565 functionTemplateDecl(hasName("f")));
1566 EXPECT_FALSE(testStructuralMatch(t));
1569 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1570 DifferentValueInDependentScopeDeclRefExpr) {
1571 std::string Code =
1573 template <typename>
1574 struct S1;
1576 template <bool>
1577 struct enable_if;
1579 auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1580 struct S
1582 template <typename T, typename enable_if<S1<T>::value1>::type>
1583 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1586 Code + R"(
1587 struct S
1589 template <typename T, typename enable_if<S1<T>::value2>::type>
1590 void f();
1593 Lang_CXX03,
1594 functionTemplateDecl(hasName("f")));
1595 EXPECT_FALSE(testStructuralMatch(t));
1598 TEST_F(
1599 StructuralEquivalenceTemplateTest,
1600 ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) {
1601 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1603 template <class T> struct Primary {};
1604 namespace N {
1605 struct Arg;
1607 // Explicit instantiation with qualified name.
1608 template struct Primary<N::Arg>;
1611 template <class T> struct Primary {};
1612 namespace N {
1613 struct Arg;
1615 using namespace N;
1616 // Explicit instantiation with UNqualified name.
1617 template struct Primary<Arg>;
1619 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1620 EXPECT_TRUE(testStructuralMatch(t));
1623 TEST_F(
1624 StructuralEquivalenceTemplateTest,
1625 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) {
1626 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1628 template <class T> struct Primary {};
1629 namespace N {
1630 struct Arg { int a; };
1632 // Explicit instantiation with qualified name.
1633 template struct Primary<N::Arg>;
1636 template <class T> struct Primary {};
1637 namespace N {
1638 // This struct is not equivalent with the other in the prev TU.
1639 struct Arg { double b; }; // -- Field mismatch.
1641 using namespace N;
1642 // Explicit instantiation with UNqualified name.
1643 template struct Primary<Arg>;
1645 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1646 EXPECT_FALSE(testStructuralMatch(t));
1649 TEST_F(
1650 StructuralEquivalenceTemplateTest,
1651 ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) {
1652 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1654 template <template <class> class T> struct Primary {};
1655 namespace N {
1656 template <class T> struct Arg;
1658 // Explicit instantiation with qualified name.
1659 template struct Primary<N::Arg>;
1662 template <template <class> class T> struct Primary {};
1663 namespace N {
1664 template <class T> struct Arg;
1666 using namespace N;
1667 // Explicit instantiation with UNqualified name.
1668 template struct Primary<Arg>;
1670 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1671 EXPECT_TRUE(testStructuralMatch(t));
1674 TEST_F(
1675 StructuralEquivalenceTemplateTest,
1676 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) {
1677 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1679 template <template <class> class T> struct Primary {};
1680 namespace N {
1681 template <class T> struct Arg { int a; };
1683 // Explicit instantiation with qualified name.
1684 template struct Primary<N::Arg>;
1687 template <template <class> class T> struct Primary {};
1688 namespace N {
1689 // This template is not equivalent with the other in the prev TU.
1690 template <class T> struct Arg { double b; }; // -- Field mismatch.
1692 using namespace N;
1693 // Explicit instantiation with UNqualified name.
1694 template struct Primary<Arg>;
1696 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1697 EXPECT_FALSE(testStructuralMatch(t));
1700 TEST_F(StructuralEquivalenceTemplateTest,
1701 IgnoreTemplateParmDepthAtTemplateTypeParmDecl) {
1702 auto Decls = makeDecls<ClassTemplateDecl>(
1704 template<class> struct A;
1707 template<class> struct S {
1708 template<class> friend struct A;
1711 Lang_CXX03, classTemplateDecl(hasName("A")),
1712 classTemplateDecl(hasName("A")));
1713 EXPECT_TRUE(testStructuralMatch(Decls));
1714 EXPECT_TRUE(testStructuralMatch(Decls, true));
1717 TEST_F(StructuralEquivalenceTemplateTest,
1718 IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) {
1719 auto Decls = makeDecls<ClassTemplateDecl>(
1721 template<class T, T U> struct A;
1724 template<class T> struct S {
1725 template<class P, P Q> friend struct A;
1728 Lang_CXX03, classTemplateDecl(hasName("A")),
1729 classTemplateDecl(hasName("A")));
1730 EXPECT_FALSE(testStructuralMatch(Decls));
1731 EXPECT_TRUE(testStructuralMatch(Decls, /*IgnoreTemplateParmDepth=*/true));
1734 TEST_F(
1735 StructuralEquivalenceTemplateTest,
1736 ClassTemplSpecWithInequivalentShadowedTemplArg) {
1737 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1739 template <template <class> class T> struct Primary {};
1740 template <class T> struct Arg { int a; };
1741 // Explicit instantiation with ::Arg
1742 template struct Primary<Arg>;
1745 template <template <class> class T> struct Primary {};
1746 template <class T> struct Arg { int a; };
1747 namespace N {
1748 // This template is not equivalent with the other in the global scope.
1749 template <class T> struct Arg { double b; }; // -- Field mismatch.
1750 // Explicit instantiation with N::Arg which shadows ::Arg
1751 template struct Primary<Arg>;
1754 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1755 EXPECT_FALSE(testStructuralMatch(t));
1757 struct StructuralEquivalenceCacheTest : public StructuralEquivalenceTest {
1758 llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls;
1760 template <typename NodeType, typename MatcherType>
1761 std::pair<NodeType *, NodeType *>
1762 findDeclPair(std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> TU,
1763 MatcherType M) {
1764 NodeType *D0 = FirstDeclMatcher<NodeType>().match(get<0>(TU), M);
1765 NodeType *D1 = FirstDeclMatcher<NodeType>().match(get<1>(TU), M);
1766 return {D0, D1};
1769 template <typename NodeType>
1770 bool isInNonEqCache(std::pair<NodeType *, NodeType *> D) {
1771 return NonEquivalentDecls.count(D) > 0;
1775 TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) {
1776 auto TU = makeTuDecls(
1778 class A {};
1779 class B {};
1780 void x(A, A);
1783 class A {};
1784 class B {};
1785 void x(A, B);
1787 Lang_CXX03);
1789 StructuralEquivalenceContext Ctx(
1790 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1791 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1793 auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1794 EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
1796 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1797 TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1798 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1799 TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1802 TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
1803 auto TU = makeTuDecls(
1805 bool x() { return true; }
1808 bool x() { return false; }
1810 Lang_CXX03);
1812 StructuralEquivalenceContext Ctx(
1813 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1814 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1816 auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1817 EXPECT_FALSE(Ctx.IsEquivalent(X.first->getBody(), X.second->getBody()));
1821 TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
1822 auto TU = makeTuDecls(
1824 int p;
1827 int q;
1829 Lang_CXX03);
1831 StructuralEquivalenceContext Ctx(
1832 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1833 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1835 auto Var = findDeclPair<VarDecl>(TU, varDecl());
1836 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1839 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
1840 auto TU = makeTuDecls(
1842 int p;
1845 static int p;
1847 Lang_CXX03);
1849 StructuralEquivalenceContext Ctx(
1850 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1851 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1853 auto Var = findDeclPair<VarDecl>(TU, varDecl());
1854 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1857 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
1858 auto TU = makeTuDecls(
1860 int p = 1;
1863 int p = 2;
1865 Lang_CXX03);
1867 StructuralEquivalenceContext Ctx(
1868 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1869 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1871 auto Var = findDeclPair<VarDecl>(TU, varDecl());
1872 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1875 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
1876 auto TU = makeTuDecls(
1878 class A {};
1879 class B { int i; };
1880 void x(A *);
1881 void y(A *);
1882 class C {
1883 friend void x(A *);
1884 friend void y(A *);
1888 class A {};
1889 class B { int i; };
1890 void x(A *);
1891 void y(B *);
1892 class C {
1893 friend void x(A *);
1894 friend void y(B *);
1897 Lang_CXX03);
1899 StructuralEquivalenceContext Ctx(
1900 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1901 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1903 auto C = findDeclPair<CXXRecordDecl>(
1904 TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1905 EXPECT_FALSE(Ctx.IsEquivalent(C.first, C.second));
1907 EXPECT_FALSE(isInNonEqCache(C));
1908 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1909 TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1910 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1911 TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1912 EXPECT_FALSE(isInNonEqCache(
1913 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
1914 EXPECT_FALSE(isInNonEqCache(
1915 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("y")))));
1918 TEST_F(StructuralEquivalenceCacheTest, Cycle) {
1919 auto TU = makeTuDecls(
1921 class C;
1922 class A { C *c; };
1923 void x(A *);
1924 class C {
1925 friend void x(A *);
1929 class C;
1930 class A { C *c; };
1931 void x(A *);
1932 class C {
1933 friend void x(A *);
1936 Lang_CXX03);
1938 StructuralEquivalenceContext Ctx(
1939 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1940 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1942 auto C = findDeclPair<CXXRecordDecl>(
1943 TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1944 EXPECT_TRUE(Ctx.IsEquivalent(C.first, C.second));
1946 EXPECT_FALSE(isInNonEqCache(C));
1947 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1948 TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1949 EXPECT_FALSE(isInNonEqCache(
1950 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
1953 struct StructuralEquivalenceStmtTest : StructuralEquivalenceTest {};
1955 /// Fallback matcher to be used only when there is no specific matcher for a
1956 /// Expr subclass. Remove this once all Expr subclasses have their own matcher.
1957 static auto &fallbackExprMatcher = expr;
1959 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExpr) {
1960 auto t = makeWrappedStmts("lbl: &&lbl;", "lbl: &&lbl;", Lang_CXX03,
1961 addrLabelExpr());
1962 EXPECT_TRUE(testStructuralMatch(t));
1965 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExprDifferentLabel) {
1966 auto t = makeWrappedStmts("lbl1: lbl2: &&lbl1;", "lbl1: lbl2: &&lbl2;",
1967 Lang_CXX03, addrLabelExpr());
1968 // FIXME: Should be false. LabelDecl are incorrectly matched.
1969 EXPECT_TRUE(testStructuralMatch(t));
1972 static const std::string MemoryOrderSrc = R"(
1973 enum memory_order {
1974 memory_order_relaxed,
1975 memory_order_consume,
1976 memory_order_acquire,
1977 memory_order_release,
1978 memory_order_acq_rel,
1979 memory_order_seq_cst
1983 TEST_F(StructuralEquivalenceStmtTest, AtomicExpr) {
1984 std::string Prefix = "char a, b; " + MemoryOrderSrc;
1985 auto t = makeStmts(
1986 Prefix +
1987 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
1988 Prefix +
1989 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
1990 Lang_CXX03, atomicExpr());
1991 EXPECT_TRUE(testStructuralMatch(t));
1994 TEST_F(StructuralEquivalenceStmtTest, AtomicExprDifferentOp) {
1995 std::string Prefix = "char a, b; " + MemoryOrderSrc;
1996 auto t = makeStmts(
1997 Prefix +
1998 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
1999 Prefix +
2000 "void wrapped() { __atomic_store(&a, &b, memory_order_seq_cst); }",
2001 Lang_CXX03, atomicExpr());
2002 EXPECT_FALSE(testStructuralMatch(t));
2005 TEST_F(StructuralEquivalenceStmtTest, BinaryOperator) {
2006 auto t = makeWrappedStmts("1 + 1", "1 + 1", Lang_CXX03, binaryOperator());
2007 EXPECT_TRUE(testStructuralMatch(t));
2010 TEST_F(StructuralEquivalenceStmtTest, BinaryOperatorDifferentOps) {
2011 auto t = makeWrappedStmts("1 + 1", "1 - 1", Lang_CXX03, binaryOperator());
2012 EXPECT_FALSE(testStructuralMatch(t));
2015 TEST_F(StructuralEquivalenceStmtTest, CallExpr) {
2016 std::string Src = "int call(); int wrapped() { call(); }";
2017 auto t = makeStmts(Src, Src, Lang_CXX03, callExpr());
2018 EXPECT_TRUE(testStructuralMatch(t));
2021 TEST_F(StructuralEquivalenceStmtTest, CallExprDifferentCallee) {
2022 std::string FunctionSrc = "int func1(); int func2();\n";
2023 auto t = makeStmts(FunctionSrc + "void wrapper() { func1(); }",
2024 FunctionSrc + "void wrapper() { func2(); }", Lang_CXX03,
2025 callExpr());
2026 EXPECT_FALSE(testStructuralMatch(t));
2029 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteral) {
2030 auto t = makeWrappedStmts("'a'", "'a'", Lang_CXX03, characterLiteral());
2031 EXPECT_TRUE(testStructuralMatch(t));
2034 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteralDifferentValues) {
2035 auto t = makeWrappedStmts("'a'", "'b'", Lang_CXX03, characterLiteral());
2036 EXPECT_FALSE(testStructuralMatch(t));
2039 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExpr) {
2040 auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_lvalue_expr(1)",
2041 Lang_CXX03, fallbackExprMatcher());
2042 EXPECT_TRUE(testStructuralMatch(t));
2045 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExprDifferentKind) {
2046 auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_rvalue_expr(1)",
2047 Lang_CXX03, fallbackExprMatcher());
2048 EXPECT_FALSE(testStructuralMatch(t));
2051 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteral) {
2052 auto t = makeWrappedStmts("1.0", "1.0", Lang_CXX03, fallbackExprMatcher());
2053 EXPECT_TRUE(testStructuralMatch(t));
2056 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentSpelling) {
2057 auto t = makeWrappedStmts("0x10.1p0", "16.0625", Lang_CXX17,
2058 fallbackExprMatcher());
2059 // Same value but with different spelling is equivalent.
2060 EXPECT_TRUE(testStructuralMatch(t));
2063 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentType) {
2064 auto t = makeWrappedStmts("1.0", "1.0f", Lang_CXX03, fallbackExprMatcher());
2065 EXPECT_FALSE(testStructuralMatch(t));
2068 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentValue) {
2069 auto t = makeWrappedStmts("1.01", "1.0", Lang_CXX03, fallbackExprMatcher());
2070 EXPECT_FALSE(testStructuralMatch(t));
2073 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSame) {
2074 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2075 "_Generic(0u, unsigned int: 0, float: 1)", Lang_C99,
2076 genericSelectionExpr());
2077 EXPECT_TRUE(testStructuralMatch(t));
2080 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSignsDiffer) {
2081 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2082 "_Generic(0, int: 0, float: 1)", Lang_C99,
2083 genericSelectionExpr());
2084 EXPECT_FALSE(testStructuralMatch(t));
2087 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprOrderDiffers) {
2088 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2089 "_Generic(0u, float: 1, unsigned int: 0)", Lang_C99,
2090 genericSelectionExpr());
2091 EXPECT_FALSE(testStructuralMatch(t));
2094 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) {
2095 auto t = makeStmts(
2097 template <typename T>
2098 void f() {
2099 T x;
2100 (void)_Generic(x, int: 0, float: 1);
2102 void g() { f<int>(); }
2105 template <typename T>
2106 void f() {
2107 T x;
2108 (void)_Generic(x, int: 0, float: 1);
2110 void g() { f<int>(); }
2112 Lang_CXX03, genericSelectionExpr());
2113 EXPECT_TRUE(testStructuralMatch(t));
2116 TEST_F(StructuralEquivalenceStmtTest,
2117 GenericSelectionExprDependentResultOrderDiffers) {
2118 auto t = makeStmts(
2120 template <typename T>
2121 void f() {
2122 T x;
2123 (void)_Generic(x, float: 1, int: 0);
2125 void g() { f<int>(); }
2128 template <typename T>
2129 void f() {
2130 T x;
2131 (void)_Generic(x, int: 0, float: 1);
2133 void g() { f<int>(); }
2135 Lang_CXX03, genericSelectionExpr());
2137 EXPECT_FALSE(testStructuralMatch(t));
2139 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteral) {
2140 auto t = makeWrappedStmts("1", "1", Lang_CXX03, integerLiteral());
2141 EXPECT_TRUE(testStructuralMatch(t));
2144 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentSpelling) {
2145 auto t = makeWrappedStmts("1", "0x1", Lang_CXX03, integerLiteral());
2146 // Same value but with different spelling is equivalent.
2147 EXPECT_TRUE(testStructuralMatch(t));
2150 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentValue) {
2151 auto t = makeWrappedStmts("1", "2", Lang_CXX03, integerLiteral());
2152 EXPECT_FALSE(testStructuralMatch(t));
2155 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentTypes) {
2156 auto t = makeWrappedStmts("1", "1L", Lang_CXX03, integerLiteral());
2157 EXPECT_FALSE(testStructuralMatch(t));
2160 TEST_F(StructuralEquivalenceStmtTest, MemberExpr) {
2161 std::string ClassSrc = "struct C { int a; int b; };";
2162 auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2163 ClassSrc + "int wrapper() { C c; return c.a; }",
2164 Lang_CXX03, memberExpr());
2165 EXPECT_TRUE(testStructuralMatch(t));
2168 TEST_F(StructuralEquivalenceStmtTest, MemberExprDifferentMember) {
2169 std::string ClassSrc = "struct C { int a; int b; };";
2170 auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2171 ClassSrc + "int wrapper() { C c; return c.b; }",
2172 Lang_CXX03, memberExpr());
2173 EXPECT_FALSE(testStructuralMatch(t));
2176 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteral) {
2177 auto t =
2178 makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX, fallbackExprMatcher());
2179 EXPECT_TRUE(testStructuralMatch(t));
2182 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteralDifferentContent) {
2183 auto t =
2184 makeWrappedStmts("@\"a\"", "@\"b\"", Lang_OBJCXX, fallbackExprMatcher());
2185 EXPECT_FALSE(testStructuralMatch(t));
2188 TEST_F(StructuralEquivalenceStmtTest, StringLiteral) {
2189 auto t = makeWrappedStmts("\"a\"", "\"a\"", Lang_CXX03, stringLiteral());
2190 EXPECT_TRUE(testStructuralMatch(t));
2193 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentContent) {
2194 auto t = makeWrappedStmts("\"a\"", "\"b\"", Lang_CXX03, stringLiteral());
2195 EXPECT_FALSE(testStructuralMatch(t));
2198 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentLength) {
2199 auto t = makeWrappedStmts("\"a\"", "\"aa\"", Lang_CXX03, stringLiteral());
2200 EXPECT_FALSE(testStructuralMatch(t));
2203 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExpr) {
2204 auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(int)", Lang_CXX03,
2205 fallbackExprMatcher());
2206 EXPECT_TRUE(testStructuralMatch(t));
2209 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentType) {
2210 auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(long)", Lang_CXX03,
2211 fallbackExprMatcher());
2212 EXPECT_FALSE(testStructuralMatch(t));
2215 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTrait) {
2216 auto t = makeWrappedStmts(
2217 "__is_pod(int)", "__is_trivially_constructible(int)", Lang_CXX03, expr());
2218 EXPECT_FALSE(testStructuralMatch(t));
2221 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTraits) {
2222 auto t = makeWrappedStmts("__is_constructible(int)",
2223 "__is_constructible(int, int)", Lang_CXX03, expr());
2224 EXPECT_FALSE(testStructuralMatch(t));
2227 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExpr) {
2228 auto t = makeWrappedStmts("sizeof(int)", "sizeof(int)", Lang_CXX03,
2229 unaryExprOrTypeTraitExpr());
2230 EXPECT_TRUE(testStructuralMatch(t));
2233 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentKind) {
2234 auto t = makeWrappedStmts("sizeof(int)", "alignof(long)", Lang_CXX11,
2235 unaryExprOrTypeTraitExpr());
2236 EXPECT_FALSE(testStructuralMatch(t));
2239 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentType) {
2240 auto t = makeWrappedStmts("sizeof(int)", "sizeof(long)", Lang_CXX03,
2241 unaryExprOrTypeTraitExpr());
2242 EXPECT_FALSE(testStructuralMatch(t));
2245 TEST_F(StructuralEquivalenceStmtTest, UnaryOperator) {
2246 auto t = makeWrappedStmts("+1", "+1", Lang_CXX03, unaryOperator());
2247 EXPECT_TRUE(testStructuralMatch(t));
2250 TEST_F(StructuralEquivalenceStmtTest, UnaryOperatorDifferentOps) {
2251 auto t = makeWrappedStmts("+1", "-1", Lang_CXX03, unaryOperator());
2252 EXPECT_FALSE(testStructuralMatch(t));
2255 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
2256 auto t = makeStmts(
2258 void f1(int);
2259 template <typename T>
2260 void f(T t) {
2261 f1(t);
2263 void g() { f<int>(1); }
2266 void f2(int);
2267 template <typename T>
2268 void f(T t) {
2269 f2(t);
2271 void g() { f<int>(1); }
2273 Lang_CXX03, unresolvedLookupExpr());
2274 EXPECT_FALSE(testStructuralMatch(t));
2277 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentQualifier) {
2278 auto t = makeStmts(
2280 struct X {
2281 static void g(int);
2282 static void g(char);
2285 template <typename T>
2286 void f(T t) {
2287 X::g(t);
2290 void g() { f<int>(1); }
2293 struct Y {
2294 static void g(int);
2295 static void g(char);
2298 template <typename T>
2299 void f(T t) {
2300 Y::g(t);
2303 void g() { f<int>(1); }
2305 Lang_CXX03, unresolvedLookupExpr());
2306 EXPECT_FALSE(testStructuralMatch(t));
2309 TEST_F(StructuralEquivalenceStmtTest,
2310 UnresolvedLookupDifferentTemplateArgument) {
2311 auto t = makeStmts(
2313 struct A {};
2314 template<typename T1, typename T2>
2315 void g() {}
2317 template <typename T>
2318 void f() {
2319 g<A, T>();
2322 void h() { f<int>(); }
2325 struct B {};
2326 template<typename T1, typename T2>
2327 void g() {}
2329 template <typename T>
2330 void f() {
2331 g<B, T>();
2334 void h() { f<int>(); }
2336 Lang_CXX03, unresolvedLookupExpr());
2337 EXPECT_FALSE(testStructuralMatch(t));
2340 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
2341 auto t = makeStmts(
2343 struct A {};
2344 struct B {
2345 template<typename T1, typename T2>
2346 static void g(int) {};
2347 template<typename T1, typename T2>
2348 static void g(char) {};
2351 template <typename T1, typename T2>
2352 void f(T2 x) {
2353 B::g<A, T1>(x);
2356 void g() { f<char, int>(1); }
2359 struct A {};
2360 struct B {
2361 template<typename T1, typename T2>
2362 static void g(int) {};
2363 template<typename T1, typename T2>
2364 static void g(char) {};
2367 template <typename T1, typename T2>
2368 void f(T2 x) {
2369 B::g<A, T1>(x);
2372 void g() { f<char, int>(1); }
2374 Lang_CXX03, unresolvedLookupExpr());
2375 EXPECT_TRUE(testStructuralMatch(t));
2378 TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
2379 auto S = makeStmts(
2381 void foo() {
2382 goto L1;
2383 L1: foo();
2387 void foo() {
2388 goto L2;
2389 L2: foo();
2392 Lang_CXX03, gotoStmt());
2393 EXPECT_FALSE(testStructuralMatch(S));
2396 TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
2397 std::string Prefix = "enum Test { AAA, BBB };";
2398 auto t = makeStmts(
2399 Prefix + "void foo(int i) {if (i > 0) {i = AAA;} else {i = BBB;}}",
2400 Prefix + "void foo(int i) {if (i > 0) {i = BBB;} else {i = AAA;}}",
2401 Lang_CXX03, ifStmt());
2402 EXPECT_FALSE(testStructuralMatch(t));
2405 } // end namespace ast_matchers
2406 } // end namespace clang