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