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 llvm::DenseSet
<std::pair
<Decl
*, Decl
*>> NonEquivalentDecls01
;
138 llvm::DenseSet
<std::pair
<Decl
*, Decl
*>> NonEquivalentDecls10
;
139 StructuralEquivalenceContext
Ctx01(
140 D0
->getASTContext(), D1
->getASTContext(), NonEquivalentDecls01
,
141 StructuralEquivalenceKind::Default
, /*StrictTypeSpelling=*/false,
142 /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
143 IgnoreTemplateParmDepth
);
144 StructuralEquivalenceContext
Ctx10(
145 D1
->getASTContext(), D0
->getASTContext(), NonEquivalentDecls10
,
146 StructuralEquivalenceKind::Default
, /*StrictTypeSpelling=*/false,
147 /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
148 IgnoreTemplateParmDepth
);
149 bool Eq01
= Ctx01
.IsEquivalent(D0
, D1
);
150 bool Eq10
= Ctx10
.IsEquivalent(D1
, D0
);
151 EXPECT_EQ(Eq01
, Eq10
);
155 bool testStructuralMatch(StmtWithASTContext S0
, StmtWithASTContext S1
) {
156 llvm::DenseSet
<std::pair
<Decl
*, Decl
*>> NonEquivalentDecls01
;
157 llvm::DenseSet
<std::pair
<Decl
*, Decl
*>> NonEquivalentDecls10
;
158 StructuralEquivalenceContext
Ctx01(
159 *S0
.Context
, *S1
.Context
, NonEquivalentDecls01
,
160 StructuralEquivalenceKind::Default
, false, false);
161 StructuralEquivalenceContext
Ctx10(
162 *S1
.Context
, *S0
.Context
, NonEquivalentDecls10
,
163 StructuralEquivalenceKind::Default
, false, false);
164 bool Eq01
= Ctx01
.IsEquivalent(S0
.S
, S1
.S
);
165 bool Eq10
= Ctx10
.IsEquivalent(S1
.S
, S0
.S
);
166 EXPECT_EQ(Eq01
, Eq10
);
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(StructuralEquivalenceTest
, NamespaceOfRecordMember
) {
1028 auto Decls
= makeNamedDecls(
1034 namespace N { class X; }
1035 class Y { N::X* x; };
1038 EXPECT_FALSE(testStructuralMatch(Decls
));
1041 TEST_F(StructuralEquivalenceTest
, StructDefinitionInPrototype
) {
1043 makeNamedDecls("struct Param { int a; }; void foo(struct Param *p);",
1044 "void foo(struct Param { int a; } *p);", Lang_C89
);
1045 EXPECT_TRUE(testStructuralMatch(Decls
));
1048 TEST_F(StructuralEquivalenceTest
, StructDefinitionInPrototypeDifferentName
) {
1050 makeNamedDecls("struct Param1 { int a; }; void foo(struct Param1 *p);",
1051 "void foo(struct Param2 { int a; } *p);", Lang_C89
);
1052 EXPECT_FALSE(testStructuralMatch(Decls
));
1055 TEST_F(StructuralEquivalenceRecordContextTest
, RecordInsideFunction
) {
1056 auto Decls
= makeNamedDecls("struct Param { int a; };",
1057 "void f() { struct Param { int a; }; }", Lang_C89
,
1059 EXPECT_TRUE(testStructuralMatch(Decls
));
1062 struct StructuralEquivalenceEnumTest
: StructuralEquivalenceTest
{};
1064 TEST_F(StructuralEquivalenceEnumTest
, FwdDeclEnumShouldBeEqualWithFwdDeclEnum
) {
1065 auto t
= makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11
);
1066 EXPECT_TRUE(testStructuralMatch(t
));
1069 TEST_F(StructuralEquivalenceEnumTest
,
1070 FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition
) {
1072 makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11
);
1073 EXPECT_TRUE(testStructuralMatch(t
));
1076 TEST_F(StructuralEquivalenceEnumTest
,
1077 EnumShouldBeEqualWithEnumWhichHasDefinition
) {
1078 auto t
= makeNamedDecls("enum class foo { A };", "enum class foo { A };",
1080 EXPECT_TRUE(testStructuralMatch(t
));
1083 TEST_F(StructuralEquivalenceEnumTest
, EnumsWithDifferentBody
) {
1084 auto t
= makeNamedDecls("enum class foo { B };", "enum class foo { A };",
1086 EXPECT_FALSE(testStructuralMatch(t
));
1089 struct StructuralEquivalenceEnumConstantTest
: StructuralEquivalenceTest
{};
1091 TEST_F(StructuralEquivalenceEnumConstantTest
, EnumConstantsWithSameValues
) {
1092 auto t
= makeNamedDecls("enum foo { foo = 1 };", "enum foo { foo = 1 };",
1094 EXPECT_TRUE(testStructuralMatch(t
));
1097 TEST_F(StructuralEquivalenceEnumConstantTest
,
1098 EnumConstantsWithDifferentValues
) {
1100 makeNamedDecls("enum e { foo = 1 };", "enum e { foo = 2 };", Lang_C89
);
1101 EXPECT_FALSE(testStructuralMatch(t
));
1104 TEST_F(StructuralEquivalenceEnumConstantTest
,
1105 EnumConstantsWithDifferentExprsButSameValues
) {
1106 auto t
= makeNamedDecls("enum e { foo = 1 + 1 };", "enum e { foo = 2 };",
1108 EXPECT_FALSE(testStructuralMatch(t
));
1111 TEST_F(StructuralEquivalenceEnumConstantTest
,
1112 EnumConstantsWithDifferentSignedness
) {
1113 auto t
= makeNamedDecls("enum e : unsigned { foo = 1 };",
1114 "enum e : int { foo = 1 };", Lang_CXX11
);
1115 EXPECT_FALSE(testStructuralMatch(t
));
1118 TEST_F(StructuralEquivalenceEnumConstantTest
, EnumConstantsWithDifferentWidth
) {
1119 auto t
= makeNamedDecls("enum e : short { foo = 1 };",
1120 "enum e : int { foo = 1 };", Lang_CXX11
);
1121 EXPECT_FALSE(testStructuralMatch(t
));
1124 TEST_F(StructuralEquivalenceEnumConstantTest
, EnumConstantsWithDifferentName
) {
1126 makeDecls
<EnumConstantDecl
>("enum e { foo = 1 };", "enum e { bar = 1 };",
1127 Lang_CXX11
, enumConstantDecl());
1128 EXPECT_FALSE(testStructuralMatch(t
));
1131 struct StructuralEquivalenceObjCCategoryTest
: StructuralEquivalenceTest
{};
1133 TEST_F(StructuralEquivalenceObjCCategoryTest
, MatchinCategoryNames
) {
1134 auto t
= makeDecls
<ObjCCategoryDecl
>("@interface A @end @interface A(X) @end",
1135 "@interface A @end @interface A(X) @end",
1136 Lang_OBJC
, objcCategoryDecl());
1137 EXPECT_TRUE(testStructuralMatch(t
));
1140 TEST_F(StructuralEquivalenceObjCCategoryTest
, CategoriesForDifferentClasses
) {
1141 auto t
= makeDecls
<ObjCCategoryDecl
>("@interface A @end @interface A(X) @end",
1142 "@interface B @end @interface B(X) @end",
1143 Lang_OBJC
, objcCategoryDecl());
1144 EXPECT_FALSE(testStructuralMatch(t
));
1147 TEST_F(StructuralEquivalenceObjCCategoryTest
, CategoriesWithDifferentNames
) {
1148 auto t
= makeDecls
<ObjCCategoryDecl
>("@interface A @end @interface A(X) @end",
1149 "@interface A @end @interface A(Y) @end",
1150 Lang_OBJC
, objcCategoryDecl());
1151 EXPECT_FALSE(testStructuralMatch(t
));
1154 TEST_F(StructuralEquivalenceObjCCategoryTest
, CategoriesWithoutInterfaces
) {
1155 auto t
= makeDecls
<ObjCCategoryDecl
>(" @interface A(X) @end",
1156 "@interface A @end @interface A(X) @end",
1157 Lang_OBJC
, objcCategoryDecl());
1158 EXPECT_FALSE(testStructuralMatch(t
));
1160 auto t2
= makeDecls
<ObjCCategoryDecl
>("@interface A(X) @end",
1161 "@interface A(X) @end",
1162 Lang_OBJC
, objcCategoryDecl());
1163 EXPECT_TRUE(testStructuralMatch(t2
));
1166 TEST_F(StructuralEquivalenceObjCCategoryTest
, CategoryAndExtension
) {
1167 auto t
= makeDecls
<ObjCCategoryDecl
>("@interface A @end @interface A(X) @end",
1168 "@interface A @end @interface A() @end",
1169 Lang_OBJC
, objcCategoryDecl());
1170 EXPECT_FALSE(testStructuralMatch(t
));
1173 TEST_F(StructuralEquivalenceObjCCategoryTest
, MatchingProtocols
) {
1174 auto t
= makeDecls
<ObjCCategoryDecl
>(
1175 "@protocol P @end @interface A @end @interface A(X)<P> @end",
1176 "@protocol P @end @interface A @end @interface A(X)<P> @end", Lang_OBJC
,
1177 objcCategoryDecl());
1178 EXPECT_TRUE(testStructuralMatch(t
));
1181 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentProtocols
) {
1182 auto t
= makeDecls
<ObjCCategoryDecl
>(
1183 "@protocol P @end @interface A @end @interface A(X)<P> @end",
1184 "@protocol Q @end @interface A @end @interface A(X)<Q> @end", Lang_OBJC
,
1185 objcCategoryDecl());
1186 EXPECT_FALSE(testStructuralMatch(t
));
1189 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentProtocolsOrder
) {
1190 auto t
= makeDecls
<ObjCCategoryDecl
>(
1191 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<P, "
1193 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<Q, "
1195 Lang_OBJC
, objcCategoryDecl());
1196 EXPECT_FALSE(testStructuralMatch(t
));
1199 TEST_F(StructuralEquivalenceObjCCategoryTest
, MatchingIvars
) {
1200 auto t
= makeDecls
<ObjCCategoryDecl
>(
1201 "@interface A @end @interface A() { int x; } @end",
1202 "@interface A @end @interface A() { int x; } @end", Lang_OBJC
,
1203 objcCategoryDecl());
1204 EXPECT_TRUE(testStructuralMatch(t
));
1207 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentIvarName
) {
1208 auto t
= makeDecls
<ObjCCategoryDecl
>(
1209 "@interface A @end @interface A() { int x; } @end",
1210 "@interface A @end @interface A() { int y; } @end", Lang_OBJC
,
1211 objcCategoryDecl());
1212 EXPECT_FALSE(testStructuralMatch(t
));
1215 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentIvarType
) {
1216 auto t
= makeDecls
<ObjCCategoryDecl
>(
1217 "@interface A @end @interface A() { int x; } @end",
1218 "@interface A @end @interface A() { float x; } @end", Lang_OBJC
,
1219 objcCategoryDecl());
1220 EXPECT_FALSE(testStructuralMatch(t
));
1223 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentIvarBitfieldWidth
) {
1224 auto t
= makeDecls
<ObjCCategoryDecl
>(
1225 "@interface A @end @interface A() { int x: 1; } @end",
1226 "@interface A @end @interface A() { int x: 2; } @end", Lang_OBJC
,
1227 objcCategoryDecl());
1228 EXPECT_FALSE(testStructuralMatch(t
));
1231 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentIvarVisibility
) {
1232 auto t
= makeDecls
<ObjCCategoryDecl
>(
1233 "@interface A @end @interface A() { @public int x; } @end",
1234 "@interface A @end @interface A() { @protected int x; } @end", Lang_OBJC
,
1235 objcCategoryDecl());
1236 EXPECT_FALSE(testStructuralMatch(t
));
1239 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentIvarNumber
) {
1240 auto t
= makeDecls
<ObjCCategoryDecl
>(
1241 "@interface A @end @interface A() { int x; } @end",
1242 "@interface A @end @interface A() {} @end", Lang_OBJC
,
1243 objcCategoryDecl());
1244 EXPECT_FALSE(testStructuralMatch(t
));
1247 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentIvarOrder
) {
1248 auto t
= makeDecls
<ObjCCategoryDecl
>(
1249 "@interface A @end @interface A() { int x; int y; } @end",
1250 "@interface A @end @interface A() { int y; int x; } @end", Lang_OBJC
,
1251 objcCategoryDecl());
1252 EXPECT_FALSE(testStructuralMatch(t
));
1255 TEST_F(StructuralEquivalenceObjCCategoryTest
, MatchingMethods
) {
1256 auto t
= makeDecls
<ObjCCategoryDecl
>(
1257 "@interface A @end @interface A(X) -(void)test; @end",
1258 "@interface A @end @interface A(X) -(void)test; @end", Lang_OBJC
,
1259 objcCategoryDecl());
1260 EXPECT_TRUE(testStructuralMatch(t
));
1263 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentMethodName
) {
1264 auto t
= makeDecls
<ObjCCategoryDecl
>(
1265 "@interface A @end @interface A(X) -(void)test; @end",
1266 "@interface A @end @interface A(X) -(void)wasd; @end", Lang_OBJC
,
1267 objcCategoryDecl());
1268 EXPECT_FALSE(testStructuralMatch(t
));
1270 auto t2
= makeDecls
<ObjCCategoryDecl
>(
1271 "@interface A @end @interface A(X) -(void)test:(int)x more:(int)y; @end",
1272 "@interface A @end @interface A(X) -(void)test:(int)x :(int)y; @end",
1273 Lang_OBJC
, objcCategoryDecl());
1274 EXPECT_FALSE(testStructuralMatch(t2
));
1277 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentMethodClassInstance
) {
1278 auto t
= makeDecls
<ObjCCategoryDecl
>(
1279 "@interface A @end @interface A(X) -(void)test; @end",
1280 "@interface A @end @interface A(X) +(void)test; @end", Lang_OBJC
,
1281 objcCategoryDecl());
1282 EXPECT_FALSE(testStructuralMatch(t
));
1285 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentMethodReturnType
) {
1286 auto t
= makeDecls
<ObjCCategoryDecl
>(
1287 "@interface A @end @interface A(X) -(void)test; @end",
1288 "@interface A @end @interface A(X) -(int)test; @end", Lang_OBJC
,
1289 objcCategoryDecl());
1290 EXPECT_FALSE(testStructuralMatch(t
));
1293 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentMethodParameterType
) {
1294 auto t
= makeDecls
<ObjCCategoryDecl
>(
1295 "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1296 "@interface A @end @interface A(X) -(void)test:(float)x; @end", Lang_OBJC
,
1297 objcCategoryDecl());
1298 EXPECT_FALSE(testStructuralMatch(t
));
1301 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentMethodParameterName
) {
1302 auto t
= makeDecls
<ObjCCategoryDecl
>(
1303 "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1304 "@interface A @end @interface A(X) -(void)test:(int)y; @end", Lang_OBJC
,
1305 objcCategoryDecl());
1306 EXPECT_TRUE(testStructuralMatch(t
));
1309 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentMethodNumber
) {
1310 auto t
= makeDecls
<ObjCCategoryDecl
>(
1311 "@interface A @end @interface A(X) -(void)test; @end",
1312 "@interface A @end @interface A(X) @end", Lang_OBJC
, objcCategoryDecl());
1313 EXPECT_FALSE(testStructuralMatch(t
));
1316 TEST_F(StructuralEquivalenceObjCCategoryTest
, DifferentMethodOrder
) {
1317 auto t
= makeDecls
<ObjCCategoryDecl
>(
1318 "@interface A @end @interface A(X) -(void)u; -(void)v; @end",
1319 "@interface A @end @interface A(X) -(void)v; -(void)u; @end", Lang_OBJC
,
1320 objcCategoryDecl());
1321 EXPECT_FALSE(testStructuralMatch(t
));
1324 struct StructuralEquivalenceTemplateTest
: StructuralEquivalenceTest
{};
1326 TEST_F(StructuralEquivalenceTemplateTest
, ExactlySameTemplates
) {
1327 auto t
= makeNamedDecls("template <class T> struct foo;",
1328 "template <class T> struct foo;", Lang_CXX03
);
1329 EXPECT_TRUE(testStructuralMatch(t
));
1332 TEST_F(StructuralEquivalenceTemplateTest
, DifferentTemplateArgName
) {
1333 auto t
= makeNamedDecls("template <class T> struct foo;",
1334 "template <class U> struct foo;", Lang_CXX03
);
1335 EXPECT_TRUE(testStructuralMatch(t
));
1338 TEST_F(StructuralEquivalenceTemplateTest
, DifferentTemplateArgKind
) {
1339 auto t
= makeNamedDecls("template <class T> struct foo;",
1340 "template <int T> struct foo;", Lang_CXX03
);
1341 EXPECT_FALSE(testStructuralMatch(t
));
1344 TEST_F(StructuralEquivalenceTemplateTest
, BitFieldDecl
) {
1345 const char *Code
= "class foo { int a : 2; };";
1346 auto t
= makeNamedDecls(Code
, Code
, Lang_CXX03
);
1347 EXPECT_TRUE(testStructuralMatch(t
));
1350 TEST_F(StructuralEquivalenceTemplateTest
, BitFieldDeclDifferentWidth
) {
1351 auto t
= makeNamedDecls("class foo { int a : 2; };",
1352 "class foo { int a : 4; };", Lang_CXX03
);
1353 EXPECT_FALSE(testStructuralMatch(t
));
1356 TEST_F(StructuralEquivalenceTemplateTest
, DependentBitFieldDecl
) {
1357 const char *Code
= "template <class T> class foo { int a : sizeof(T); };";
1358 auto t
= makeNamedDecls(Code
, Code
, Lang_CXX03
);
1359 EXPECT_TRUE(testStructuralMatch(t
));
1362 TEST_F(StructuralEquivalenceTemplateTest
, DependentBitFieldDeclDifferentVal
) {
1363 auto t
= makeNamedDecls(
1364 "template <class A, class B> class foo { int a : sizeof(A); };",
1365 "template <class A, class B> class foo { int a : sizeof(B); };",
1367 EXPECT_FALSE(testStructuralMatch(t
));
1370 TEST_F(StructuralEquivalenceTemplateTest
, DependentBitFieldDeclDifferentVal2
) {
1371 auto t
= makeNamedDecls(
1372 "template <class A> class foo { int a : sizeof(A); };",
1373 "template <class A> class foo { int a : sizeof(A) + 1; };", Lang_CXX03
);
1374 EXPECT_FALSE(testStructuralMatch(t
));
1377 TEST_F(StructuralEquivalenceTemplateTest
, ExplicitBoolSame
) {
1378 auto Decls
= makeNamedDecls(
1379 "template <bool b> struct foo {explicit(b) foo(int);};",
1380 "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX20
);
1381 CXXConstructorDecl
*First
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
1382 get
<0>(Decls
), cxxConstructorDecl(hasName("foo<b>")));
1383 CXXConstructorDecl
*Second
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
1384 get
<1>(Decls
), cxxConstructorDecl(hasName("foo<b>")));
1385 EXPECT_TRUE(testStructuralMatch(First
, Second
));
1388 TEST_F(StructuralEquivalenceTemplateTest
, ExplicitBoolDifference
) {
1389 auto Decls
= makeNamedDecls(
1390 "template <bool b> struct foo {explicit(b) foo(int);};",
1391 "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX20
);
1392 CXXConstructorDecl
*First
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
1393 get
<0>(Decls
), cxxConstructorDecl(hasName("foo<b>")));
1394 CXXConstructorDecl
*Second
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
1395 get
<1>(Decls
), cxxConstructorDecl(hasName("foo<b>")));
1396 EXPECT_FALSE(testStructuralMatch(First
, Second
));
1399 TEST_F(StructuralEquivalenceTemplateTest
,
1400 TemplateVsSubstTemplateTemplateParmInArgEq
) {
1401 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1403 template <typename P1> class Arg { };
1404 template <template <typename PP1> class P1> class Primary { };
1407 // Make specialization with simple template.
1412 template <typename P1> class Arg { };
1413 template <template <typename PP1> class P1> class Primary { };
1415 template <template <typename PP1> class P1> class Templ {
1417 // Make specialization with substituted template template param.
1422 // Instantiate with substitution Arg into P1.
1423 template class Templ <Arg>;
1425 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1426 EXPECT_TRUE(testStructuralMatch(t
));
1429 TEST_F(StructuralEquivalenceTemplateTest
,
1430 TemplateVsSubstTemplateTemplateParmInArgNotEq
) {
1431 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1433 template <typename P1> class Arg { };
1434 template <template <typename PP1> class P1> class Primary { };
1437 // Make specialization with simple template.
1442 // Arg is different from the other, this should cause non-equivalence.
1443 template <typename P1> class Arg { int X; };
1444 template <template <typename PP1> class P1> class Primary { };
1446 template <template <typename PP1> class P1> class Templ {
1448 // Make specialization with substituted template template param.
1453 // Instantiate with substitution Arg into P1.
1454 template class Templ <Arg>;
1456 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1457 EXPECT_FALSE(testStructuralMatch(t
));
1460 struct StructuralEquivalenceDependentTemplateArgsTest
1461 : StructuralEquivalenceTemplateTest
{};
1463 TEST_F(StructuralEquivalenceDependentTemplateArgsTest
,
1464 SameStructsInDependentArgs
) {
1475 template <typename T, typename enable_if<S1<T>>::type>
1479 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
, Code
, Lang_CXX11
,
1480 functionTemplateDecl(hasName("f")));
1481 EXPECT_TRUE(testStructuralMatch(t
));
1484 TEST_F(StructuralEquivalenceDependentTemplateArgsTest
,
1485 DifferentStructsInDependentArgs
) {
1497 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
+ R
"(
1500 template <typename T, typename enable_if<S1<T>>::type>
1507 template <typename T, typename enable_if<S2<T>>::type>
1512 functionTemplateDecl(hasName("f")));
1513 EXPECT_FALSE(testStructuralMatch(t
));
1516 TEST_F(StructuralEquivalenceDependentTemplateArgsTest
,
1517 SameStructsInDependentScopeDeclRefExpr
) {
1528 template <typename T, typename enable_if<S1<T>::value>::type>
1529 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1532 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
, Code
, Lang_CXX11
,
1533 functionTemplateDecl(hasName("f")));
1534 EXPECT_TRUE(testStructuralMatch(t
));
1537 TEST_F(StructuralEquivalenceDependentTemplateArgsTest
,
1538 DifferentStructsInDependentScopeDeclRefExpr
) {
1550 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
+ R
"(
1553 template <typename T, typename enable_if<S1<T>::value>::type>
1554 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1560 template <typename T, typename enable_if<S2<T>::value>::type>
1565 functionTemplateDecl(hasName("f")));
1566 EXPECT_FALSE(testStructuralMatch(t
));
1569 TEST_F(StructuralEquivalenceDependentTemplateArgsTest
,
1570 DifferentValueInDependentScopeDeclRefExpr
) {
1579 auto t
= makeDecls
<FunctionTemplateDecl
>(Code
+ R
"(
1582 template <typename T, typename enable_if<S1<T>::value1>::type>
1583 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1589 template <typename T, typename enable_if<S1<T>::value2>::type>
1594 functionTemplateDecl(hasName("f")));
1595 EXPECT_FALSE(testStructuralMatch(t
));
1599 StructuralEquivalenceTemplateTest
,
1600 ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual
) {
1601 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1603 template <class T> struct Primary {};
1607 // Explicit instantiation with qualified name.
1608 template struct Primary<N::Arg>;
1611 template <class T> struct Primary {};
1616 // Explicit instantiation with UNqualified name.
1617 template struct Primary<Arg>;
1619 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1620 EXPECT_TRUE(testStructuralMatch(t
));
1624 StructuralEquivalenceTemplateTest
,
1625 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs
) {
1626 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1628 template <class T> struct Primary {};
1630 struct Arg { int a; };
1632 // Explicit instantiation with qualified name.
1633 template struct Primary<N::Arg>;
1636 template <class T> struct Primary {};
1638 // This struct is not equivalent with the other in the prev TU.
1639 struct Arg { double b; }; // -- Field mismatch.
1642 // Explicit instantiation with UNqualified name.
1643 template struct Primary<Arg>;
1645 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1646 EXPECT_FALSE(testStructuralMatch(t
));
1650 StructuralEquivalenceTemplateTest
,
1651 ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual
) {
1652 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1654 template <template <class> class T> struct Primary {};
1656 template <class T> struct Arg;
1658 // Explicit instantiation with qualified name.
1659 template struct Primary<N::Arg>;
1662 template <template <class> class T> struct Primary {};
1664 template <class T> struct Arg;
1667 // Explicit instantiation with UNqualified name.
1668 template struct Primary<Arg>;
1670 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1671 EXPECT_TRUE(testStructuralMatch(t
));
1675 StructuralEquivalenceTemplateTest
,
1676 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs
) {
1677 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1679 template <template <class> class T> struct Primary {};
1681 template <class T> struct Arg { int a; };
1683 // Explicit instantiation with qualified name.
1684 template struct Primary<N::Arg>;
1687 template <template <class> class T> struct Primary {};
1689 // This template is not equivalent with the other in the prev TU.
1690 template <class T> struct Arg { double b; }; // -- Field mismatch.
1693 // Explicit instantiation with UNqualified name.
1694 template struct Primary<Arg>;
1696 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1697 EXPECT_FALSE(testStructuralMatch(t
));
1700 TEST_F(StructuralEquivalenceTemplateTest
,
1701 IgnoreTemplateParmDepthAtTemplateTypeParmDecl
) {
1702 auto Decls
= makeDecls
<ClassTemplateDecl
>(
1704 template<class> struct A;
1707 template<class> struct S {
1708 template<class> friend struct A;
1711 Lang_CXX03
, classTemplateDecl(hasName("A")),
1712 classTemplateDecl(hasName("A")));
1713 EXPECT_TRUE(testStructuralMatch(Decls
));
1714 EXPECT_TRUE(testStructuralMatch(Decls
, true));
1717 TEST_F(StructuralEquivalenceTemplateTest
,
1718 IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl
) {
1719 auto Decls
= makeDecls
<ClassTemplateDecl
>(
1721 template<class T, T U> struct A;
1724 template<class T> struct S {
1725 template<class P, P Q> friend struct A;
1728 Lang_CXX03
, classTemplateDecl(hasName("A")),
1729 classTemplateDecl(hasName("A")));
1730 EXPECT_FALSE(testStructuralMatch(Decls
));
1731 EXPECT_TRUE(testStructuralMatch(Decls
, /*IgnoreTemplateParmDepth=*/true));
1735 StructuralEquivalenceTemplateTest
,
1736 ClassTemplSpecWithInequivalentShadowedTemplArg
) {
1737 auto t
= makeDecls
<ClassTemplateSpecializationDecl
>(
1739 template <template <class> class T> struct Primary {};
1740 template <class T> struct Arg { int a; };
1741 // Explicit instantiation with ::Arg
1742 template struct Primary<Arg>;
1745 template <template <class> class T> struct Primary {};
1746 template <class T> struct Arg { int a; };
1748 // This template is not equivalent with the other in the global scope.
1749 template <class T> struct Arg { double b; }; // -- Field mismatch.
1750 // Explicit instantiation with N::Arg which shadows ::Arg
1751 template struct Primary<Arg>;
1754 Lang_CXX03
, classTemplateSpecializationDecl(hasName("Primary")));
1755 EXPECT_FALSE(testStructuralMatch(t
));
1757 struct StructuralEquivalenceCacheTest
: public StructuralEquivalenceTest
{
1758 llvm::DenseSet
<std::pair
<Decl
*, Decl
*>> NonEquivalentDecls
;
1760 template <typename NodeType
, typename MatcherType
>
1761 std::pair
<NodeType
*, NodeType
*>
1762 findDeclPair(std::tuple
<TranslationUnitDecl
*, TranslationUnitDecl
*> TU
,
1764 NodeType
*D0
= FirstDeclMatcher
<NodeType
>().match(get
<0>(TU
), M
);
1765 NodeType
*D1
= FirstDeclMatcher
<NodeType
>().match(get
<1>(TU
), M
);
1769 template <typename NodeType
>
1770 bool isInNonEqCache(std::pair
<NodeType
*, NodeType
*> D
) {
1771 return NonEquivalentDecls
.count(D
) > 0;
1775 TEST_F(StructuralEquivalenceCacheTest
, SimpleNonEq
) {
1776 auto TU
= makeTuDecls(
1789 StructuralEquivalenceContext
Ctx(
1790 get
<0>(TU
)->getASTContext(), get
<1>(TU
)->getASTContext(),
1791 NonEquivalentDecls
, StructuralEquivalenceKind::Default
, false, false);
1793 auto X
= findDeclPair
<FunctionDecl
>(TU
, functionDecl(hasName("x")));
1794 EXPECT_FALSE(Ctx
.IsEquivalent(X
.first
, X
.second
));
1796 EXPECT_FALSE(isInNonEqCache(findDeclPair
<CXXRecordDecl
>(
1797 TU
, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1798 EXPECT_FALSE(isInNonEqCache(findDeclPair
<CXXRecordDecl
>(
1799 TU
, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1802 TEST_F(StructuralEquivalenceCacheTest
, ReturnStmtNonEq
) {
1803 auto TU
= makeTuDecls(
1805 bool x() { return true; }
1808 bool x() { return false; }
1812 StructuralEquivalenceContext
Ctx(
1813 get
<0>(TU
)->getASTContext(), get
<1>(TU
)->getASTContext(),
1814 NonEquivalentDecls
, StructuralEquivalenceKind::Default
, false, false);
1816 auto X
= findDeclPair
<FunctionDecl
>(TU
, functionDecl(hasName("x")));
1817 EXPECT_FALSE(Ctx
.IsEquivalent(X
.first
->getBody(), X
.second
->getBody()));
1821 TEST_F(StructuralEquivalenceCacheTest
, VarDeclNoEq
) {
1822 auto TU
= makeTuDecls(
1831 StructuralEquivalenceContext
Ctx(
1832 get
<0>(TU
)->getASTContext(), get
<1>(TU
)->getASTContext(),
1833 NonEquivalentDecls
, StructuralEquivalenceKind::Default
, false, false);
1835 auto Var
= findDeclPair
<VarDecl
>(TU
, varDecl());
1836 EXPECT_FALSE(Ctx
.IsEquivalent(Var
.first
, Var
.second
));
1839 TEST_F(StructuralEquivalenceCacheTest
, VarDeclWithDifferentStorageClassNoEq
) {
1840 auto TU
= makeTuDecls(
1849 StructuralEquivalenceContext
Ctx(
1850 get
<0>(TU
)->getASTContext(), get
<1>(TU
)->getASTContext(),
1851 NonEquivalentDecls
, StructuralEquivalenceKind::Default
, false, false);
1853 auto Var
= findDeclPair
<VarDecl
>(TU
, varDecl());
1854 EXPECT_FALSE(Ctx
.IsEquivalent(Var
.first
, Var
.second
));
1857 TEST_F(StructuralEquivalenceCacheTest
, VarDeclWithInitNoEq
) {
1858 auto TU
= makeTuDecls(
1867 StructuralEquivalenceContext
Ctx(
1868 get
<0>(TU
)->getASTContext(), get
<1>(TU
)->getASTContext(),
1869 NonEquivalentDecls
, StructuralEquivalenceKind::Default
, false, false);
1871 auto Var
= findDeclPair
<VarDecl
>(TU
, varDecl());
1872 EXPECT_FALSE(Ctx
.IsEquivalent(Var
.first
, Var
.second
));
1875 TEST_F(StructuralEquivalenceCacheTest
, SpecialNonEq
) {
1876 auto TU
= makeTuDecls(
1899 StructuralEquivalenceContext
Ctx(
1900 get
<0>(TU
)->getASTContext(), get
<1>(TU
)->getASTContext(),
1901 NonEquivalentDecls
, StructuralEquivalenceKind::Default
, false, false);
1903 auto C
= findDeclPair
<CXXRecordDecl
>(
1904 TU
, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1905 EXPECT_FALSE(Ctx
.IsEquivalent(C
.first
, C
.second
));
1907 EXPECT_FALSE(isInNonEqCache(C
));
1908 EXPECT_FALSE(isInNonEqCache(findDeclPair
<CXXRecordDecl
>(
1909 TU
, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1910 EXPECT_FALSE(isInNonEqCache(findDeclPair
<CXXRecordDecl
>(
1911 TU
, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1912 EXPECT_FALSE(isInNonEqCache(
1913 findDeclPair
<FunctionDecl
>(TU
, functionDecl(hasName("x")))));
1914 EXPECT_FALSE(isInNonEqCache(
1915 findDeclPair
<FunctionDecl
>(TU
, functionDecl(hasName("y")))));
1918 TEST_F(StructuralEquivalenceCacheTest
, Cycle
) {
1919 auto TU
= makeTuDecls(
1938 StructuralEquivalenceContext
Ctx(
1939 get
<0>(TU
)->getASTContext(), get
<1>(TU
)->getASTContext(),
1940 NonEquivalentDecls
, StructuralEquivalenceKind::Default
, false, false);
1942 auto C
= findDeclPair
<CXXRecordDecl
>(
1943 TU
, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1944 EXPECT_TRUE(Ctx
.IsEquivalent(C
.first
, C
.second
));
1946 EXPECT_FALSE(isInNonEqCache(C
));
1947 EXPECT_FALSE(isInNonEqCache(findDeclPair
<CXXRecordDecl
>(
1948 TU
, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1949 EXPECT_FALSE(isInNonEqCache(
1950 findDeclPair
<FunctionDecl
>(TU
, functionDecl(hasName("x")))));
1953 struct StructuralEquivalenceStmtTest
: StructuralEquivalenceTest
{};
1955 /// Fallback matcher to be used only when there is no specific matcher for a
1956 /// Expr subclass. Remove this once all Expr subclasses have their own matcher.
1957 static auto &fallbackExprMatcher
= expr
;
1959 TEST_F(StructuralEquivalenceStmtTest
, AddrLabelExpr
) {
1960 auto t
= makeWrappedStmts("lbl: &&lbl;", "lbl: &&lbl;", Lang_CXX03
,
1962 EXPECT_TRUE(testStructuralMatch(t
));
1965 TEST_F(StructuralEquivalenceStmtTest
, AddrLabelExprDifferentLabel
) {
1966 auto t
= makeWrappedStmts("lbl1: lbl2: &&lbl1;", "lbl1: lbl2: &&lbl2;",
1967 Lang_CXX03
, addrLabelExpr());
1968 // FIXME: Should be false. LabelDecl are incorrectly matched.
1969 EXPECT_TRUE(testStructuralMatch(t
));
1972 static const std::string MemoryOrderSrc
= R
"(
1974 memory_order_relaxed,
1975 memory_order_consume,
1976 memory_order_acquire,
1977 memory_order_release,
1978 memory_order_acq_rel,
1979 memory_order_seq_cst
1983 TEST_F(StructuralEquivalenceStmtTest
, AtomicExpr
) {
1984 std::string Prefix
= "char a, b; " + MemoryOrderSrc
;
1987 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
1989 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
1990 Lang_CXX03
, atomicExpr());
1991 EXPECT_TRUE(testStructuralMatch(t
));
1994 TEST_F(StructuralEquivalenceStmtTest
, AtomicExprDifferentOp
) {
1995 std::string Prefix
= "char a, b; " + MemoryOrderSrc
;
1998 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2000 "void wrapped() { __atomic_store(&a, &b, memory_order_seq_cst); }",
2001 Lang_CXX03
, atomicExpr());
2002 EXPECT_FALSE(testStructuralMatch(t
));
2005 TEST_F(StructuralEquivalenceStmtTest
, BinaryOperator
) {
2006 auto t
= makeWrappedStmts("1 + 1", "1 + 1", Lang_CXX03
, binaryOperator());
2007 EXPECT_TRUE(testStructuralMatch(t
));
2010 TEST_F(StructuralEquivalenceStmtTest
, BinaryOperatorDifferentOps
) {
2011 auto t
= makeWrappedStmts("1 + 1", "1 - 1", Lang_CXX03
, binaryOperator());
2012 EXPECT_FALSE(testStructuralMatch(t
));
2015 TEST_F(StructuralEquivalenceStmtTest
, CallExpr
) {
2016 std::string Src
= "int call(); int wrapped() { call(); }";
2017 auto t
= makeStmts(Src
, Src
, Lang_CXX03
, callExpr());
2018 EXPECT_TRUE(testStructuralMatch(t
));
2021 TEST_F(StructuralEquivalenceStmtTest
, CallExprDifferentCallee
) {
2022 std::string FunctionSrc
= "int func1(); int func2();\n";
2023 auto t
= makeStmts(FunctionSrc
+ "void wrapper() { func1(); }",
2024 FunctionSrc
+ "void wrapper() { func2(); }", Lang_CXX03
,
2026 EXPECT_FALSE(testStructuralMatch(t
));
2029 TEST_F(StructuralEquivalenceStmtTest
, CharacterLiteral
) {
2030 auto t
= makeWrappedStmts("'a'", "'a'", Lang_CXX03
, characterLiteral());
2031 EXPECT_TRUE(testStructuralMatch(t
));
2034 TEST_F(StructuralEquivalenceStmtTest
, CharacterLiteralDifferentValues
) {
2035 auto t
= makeWrappedStmts("'a'", "'b'", Lang_CXX03
, characterLiteral());
2036 EXPECT_FALSE(testStructuralMatch(t
));
2039 TEST_F(StructuralEquivalenceStmtTest
, ExpressionTraitExpr
) {
2040 auto t
= makeWrappedStmts("__is_lvalue_expr(1)", "__is_lvalue_expr(1)",
2041 Lang_CXX03
, fallbackExprMatcher());
2042 EXPECT_TRUE(testStructuralMatch(t
));
2045 TEST_F(StructuralEquivalenceStmtTest
, ExpressionTraitExprDifferentKind
) {
2046 auto t
= makeWrappedStmts("__is_lvalue_expr(1)", "__is_rvalue_expr(1)",
2047 Lang_CXX03
, fallbackExprMatcher());
2048 EXPECT_FALSE(testStructuralMatch(t
));
2051 TEST_F(StructuralEquivalenceStmtTest
, FloatingLiteral
) {
2052 auto t
= makeWrappedStmts("1.0", "1.0", Lang_CXX03
, fallbackExprMatcher());
2053 EXPECT_TRUE(testStructuralMatch(t
));
2056 TEST_F(StructuralEquivalenceStmtTest
, FloatingLiteralDifferentSpelling
) {
2057 auto t
= makeWrappedStmts("0x10.1p0", "16.0625", Lang_CXX17
,
2058 fallbackExprMatcher());
2059 // Same value but with different spelling is equivalent.
2060 EXPECT_TRUE(testStructuralMatch(t
));
2063 TEST_F(StructuralEquivalenceStmtTest
, FloatingLiteralDifferentType
) {
2064 auto t
= makeWrappedStmts("1.0", "1.0f", Lang_CXX03
, fallbackExprMatcher());
2065 EXPECT_FALSE(testStructuralMatch(t
));
2068 TEST_F(StructuralEquivalenceStmtTest
, FloatingLiteralDifferentValue
) {
2069 auto t
= makeWrappedStmts("1.01", "1.0", Lang_CXX03
, fallbackExprMatcher());
2070 EXPECT_FALSE(testStructuralMatch(t
));
2073 TEST_F(StructuralEquivalenceStmtTest
, GenericSelectionExprSame
) {
2074 auto t
= makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2075 "_Generic(0u, unsigned int: 0, float: 1)", Lang_C99
,
2076 genericSelectionExpr());
2077 EXPECT_TRUE(testStructuralMatch(t
));
2080 TEST_F(StructuralEquivalenceStmtTest
, GenericSelectionExprSignsDiffer
) {
2081 auto t
= makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2082 "_Generic(0, int: 0, float: 1)", Lang_C99
,
2083 genericSelectionExpr());
2084 EXPECT_FALSE(testStructuralMatch(t
));
2087 TEST_F(StructuralEquivalenceStmtTest
, GenericSelectionExprOrderDiffers
) {
2088 auto t
= makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2089 "_Generic(0u, float: 1, unsigned int: 0)", Lang_C99
,
2090 genericSelectionExpr());
2091 EXPECT_FALSE(testStructuralMatch(t
));
2094 TEST_F(StructuralEquivalenceStmtTest
, GenericSelectionExprDependentResultSame
) {
2097 template <typename T>
2100 (void)_Generic(x, int: 0, float: 1);
2102 void g() { f<int>(); }
2105 template <typename T>
2108 (void)_Generic(x, int: 0, float: 1);
2110 void g() { f<int>(); }
2112 Lang_CXX03
, genericSelectionExpr());
2113 EXPECT_TRUE(testStructuralMatch(t
));
2116 TEST_F(StructuralEquivalenceStmtTest
,
2117 GenericSelectionExprDependentResultOrderDiffers
) {
2120 template <typename T>
2123 (void)_Generic(x, float: 1, int: 0);
2125 void g() { f<int>(); }
2128 template <typename T>
2131 (void)_Generic(x, int: 0, float: 1);
2133 void g() { f<int>(); }
2135 Lang_CXX03
, genericSelectionExpr());
2137 EXPECT_FALSE(testStructuralMatch(t
));
2139 TEST_F(StructuralEquivalenceStmtTest
, IntegerLiteral
) {
2140 auto t
= makeWrappedStmts("1", "1", Lang_CXX03
, integerLiteral());
2141 EXPECT_TRUE(testStructuralMatch(t
));
2144 TEST_F(StructuralEquivalenceStmtTest
, IntegerLiteralDifferentSpelling
) {
2145 auto t
= makeWrappedStmts("1", "0x1", Lang_CXX03
, integerLiteral());
2146 // Same value but with different spelling is equivalent.
2147 EXPECT_TRUE(testStructuralMatch(t
));
2150 TEST_F(StructuralEquivalenceStmtTest
, IntegerLiteralDifferentValue
) {
2151 auto t
= makeWrappedStmts("1", "2", Lang_CXX03
, integerLiteral());
2152 EXPECT_FALSE(testStructuralMatch(t
));
2155 TEST_F(StructuralEquivalenceStmtTest
, IntegerLiteralDifferentTypes
) {
2156 auto t
= makeWrappedStmts("1", "1L", Lang_CXX03
, integerLiteral());
2157 EXPECT_FALSE(testStructuralMatch(t
));
2160 TEST_F(StructuralEquivalenceStmtTest
, MemberExpr
) {
2161 std::string ClassSrc
= "struct C { int a; int b; };";
2162 auto t
= makeStmts(ClassSrc
+ "int wrapper() { C c; return c.a; }",
2163 ClassSrc
+ "int wrapper() { C c; return c.a; }",
2164 Lang_CXX03
, memberExpr());
2165 EXPECT_TRUE(testStructuralMatch(t
));
2168 TEST_F(StructuralEquivalenceStmtTest
, MemberExprDifferentMember
) {
2169 std::string ClassSrc
= "struct C { int a; int b; };";
2170 auto t
= makeStmts(ClassSrc
+ "int wrapper() { C c; return c.a; }",
2171 ClassSrc
+ "int wrapper() { C c; return c.b; }",
2172 Lang_CXX03
, memberExpr());
2173 EXPECT_FALSE(testStructuralMatch(t
));
2176 TEST_F(StructuralEquivalenceStmtTest
, ObjCStringLiteral
) {
2178 makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX
, fallbackExprMatcher());
2179 EXPECT_TRUE(testStructuralMatch(t
));
2182 TEST_F(StructuralEquivalenceStmtTest
, ObjCStringLiteralDifferentContent
) {
2184 makeWrappedStmts("@\"a\"", "@\"b\"", Lang_OBJCXX
, fallbackExprMatcher());
2185 EXPECT_FALSE(testStructuralMatch(t
));
2188 TEST_F(StructuralEquivalenceStmtTest
, StringLiteral
) {
2189 auto t
= makeWrappedStmts("\"a\"", "\"a\"", Lang_CXX03
, stringLiteral());
2190 EXPECT_TRUE(testStructuralMatch(t
));
2193 TEST_F(StructuralEquivalenceStmtTest
, StringLiteralDifferentContent
) {
2194 auto t
= makeWrappedStmts("\"a\"", "\"b\"", Lang_CXX03
, stringLiteral());
2195 EXPECT_FALSE(testStructuralMatch(t
));
2198 TEST_F(StructuralEquivalenceStmtTest
, StringLiteralDifferentLength
) {
2199 auto t
= makeWrappedStmts("\"a\"", "\"aa\"", Lang_CXX03
, stringLiteral());
2200 EXPECT_FALSE(testStructuralMatch(t
));
2203 TEST_F(StructuralEquivalenceStmtTest
, TypeTraitExpr
) {
2204 auto t
= makeWrappedStmts("__is_pod(int)", "__is_pod(int)", Lang_CXX03
,
2205 fallbackExprMatcher());
2206 EXPECT_TRUE(testStructuralMatch(t
));
2209 TEST_F(StructuralEquivalenceStmtTest
, TypeTraitExprDifferentType
) {
2210 auto t
= makeWrappedStmts("__is_pod(int)", "__is_pod(long)", Lang_CXX03
,
2211 fallbackExprMatcher());
2212 EXPECT_FALSE(testStructuralMatch(t
));
2215 TEST_F(StructuralEquivalenceStmtTest
, TypeTraitExprDifferentTrait
) {
2216 auto t
= makeWrappedStmts(
2217 "__is_pod(int)", "__is_trivially_constructible(int)", Lang_CXX03
, expr());
2218 EXPECT_FALSE(testStructuralMatch(t
));
2221 TEST_F(StructuralEquivalenceStmtTest
, TypeTraitExprDifferentTraits
) {
2222 auto t
= makeWrappedStmts("__is_constructible(int)",
2223 "__is_constructible(int, int)", Lang_CXX03
, expr());
2224 EXPECT_FALSE(testStructuralMatch(t
));
2227 TEST_F(StructuralEquivalenceStmtTest
, UnaryExprOrTypeTraitExpr
) {
2228 auto t
= makeWrappedStmts("sizeof(int)", "sizeof(int)", Lang_CXX03
,
2229 unaryExprOrTypeTraitExpr());
2230 EXPECT_TRUE(testStructuralMatch(t
));
2233 TEST_F(StructuralEquivalenceStmtTest
, UnaryExprOrTypeTraitExprDifferentKind
) {
2234 auto t
= makeWrappedStmts("sizeof(int)", "alignof(long)", Lang_CXX11
,
2235 unaryExprOrTypeTraitExpr());
2236 EXPECT_FALSE(testStructuralMatch(t
));
2239 TEST_F(StructuralEquivalenceStmtTest
, UnaryExprOrTypeTraitExprDifferentType
) {
2240 auto t
= makeWrappedStmts("sizeof(int)", "sizeof(long)", Lang_CXX03
,
2241 unaryExprOrTypeTraitExpr());
2242 EXPECT_FALSE(testStructuralMatch(t
));
2245 TEST_F(StructuralEquivalenceStmtTest
, UnaryOperator
) {
2246 auto t
= makeWrappedStmts("+1", "+1", Lang_CXX03
, unaryOperator());
2247 EXPECT_TRUE(testStructuralMatch(t
));
2250 TEST_F(StructuralEquivalenceStmtTest
, UnaryOperatorDifferentOps
) {
2251 auto t
= makeWrappedStmts("+1", "-1", Lang_CXX03
, unaryOperator());
2252 EXPECT_FALSE(testStructuralMatch(t
));
2255 TEST_F(StructuralEquivalenceStmtTest
, UnresolvedLookupDifferentName
) {
2259 template <typename T>
2263 void g() { f<int>(1); }
2267 template <typename T>
2271 void g() { f<int>(1); }
2273 Lang_CXX03
, unresolvedLookupExpr());
2274 EXPECT_FALSE(testStructuralMatch(t
));
2277 TEST_F(StructuralEquivalenceStmtTest
, UnresolvedLookupDifferentQualifier
) {
2282 static void g(char);
2285 template <typename T>
2290 void g() { f<int>(1); }
2295 static void g(char);
2298 template <typename T>
2303 void g() { f<int>(1); }
2305 Lang_CXX03
, unresolvedLookupExpr());
2306 EXPECT_FALSE(testStructuralMatch(t
));
2309 TEST_F(StructuralEquivalenceStmtTest
,
2310 UnresolvedLookupDifferentTemplateArgument
) {
2314 template<typename T1, typename T2>
2317 template <typename T>
2322 void h() { f<int>(); }
2326 template<typename T1, typename T2>
2329 template <typename T>
2334 void h() { f<int>(); }
2336 Lang_CXX03
, unresolvedLookupExpr());
2337 EXPECT_FALSE(testStructuralMatch(t
));
2340 TEST_F(StructuralEquivalenceStmtTest
, UnresolvedLookup
) {
2345 template<typename T1, typename T2>
2346 static void g(int) {};
2347 template<typename T1, typename T2>
2348 static void g(char) {};
2351 template <typename T1, typename T2>
2356 void g() { f<char, int>(1); }
2361 template<typename T1, typename T2>
2362 static void g(int) {};
2363 template<typename T1, typename T2>
2364 static void g(char) {};
2367 template <typename T1, typename T2>
2372 void g() { f<char, int>(1); }
2374 Lang_CXX03
, unresolvedLookupExpr());
2375 EXPECT_TRUE(testStructuralMatch(t
));
2378 TEST_F(StructuralEquivalenceCacheTest
, GotoStmtNoEq
) {
2392 Lang_CXX03
, gotoStmt());
2393 EXPECT_FALSE(testStructuralMatch(S
));
2396 TEST_F(StructuralEquivalenceStmtTest
, DeclRefExpr
) {
2397 std::string Prefix
= "enum Test { AAA, BBB };";
2399 Prefix
+ "void foo(int i) {if (i > 0) {i = AAA;} else {i = BBB;}}",
2400 Prefix
+ "void foo(int i) {if (i > 0) {i = BBB;} else {i = AAA;}}",
2401 Lang_CXX03
, ifStmt());
2402 EXPECT_FALSE(testStructuralMatch(t
));
2405 } // end namespace ast_matchers
2406 } // end namespace clang