[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / clang / unittests / AST / StructuralEquivalenceTest.cpp
blob7cf52df9b14d05490ade9a517abed71746dec3e3
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 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls01;
138 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls10;
139 StructuralEquivalenceContext Ctx01(
140 D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
141 StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
142 /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
143 IgnoreTemplateParmDepth);
144 StructuralEquivalenceContext Ctx10(
145 D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
146 StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
147 /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
148 IgnoreTemplateParmDepth);
149 bool Eq01 = Ctx01.IsEquivalent(D0, D1);
150 bool Eq10 = Ctx10.IsEquivalent(D1, D0);
151 EXPECT_EQ(Eq01, Eq10);
152 return Eq01;
155 bool testStructuralMatch(StmtWithASTContext S0, StmtWithASTContext S1) {
156 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls01;
157 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls10;
158 StructuralEquivalenceContext Ctx01(
159 *S0.Context, *S1.Context, NonEquivalentDecls01,
160 StructuralEquivalenceKind::Default, false, false);
161 StructuralEquivalenceContext Ctx10(
162 *S1.Context, *S0.Context, NonEquivalentDecls10,
163 StructuralEquivalenceKind::Default, false, false);
164 bool Eq01 = Ctx01.IsEquivalent(S0.S, S1.S);
165 bool Eq10 = Ctx10.IsEquivalent(S1.S, S0.S);
166 EXPECT_EQ(Eq01, Eq10);
167 return Eq01;
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(StructuralEquivalenceRecordContextTest,
1028 ClassTemplateSpecializationContext) {
1029 std::string Code =
1031 template <typename T> struct O {
1032 struct M {};
1035 auto t = makeDecls<VarDecl>(Code + R"(
1036 typedef O<int>::M MT1;
1037 MT1 A;
1039 Code + R"(
1040 namespace {
1041 struct I {};
1042 } // namespace
1043 typedef O<I>::M MT2;
1044 MT2 A;
1046 Lang_CXX11, varDecl(hasName("A")));
1047 EXPECT_FALSE(testStructuralMatch(t));
1050 TEST_F(StructuralEquivalenceTest, NamespaceOfRecordMember) {
1051 auto Decls = makeNamedDecls(
1053 class X;
1054 class Y { X* x; };
1057 namespace N { class X; }
1058 class Y { N::X* x; };
1060 Lang_CXX03, "Y");
1061 EXPECT_FALSE(testStructuralMatch(Decls));
1064 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototype) {
1065 auto Decls =
1066 makeNamedDecls("struct Param { int a; }; void foo(struct Param *p);",
1067 "void foo(struct Param { int a; } *p);", Lang_C89);
1068 EXPECT_TRUE(testStructuralMatch(Decls));
1071 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototypeDifferentName) {
1072 auto Decls =
1073 makeNamedDecls("struct Param1 { int a; }; void foo(struct Param1 *p);",
1074 "void foo(struct Param2 { int a; } *p);", Lang_C89);
1075 EXPECT_FALSE(testStructuralMatch(Decls));
1078 TEST_F(StructuralEquivalenceRecordContextTest, RecordInsideFunction) {
1079 auto Decls = makeNamedDecls("struct Param { int a; };",
1080 "void f() { struct Param { int a; }; }", Lang_C89,
1081 "Param");
1082 EXPECT_TRUE(testStructuralMatch(Decls));
1085 struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
1087 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
1088 auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
1089 EXPECT_TRUE(testStructuralMatch(t));
1092 TEST_F(StructuralEquivalenceEnumTest,
1093 FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
1094 auto t =
1095 makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
1096 EXPECT_TRUE(testStructuralMatch(t));
1099 TEST_F(StructuralEquivalenceEnumTest,
1100 EnumShouldBeEqualWithEnumWhichHasDefinition) {
1101 auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
1102 Lang_CXX11);
1103 EXPECT_TRUE(testStructuralMatch(t));
1106 TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
1107 auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
1108 Lang_CXX11);
1109 EXPECT_FALSE(testStructuralMatch(t));
1112 TEST_F(StructuralEquivalenceEnumTest, AnonymousEnumsWithSameConsts) {
1113 // field x is required to trigger comparison of the anonymous enum
1114 auto t = makeNamedDecls("struct foo { enum { A } x; };",
1115 "struct foo { enum { A } x;};", Lang_CXX11);
1116 EXPECT_TRUE(testStructuralMatch(t));
1119 TEST_F(StructuralEquivalenceEnumTest, AnonymousEnumsWithDiffConsts) {
1120 // field x is required to trigger comparison of the anonymous enum
1121 auto t = makeNamedDecls("struct foo { enum { A } x; };",
1122 "struct foo { enum { B } x;};", Lang_CXX11);
1123 EXPECT_FALSE(testStructuralMatch(t));
1126 struct StructuralEquivalenceEnumConstantTest : StructuralEquivalenceTest {};
1128 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithSameValues) {
1129 auto t = makeNamedDecls("enum foo { foo = 1 };", "enum foo { foo = 1 };",
1130 Lang_C89);
1131 EXPECT_TRUE(testStructuralMatch(t));
1134 TEST_F(StructuralEquivalenceEnumConstantTest,
1135 EnumConstantsWithDifferentValues) {
1136 auto t =
1137 makeNamedDecls("enum e { foo = 1 };", "enum e { foo = 2 };", Lang_C89);
1138 EXPECT_FALSE(testStructuralMatch(t));
1141 TEST_F(StructuralEquivalenceEnumConstantTest,
1142 EnumConstantsWithDifferentExprsButSameValues) {
1143 auto t = makeNamedDecls("enum e { foo = 1 + 1 };", "enum e { foo = 2 };",
1144 Lang_CXX11);
1145 EXPECT_FALSE(testStructuralMatch(t));
1148 TEST_F(StructuralEquivalenceEnumConstantTest,
1149 EnumConstantsWithDifferentSignedness) {
1150 auto t = makeNamedDecls("enum e : unsigned { foo = 1 };",
1151 "enum e : int { foo = 1 };", Lang_CXX11);
1152 EXPECT_FALSE(testStructuralMatch(t));
1155 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentWidth) {
1156 auto t = makeNamedDecls("enum e : short { foo = 1 };",
1157 "enum e : int { foo = 1 };", Lang_CXX11);
1158 EXPECT_FALSE(testStructuralMatch(t));
1161 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentName) {
1162 auto t =
1163 makeDecls<EnumConstantDecl>("enum e { foo = 1 };", "enum e { bar = 1 };",
1164 Lang_CXX11, enumConstantDecl());
1165 EXPECT_FALSE(testStructuralMatch(t));
1168 struct StructuralEquivalenceObjCCategoryTest : StructuralEquivalenceTest {};
1170 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchinCategoryNames) {
1171 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1172 "@interface A @end @interface A(X) @end",
1173 Lang_OBJC, objcCategoryDecl());
1174 EXPECT_TRUE(testStructuralMatch(t));
1177 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesForDifferentClasses) {
1178 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1179 "@interface B @end @interface B(X) @end",
1180 Lang_OBJC, objcCategoryDecl());
1181 EXPECT_FALSE(testStructuralMatch(t));
1184 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithDifferentNames) {
1185 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1186 "@interface A @end @interface A(Y) @end",
1187 Lang_OBJC, objcCategoryDecl());
1188 EXPECT_FALSE(testStructuralMatch(t));
1191 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithoutInterfaces) {
1192 auto t = makeDecls<ObjCCategoryDecl>(" @interface A(X) @end",
1193 "@interface A @end @interface A(X) @end",
1194 Lang_OBJC, objcCategoryDecl());
1195 EXPECT_FALSE(testStructuralMatch(t));
1197 auto t2 = makeDecls<ObjCCategoryDecl>("@interface A(X) @end",
1198 "@interface A(X) @end",
1199 Lang_OBJC, objcCategoryDecl());
1200 EXPECT_TRUE(testStructuralMatch(t2));
1203 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoryAndExtension) {
1204 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1205 "@interface A @end @interface A() @end",
1206 Lang_OBJC, objcCategoryDecl());
1207 EXPECT_FALSE(testStructuralMatch(t));
1210 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingProtocols) {
1211 auto t = makeDecls<ObjCCategoryDecl>(
1212 "@protocol P @end @interface A @end @interface A(X)<P> @end",
1213 "@protocol P @end @interface A @end @interface A(X)<P> @end", Lang_OBJC,
1214 objcCategoryDecl());
1215 EXPECT_TRUE(testStructuralMatch(t));
1218 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocols) {
1219 auto t = makeDecls<ObjCCategoryDecl>(
1220 "@protocol P @end @interface A @end @interface A(X)<P> @end",
1221 "@protocol Q @end @interface A @end @interface A(X)<Q> @end", Lang_OBJC,
1222 objcCategoryDecl());
1223 EXPECT_FALSE(testStructuralMatch(t));
1226 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocolsOrder) {
1227 auto t = makeDecls<ObjCCategoryDecl>(
1228 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<P, "
1229 "Q> @end",
1230 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<Q, "
1231 "P> @end",
1232 Lang_OBJC, objcCategoryDecl());
1233 EXPECT_FALSE(testStructuralMatch(t));
1236 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingIvars) {
1237 auto t = makeDecls<ObjCCategoryDecl>(
1238 "@interface A @end @interface A() { int x; } @end",
1239 "@interface A @end @interface A() { int x; } @end", Lang_OBJC,
1240 objcCategoryDecl());
1241 EXPECT_TRUE(testStructuralMatch(t));
1244 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarName) {
1245 auto t = makeDecls<ObjCCategoryDecl>(
1246 "@interface A @end @interface A() { int x; } @end",
1247 "@interface A @end @interface A() { int y; } @end", Lang_OBJC,
1248 objcCategoryDecl());
1249 EXPECT_FALSE(testStructuralMatch(t));
1252 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarType) {
1253 auto t = makeDecls<ObjCCategoryDecl>(
1254 "@interface A @end @interface A() { int x; } @end",
1255 "@interface A @end @interface A() { float x; } @end", Lang_OBJC,
1256 objcCategoryDecl());
1257 EXPECT_FALSE(testStructuralMatch(t));
1260 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarBitfieldWidth) {
1261 auto t = makeDecls<ObjCCategoryDecl>(
1262 "@interface A @end @interface A() { int x: 1; } @end",
1263 "@interface A @end @interface A() { int x: 2; } @end", Lang_OBJC,
1264 objcCategoryDecl());
1265 EXPECT_FALSE(testStructuralMatch(t));
1268 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarVisibility) {
1269 auto t = makeDecls<ObjCCategoryDecl>(
1270 "@interface A @end @interface A() { @public int x; } @end",
1271 "@interface A @end @interface A() { @protected int x; } @end", Lang_OBJC,
1272 objcCategoryDecl());
1273 EXPECT_FALSE(testStructuralMatch(t));
1276 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarNumber) {
1277 auto t = makeDecls<ObjCCategoryDecl>(
1278 "@interface A @end @interface A() { int x; } @end",
1279 "@interface A @end @interface A() {} @end", Lang_OBJC,
1280 objcCategoryDecl());
1281 EXPECT_FALSE(testStructuralMatch(t));
1284 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarOrder) {
1285 auto t = makeDecls<ObjCCategoryDecl>(
1286 "@interface A @end @interface A() { int x; int y; } @end",
1287 "@interface A @end @interface A() { int y; int x; } @end", Lang_OBJC,
1288 objcCategoryDecl());
1289 EXPECT_FALSE(testStructuralMatch(t));
1292 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingMethods) {
1293 auto t = makeDecls<ObjCCategoryDecl>(
1294 "@interface A @end @interface A(X) -(void)test; @end",
1295 "@interface A @end @interface A(X) -(void)test; @end", Lang_OBJC,
1296 objcCategoryDecl());
1297 EXPECT_TRUE(testStructuralMatch(t));
1300 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodName) {
1301 auto t = makeDecls<ObjCCategoryDecl>(
1302 "@interface A @end @interface A(X) -(void)test; @end",
1303 "@interface A @end @interface A(X) -(void)wasd; @end", Lang_OBJC,
1304 objcCategoryDecl());
1305 EXPECT_FALSE(testStructuralMatch(t));
1307 auto t2 = makeDecls<ObjCCategoryDecl>(
1308 "@interface A @end @interface A(X) -(void)test:(int)x more:(int)y; @end",
1309 "@interface A @end @interface A(X) -(void)test:(int)x :(int)y; @end",
1310 Lang_OBJC, objcCategoryDecl());
1311 EXPECT_FALSE(testStructuralMatch(t2));
1314 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodClassInstance) {
1315 auto t = makeDecls<ObjCCategoryDecl>(
1316 "@interface A @end @interface A(X) -(void)test; @end",
1317 "@interface A @end @interface A(X) +(void)test; @end", Lang_OBJC,
1318 objcCategoryDecl());
1319 EXPECT_FALSE(testStructuralMatch(t));
1322 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodReturnType) {
1323 auto t = makeDecls<ObjCCategoryDecl>(
1324 "@interface A @end @interface A(X) -(void)test; @end",
1325 "@interface A @end @interface A(X) -(int)test; @end", Lang_OBJC,
1326 objcCategoryDecl());
1327 EXPECT_FALSE(testStructuralMatch(t));
1330 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterType) {
1331 auto t = makeDecls<ObjCCategoryDecl>(
1332 "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1333 "@interface A @end @interface A(X) -(void)test:(float)x; @end", Lang_OBJC,
1334 objcCategoryDecl());
1335 EXPECT_FALSE(testStructuralMatch(t));
1338 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterName) {
1339 auto t = makeDecls<ObjCCategoryDecl>(
1340 "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1341 "@interface A @end @interface A(X) -(void)test:(int)y; @end", Lang_OBJC,
1342 objcCategoryDecl());
1343 EXPECT_TRUE(testStructuralMatch(t));
1346 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodNumber) {
1347 auto t = makeDecls<ObjCCategoryDecl>(
1348 "@interface A @end @interface A(X) -(void)test; @end",
1349 "@interface A @end @interface A(X) @end", Lang_OBJC, objcCategoryDecl());
1350 EXPECT_FALSE(testStructuralMatch(t));
1353 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodOrder) {
1354 auto t = makeDecls<ObjCCategoryDecl>(
1355 "@interface A @end @interface A(X) -(void)u; -(void)v; @end",
1356 "@interface A @end @interface A(X) -(void)v; -(void)u; @end", Lang_OBJC,
1357 objcCategoryDecl());
1358 EXPECT_FALSE(testStructuralMatch(t));
1361 struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
1363 TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
1364 auto t = makeNamedDecls("template <class T> struct foo;",
1365 "template <class T> struct foo;", Lang_CXX03);
1366 EXPECT_TRUE(testStructuralMatch(t));
1369 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
1370 auto t = makeNamedDecls("template <class T> struct foo;",
1371 "template <class U> struct foo;", Lang_CXX03);
1372 EXPECT_TRUE(testStructuralMatch(t));
1375 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
1376 auto t = makeNamedDecls("template <class T> struct foo;",
1377 "template <int T> struct foo;", Lang_CXX03);
1378 EXPECT_FALSE(testStructuralMatch(t));
1381 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDecl) {
1382 const char *Code = "class foo { int a : 2; };";
1383 auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1384 EXPECT_TRUE(testStructuralMatch(t));
1387 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDeclDifferentWidth) {
1388 auto t = makeNamedDecls("class foo { int a : 2; };",
1389 "class foo { int a : 4; };", Lang_CXX03);
1390 EXPECT_FALSE(testStructuralMatch(t));
1393 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDecl) {
1394 const char *Code = "template <class T> class foo { int a : sizeof(T); };";
1395 auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1396 EXPECT_TRUE(testStructuralMatch(t));
1399 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal) {
1400 auto t = makeNamedDecls(
1401 "template <class A, class B> class foo { int a : sizeof(A); };",
1402 "template <class A, class B> class foo { int a : sizeof(B); };",
1403 Lang_CXX03);
1404 EXPECT_FALSE(testStructuralMatch(t));
1407 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal2) {
1408 auto t = makeNamedDecls(
1409 "template <class A> class foo { int a : sizeof(A); };",
1410 "template <class A> class foo { int a : sizeof(A) + 1; };", Lang_CXX03);
1411 EXPECT_FALSE(testStructuralMatch(t));
1414 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
1415 auto Decls = makeNamedDecls(
1416 "template <bool b> struct foo {explicit(b) foo(int);};",
1417 "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX20);
1418 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1419 get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1420 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1421 get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1422 EXPECT_TRUE(testStructuralMatch(First, Second));
1425 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
1426 auto Decls = makeNamedDecls(
1427 "template <bool b> struct foo {explicit(b) foo(int);};",
1428 "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX20);
1429 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1430 get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1431 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1432 get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1433 EXPECT_FALSE(testStructuralMatch(First, Second));
1436 TEST_F(StructuralEquivalenceTemplateTest,
1437 TemplateVsSubstTemplateTemplateParmInArgEq) {
1438 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1440 template <typename P1> class Arg { };
1441 template <template <typename PP1> class P1> class Primary { };
1443 void f() {
1444 // Make specialization with simple template.
1445 Primary <Arg> A;
1449 template <typename P1> class Arg { };
1450 template <template <typename PP1> class P1> class Primary { };
1452 template <template <typename PP1> class P1> class Templ {
1453 void f() {
1454 // Make specialization with substituted template template param.
1455 Primary <P1> A;
1459 // Instantiate with substitution Arg into P1.
1460 template class Templ <Arg>;
1462 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1463 EXPECT_TRUE(testStructuralMatch(t));
1466 TEST_F(StructuralEquivalenceTemplateTest,
1467 TemplateVsSubstTemplateTemplateParmInArgNotEq) {
1468 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1470 template <typename P1> class Arg { };
1471 template <template <typename PP1> class P1> class Primary { };
1473 void f() {
1474 // Make specialization with simple template.
1475 Primary <Arg> A;
1479 // Arg is different from the other, this should cause non-equivalence.
1480 template <typename P1> class Arg { int X; };
1481 template <template <typename PP1> class P1> class Primary { };
1483 template <template <typename PP1> class P1> class Templ {
1484 void f() {
1485 // Make specialization with substituted template template param.
1486 Primary <P1> A;
1490 // Instantiate with substitution Arg into P1.
1491 template class Templ <Arg>;
1493 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1494 EXPECT_FALSE(testStructuralMatch(t));
1497 struct StructuralEquivalenceDependentTemplateArgsTest
1498 : StructuralEquivalenceTemplateTest {};
1500 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1501 SameStructsInDependentArgs) {
1502 std::string Code =
1504 template <typename>
1505 struct S1;
1507 template <typename>
1508 struct enable_if;
1510 struct S
1512 template <typename T, typename enable_if<S1<T>>::type>
1513 void f();
1516 auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1517 functionTemplateDecl(hasName("f")));
1518 EXPECT_TRUE(testStructuralMatch(t));
1521 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1522 DifferentStructsInDependentArgs) {
1523 std::string Code =
1525 template <typename>
1526 struct S1;
1528 template <typename>
1529 struct S2;
1531 template <typename>
1532 struct enable_if;
1534 auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1535 struct S
1537 template <typename T, typename enable_if<S1<T>>::type>
1538 void f();
1541 Code + R"(
1542 struct S
1544 template <typename T, typename enable_if<S2<T>>::type>
1545 void f();
1548 Lang_CXX11,
1549 functionTemplateDecl(hasName("f")));
1550 EXPECT_FALSE(testStructuralMatch(t));
1553 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1554 SameStructsInDependentScopeDeclRefExpr) {
1555 std::string Code =
1557 template <typename>
1558 struct S1;
1560 template <bool>
1561 struct enable_if;
1563 struct S
1565 template <typename T, typename enable_if<S1<T>::value>::type>
1566 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1569 auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1570 functionTemplateDecl(hasName("f")));
1571 EXPECT_TRUE(testStructuralMatch(t));
1574 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1575 DifferentStructsInDependentScopeDeclRefExpr) {
1576 std::string Code =
1578 template <typename>
1579 struct S1;
1581 template <typename>
1582 struct S2;
1584 template <bool>
1585 struct enable_if;
1587 auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1588 struct S
1590 template <typename T, typename enable_if<S1<T>::value>::type>
1591 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1594 Code + R"(
1595 struct S
1597 template <typename T, typename enable_if<S2<T>::value>::type>
1598 void f();
1601 Lang_CXX03,
1602 functionTemplateDecl(hasName("f")));
1603 EXPECT_FALSE(testStructuralMatch(t));
1606 TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1607 DifferentValueInDependentScopeDeclRefExpr) {
1608 std::string Code =
1610 template <typename>
1611 struct S1;
1613 template <bool>
1614 struct enable_if;
1616 auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1617 struct S
1619 template <typename T, typename enable_if<S1<T>::value1>::type>
1620 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1623 Code + R"(
1624 struct S
1626 template <typename T, typename enable_if<S1<T>::value2>::type>
1627 void f();
1630 Lang_CXX03,
1631 functionTemplateDecl(hasName("f")));
1632 EXPECT_FALSE(testStructuralMatch(t));
1635 TEST_F(
1636 StructuralEquivalenceTemplateTest,
1637 ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) {
1638 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1640 template <class T> struct Primary {};
1641 namespace N {
1642 struct Arg;
1644 // Explicit instantiation with qualified name.
1645 template struct Primary<N::Arg>;
1648 template <class T> struct Primary {};
1649 namespace N {
1650 struct Arg;
1652 using namespace N;
1653 // Explicit instantiation with UNqualified name.
1654 template struct Primary<Arg>;
1656 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1657 EXPECT_TRUE(testStructuralMatch(t));
1660 TEST_F(
1661 StructuralEquivalenceTemplateTest,
1662 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) {
1663 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1665 template <class T> struct Primary {};
1666 namespace N {
1667 struct Arg { int a; };
1669 // Explicit instantiation with qualified name.
1670 template struct Primary<N::Arg>;
1673 template <class T> struct Primary {};
1674 namespace N {
1675 // This struct is not equivalent with the other in the prev TU.
1676 struct Arg { double b; }; // -- Field mismatch.
1678 using namespace N;
1679 // Explicit instantiation with UNqualified name.
1680 template struct Primary<Arg>;
1682 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1683 EXPECT_FALSE(testStructuralMatch(t));
1686 TEST_F(
1687 StructuralEquivalenceTemplateTest,
1688 ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) {
1689 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1691 template <template <class> class T> struct Primary {};
1692 namespace N {
1693 template <class T> struct Arg;
1695 // Explicit instantiation with qualified name.
1696 template struct Primary<N::Arg>;
1699 template <template <class> class T> struct Primary {};
1700 namespace N {
1701 template <class T> struct Arg;
1703 using namespace N;
1704 // Explicit instantiation with UNqualified name.
1705 template struct Primary<Arg>;
1707 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1708 EXPECT_TRUE(testStructuralMatch(t));
1711 TEST_F(
1712 StructuralEquivalenceTemplateTest,
1713 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) {
1714 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1716 template <template <class> class T> struct Primary {};
1717 namespace N {
1718 template <class T> struct Arg { int a; };
1720 // Explicit instantiation with qualified name.
1721 template struct Primary<N::Arg>;
1724 template <template <class> class T> struct Primary {};
1725 namespace N {
1726 // This template is not equivalent with the other in the prev TU.
1727 template <class T> struct Arg { double b; }; // -- Field mismatch.
1729 using namespace N;
1730 // Explicit instantiation with UNqualified name.
1731 template struct Primary<Arg>;
1733 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1734 EXPECT_FALSE(testStructuralMatch(t));
1737 TEST_F(StructuralEquivalenceTemplateTest,
1738 IgnoreTemplateParmDepthAtTemplateTypeParmDecl) {
1739 auto Decls = makeDecls<ClassTemplateDecl>(
1741 template<class> struct A;
1744 template<class> struct S {
1745 template<class> friend struct A;
1748 Lang_CXX03, classTemplateDecl(hasName("A")),
1749 classTemplateDecl(hasName("A")));
1750 EXPECT_TRUE(testStructuralMatch(Decls));
1751 EXPECT_TRUE(testStructuralMatch(Decls, true));
1754 TEST_F(StructuralEquivalenceTemplateTest,
1755 IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) {
1756 auto Decls = makeDecls<ClassTemplateDecl>(
1758 template<class T, T U> struct A;
1761 template<class T> struct S {
1762 template<class P, P Q> friend struct A;
1765 Lang_CXX03, classTemplateDecl(hasName("A")),
1766 classTemplateDecl(hasName("A")));
1767 EXPECT_FALSE(testStructuralMatch(Decls));
1768 EXPECT_TRUE(testStructuralMatch(Decls, /*IgnoreTemplateParmDepth=*/true));
1771 TEST_F(
1772 StructuralEquivalenceTemplateTest,
1773 ClassTemplSpecWithInequivalentShadowedTemplArg) {
1774 auto t = makeDecls<ClassTemplateSpecializationDecl>(
1776 template <template <class> class T> struct Primary {};
1777 template <class T> struct Arg { int a; };
1778 // Explicit instantiation with ::Arg
1779 template struct Primary<Arg>;
1782 template <template <class> class T> struct Primary {};
1783 template <class T> struct Arg { int a; };
1784 namespace N {
1785 // This template is not equivalent with the other in the global scope.
1786 template <class T> struct Arg { double b; }; // -- Field mismatch.
1787 // Explicit instantiation with N::Arg which shadows ::Arg
1788 template struct Primary<Arg>;
1791 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1792 EXPECT_FALSE(testStructuralMatch(t));
1794 struct StructuralEquivalenceCacheTest : public StructuralEquivalenceTest {
1795 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls;
1797 template <typename NodeType, typename MatcherType>
1798 std::pair<NodeType *, NodeType *>
1799 findDeclPair(std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> TU,
1800 MatcherType M) {
1801 NodeType *D0 = FirstDeclMatcher<NodeType>().match(get<0>(TU), M);
1802 NodeType *D1 = FirstDeclMatcher<NodeType>().match(get<1>(TU), M);
1803 return {D0, D1};
1806 template <typename NodeType>
1807 bool isInNonEqCache(std::pair<NodeType *, NodeType *> D,
1808 bool IgnoreTemplateParmDepth = false) {
1809 return NonEquivalentDecls.count(
1810 std::make_tuple(D.first, D.second, IgnoreTemplateParmDepth)) > 0;
1814 TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) {
1815 auto TU = makeTuDecls(
1817 class A {};
1818 class B {};
1819 void x(A, A);
1822 class A {};
1823 class B {};
1824 void x(A, B);
1826 Lang_CXX03);
1828 StructuralEquivalenceContext Ctx(
1829 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1830 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1832 auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1833 EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
1835 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1836 TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1837 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1838 TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1841 TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
1842 auto TU = makeTuDecls(
1844 bool x() { return true; }
1847 bool x() { return false; }
1849 Lang_CXX03);
1851 StructuralEquivalenceContext Ctx(
1852 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1853 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1855 auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1856 EXPECT_FALSE(Ctx.IsEquivalent(X.first->getBody(), X.second->getBody()));
1860 TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
1861 auto TU = makeTuDecls(
1863 int p;
1866 int q;
1868 Lang_CXX03);
1870 StructuralEquivalenceContext Ctx(
1871 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1872 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1874 auto Var = findDeclPair<VarDecl>(TU, varDecl());
1875 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1878 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
1879 auto TU = makeTuDecls(
1881 int p;
1884 static int p;
1886 Lang_CXX03);
1888 StructuralEquivalenceContext Ctx(
1889 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1890 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1892 auto Var = findDeclPair<VarDecl>(TU, varDecl());
1893 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1896 TEST_F(StructuralEquivalenceCacheTest,
1897 NonTypeTemplateParmWithDifferentPositionNoEq) {
1898 auto TU = makeTuDecls(
1900 template<int T>
1901 struct A {
1902 template<int U>
1903 void foo() {}
1907 template<int U>
1908 struct A {
1909 template<int V, int T>
1910 void foo() {}
1913 Lang_CXX03);
1915 StructuralEquivalenceContext Ctx(
1916 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1917 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1919 auto NTTP = findDeclPair<NonTypeTemplateParmDecl>(
1920 TU, nonTypeTemplateParmDecl(hasName("T")));
1921 EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second));
1924 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
1925 auto TU = makeTuDecls(
1927 int p = 1;
1930 int p = 2;
1932 Lang_CXX03);
1934 StructuralEquivalenceContext Ctx(
1935 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1936 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1938 auto Var = findDeclPair<VarDecl>(TU, varDecl());
1939 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1942 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
1943 auto TU = makeTuDecls(
1945 class A {};
1946 class B { int i; };
1947 void x(A *);
1948 void y(A *);
1949 class C {
1950 friend void x(A *);
1951 friend void y(A *);
1955 class A {};
1956 class B { int i; };
1957 void x(A *);
1958 void y(B *);
1959 class C {
1960 friend void x(A *);
1961 friend void y(B *);
1964 Lang_CXX03);
1966 StructuralEquivalenceContext Ctx(
1967 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1968 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1970 auto C = findDeclPair<CXXRecordDecl>(
1971 TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1972 EXPECT_FALSE(Ctx.IsEquivalent(C.first, C.second));
1974 EXPECT_FALSE(isInNonEqCache(C));
1975 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1976 TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1977 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1978 TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1979 EXPECT_FALSE(isInNonEqCache(
1980 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
1981 EXPECT_FALSE(isInNonEqCache(
1982 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("y")))));
1985 TEST_F(StructuralEquivalenceCacheTest, Cycle) {
1986 auto TU = makeTuDecls(
1988 class C;
1989 class A { C *c; };
1990 void x(A *);
1991 class C {
1992 friend void x(A *);
1996 class C;
1997 class A { C *c; };
1998 void x(A *);
1999 class C {
2000 friend void x(A *);
2003 Lang_CXX03);
2005 StructuralEquivalenceContext Ctx(
2006 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
2007 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
2009 auto C = findDeclPair<CXXRecordDecl>(
2010 TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
2011 EXPECT_TRUE(Ctx.IsEquivalent(C.first, C.second));
2013 EXPECT_FALSE(isInNonEqCache(C));
2014 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
2015 TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
2016 EXPECT_FALSE(isInNonEqCache(
2017 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
2020 TEST_F(StructuralEquivalenceCacheTest, TemplateParmDepth) {
2021 // In 'friend struct Y' ClassTemplateDecl has the TU as parent context.
2022 // This declaration has template depth 1 (it is already inside a template).
2023 // It has not a previous declaration and is an "undeclared" friend.
2025 // Second TU has a specialization of 'struct X'.
2026 // In this case 'friend struct Y' has the ClassTemplateSpecializationDecl as
2027 // parent. It has template depth 0 (it is in the specialization). It has the
2028 // first 'struct Y' declaration as previous declaration and canonical
2029 // declaration.
2031 // When these two 'friend struct Y' are compared, only the template depth is
2032 // different.
2033 // FIXME: Structural equivalence checks the depth only in types, not in
2034 // TemplateParmDecl. For this reason the second 'A1' argument is needed (as a
2035 // type) in the template to make the check fail.
2036 auto TU = makeTuDecls(
2038 template <class A1, A1>
2039 struct Y;
2041 template <class A>
2042 struct X {
2043 template <class A1, A1>
2044 friend struct Y;
2048 template <class A1, A1>
2049 struct Y;
2051 template <class A>
2052 struct X {
2053 template <class A1, A1>
2054 friend struct Y;
2057 X<int> x;
2059 Lang_CXX03);
2061 auto *D0 = LastDeclMatcher<ClassTemplateDecl>().match(
2062 get<0>(TU), classTemplateDecl(hasName("Y"), unless(isImplicit())));
2063 auto *D1 = LastDeclMatcher<ClassTemplateDecl>().match(
2064 get<1>(TU), classTemplateDecl(hasName("Y"), unless(isImplicit())));
2065 ASSERT_EQ(D0->getTemplateDepth(), 1u);
2066 ASSERT_EQ(D1->getTemplateDepth(), 0u);
2068 StructuralEquivalenceContext Ctx_NoIgnoreTemplateParmDepth(
2069 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
2070 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false,
2071 false, false);
2073 EXPECT_FALSE(Ctx_NoIgnoreTemplateParmDepth.IsEquivalent(D0, D1));
2075 Decl *NonEqDecl0 =
2076 D0->getCanonicalDecl()->getTemplateParameters()->getParam(1);
2077 Decl *NonEqDecl1 =
2078 D1->getCanonicalDecl()->getTemplateParameters()->getParam(1);
2079 EXPECT_TRUE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), false));
2080 EXPECT_FALSE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), true));
2082 StructuralEquivalenceContext Ctx_IgnoreTemplateParmDepth(
2083 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
2084 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false,
2085 false, true);
2087 EXPECT_TRUE(Ctx_IgnoreTemplateParmDepth.IsEquivalent(D0, D1));
2089 EXPECT_FALSE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), true));
2092 struct StructuralEquivalenceStmtTest : StructuralEquivalenceTest {};
2094 /// Fallback matcher to be used only when there is no specific matcher for a
2095 /// Expr subclass. Remove this once all Expr subclasses have their own matcher.
2096 static auto &fallbackExprMatcher = expr;
2098 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExpr) {
2099 auto t = makeWrappedStmts("lbl: &&lbl;", "lbl: &&lbl;", Lang_CXX03,
2100 addrLabelExpr());
2101 EXPECT_TRUE(testStructuralMatch(t));
2104 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExprDifferentLabel) {
2105 auto t = makeWrappedStmts("lbl1: lbl2: &&lbl1;", "lbl1: lbl2: &&lbl2;",
2106 Lang_CXX03, addrLabelExpr());
2107 // FIXME: Should be false. LabelDecl are incorrectly matched.
2108 EXPECT_TRUE(testStructuralMatch(t));
2111 static const std::string MemoryOrderSrc = R"(
2112 enum memory_order {
2113 memory_order_relaxed,
2114 memory_order_consume,
2115 memory_order_acquire,
2116 memory_order_release,
2117 memory_order_acq_rel,
2118 memory_order_seq_cst
2122 TEST_F(StructuralEquivalenceStmtTest, AtomicExpr) {
2123 std::string Prefix = "char a, b; " + MemoryOrderSrc;
2124 auto t = makeStmts(
2125 Prefix +
2126 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2127 Prefix +
2128 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2129 Lang_CXX03, atomicExpr());
2130 EXPECT_TRUE(testStructuralMatch(t));
2133 TEST_F(StructuralEquivalenceStmtTest, AtomicExprDifferentOp) {
2134 std::string Prefix = "char a, b; " + MemoryOrderSrc;
2135 auto t = makeStmts(
2136 Prefix +
2137 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2138 Prefix +
2139 "void wrapped() { __atomic_store(&a, &b, memory_order_seq_cst); }",
2140 Lang_CXX03, atomicExpr());
2141 EXPECT_FALSE(testStructuralMatch(t));
2144 TEST_F(StructuralEquivalenceStmtTest, BinaryOperator) {
2145 auto t = makeWrappedStmts("1 + 1", "1 + 1", Lang_CXX03, binaryOperator());
2146 EXPECT_TRUE(testStructuralMatch(t));
2149 TEST_F(StructuralEquivalenceStmtTest, BinaryOperatorDifferentOps) {
2150 auto t = makeWrappedStmts("1 + 1", "1 - 1", Lang_CXX03, binaryOperator());
2151 EXPECT_FALSE(testStructuralMatch(t));
2154 TEST_F(StructuralEquivalenceStmtTest, CallExpr) {
2155 std::string Src = "int call(); int wrapped() { call(); }";
2156 auto t = makeStmts(Src, Src, Lang_CXX03, callExpr());
2157 EXPECT_TRUE(testStructuralMatch(t));
2160 TEST_F(StructuralEquivalenceStmtTest, CallExprDifferentCallee) {
2161 std::string FunctionSrc = "int func1(); int func2();\n";
2162 auto t = makeStmts(FunctionSrc + "void wrapper() { func1(); }",
2163 FunctionSrc + "void wrapper() { func2(); }", Lang_CXX03,
2164 callExpr());
2165 EXPECT_FALSE(testStructuralMatch(t));
2168 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteral) {
2169 auto t = makeWrappedStmts("'a'", "'a'", Lang_CXX03, characterLiteral());
2170 EXPECT_TRUE(testStructuralMatch(t));
2173 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteralDifferentValues) {
2174 auto t = makeWrappedStmts("'a'", "'b'", Lang_CXX03, characterLiteral());
2175 EXPECT_FALSE(testStructuralMatch(t));
2178 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExpr) {
2179 auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_lvalue_expr(1)",
2180 Lang_CXX03, fallbackExprMatcher());
2181 EXPECT_TRUE(testStructuralMatch(t));
2184 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExprDifferentKind) {
2185 auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_rvalue_expr(1)",
2186 Lang_CXX03, fallbackExprMatcher());
2187 EXPECT_FALSE(testStructuralMatch(t));
2190 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteral) {
2191 auto t = makeWrappedStmts("1.0", "1.0", Lang_CXX03, fallbackExprMatcher());
2192 EXPECT_TRUE(testStructuralMatch(t));
2195 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentSpelling) {
2196 auto t = makeWrappedStmts("0x10.1p0", "16.0625", Lang_CXX17,
2197 fallbackExprMatcher());
2198 // Same value but with different spelling is equivalent.
2199 EXPECT_TRUE(testStructuralMatch(t));
2202 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentType) {
2203 auto t = makeWrappedStmts("1.0", "1.0f", Lang_CXX03, fallbackExprMatcher());
2204 EXPECT_FALSE(testStructuralMatch(t));
2207 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentValue) {
2208 auto t = makeWrappedStmts("1.01", "1.0", Lang_CXX03, fallbackExprMatcher());
2209 EXPECT_FALSE(testStructuralMatch(t));
2212 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSame) {
2213 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2214 "_Generic(0u, unsigned int: 0, float: 1)", Lang_C99,
2215 genericSelectionExpr());
2216 EXPECT_TRUE(testStructuralMatch(t));
2219 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSignsDiffer) {
2220 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2221 "_Generic(0, int: 0, float: 1)", Lang_C99,
2222 genericSelectionExpr());
2223 EXPECT_FALSE(testStructuralMatch(t));
2226 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprOrderDiffers) {
2227 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2228 "_Generic(0u, float: 1, unsigned int: 0)", Lang_C99,
2229 genericSelectionExpr());
2230 EXPECT_FALSE(testStructuralMatch(t));
2233 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) {
2234 auto t = makeStmts(
2236 template <typename T>
2237 void f() {
2238 T x;
2239 (void)_Generic(x, int: 0, float: 1);
2241 void g() { f<int>(); }
2244 template <typename T>
2245 void f() {
2246 T x;
2247 (void)_Generic(x, int: 0, float: 1);
2249 void g() { f<int>(); }
2251 Lang_CXX03, genericSelectionExpr());
2252 EXPECT_TRUE(testStructuralMatch(t));
2255 TEST_F(StructuralEquivalenceStmtTest,
2256 GenericSelectionExprDependentResultOrderDiffers) {
2257 auto t = makeStmts(
2259 template <typename T>
2260 void f() {
2261 T x;
2262 (void)_Generic(x, float: 1, int: 0);
2264 void g() { f<int>(); }
2267 template <typename T>
2268 void f() {
2269 T x;
2270 (void)_Generic(x, int: 0, float: 1);
2272 void g() { f<int>(); }
2274 Lang_CXX03, genericSelectionExpr());
2276 EXPECT_FALSE(testStructuralMatch(t));
2278 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteral) {
2279 auto t = makeWrappedStmts("1", "1", Lang_CXX03, integerLiteral());
2280 EXPECT_TRUE(testStructuralMatch(t));
2283 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentSpelling) {
2284 auto t = makeWrappedStmts("1", "0x1", Lang_CXX03, integerLiteral());
2285 // Same value but with different spelling is equivalent.
2286 EXPECT_TRUE(testStructuralMatch(t));
2289 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentValue) {
2290 auto t = makeWrappedStmts("1", "2", Lang_CXX03, integerLiteral());
2291 EXPECT_FALSE(testStructuralMatch(t));
2294 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentTypes) {
2295 auto t = makeWrappedStmts("1", "1L", Lang_CXX03, integerLiteral());
2296 EXPECT_FALSE(testStructuralMatch(t));
2299 TEST_F(StructuralEquivalenceStmtTest, MemberExpr) {
2300 std::string ClassSrc = "struct C { int a; int b; };";
2301 auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2302 ClassSrc + "int wrapper() { C c; return c.a; }",
2303 Lang_CXX03, memberExpr());
2304 EXPECT_TRUE(testStructuralMatch(t));
2307 TEST_F(StructuralEquivalenceStmtTest, MemberExprDifferentMember) {
2308 std::string ClassSrc = "struct C { int a; int b; };";
2309 auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2310 ClassSrc + "int wrapper() { C c; return c.b; }",
2311 Lang_CXX03, memberExpr());
2312 EXPECT_FALSE(testStructuralMatch(t));
2315 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteral) {
2316 auto t =
2317 makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX, fallbackExprMatcher());
2318 EXPECT_TRUE(testStructuralMatch(t));
2321 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteralDifferentContent) {
2322 auto t =
2323 makeWrappedStmts("@\"a\"", "@\"b\"", Lang_OBJCXX, fallbackExprMatcher());
2324 EXPECT_FALSE(testStructuralMatch(t));
2327 TEST_F(StructuralEquivalenceStmtTest, StringLiteral) {
2328 auto t = makeWrappedStmts("\"a\"", "\"a\"", Lang_CXX03, stringLiteral());
2329 EXPECT_TRUE(testStructuralMatch(t));
2332 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentContent) {
2333 auto t = makeWrappedStmts("\"a\"", "\"b\"", Lang_CXX03, stringLiteral());
2334 EXPECT_FALSE(testStructuralMatch(t));
2337 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentLength) {
2338 auto t = makeWrappedStmts("\"a\"", "\"aa\"", Lang_CXX03, stringLiteral());
2339 EXPECT_FALSE(testStructuralMatch(t));
2342 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExpr) {
2343 auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(int)", Lang_CXX03,
2344 fallbackExprMatcher());
2345 EXPECT_TRUE(testStructuralMatch(t));
2348 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentType) {
2349 auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(long)", Lang_CXX03,
2350 fallbackExprMatcher());
2351 EXPECT_FALSE(testStructuralMatch(t));
2354 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTrait) {
2355 auto t = makeWrappedStmts(
2356 "__is_pod(int)", "__is_trivially_constructible(int)", Lang_CXX03, expr());
2357 EXPECT_FALSE(testStructuralMatch(t));
2360 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTraits) {
2361 auto t = makeWrappedStmts("__is_constructible(int)",
2362 "__is_constructible(int, int)", Lang_CXX03, expr());
2363 EXPECT_FALSE(testStructuralMatch(t));
2366 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExpr) {
2367 auto t = makeWrappedStmts("sizeof(int)", "sizeof(int)", Lang_CXX03,
2368 unaryExprOrTypeTraitExpr());
2369 EXPECT_TRUE(testStructuralMatch(t));
2372 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentKind) {
2373 auto t = makeWrappedStmts("sizeof(int)", "alignof(long)", Lang_CXX11,
2374 unaryExprOrTypeTraitExpr());
2375 EXPECT_FALSE(testStructuralMatch(t));
2378 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentType) {
2379 auto t = makeWrappedStmts("sizeof(int)", "sizeof(long)", Lang_CXX03,
2380 unaryExprOrTypeTraitExpr());
2381 EXPECT_FALSE(testStructuralMatch(t));
2384 TEST_F(StructuralEquivalenceStmtTest, UnaryOperator) {
2385 auto t = makeWrappedStmts("+1", "+1", Lang_CXX03, unaryOperator());
2386 EXPECT_TRUE(testStructuralMatch(t));
2389 TEST_F(StructuralEquivalenceStmtTest, UnaryOperatorDifferentOps) {
2390 auto t = makeWrappedStmts("+1", "-1", Lang_CXX03, unaryOperator());
2391 EXPECT_FALSE(testStructuralMatch(t));
2394 TEST_F(StructuralEquivalenceStmtTest,
2395 CXXOperatorCallExprVsUnaryBinaryOperator) {
2396 auto t = makeNamedDecls(
2398 template <typename T, T x>
2399 class A;
2400 template <typename T, T x, T y>
2401 void foo(
2402 A<T, x + y>,
2403 A<T, x - y>,
2404 A<T, -x>,
2405 A<T, x * y>,
2406 A<T, *x>,
2407 A<T, x / y>,
2408 A<T, x % y>,
2409 A<T, x ^ y>,
2410 A<T, x & y>,
2411 A<T, &x>,
2412 A<T, x | y>,
2413 A<T, ~x>,
2414 A<T, !x>,
2415 A<T, x < y>,
2416 A<T, (x > y)>,
2417 A<T, x << y>,
2418 A<T, (x >> y)>,
2419 A<T, x == y>,
2420 A<T, x != y>,
2421 A<T, x <= y>,
2422 A<T, x >= y>,
2423 A<T, x <=> y>,
2424 A<T, x && y>,
2425 A<T, x || y>,
2426 A<T, ++x>,
2427 A<T, --x>,
2428 A<T, (x , y)>,
2429 A<T, x ->* y>,
2430 A<T, x -> y>
2434 struct Bar {
2435 Bar& operator=(Bar&);
2436 Bar& operator->();
2439 Bar& operator+(Bar&, Bar&);
2440 Bar& operator+(Bar&);
2441 Bar& operator-(Bar&, Bar&);
2442 Bar& operator-(Bar&);
2443 Bar& operator*(Bar&, Bar&);
2444 Bar& operator*(Bar&);
2445 Bar& operator/(Bar&, Bar&);
2446 Bar& operator%(Bar&, Bar&);
2447 Bar& operator^(Bar&, Bar&);
2448 Bar& operator&(Bar&, Bar&);
2449 Bar& operator&(Bar&);
2450 Bar& operator|(Bar&, Bar&);
2451 Bar& operator~(Bar&);
2452 Bar& operator!(Bar&);
2453 Bar& operator<(Bar&, Bar&);
2454 Bar& operator>(Bar&, Bar&);
2455 Bar& operator+=(Bar&, Bar&);
2456 Bar& operator-=(Bar&, Bar&);
2457 Bar& operator*=(Bar&, Bar&);
2458 Bar& operator/=(Bar&, Bar&);
2459 Bar& operator%=(Bar&, Bar&);
2460 Bar& operator^=(Bar&, Bar&);
2461 Bar& operator&=(Bar&, Bar&);
2462 Bar& operator|=(Bar&, Bar&);
2463 Bar& operator<<(Bar&, Bar&);
2464 Bar& operator>>(Bar&, Bar&);
2465 Bar& operator<<=(Bar&, Bar&);
2466 Bar& operator>>=(Bar&, Bar&);
2467 Bar& operator==(Bar&, Bar&);
2468 Bar& operator!=(Bar&, Bar&);
2469 Bar& operator<=(Bar&, Bar&);
2470 Bar& operator>=(Bar&, Bar&);
2471 Bar& operator<=>(Bar&, Bar&);
2472 Bar& operator&&(Bar&, Bar&);
2473 Bar& operator||(Bar&, Bar&);
2474 Bar& operator++(Bar&);
2475 Bar& operator--(Bar&);
2476 Bar& operator,(Bar&, Bar&);
2477 Bar& operator->*(Bar&, Bar&);
2479 template <typename T, T x>
2480 class A;
2481 template <typename T, T x, T y>
2482 void foo(
2483 A<T, x + y>,
2484 A<T, x - y>,
2485 A<T, -x>,
2486 A<T, x * y>,
2487 A<T, *x>,
2488 A<T, x / y>,
2489 A<T, x % y>,
2490 A<T, x ^ y>,
2491 A<T, x & y>,
2492 A<T, &x>,
2493 A<T, x | y>,
2494 A<T, ~x>,
2495 A<T, !x>,
2496 A<T, x < y>,
2497 A<T, (x > y)>,
2498 A<T, x << y>,
2499 A<T, (x >> y)>,
2500 A<T, x == y>,
2501 A<T, x != y>,
2502 A<T, x <= y>,
2503 A<T, x >= y>,
2504 A<T, x <=> y>,
2505 A<T, x && y>,
2506 A<T, x || y>,
2507 A<T, ++x>,
2508 A<T, --x>,
2509 A<T, (x , y)>,
2510 A<T, x ->* y>,
2511 A<T, x -> y>
2514 Lang_CXX20);
2515 EXPECT_TRUE(testStructuralMatch(t));
2518 TEST_F(StructuralEquivalenceStmtTest,
2519 CXXOperatorCallExprVsUnaryBinaryOperatorNe) {
2520 auto t = makeNamedDecls(
2522 template <typename T, T x>
2523 class A;
2524 template <typename T, T x, T y>
2525 void foo(
2526 A<T, x + y>
2530 struct Bar;
2532 Bar& operator-(Bar&, Bar&);
2534 template <typename T, T x>
2535 class A;
2536 template <typename T, T x, T y>
2537 void foo(
2538 A<T, x - y>
2541 Lang_CXX11);
2542 EXPECT_FALSE(testStructuralMatch(t));
2545 TEST_F(StructuralEquivalenceStmtTest, NonTypeTemplateParm) {
2546 auto t = makeNamedDecls(
2548 template <typename T, T x>
2549 class A;
2550 template <typename T, T x, T y>
2551 void foo(A<T, x>);
2554 template <typename T, T x>
2555 class A;
2556 template <typename T, T x, T y>
2557 void foo(A<T, y>);
2559 Lang_CXX11);
2560 EXPECT_FALSE(testStructuralMatch(t));
2563 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
2564 auto t = makeStmts(
2566 void f1(int);
2567 template <typename T>
2568 void f(T t) {
2569 f1(t);
2571 void g() { f<int>(1); }
2574 void f2(int);
2575 template <typename T>
2576 void f(T t) {
2577 f2(t);
2579 void g() { f<int>(1); }
2581 Lang_CXX03, unresolvedLookupExpr());
2582 EXPECT_FALSE(testStructuralMatch(t));
2585 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentQualifier) {
2586 auto t = makeStmts(
2588 struct X {
2589 static void g(int);
2590 static void g(char);
2593 template <typename T>
2594 void f(T t) {
2595 X::g(t);
2598 void g() { f<int>(1); }
2601 struct Y {
2602 static void g(int);
2603 static void g(char);
2606 template <typename T>
2607 void f(T t) {
2608 Y::g(t);
2611 void g() { f<int>(1); }
2613 Lang_CXX03, unresolvedLookupExpr());
2614 EXPECT_FALSE(testStructuralMatch(t));
2617 TEST_F(StructuralEquivalenceStmtTest,
2618 UnresolvedLookupDifferentTemplateArgument) {
2619 auto t = makeStmts(
2621 struct A {};
2622 template<typename T1, typename T2>
2623 void g() {}
2625 template <typename T>
2626 void f() {
2627 g<A, T>();
2630 void h() { f<int>(); }
2633 struct B {};
2634 template<typename T1, typename T2>
2635 void g() {}
2637 template <typename T>
2638 void f() {
2639 g<B, T>();
2642 void h() { f<int>(); }
2644 Lang_CXX03, unresolvedLookupExpr());
2645 EXPECT_FALSE(testStructuralMatch(t));
2648 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
2649 auto t = makeStmts(
2651 struct A {};
2652 struct B {
2653 template<typename T1, typename T2>
2654 static void g(int) {};
2655 template<typename T1, typename T2>
2656 static void g(char) {};
2659 template <typename T1, typename T2>
2660 void f(T2 x) {
2661 B::g<A, T1>(x);
2664 void g() { f<char, int>(1); }
2667 struct A {};
2668 struct B {
2669 template<typename T1, typename T2>
2670 static void g(int) {};
2671 template<typename T1, typename T2>
2672 static void g(char) {};
2675 template <typename T1, typename T2>
2676 void f(T2 x) {
2677 B::g<A, T1>(x);
2680 void g() { f<char, int>(1); }
2682 Lang_CXX03, unresolvedLookupExpr());
2683 EXPECT_TRUE(testStructuralMatch(t));
2686 TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
2687 auto S = makeStmts(
2689 void foo() {
2690 goto L1;
2691 L1: foo();
2695 void foo() {
2696 goto L2;
2697 L2: foo();
2700 Lang_CXX03, gotoStmt());
2701 EXPECT_FALSE(testStructuralMatch(S));
2704 TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
2705 std::string Prefix = "enum Test { AAA, BBB };";
2706 auto t = makeStmts(
2707 Prefix + "void foo(int i) {if (i > 0) {i = AAA;} else {i = BBB;}}",
2708 Prefix + "void foo(int i) {if (i > 0) {i = BBB;} else {i = AAA;}}",
2709 Lang_CXX03, ifStmt());
2710 EXPECT_FALSE(testStructuralMatch(t));
2713 TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
2714 auto S = makeStmts(
2716 template <class T>
2717 void foo() {
2718 (void)T().x;
2720 struct A { int x; };
2721 void bar() {
2722 foo<A>();
2726 template <class T>
2727 void foo() {
2728 (void)T().y;
2730 struct A { int y; };
2731 void bar() {
2732 foo<A>();
2735 Lang_CXX11, cxxDependentScopeMemberExpr());
2736 EXPECT_FALSE(testStructuralMatch(S));
2739 } // end namespace ast_matchers
2740 } // end namespace clang