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"
16 namespace ast_matchers
{
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
,
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
,
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
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
{
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
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
);
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
);
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
>(
244 template <class T> struct foo;
245 template<> struct foo<char> : 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
) {
262 template <class T> class Base {
265 class Derived : Base<Derived> {
268 void foo(NS::Derived &);
270 auto Decls
= makeNamedDecls(Code
, Code
, Lang_CXX03
);
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.
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")));
291 FirstDeclMatcher
<FieldDecl
>().match(get
<1>(Decls
), fieldDecl(hasName("a")));
293 // Reorder the FieldDecls
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();",
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
) {
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
));
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
) {
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;",
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)(); };",
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
)
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
)
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.
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); };",
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; };",
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(); };",
582 cxxConversionDecl());
583 EXPECT_FALSE(testStructuralMatch(t
));
586 TEST_F(StructuralEquivalenceCXXMethodTest
, Operator
) {
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; };",
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(); };",
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
) {
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.
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
) {
664 struct foo: A, virtual B {
669 auto t
= makeNamedDecls(Code
, Code
, Lang_CXX03
);
670 EXPECT_TRUE(testStructuralMatch(t
));
673 TEST_F(StructuralEquivalenceRecordTest
, UnnamedRecordsShouldBeInequivalent
) {
674 auto t
= makeTuDecls(
686 auto *TU
= get
<0>(t
);
688 FirstDeclMatcher
<FieldDecl
>().match(TU
, fieldDecl(hasName("entry0")));
690 FirstDeclMatcher
<FieldDecl
>().match(TU
, fieldDecl(hasName("entry1")));
691 auto *R0
= getRecordDecl(Entry0
);
692 auto *R1
= getRecordDecl(Entry1
);
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(
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();
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(
739 struct X { // The order is reversed.
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();
759 FirstDeclMatcher
<RecordDecl
>().match(TU
, recordDecl(hasName("X")));
761 FirstDeclMatcher
<RecordDecl
>().match(TU1
, recordDecl(hasName("X")));
763 EXPECT_FALSE(testStructuralMatch(X
, X1
));
766 EXPECT_TRUE(testStructuralMatch(RA
, RA
));
767 EXPECT_TRUE(testStructuralMatch(RA1
, RA1
));
768 EXPECT_FALSE(testStructuralMatch(RA1
, RA
));
771 TEST_F(StructuralEquivalenceRecordTest
,
772 UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined
) {
784 auto t
= makeTuDecls(Code
, Code
, Lang_C99
);
786 auto *FromTU
= get
<0>(t
);
788 FirstDeclMatcher
<FieldDecl
>().match(FromTU
, fieldDecl(hasName("entry1")));
790 auto *ToTU
= get
<1>(t
);
792 FirstDeclMatcher
<FieldDecl
>().match(ToTU
, fieldDecl(hasName("entry0")));
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
);
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
) {
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; };",
831 EXPECT_TRUE(testStructuralMatch(t
));
834 TEST_F(StructuralEquivalenceRecordTest
, RecordsWithDifferentBody
) {
835 auto t
= makeNamedDecls("class foo { int B; };", "class foo { int A; };",
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; };",
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; };",
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; };",
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 = [](){}; }",
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){}; }",
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](){}; }",
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](){}; }",
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);",
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
) {
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
) {
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
) {
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; } }",
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; } }",
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; } }",
998 EXPECT_TRUE(testStructuralMatch(Decls
));
1001 TEST_F(StructuralEquivalenceRecordContextTest
, NamespaceInlineTopLevel
) {
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
) {
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; } }",
1024 EXPECT_TRUE(testStructuralMatch(Decls
));
1027 TEST_F(StructuralEquivalenceRecordContextTest
,
1028 ClassTemplateSpecializationContext
) {
1031 template <typename T> struct O {
1035 auto t
= makeDecls
<VarDecl
>(Code
+ R
"(
1036 typedef O<int>::M MT1;
1043 typedef O<I>::M MT2;
1046 Lang_CXX11
, varDecl(hasName("A")));
1047 EXPECT_FALSE(testStructuralMatch(t
));
1050 TEST_F(StructuralEquivalenceTest
, NamespaceOfRecordMember
) {
1051 auto Decls
= makeNamedDecls(
1057 namespace N { class X; }
1058 class Y { N::X* x; };
1061 EXPECT_FALSE(testStructuralMatch(Decls
));
1064 TEST_F(StructuralEquivalenceTest
, StructDefinitionInPrototype
) {
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
) {
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
,
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
) {
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 };",
1103 EXPECT_TRUE(testStructuralMatch(t
));
1106 TEST_F(StructuralEquivalenceEnumTest
, EnumsWithDifferentBody
) {
1107 auto t
= makeNamedDecls("enum class foo { B };", "enum class foo { A };",
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 };",
1131 EXPECT_TRUE(testStructuralMatch(t
));
1134 TEST_F(StructuralEquivalenceEnumConstantTest
,
1135 EnumConstantsWithDifferentValues
) {
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 };",
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
) {
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, "
1230 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<Q, "
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); };",
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 { };
1444 // Make specialization with simple template.
1449 template <typename P1> class Arg { };
1450 template <template <typename PP1> class P1> class Primary { };
1452 template <template <typename PP1> class P1> class Templ {
1454 // Make specialization with substituted template template param.
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 { };
1474 // Make specialization with simple template.
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 {
1485 // Make specialization with substituted template template param.
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
) {
1512 template <typename T, typename enable_if<S1<T>>::type>
1516 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
, Code
, Lang_CXX11
,
1517 functionTemplateDecl(hasName("f")));
1518 EXPECT_TRUE(testStructuralMatch(t
));
1521 TEST_F(StructuralEquivalenceDependentTemplateArgsTest
,
1522 DifferentStructsInDependentArgs
) {
1534 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
+ R
"(
1537 template <typename T, typename enable_if<S1<T>>::type>
1544 template <typename T, typename enable_if<S2<T>>::type>
1549 functionTemplateDecl(hasName("f")));
1550 EXPECT_FALSE(testStructuralMatch(t
));
1553 TEST_F(StructuralEquivalenceDependentTemplateArgsTest
,
1554 SameStructsInDependentScopeDeclRefExpr
) {
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
) {
1587 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
+ R
"(
1590 template <typename T, typename enable_if<S1<T>::value>::type>
1591 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1597 template <typename T, typename enable_if<S2<T>::value>::type>
1602 functionTemplateDecl(hasName("f")));
1603 EXPECT_FALSE(testStructuralMatch(t
));
1606 TEST_F(StructuralEquivalenceDependentTemplateArgsTest
,
1607 DifferentValueInDependentScopeDeclRefExpr
) {
1616 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
+ R
"(
1619 template <typename T, typename enable_if<S1<T>::value1>::type>
1620 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1626 template <typename T, typename enable_if<S1<T>::value2>::type>
1631 functionTemplateDecl(hasName("f")));
1632 EXPECT_FALSE(testStructuralMatch(t
));
1636 StructuralEquivalenceTemplateTest
,
1637 ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual
) {
1638 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1640 template <class T> struct Primary {};
1644 // Explicit instantiation with qualified name.
1645 template struct Primary<N::Arg>;
1648 template <class T> struct Primary {};
1653 // Explicit instantiation with UNqualified name.
1654 template struct Primary<Arg>;
1656 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1657 EXPECT_TRUE(testStructuralMatch(t
));
1661 StructuralEquivalenceTemplateTest
,
1662 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs
) {
1663 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1665 template <class T> struct Primary {};
1667 struct Arg { int a; };
1669 // Explicit instantiation with qualified name.
1670 template struct Primary<N::Arg>;
1673 template <class T> struct Primary {};
1675 // This struct is not equivalent with the other in the prev TU.
1676 struct Arg { double b; }; // -- Field mismatch.
1679 // Explicit instantiation with UNqualified name.
1680 template struct Primary<Arg>;
1682 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1683 EXPECT_FALSE(testStructuralMatch(t
));
1687 StructuralEquivalenceTemplateTest
,
1688 ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual
) {
1689 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1691 template <template <class> class T> struct Primary {};
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 {};
1701 template <class T> struct Arg;
1704 // Explicit instantiation with UNqualified name.
1705 template struct Primary<Arg>;
1707 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1708 EXPECT_TRUE(testStructuralMatch(t
));
1712 StructuralEquivalenceTemplateTest
,
1713 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs
) {
1714 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1716 template <template <class> class T> struct Primary {};
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 {};
1726 // This template is not equivalent with the other in the prev TU.
1727 template <class T> struct Arg { double b; }; // -- Field mismatch.
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));
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; };
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
,
1801 NodeType
*D0
= FirstDeclMatcher
<NodeType
>().match(get
<0>(TU
), M
);
1802 NodeType
*D1
= FirstDeclMatcher
<NodeType
>().match(get
<1>(TU
), M
);
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(
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; }
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(
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(
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(
1909 template<int V, int T>
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(
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(
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(
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
2031 // When these two 'friend struct Y' are compared, only the template depth is
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>
2043 template <class A1, A1>
2048 template <class A1, A1>
2053 template <class A1, A1>
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,
2073 EXPECT_FALSE(Ctx_NoIgnoreTemplateParmDepth
.IsEquivalent(D0
, D1
));
2076 D0
->getCanonicalDecl()->getTemplateParameters()->getParam(1);
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,
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
,
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
"(
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
;
2126 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
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
;
2137 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
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
,
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
) {
2236 template <typename T>
2239 (void)_Generic(x, int: 0, float: 1);
2241 void g() { f<int>(); }
2244 template <typename T>
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
) {
2259 template <typename T>
2262 (void)_Generic(x, float: 1, int: 0);
2264 void g() { f<int>(); }
2267 template <typename T>
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
) {
2317 makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX
, fallbackExprMatcher());
2318 EXPECT_TRUE(testStructuralMatch(t
));
2321 TEST_F(StructuralEquivalenceStmtTest
, ObjCStringLiteralDifferentContent
) {
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>
2400 template <typename T, T x, T y>
2435 Bar& operator=(Bar&);
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>
2481 template <typename T, T x, T y>
2515 EXPECT_TRUE(testStructuralMatch(t
));
2518 TEST_F(StructuralEquivalenceStmtTest
,
2519 CXXOperatorCallExprVsUnaryBinaryOperatorNe
) {
2520 auto t
= makeNamedDecls(
2522 template <typename T, T x>
2524 template <typename T, T x, T y>
2532 Bar& operator-(Bar&, Bar&);
2534 template <typename T, T x>
2536 template <typename T, T x, T y>
2542 EXPECT_FALSE(testStructuralMatch(t
));
2545 TEST_F(StructuralEquivalenceStmtTest
, NonTypeTemplateParm
) {
2546 auto t
= makeNamedDecls(
2548 template <typename T, T x>
2550 template <typename T, T x, T y>
2554 template <typename T, T x>
2556 template <typename T, T x, T y>
2560 EXPECT_FALSE(testStructuralMatch(t
));
2563 TEST_F(StructuralEquivalenceStmtTest
, UnresolvedLookupDifferentName
) {
2567 template <typename T>
2571 void g() { f<int>(1); }
2575 template <typename T>
2579 void g() { f<int>(1); }
2581 Lang_CXX03
, unresolvedLookupExpr());
2582 EXPECT_FALSE(testStructuralMatch(t
));
2585 TEST_F(StructuralEquivalenceStmtTest
, UnresolvedLookupDifferentQualifier
) {
2590 static void g(char);
2593 template <typename T>
2598 void g() { f<int>(1); }
2603 static void g(char);
2606 template <typename T>
2611 void g() { f<int>(1); }
2613 Lang_CXX03
, unresolvedLookupExpr());
2614 EXPECT_FALSE(testStructuralMatch(t
));
2617 TEST_F(StructuralEquivalenceStmtTest
,
2618 UnresolvedLookupDifferentTemplateArgument
) {
2622 template<typename T1, typename T2>
2625 template <typename T>
2630 void h() { f<int>(); }
2634 template<typename T1, typename T2>
2637 template <typename T>
2642 void h() { f<int>(); }
2644 Lang_CXX03
, unresolvedLookupExpr());
2645 EXPECT_FALSE(testStructuralMatch(t
));
2648 TEST_F(StructuralEquivalenceStmtTest
, UnresolvedLookup
) {
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>
2664 void g() { f<char, int>(1); }
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>
2680 void g() { f<char, int>(1); }
2682 Lang_CXX03
, unresolvedLookupExpr());
2683 EXPECT_TRUE(testStructuralMatch(t
));
2686 TEST_F(StructuralEquivalenceCacheTest
, GotoStmtNoEq
) {
2700 Lang_CXX03
, gotoStmt());
2701 EXPECT_FALSE(testStructuralMatch(S
));
2704 TEST_F(StructuralEquivalenceStmtTest
, DeclRefExpr
) {
2705 std::string Prefix
= "enum Test { AAA, BBB };";
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
) {
2720 struct A { int x; };
2730 struct A { int y; };
2735 Lang_CXX11
, cxxDependentScopeMemberExpr());
2736 EXPECT_FALSE(testStructuralMatch(S
));
2739 } // end namespace ast_matchers
2740 } // end namespace clang