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" 10 11 #include "DeclMatcher.h" 12 13 #include "gtest/gtest.h" 14 15 namespace clang { 16 namespace ast_matchers { 17 18 using std::get; 19 20 struct StructuralEquivalenceTest : ::testing::Test { 21 std::unique_ptr<ASTUnit> AST0, AST1; 22 std::string Code0, Code1; // Buffers for SourceManager 23 24 // Parses the source code in the specified language and sets the ASTs of 25 // the current test instance to the parse result. 26 void makeASTUnits(const std::string &SrcCode0, const std::string &SrcCode1, 27 TestLanguage Lang) { 28 this->Code0 = SrcCode0; 29 this->Code1 = SrcCode1; 30 std::vector<std::string> Args = getCommandLineArgsForTesting(Lang); 31 32 const char *const InputFileName = "input.cc"; 33 34 AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName); 35 AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName); 36 } 37 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); 47 48 NodeType *D0 = FirstDeclMatcher<NodeType>().match( 49 AST0->getASTContext().getTranslationUnitDecl(), Matcher0); 50 NodeType *D1 = FirstDeclMatcher<NodeType>().match( 51 AST1->getASTContext().getTranslationUnitDecl(), Matcher1); 52 53 return std::make_tuple(D0, D1); 54 } 55 56 std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> 57 makeTuDecls(const std::string &SrcCode0, const std::string &SrcCode1, 58 TestLanguage Lang) { 59 makeASTUnits(SrcCode0, SrcCode1, Lang); 60 61 return std::make_tuple(AST0->getASTContext().getTranslationUnitDecl(), 62 AST1->getASTContext().getTranslationUnitDecl()); 63 } 64 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); 73 } 74 75 // Get a pair of Decl pointers to the synthesized declarations from the given 76 // code snippets. We search for the first NamedDecl with given name in both 77 // snippets. 78 std::tuple<NamedDecl *, NamedDecl *> 79 makeNamedDecls(const std::string &SrcCode0, const std::string &SrcCode1, 80 TestLanguage Lang, const char *const Identifier = "foo") { 81 auto Matcher = namedDecl(hasName(Identifier)); 82 return makeDecls<NamedDecl>(SrcCode0, SrcCode1, Lang, Matcher); 83 } 84 85 // Wraps a Stmt and the ASTContext that contains it. 86 struct StmtWithASTContext { 87 Stmt *S; 88 ASTContext *Context; 89 explicit StmtWithASTContext(Stmt &S, ASTContext &Context) 90 : S(&S), Context(&Context) {} 91 explicit StmtWithASTContext(FunctionDecl *FD) 92 : S(FD->getBody()), Context(&FD->getASTContext()) {} 93 }; 94 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); 104 105 Stmt *S0 = FirstDeclMatcher<Stmt>().match( 106 AST0->getASTContext().getTranslationUnitDecl(), Matcher0); 107 Stmt *S1 = FirstDeclMatcher<Stmt>().match( 108 AST1->getASTContext().getTranslationUnitDecl(), Matcher1); 109 110 return std::make_tuple(StmtWithASTContext(*S0, AST0->getASTContext()), 111 StmtWithASTContext(*S1, AST1->getASTContext())); 112 } 113 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); 121 } 122 123 // Convenience function for makeStmts that wraps the code inside a function 124 // body. 125 template <typename MatcherType> 126 std::tuple<StmtWithASTContext, StmtWithASTContext> 127 makeWrappedStmts(const std::string &SrcCode0, const std::string &SrcCode1, 128 TestLanguage Lang, const MatcherType &AMatcher) { 129 auto Wrap = [](const std::string &Src) { 130 return "void wrapped() {" + Src + ";}"; 131 }; 132 return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher); 133 } 134 135 bool testStructuralMatch(Decl *D0, Decl *D1, 136 bool IgnoreTemplateParmDepth = false) { 137 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls01; 138 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls10; 139 StructuralEquivalenceContext Ctx01( 140 D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01, 141 StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false, 142 /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false, 143 IgnoreTemplateParmDepth); 144 StructuralEquivalenceContext Ctx10( 145 D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10, 146 StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false, 147 /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false, 148 IgnoreTemplateParmDepth); 149 bool Eq01 = Ctx01.IsEquivalent(D0, D1); 150 bool Eq10 = Ctx10.IsEquivalent(D1, D0); 151 EXPECT_EQ(Eq01, Eq10); 152 return Eq01; 153 } 154 155 bool testStructuralMatch(StmtWithASTContext S0, StmtWithASTContext S1) { 156 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls01; 157 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls10; 158 StructuralEquivalenceContext Ctx01( 159 *S0.Context, *S1.Context, NonEquivalentDecls01, 160 StructuralEquivalenceKind::Default, false, false); 161 StructuralEquivalenceContext Ctx10( 162 *S1.Context, *S0.Context, NonEquivalentDecls10, 163 StructuralEquivalenceKind::Default, false, false); 164 bool Eq01 = Ctx01.IsEquivalent(S0.S, S1.S); 165 bool Eq10 = Ctx10.IsEquivalent(S1.S, S0.S); 166 EXPECT_EQ(Eq01, Eq10); 167 return Eq01; 168 } 169 170 bool 171 testStructuralMatch(std::tuple<StmtWithASTContext, StmtWithASTContext> t) { 172 return testStructuralMatch(get<0>(t), get<1>(t)); 173 } 174 175 bool testStructuralMatch(std::tuple<Decl *, Decl *> t, 176 bool IgnoreTemplateParmDepth = false) { 177 return testStructuralMatch(get<0>(t), get<1>(t), IgnoreTemplateParmDepth); 178 } 179 }; 180 181 TEST_F(StructuralEquivalenceTest, Int) { 182 auto Decls = makeNamedDecls("int foo;", "int foo;", Lang_CXX03); 183 EXPECT_TRUE(testStructuralMatch(Decls)); 184 } 185 186 TEST_F(StructuralEquivalenceTest, IntVsSignedInt) { 187 auto Decls = makeNamedDecls("int foo;", "signed int foo;", Lang_CXX03); 188 EXPECT_TRUE(testStructuralMatch(Decls)); 189 } 190 191 TEST_F(StructuralEquivalenceTest, Char) { 192 auto Decls = makeNamedDecls("char foo;", "char foo;", Lang_CXX03); 193 EXPECT_TRUE(testStructuralMatch(Decls)); 194 } 195 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)); 201 } 202 203 TEST_F(StructuralEquivalenceTest, ForwardRecordDecl) { 204 auto Decls = makeNamedDecls("struct foo;", "struct foo;", Lang_CXX03); 205 EXPECT_TRUE(testStructuralMatch(Decls)); 206 } 207 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)); 212 } 213 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)); 218 } 219 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)); 228 } 229 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)); 238 } 239 240 TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpecWithInheritance) { 241 auto Decls = makeDecls<ClassTemplateSpecializationDecl>( 242 R"( 243 struct true_type{}; 244 template <class T> struct foo; 245 template<> struct foo<char> : true_type {}; 246 )", 247 R"( 248 struct true_type{}; 249 template <class T> struct foo; 250 template<> struct foo<signed char> : true_type {}; 251 )", 252 Lang_CXX03, classTemplateSpecializationDecl()); 253 EXPECT_FALSE(testStructuralMatch(Decls)); 254 } 255 256 // This test is disabled for now. 257 // FIXME Enable it, once the check is implemented. 258 TEST_F(StructuralEquivalenceTest, DISABLED_WrongOrderInNamespace) { 259 auto Code = 260 R"( 261 namespace NS { 262 template <class T> class Base { 263 int a; 264 }; 265 class Derived : Base<Derived> { 266 }; 267 } 268 void foo(NS::Derived &); 269 )"; 270 auto Decls = makeNamedDecls(Code, Code, Lang_CXX03); 271 272 NamespaceDecl *NS = 273 LastDeclMatcher<NamespaceDecl>().match(get<1>(Decls), namespaceDecl()); 274 ClassTemplateDecl *TD = LastDeclMatcher<ClassTemplateDecl>().match( 275 get<1>(Decls), classTemplateDecl(hasName("Base"))); 276 277 // Reorder the decls, move the TD to the last place in the DC. 278 NS->removeDecl(TD); 279 NS->addDeclInternal(TD); 280 281 EXPECT_FALSE(testStructuralMatch(Decls)); 282 } 283 284 TEST_F(StructuralEquivalenceTest, WrongOrderOfFieldsInClass) { 285 auto Code = "class X { int a; int b; };"; 286 auto Decls = makeNamedDecls(Code, Code, Lang_CXX03, "X"); 287 288 CXXRecordDecl *RD = FirstDeclMatcher<CXXRecordDecl>().match( 289 get<1>(Decls), cxxRecordDecl(hasName("X"))); 290 FieldDecl *FD = 291 FirstDeclMatcher<FieldDecl>().match(get<1>(Decls), fieldDecl(hasName("a"))); 292 293 // Reorder the FieldDecls 294 RD->removeDecl(FD); 295 RD->addDeclInternal(FD); 296 297 EXPECT_FALSE(testStructuralMatch(Decls)); 298 } 299 300 struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest { 301 }; 302 303 TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) { 304 auto t = makeNamedDecls("void foo();", "template<class T> void foo();", 305 Lang_CXX03); 306 EXPECT_FALSE(testStructuralMatch(t)); 307 } 308 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)); 315 } 316 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)); 323 } 324 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)); 330 } 331 332 TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) { 333 auto t = 334 makeNamedDecls("void foo(int&);", "void foo(const int&);", Lang_CXX03); 335 EXPECT_FALSE(testStructuralMatch(t)); 336 } 337 338 TEST_F(StructuralEquivalenceFunctionTest, ParamConstSimple) { 339 auto t = makeNamedDecls("void foo(int);", "void foo(const int);", Lang_CXX03); 340 EXPECT_TRUE(testStructuralMatch(t)); 341 // consider this OK 342 } 343 344 TEST_F(StructuralEquivalenceFunctionTest, Throw) { 345 auto t = makeNamedDecls("void foo();", "void foo() throw();", Lang_CXX03); 346 EXPECT_FALSE(testStructuralMatch(t)); 347 } 348 349 TEST_F(StructuralEquivalenceFunctionTest, Noexcept) { 350 auto t = makeNamedDecls("void foo();", 351 "void foo() noexcept;", Lang_CXX11); 352 EXPECT_FALSE(testStructuralMatch(t)); 353 } 354 355 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexcept) { 356 auto t = makeNamedDecls("void foo() throw();", 357 "void foo() noexcept;", Lang_CXX11); 358 EXPECT_FALSE(testStructuralMatch(t)); 359 } 360 361 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptFalse) { 362 auto t = makeNamedDecls("void foo() throw();", 363 "void foo() noexcept(false);", Lang_CXX11); 364 EXPECT_FALSE(testStructuralMatch(t)); 365 } 366 367 TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptTrue) { 368 auto t = makeNamedDecls("void foo() throw();", 369 "void foo() noexcept(true);", Lang_CXX11); 370 EXPECT_FALSE(testStructuralMatch(t)); 371 } 372 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)); 377 } 378 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)); 383 } 384 385 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptFalse) { 386 auto t = makeNamedDecls("void foo() noexcept;", 387 "void foo() noexcept(false);", Lang_CXX11); 388 EXPECT_FALSE(testStructuralMatch(t)); 389 } 390 391 TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptTrue) { 392 auto t = makeNamedDecls("void foo() noexcept;", 393 "void foo() noexcept(true);", Lang_CXX11); 394 EXPECT_FALSE(testStructuralMatch(t)); 395 } 396 397 TEST_F(StructuralEquivalenceFunctionTest, ReturnType) { 398 auto t = makeNamedDecls("char foo();", "int foo();", Lang_CXX03); 399 EXPECT_FALSE(testStructuralMatch(t)); 400 } 401 402 TEST_F(StructuralEquivalenceFunctionTest, ReturnConst) { 403 auto t = makeNamedDecls("char foo();", "const char foo();", Lang_CXX03); 404 EXPECT_FALSE(testStructuralMatch(t)); 405 } 406 407 TEST_F(StructuralEquivalenceFunctionTest, ReturnRef) { 408 auto t = makeNamedDecls("char &foo();", 409 "char &&foo();", Lang_CXX11); 410 EXPECT_FALSE(testStructuralMatch(t)); 411 } 412 413 TEST_F(StructuralEquivalenceFunctionTest, ParamCount) { 414 auto t = makeNamedDecls("void foo(int);", "void foo(int, int);", Lang_CXX03); 415 EXPECT_FALSE(testStructuralMatch(t)); 416 } 417 418 TEST_F(StructuralEquivalenceFunctionTest, ParamType) { 419 auto t = makeNamedDecls("void foo(int);", "void foo(char);", Lang_CXX03); 420 EXPECT_FALSE(testStructuralMatch(t)); 421 } 422 423 TEST_F(StructuralEquivalenceFunctionTest, ParamName) { 424 auto t = makeNamedDecls("void foo(int a);", "void foo(int b);", Lang_CXX03); 425 EXPECT_TRUE(testStructuralMatch(t)); 426 } 427 428 TEST_F(StructuralEquivalenceFunctionTest, Variadic) { 429 auto t = 430 makeNamedDecls("void foo(int x...);", "void foo(int x);", Lang_CXX03); 431 EXPECT_FALSE(testStructuralMatch(t)); 432 } 433 434 TEST_F(StructuralEquivalenceFunctionTest, ParamPtr) { 435 auto t = makeNamedDecls("void foo(int *);", "void foo(int);", Lang_CXX03); 436 EXPECT_FALSE(testStructuralMatch(t)); 437 } 438 439 TEST_F(StructuralEquivalenceFunctionTest, NameInParen) { 440 auto t = makeNamedDecls("void ((foo))();", "void foo();", Lang_CXX03); 441 EXPECT_TRUE(testStructuralMatch(t)); 442 } 443 444 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithExceptionSpec) { 445 auto t = makeNamedDecls( 446 "void (foo)() throw(int);", 447 "void (foo)() noexcept;", 448 Lang_CXX11); 449 EXPECT_FALSE(testStructuralMatch(t)); 450 } 451 452 TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) { 453 auto t = makeNamedDecls( 454 "struct A { void (foo)() const; };", 455 "struct A { void (foo)(); };", 456 Lang_CXX11); 457 EXPECT_FALSE(testStructuralMatch(t)); 458 } 459 460 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) { 461 auto t = makeNamedDecls("__attribute__((noreturn)) void foo();", 462 " void foo();", Lang_C99); 463 EXPECT_TRUE(testStructuralMatch(t)); 464 } 465 466 TEST_F(StructuralEquivalenceFunctionTest, 467 FunctionsWithDifferentCallingConventions) { 468 // These attributes may not be available on certain platforms. 469 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() != 470 llvm::Triple::x86_64) 471 GTEST_SKIP(); 472 auto t = makeNamedDecls("__attribute__((preserve_all)) void foo();", 473 "__attribute__((ms_abi)) void foo();", Lang_C99); 474 EXPECT_FALSE(testStructuralMatch(t)); 475 } 476 477 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) { 478 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() != 479 llvm::Triple::x86_64) 480 GTEST_SKIP(); 481 auto t = makeNamedDecls( 482 "__attribute__((no_caller_saved_registers)) void foo();", 483 " void foo();", Lang_C99); 484 EXPECT_FALSE(testStructuralMatch(t)); 485 } 486 487 struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest { 488 }; 489 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)); 495 } 496 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)); 501 } 502 503 TEST_F(StructuralEquivalenceCXXMethodTest, DISABLED_Final) { 504 // The final-ness is not checked yet. 505 auto t = 506 makeNamedDecls("struct X { virtual void foo(); };", 507 "struct X { virtual void foo() final; };", Lang_CXX03); 508 EXPECT_FALSE(testStructuralMatch(t)); 509 } 510 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)); 515 } 516 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)); 521 } 522 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)); 527 } 528 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)); 533 } 534 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)); 540 } 541 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)); 546 } 547 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)); 553 } 554 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)); 560 } 561 562 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorExplicit) { 563 auto t = makeDecls<CXXConstructorDecl>("struct X { X(int); };", 564 "struct X { explicit X(int); };", 565 Lang_CXX11, 566 cxxConstructorDecl(hasName("X"))); 567 EXPECT_FALSE(testStructuralMatch(t)); 568 } 569 570 TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorDefault) { 571 auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };", 572 "struct X { X() = default; };", 573 Lang_CXX11, 574 cxxConstructorDecl(hasName("X"))); 575 EXPECT_FALSE(testStructuralMatch(t)); 576 } 577 578 TEST_F(StructuralEquivalenceCXXMethodTest, Conversion) { 579 auto t = makeDecls<CXXConversionDecl>("struct X { operator bool(); };", 580 "struct X { operator char(); };", 581 Lang_CXX11, 582 cxxConversionDecl()); 583 EXPECT_FALSE(testStructuralMatch(t)); 584 } 585 586 TEST_F(StructuralEquivalenceCXXMethodTest, Operator) { 587 auto t = 588 makeDecls<FunctionDecl>("struct X { int operator +(int); };", 589 "struct X { int operator -(int); };", Lang_CXX03, 590 functionDecl(hasOverloadedOperatorName("+")), 591 functionDecl(hasOverloadedOperatorName("-"))); 592 EXPECT_FALSE(testStructuralMatch(t)); 593 } 594 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)); 601 } 602 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)); 609 } 610 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(); 616 }; 617 }; 618 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)); 624 } 625 626 TEST_F(StructuralEquivalenceRecordTest, Fields) { 627 auto t = makeNamedDecls("struct foo{ int x; };", "struct foo{ char x; };", 628 Lang_CXX03); 629 EXPECT_FALSE(testStructuralMatch(t)); 630 } 631 632 TEST_F(StructuralEquivalenceRecordTest, DISABLED_Methods) { 633 // Currently, methods of a class are not checked at class equivalence. 634 auto t = makeNamedDecls("struct foo{ int x(); };", "struct foo{ char x(); };", 635 Lang_CXX03); 636 EXPECT_FALSE(testStructuralMatch(t)); 637 } 638 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)); 643 } 644 645 TEST_F(StructuralEquivalenceRecordTest, InheritanceVirtual) { 646 auto t = 647 makeNamedDecls("struct A{ }; struct foo: A { };", 648 "struct A{ }; struct foo: virtual A { };", Lang_CXX03); 649 EXPECT_FALSE(testStructuralMatch(t)); 650 } 651 652 TEST_F(StructuralEquivalenceRecordTest, DISABLED_InheritanceType) { 653 // Access specifier in inheritance is not checked yet. 654 auto t = 655 makeNamedDecls("struct A{ }; struct foo: public A { };", 656 "struct A{ }; struct foo: private A { };", Lang_CXX03); 657 EXPECT_FALSE(testStructuralMatch(t)); 658 } 659 660 TEST_F(StructuralEquivalenceRecordTest, Match) { 661 auto Code = R"( 662 struct A{ }; 663 struct B{ }; 664 struct foo: A, virtual B { 665 void x(); 666 int a; 667 }; 668 )"; 669 auto t = makeNamedDecls(Code, Code, Lang_CXX03); 670 EXPECT_TRUE(testStructuralMatch(t)); 671 } 672 673 TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) { 674 auto t = makeTuDecls( 675 R"( 676 struct A { 677 struct { 678 struct A *next; 679 } entry0; 680 struct { 681 struct A *next; 682 } entry1; 683 }; 684 )", 685 "", Lang_C99); 686 auto *TU = get<0>(t); 687 auto *Entry0 = 688 FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry0"))); 689 auto *Entry1 = 690 FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry1"))); 691 auto *R0 = getRecordDecl(Entry0); 692 auto *R1 = getRecordDecl(Entry1); 693 694 ASSERT_NE(R0, R1); 695 EXPECT_TRUE(testStructuralMatch(R0, R0)); 696 EXPECT_TRUE(testStructuralMatch(R1, R1)); 697 EXPECT_FALSE(testStructuralMatch(R0, R1)); 698 } 699 700 TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) { 701 auto t = makeTuDecls( 702 R"( 703 struct X { 704 struct { 705 int a; 706 }; 707 struct { 708 int b; 709 }; 710 }; 711 )", 712 "", Lang_C99); 713 auto *TU = get<0>(t); 714 auto *A = FirstDeclMatcher<IndirectFieldDecl>().match( 715 TU, indirectFieldDecl(hasName("a"))); 716 auto *FA = cast<FieldDecl>(A->chain().front()); 717 RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl(); 718 auto *B = FirstDeclMatcher<IndirectFieldDecl>().match( 719 TU, indirectFieldDecl(hasName("b"))); 720 auto *FB = cast<FieldDecl>(B->chain().front()); 721 RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl(); 722 723 ASSERT_NE(RA, RB); 724 EXPECT_TRUE(testStructuralMatch(RA, RA)); 725 EXPECT_TRUE(testStructuralMatch(RB, RB)); 726 EXPECT_FALSE(testStructuralMatch(RA, RB)); 727 } 728 729 TEST_F(StructuralEquivalenceRecordTest, 730 RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) { 731 auto t = makeTuDecls( 732 R"( 733 struct X { 734 struct { int a; }; 735 struct { int b; }; 736 }; 737 )", 738 R"( 739 struct X { // The order is reversed. 740 struct { int b; }; 741 struct { int a; }; 742 }; 743 )", 744 Lang_C99); 745 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(); 751 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(); 757 758 RecordDecl *X = 759 FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X"))); 760 RecordDecl *X1 = 761 FirstDeclMatcher<RecordDecl>().match(TU1, recordDecl(hasName("X"))); 762 ASSERT_NE(X, X1); 763 EXPECT_FALSE(testStructuralMatch(X, X1)); 764 765 ASSERT_NE(RA, RA1); 766 EXPECT_TRUE(testStructuralMatch(RA, RA)); 767 EXPECT_TRUE(testStructuralMatch(RA1, RA1)); 768 EXPECT_FALSE(testStructuralMatch(RA1, RA)); 769 } 770 771 TEST_F(StructuralEquivalenceRecordTest, 772 UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) { 773 auto Code = 774 R"( 775 struct A { 776 struct { 777 struct A *next; 778 } entry0; 779 struct { 780 struct A *next; 781 } entry1; 782 }; 783 )"; 784 auto t = makeTuDecls(Code, Code, Lang_C99); 785 786 auto *FromTU = get<0>(t); 787 auto *Entry1 = 788 FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("entry1"))); 789 790 auto *ToTU = get<1>(t); 791 auto *Entry0 = 792 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0"))); 793 auto *A = 794 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A"))); 795 A->startDefinition(); // Set isBeingDefined, getDefinition() will return a 796 // nullptr. This may be the case during ASTImport. 797 798 auto *R0 = getRecordDecl(Entry0); 799 auto *R1 = getRecordDecl(Entry1); 800 801 ASSERT_NE(R0, R1); 802 EXPECT_TRUE(testStructuralMatch(R0, R0)); 803 EXPECT_TRUE(testStructuralMatch(R1, R1)); 804 EXPECT_FALSE(testStructuralMatch(R0, R1)); 805 } 806 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)); 812 } 813 814 TEST_F(StructuralEquivalenceRecordTest, 815 FwdDeclRecordShouldBeEqualWithFwdDeclRecord) { 816 auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11); 817 EXPECT_TRUE(testStructuralMatch(t)); 818 } 819 820 TEST_F(StructuralEquivalenceRecordTest, 821 FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) { 822 auto t = 823 makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11); 824 EXPECT_TRUE(testStructuralMatch(t)); 825 } 826 827 TEST_F(StructuralEquivalenceRecordTest, 828 RecordShouldBeEqualWithRecordWhichHasDefinition) { 829 auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };", 830 Lang_CXX11); 831 EXPECT_TRUE(testStructuralMatch(t)); 832 } 833 834 TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) { 835 auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };", 836 Lang_CXX11); 837 EXPECT_FALSE(testStructuralMatch(t)); 838 } 839 840 TEST_F(StructuralEquivalenceRecordTest, SameFriendMultipleTimes) { 841 auto t = makeNamedDecls("struct foo { friend class X; };", 842 "struct foo { friend class X; friend class X; };", 843 Lang_CXX11); 844 EXPECT_FALSE(testStructuralMatch(t)); 845 } 846 847 TEST_F(StructuralEquivalenceRecordTest, SameFriendsDifferentOrder) { 848 auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };", 849 "struct foo { friend class Y; friend class X; };", 850 Lang_CXX11); 851 EXPECT_FALSE(testStructuralMatch(t)); 852 } 853 854 TEST_F(StructuralEquivalenceRecordTest, SameFriendsSameOrder) { 855 auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };", 856 "struct foo { friend class X; friend class Y; };", 857 Lang_CXX11); 858 EXPECT_TRUE(testStructuralMatch(t)); 859 } 860 861 struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {}; 862 863 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) { 864 // Get the LambdaExprs, unfortunately we can't match directly the underlying 865 // implicit CXXRecordDecl of the Lambda classes. 866 auto t = makeDecls<LambdaExpr>( 867 "void f() { auto L0 = [](int){}; }", 868 "void f() { auto L1 = [](){}; }", 869 Lang_CXX11, 870 lambdaExpr(), 871 lambdaExpr()); 872 CXXRecordDecl *L0 = get<0>(t)->getLambdaClass(); 873 CXXRecordDecl *L1 = get<1>(t)->getLambdaClass(); 874 EXPECT_FALSE(testStructuralMatch(L0, L1)); 875 } 876 877 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqMethods) { 878 auto t = makeDecls<LambdaExpr>( 879 "void f() { auto L0 = [](int){}; }", 880 "void f() { auto L1 = [](int){}; }", 881 Lang_CXX11, 882 lambdaExpr(), 883 lambdaExpr()); 884 CXXRecordDecl *L0 = get<0>(t)->getLambdaClass(); 885 CXXRecordDecl *L1 = get<1>(t)->getLambdaClass(); 886 EXPECT_TRUE(testStructuralMatch(L0, L1)); 887 } 888 889 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentFields) { 890 auto t = makeDecls<LambdaExpr>( 891 "void f() { char* X; auto L0 = [X](){}; }", 892 "void f() { float X; auto L1 = [X](){}; }", 893 Lang_CXX11, 894 lambdaExpr(), 895 lambdaExpr()); 896 CXXRecordDecl *L0 = get<0>(t)->getLambdaClass(); 897 CXXRecordDecl *L1 = get<1>(t)->getLambdaClass(); 898 EXPECT_FALSE(testStructuralMatch(L0, L1)); 899 } 900 901 TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqFields) { 902 auto t = makeDecls<LambdaExpr>( 903 "void f() { float X; auto L0 = [X](){}; }", 904 "void f() { float X; auto L1 = [X](){}; }", 905 Lang_CXX11, 906 lambdaExpr(), 907 lambdaExpr()); 908 CXXRecordDecl *L0 = get<0>(t)->getLambdaClass(); 909 CXXRecordDecl *L1 = get<1>(t)->getLambdaClass(); 910 EXPECT_TRUE(testStructuralMatch(L0, L1)); 911 } 912 913 TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) { 914 auto t = makeNamedDecls("struct A{ }; struct B{ }; void foo(A a, A b);", 915 "struct A{ }; struct B{ }; void foo(A a, B b);", 916 Lang_CXX03); 917 EXPECT_FALSE(testStructuralMatch(t)); 918 } 919 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)); 928 } 929 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)); 938 } 939 940 struct StructuralEquivalenceRecordContextTest : StructuralEquivalenceTest {}; 941 942 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsNamed) { 943 auto Decls = 944 makeNamedDecls("class X;", "namespace N { class X; }", Lang_CXX03, "X"); 945 EXPECT_FALSE(testStructuralMatch(Decls)); 946 } 947 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)); 952 } 953 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)); 958 } 959 960 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsAnon) { 961 auto Decls = 962 makeNamedDecls("class X;", "namespace { class X; }", Lang_CXX03, "X"); 963 EXPECT_FALSE(testStructuralMatch(Decls)); 964 } 965 966 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnon) { 967 auto Decls = makeNamedDecls("namespace { class X; }", 968 "namespace { class X; }", Lang_CXX03, "X"); 969 EXPECT_TRUE(testStructuralMatch(Decls)); 970 } 971 972 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnonAnon) { 973 auto Decls = 974 makeNamedDecls("namespace { class X; }", 975 "namespace { namespace { class X; } }", Lang_CXX03, "X"); 976 EXPECT_FALSE(testStructuralMatch(Decls)); 977 } 978 979 TEST_F(StructuralEquivalenceRecordContextTest, 980 NamespaceNamedNamedVsNamedNamed) { 981 auto Decls = makeNamedDecls("namespace A { namespace N { class X; } }", 982 "namespace B { namespace N { class X; } }", 983 Lang_CXX03, "X"); 984 EXPECT_FALSE(testStructuralMatch(Decls)); 985 } 986 987 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsInline) { 988 auto Decls = makeNamedDecls("namespace A { namespace A { class X; } }", 989 "namespace A { inline namespace A { class X; } }", 990 Lang_CXX17, "X"); 991 EXPECT_FALSE(testStructuralMatch(Decls)); 992 } 993 994 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineVsInline) { 995 auto Decls = makeNamedDecls("namespace A { inline namespace A { class X; } }", 996 "namespace A { inline namespace B { class X; } }", 997 Lang_CXX17, "X"); 998 EXPECT_TRUE(testStructuralMatch(Decls)); 999 } 1000 1001 TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineTopLevel) { 1002 auto Decls = 1003 makeNamedDecls("inline namespace A { class X; }", 1004 "inline namespace B { class X; }", Lang_CXX17, "X"); 1005 EXPECT_TRUE(testStructuralMatch(Decls)); 1006 } 1007 1008 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContext) { 1009 auto Decls = 1010 makeNamedDecls("extern \"C\" { class X; }", "class X;", Lang_CXX03, "X"); 1011 EXPECT_TRUE(testStructuralMatch(Decls)); 1012 } 1013 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)); 1018 } 1019 1020 TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextInNamespace) { 1021 auto Decls = makeNamedDecls("extern \"C\" { namespace N { class X; } }", 1022 "namespace N { extern \"C\" { class X; } }", 1023 Lang_CXX03, "X"); 1024 EXPECT_TRUE(testStructuralMatch(Decls)); 1025 } 1026 1027 TEST_F(StructuralEquivalenceRecordContextTest, 1028 ClassTemplateSpecializationContext) { 1029 std::string Code = 1030 R"( 1031 template <typename T> struct O { 1032 struct M {}; 1033 }; 1034 )"; 1035 auto t = makeDecls<VarDecl>(Code + R"( 1036 typedef O<int>::M MT1; 1037 MT1 A; 1038 )", 1039 Code + R"( 1040 namespace { 1041 struct I {}; 1042 } // namespace 1043 typedef O<I>::M MT2; 1044 MT2 A; 1045 )", 1046 Lang_CXX11, varDecl(hasName("A"))); 1047 EXPECT_FALSE(testStructuralMatch(t)); 1048 } 1049 1050 TEST_F(StructuralEquivalenceTest, NamespaceOfRecordMember) { 1051 auto Decls = makeNamedDecls( 1052 R"( 1053 class X; 1054 class Y { X* x; }; 1055 )", 1056 R"( 1057 namespace N { class X; } 1058 class Y { N::X* x; }; 1059 )", 1060 Lang_CXX03, "Y"); 1061 EXPECT_FALSE(testStructuralMatch(Decls)); 1062 } 1063 1064 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototype) { 1065 auto Decls = 1066 makeNamedDecls("struct Param { int a; }; void foo(struct Param *p);", 1067 "void foo(struct Param { int a; } *p);", Lang_C89); 1068 EXPECT_TRUE(testStructuralMatch(Decls)); 1069 } 1070 1071 TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototypeDifferentName) { 1072 auto Decls = 1073 makeNamedDecls("struct Param1 { int a; }; void foo(struct Param1 *p);", 1074 "void foo(struct Param2 { int a; } *p);", Lang_C89); 1075 EXPECT_FALSE(testStructuralMatch(Decls)); 1076 } 1077 1078 TEST_F(StructuralEquivalenceRecordContextTest, RecordInsideFunction) { 1079 auto Decls = makeNamedDecls("struct Param { int a; };", 1080 "void f() { struct Param { int a; }; }", Lang_C89, 1081 "Param"); 1082 EXPECT_TRUE(testStructuralMatch(Decls)); 1083 } 1084 1085 struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {}; 1086 1087 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) { 1088 auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11); 1089 EXPECT_TRUE(testStructuralMatch(t)); 1090 } 1091 1092 TEST_F(StructuralEquivalenceEnumTest, 1093 FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) { 1094 auto t = 1095 makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11); 1096 EXPECT_TRUE(testStructuralMatch(t)); 1097 } 1098 1099 TEST_F(StructuralEquivalenceEnumTest, 1100 EnumShouldBeEqualWithEnumWhichHasDefinition) { 1101 auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };", 1102 Lang_CXX11); 1103 EXPECT_TRUE(testStructuralMatch(t)); 1104 } 1105 1106 TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) { 1107 auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };", 1108 Lang_CXX11); 1109 EXPECT_FALSE(testStructuralMatch(t)); 1110 } 1111 1112 TEST_F(StructuralEquivalenceEnumTest, AnonymousEnumsWithSameConsts) { 1113 // field x is required to trigger comparison of the anonymous enum 1114 auto t = makeNamedDecls("struct foo { enum { A } x; };", 1115 "struct foo { enum { A } x;};", Lang_CXX11); 1116 EXPECT_TRUE(testStructuralMatch(t)); 1117 } 1118 1119 TEST_F(StructuralEquivalenceEnumTest, AnonymousEnumsWithDiffConsts) { 1120 // field x is required to trigger comparison of the anonymous enum 1121 auto t = makeNamedDecls("struct foo { enum { A } x; };", 1122 "struct foo { enum { B } x;};", Lang_CXX11); 1123 EXPECT_FALSE(testStructuralMatch(t)); 1124 } 1125 1126 struct StructuralEquivalenceEnumConstantTest : StructuralEquivalenceTest {}; 1127 1128 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithSameValues) { 1129 auto t = makeNamedDecls("enum foo { foo = 1 };", "enum foo { foo = 1 };", 1130 Lang_C89); 1131 EXPECT_TRUE(testStructuralMatch(t)); 1132 } 1133 1134 TEST_F(StructuralEquivalenceEnumConstantTest, 1135 EnumConstantsWithDifferentValues) { 1136 auto t = 1137 makeNamedDecls("enum e { foo = 1 };", "enum e { foo = 2 };", Lang_C89); 1138 EXPECT_FALSE(testStructuralMatch(t)); 1139 } 1140 1141 TEST_F(StructuralEquivalenceEnumConstantTest, 1142 EnumConstantsWithDifferentExprsButSameValues) { 1143 auto t = makeNamedDecls("enum e { foo = 1 + 1 };", "enum e { foo = 2 };", 1144 Lang_CXX11); 1145 EXPECT_FALSE(testStructuralMatch(t)); 1146 } 1147 1148 TEST_F(StructuralEquivalenceEnumConstantTest, 1149 EnumConstantsWithDifferentSignedness) { 1150 auto t = makeNamedDecls("enum e : unsigned { foo = 1 };", 1151 "enum e : int { foo = 1 };", Lang_CXX11); 1152 EXPECT_FALSE(testStructuralMatch(t)); 1153 } 1154 1155 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentWidth) { 1156 auto t = makeNamedDecls("enum e : short { foo = 1 };", 1157 "enum e : int { foo = 1 };", Lang_CXX11); 1158 EXPECT_FALSE(testStructuralMatch(t)); 1159 } 1160 1161 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentName) { 1162 auto t = 1163 makeDecls<EnumConstantDecl>("enum e { foo = 1 };", "enum e { bar = 1 };", 1164 Lang_CXX11, enumConstantDecl()); 1165 EXPECT_FALSE(testStructuralMatch(t)); 1166 } 1167 1168 struct StructuralEquivalenceObjCCategoryTest : StructuralEquivalenceTest {}; 1169 1170 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchinCategoryNames) { 1171 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end", 1172 "@interface A @end @interface A(X) @end", 1173 Lang_OBJC, objcCategoryDecl()); 1174 EXPECT_TRUE(testStructuralMatch(t)); 1175 } 1176 1177 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesForDifferentClasses) { 1178 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end", 1179 "@interface B @end @interface B(X) @end", 1180 Lang_OBJC, objcCategoryDecl()); 1181 EXPECT_FALSE(testStructuralMatch(t)); 1182 } 1183 1184 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithDifferentNames) { 1185 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end", 1186 "@interface A @end @interface A(Y) @end", 1187 Lang_OBJC, objcCategoryDecl()); 1188 EXPECT_FALSE(testStructuralMatch(t)); 1189 } 1190 1191 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithoutInterfaces) { 1192 auto t = makeDecls<ObjCCategoryDecl>(" @interface A(X) @end", 1193 "@interface A @end @interface A(X) @end", 1194 Lang_OBJC, objcCategoryDecl()); 1195 EXPECT_FALSE(testStructuralMatch(t)); 1196 1197 auto t2 = makeDecls<ObjCCategoryDecl>("@interface A(X) @end", 1198 "@interface A(X) @end", 1199 Lang_OBJC, objcCategoryDecl()); 1200 EXPECT_TRUE(testStructuralMatch(t2)); 1201 } 1202 1203 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoryAndExtension) { 1204 auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end", 1205 "@interface A @end @interface A() @end", 1206 Lang_OBJC, objcCategoryDecl()); 1207 EXPECT_FALSE(testStructuralMatch(t)); 1208 } 1209 1210 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingProtocols) { 1211 auto t = makeDecls<ObjCCategoryDecl>( 1212 "@protocol P @end @interface A @end @interface A(X)<P> @end", 1213 "@protocol P @end @interface A @end @interface A(X)<P> @end", Lang_OBJC, 1214 objcCategoryDecl()); 1215 EXPECT_TRUE(testStructuralMatch(t)); 1216 } 1217 1218 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocols) { 1219 auto t = makeDecls<ObjCCategoryDecl>( 1220 "@protocol P @end @interface A @end @interface A(X)<P> @end", 1221 "@protocol Q @end @interface A @end @interface A(X)<Q> @end", Lang_OBJC, 1222 objcCategoryDecl()); 1223 EXPECT_FALSE(testStructuralMatch(t)); 1224 } 1225 1226 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocolsOrder) { 1227 auto t = makeDecls<ObjCCategoryDecl>( 1228 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<P, " 1229 "Q> @end", 1230 "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<Q, " 1231 "P> @end", 1232 Lang_OBJC, objcCategoryDecl()); 1233 EXPECT_FALSE(testStructuralMatch(t)); 1234 } 1235 1236 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingIvars) { 1237 auto t = makeDecls<ObjCCategoryDecl>( 1238 "@interface A @end @interface A() { int x; } @end", 1239 "@interface A @end @interface A() { int x; } @end", Lang_OBJC, 1240 objcCategoryDecl()); 1241 EXPECT_TRUE(testStructuralMatch(t)); 1242 } 1243 1244 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarName) { 1245 auto t = makeDecls<ObjCCategoryDecl>( 1246 "@interface A @end @interface A() { int x; } @end", 1247 "@interface A @end @interface A() { int y; } @end", Lang_OBJC, 1248 objcCategoryDecl()); 1249 EXPECT_FALSE(testStructuralMatch(t)); 1250 } 1251 1252 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarType) { 1253 auto t = makeDecls<ObjCCategoryDecl>( 1254 "@interface A @end @interface A() { int x; } @end", 1255 "@interface A @end @interface A() { float x; } @end", Lang_OBJC, 1256 objcCategoryDecl()); 1257 EXPECT_FALSE(testStructuralMatch(t)); 1258 } 1259 1260 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarBitfieldWidth) { 1261 auto t = makeDecls<ObjCCategoryDecl>( 1262 "@interface A @end @interface A() { int x: 1; } @end", 1263 "@interface A @end @interface A() { int x: 2; } @end", Lang_OBJC, 1264 objcCategoryDecl()); 1265 EXPECT_FALSE(testStructuralMatch(t)); 1266 } 1267 1268 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarVisibility) { 1269 auto t = makeDecls<ObjCCategoryDecl>( 1270 "@interface A @end @interface A() { @public int x; } @end", 1271 "@interface A @end @interface A() { @protected int x; } @end", Lang_OBJC, 1272 objcCategoryDecl()); 1273 EXPECT_FALSE(testStructuralMatch(t)); 1274 } 1275 1276 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarNumber) { 1277 auto t = makeDecls<ObjCCategoryDecl>( 1278 "@interface A @end @interface A() { int x; } @end", 1279 "@interface A @end @interface A() {} @end", Lang_OBJC, 1280 objcCategoryDecl()); 1281 EXPECT_FALSE(testStructuralMatch(t)); 1282 } 1283 1284 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarOrder) { 1285 auto t = makeDecls<ObjCCategoryDecl>( 1286 "@interface A @end @interface A() { int x; int y; } @end", 1287 "@interface A @end @interface A() { int y; int x; } @end", Lang_OBJC, 1288 objcCategoryDecl()); 1289 EXPECT_FALSE(testStructuralMatch(t)); 1290 } 1291 1292 TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingMethods) { 1293 auto t = makeDecls<ObjCCategoryDecl>( 1294 "@interface A @end @interface A(X) -(void)test; @end", 1295 "@interface A @end @interface A(X) -(void)test; @end", Lang_OBJC, 1296 objcCategoryDecl()); 1297 EXPECT_TRUE(testStructuralMatch(t)); 1298 } 1299 1300 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodName) { 1301 auto t = makeDecls<ObjCCategoryDecl>( 1302 "@interface A @end @interface A(X) -(void)test; @end", 1303 "@interface A @end @interface A(X) -(void)wasd; @end", Lang_OBJC, 1304 objcCategoryDecl()); 1305 EXPECT_FALSE(testStructuralMatch(t)); 1306 1307 auto t2 = makeDecls<ObjCCategoryDecl>( 1308 "@interface A @end @interface A(X) -(void)test:(int)x more:(int)y; @end", 1309 "@interface A @end @interface A(X) -(void)test:(int)x :(int)y; @end", 1310 Lang_OBJC, objcCategoryDecl()); 1311 EXPECT_FALSE(testStructuralMatch(t2)); 1312 } 1313 1314 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodClassInstance) { 1315 auto t = makeDecls<ObjCCategoryDecl>( 1316 "@interface A @end @interface A(X) -(void)test; @end", 1317 "@interface A @end @interface A(X) +(void)test; @end", Lang_OBJC, 1318 objcCategoryDecl()); 1319 EXPECT_FALSE(testStructuralMatch(t)); 1320 } 1321 1322 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodReturnType) { 1323 auto t = makeDecls<ObjCCategoryDecl>( 1324 "@interface A @end @interface A(X) -(void)test; @end", 1325 "@interface A @end @interface A(X) -(int)test; @end", Lang_OBJC, 1326 objcCategoryDecl()); 1327 EXPECT_FALSE(testStructuralMatch(t)); 1328 } 1329 1330 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterType) { 1331 auto t = makeDecls<ObjCCategoryDecl>( 1332 "@interface A @end @interface A(X) -(void)test:(int)x; @end", 1333 "@interface A @end @interface A(X) -(void)test:(float)x; @end", Lang_OBJC, 1334 objcCategoryDecl()); 1335 EXPECT_FALSE(testStructuralMatch(t)); 1336 } 1337 1338 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterName) { 1339 auto t = makeDecls<ObjCCategoryDecl>( 1340 "@interface A @end @interface A(X) -(void)test:(int)x; @end", 1341 "@interface A @end @interface A(X) -(void)test:(int)y; @end", Lang_OBJC, 1342 objcCategoryDecl()); 1343 EXPECT_TRUE(testStructuralMatch(t)); 1344 } 1345 1346 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodNumber) { 1347 auto t = makeDecls<ObjCCategoryDecl>( 1348 "@interface A @end @interface A(X) -(void)test; @end", 1349 "@interface A @end @interface A(X) @end", Lang_OBJC, objcCategoryDecl()); 1350 EXPECT_FALSE(testStructuralMatch(t)); 1351 } 1352 1353 TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodOrder) { 1354 auto t = makeDecls<ObjCCategoryDecl>( 1355 "@interface A @end @interface A(X) -(void)u; -(void)v; @end", 1356 "@interface A @end @interface A(X) -(void)v; -(void)u; @end", Lang_OBJC, 1357 objcCategoryDecl()); 1358 EXPECT_FALSE(testStructuralMatch(t)); 1359 } 1360 1361 struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {}; 1362 1363 TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) { 1364 auto t = makeNamedDecls("template <class T> struct foo;", 1365 "template <class T> struct foo;", Lang_CXX03); 1366 EXPECT_TRUE(testStructuralMatch(t)); 1367 } 1368 1369 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) { 1370 auto t = makeNamedDecls("template <class T> struct foo;", 1371 "template <class U> struct foo;", Lang_CXX03); 1372 EXPECT_TRUE(testStructuralMatch(t)); 1373 } 1374 1375 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) { 1376 auto t = makeNamedDecls("template <class T> struct foo;", 1377 "template <int T> struct foo;", Lang_CXX03); 1378 EXPECT_FALSE(testStructuralMatch(t)); 1379 } 1380 1381 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDecl) { 1382 const char *Code = "class foo { int a : 2; };"; 1383 auto t = makeNamedDecls(Code, Code, Lang_CXX03); 1384 EXPECT_TRUE(testStructuralMatch(t)); 1385 } 1386 1387 TEST_F(StructuralEquivalenceTemplateTest, BitFieldDeclDifferentWidth) { 1388 auto t = makeNamedDecls("class foo { int a : 2; };", 1389 "class foo { int a : 4; };", Lang_CXX03); 1390 EXPECT_FALSE(testStructuralMatch(t)); 1391 } 1392 1393 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDecl) { 1394 const char *Code = "template <class T> class foo { int a : sizeof(T); };"; 1395 auto t = makeNamedDecls(Code, Code, Lang_CXX03); 1396 EXPECT_TRUE(testStructuralMatch(t)); 1397 } 1398 1399 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal) { 1400 auto t = makeNamedDecls( 1401 "template <class A, class B> class foo { int a : sizeof(A); };", 1402 "template <class A, class B> class foo { int a : sizeof(B); };", 1403 Lang_CXX03); 1404 EXPECT_FALSE(testStructuralMatch(t)); 1405 } 1406 1407 TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal2) { 1408 auto t = makeNamedDecls( 1409 "template <class A> class foo { int a : sizeof(A); };", 1410 "template <class A> class foo { int a : sizeof(A) + 1; };", Lang_CXX03); 1411 EXPECT_FALSE(testStructuralMatch(t)); 1412 } 1413 1414 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) { 1415 auto Decls = makeNamedDecls( 1416 "template <bool b> struct foo {explicit(b) foo(int);};", 1417 "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX20); 1418 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match( 1419 get<0>(Decls), cxxConstructorDecl(hasName("foo<b>"))); 1420 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match( 1421 get<1>(Decls), cxxConstructorDecl(hasName("foo<b>"))); 1422 EXPECT_TRUE(testStructuralMatch(First, Second)); 1423 } 1424 1425 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) { 1426 auto Decls = makeNamedDecls( 1427 "template <bool b> struct foo {explicit(b) foo(int);};", 1428 "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX20); 1429 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match( 1430 get<0>(Decls), cxxConstructorDecl(hasName("foo<b>"))); 1431 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match( 1432 get<1>(Decls), cxxConstructorDecl(hasName("foo<b>"))); 1433 EXPECT_FALSE(testStructuralMatch(First, Second)); 1434 } 1435 1436 TEST_F(StructuralEquivalenceTemplateTest, 1437 TemplateVsSubstTemplateTemplateParmInArgEq) { 1438 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1439 R"( 1440 template <typename P1> class Arg { }; 1441 template <template <typename PP1> class P1> class Primary { }; 1442 1443 void f() { 1444 // Make specialization with simple template. 1445 Primary <Arg> A; 1446 } 1447 )", 1448 R"( 1449 template <typename P1> class Arg { }; 1450 template <template <typename PP1> class P1> class Primary { }; 1451 1452 template <template <typename PP1> class P1> class Templ { 1453 void f() { 1454 // Make specialization with substituted template template param. 1455 Primary <P1> A; 1456 }; 1457 }; 1458 1459 // Instantiate with substitution Arg into P1. 1460 template class Templ <Arg>; 1461 )", 1462 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1463 EXPECT_TRUE(testStructuralMatch(t)); 1464 } 1465 1466 TEST_F(StructuralEquivalenceTemplateTest, 1467 TemplateVsSubstTemplateTemplateParmInArgNotEq) { 1468 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1469 R"( 1470 template <typename P1> class Arg { }; 1471 template <template <typename PP1> class P1> class Primary { }; 1472 1473 void f() { 1474 // Make specialization with simple template. 1475 Primary <Arg> A; 1476 } 1477 )", 1478 R"( 1479 // Arg is different from the other, this should cause non-equivalence. 1480 template <typename P1> class Arg { int X; }; 1481 template <template <typename PP1> class P1> class Primary { }; 1482 1483 template <template <typename PP1> class P1> class Templ { 1484 void f() { 1485 // Make specialization with substituted template template param. 1486 Primary <P1> A; 1487 }; 1488 }; 1489 1490 // Instantiate with substitution Arg into P1. 1491 template class Templ <Arg>; 1492 )", 1493 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1494 EXPECT_FALSE(testStructuralMatch(t)); 1495 } 1496 1497 struct StructuralEquivalenceDependentTemplateArgsTest 1498 : StructuralEquivalenceTemplateTest {}; 1499 1500 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1501 SameStructsInDependentArgs) { 1502 std::string Code = 1503 R"( 1504 template <typename> 1505 struct S1; 1506 1507 template <typename> 1508 struct enable_if; 1509 1510 struct S 1511 { 1512 template <typename T, typename enable_if<S1<T>>::type> 1513 void f(); 1514 }; 1515 )"; 1516 auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11, 1517 functionTemplateDecl(hasName("f"))); 1518 EXPECT_TRUE(testStructuralMatch(t)); 1519 } 1520 1521 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1522 DifferentStructsInDependentArgs) { 1523 std::string Code = 1524 R"( 1525 template <typename> 1526 struct S1; 1527 1528 template <typename> 1529 struct S2; 1530 1531 template <typename> 1532 struct enable_if; 1533 )"; 1534 auto t = makeDecls<FunctionTemplateDecl>(Code + R"( 1535 struct S 1536 { 1537 template <typename T, typename enable_if<S1<T>>::type> 1538 void f(); 1539 }; 1540 )", 1541 Code + R"( 1542 struct S 1543 { 1544 template <typename T, typename enable_if<S2<T>>::type> 1545 void f(); 1546 }; 1547 )", 1548 Lang_CXX11, 1549 functionTemplateDecl(hasName("f"))); 1550 EXPECT_FALSE(testStructuralMatch(t)); 1551 } 1552 1553 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1554 SameStructsInDependentScopeDeclRefExpr) { 1555 std::string Code = 1556 R"( 1557 template <typename> 1558 struct S1; 1559 1560 template <bool> 1561 struct enable_if; 1562 1563 struct S 1564 { 1565 template <typename T, typename enable_if<S1<T>::value>::type> 1566 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^ 1567 }; 1568 )"; 1569 auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11, 1570 functionTemplateDecl(hasName("f"))); 1571 EXPECT_TRUE(testStructuralMatch(t)); 1572 } 1573 1574 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1575 DifferentStructsInDependentScopeDeclRefExpr) { 1576 std::string Code = 1577 R"( 1578 template <typename> 1579 struct S1; 1580 1581 template <typename> 1582 struct S2; 1583 1584 template <bool> 1585 struct enable_if; 1586 )"; 1587 auto t = makeDecls<FunctionTemplateDecl>(Code + R"( 1588 struct S 1589 { 1590 template <typename T, typename enable_if<S1<T>::value>::type> 1591 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^ 1592 }; 1593 )", 1594 Code + R"( 1595 struct S 1596 { 1597 template <typename T, typename enable_if<S2<T>::value>::type> 1598 void f(); 1599 }; 1600 )", 1601 Lang_CXX03, 1602 functionTemplateDecl(hasName("f"))); 1603 EXPECT_FALSE(testStructuralMatch(t)); 1604 } 1605 1606 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1607 DifferentValueInDependentScopeDeclRefExpr) { 1608 std::string Code = 1609 R"( 1610 template <typename> 1611 struct S1; 1612 1613 template <bool> 1614 struct enable_if; 1615 )"; 1616 auto t = makeDecls<FunctionTemplateDecl>(Code + R"( 1617 struct S 1618 { 1619 template <typename T, typename enable_if<S1<T>::value1>::type> 1620 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^ 1621 }; 1622 )", 1623 Code + R"( 1624 struct S 1625 { 1626 template <typename T, typename enable_if<S1<T>::value2>::type> 1627 void f(); 1628 }; 1629 )", 1630 Lang_CXX03, 1631 functionTemplateDecl(hasName("f"))); 1632 EXPECT_FALSE(testStructuralMatch(t)); 1633 } 1634 1635 TEST_F( 1636 StructuralEquivalenceTemplateTest, 1637 ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) { 1638 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1639 R"( 1640 template <class T> struct Primary {}; 1641 namespace N { 1642 struct Arg; 1643 } 1644 // Explicit instantiation with qualified name. 1645 template struct Primary<N::Arg>; 1646 )", 1647 R"( 1648 template <class T> struct Primary {}; 1649 namespace N { 1650 struct Arg; 1651 } 1652 using namespace N; 1653 // Explicit instantiation with UNqualified name. 1654 template struct Primary<Arg>; 1655 )", 1656 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1657 EXPECT_TRUE(testStructuralMatch(t)); 1658 } 1659 1660 TEST_F( 1661 StructuralEquivalenceTemplateTest, 1662 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) { 1663 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1664 R"( 1665 template <class T> struct Primary {}; 1666 namespace N { 1667 struct Arg { int a; }; 1668 } 1669 // Explicit instantiation with qualified name. 1670 template struct Primary<N::Arg>; 1671 )", 1672 R"( 1673 template <class T> struct Primary {}; 1674 namespace N { 1675 // This struct is not equivalent with the other in the prev TU. 1676 struct Arg { double b; }; // -- Field mismatch. 1677 } 1678 using namespace N; 1679 // Explicit instantiation with UNqualified name. 1680 template struct Primary<Arg>; 1681 )", 1682 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1683 EXPECT_FALSE(testStructuralMatch(t)); 1684 } 1685 1686 TEST_F( 1687 StructuralEquivalenceTemplateTest, 1688 ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) { 1689 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1690 R"( 1691 template <template <class> class T> struct Primary {}; 1692 namespace N { 1693 template <class T> struct Arg; 1694 } 1695 // Explicit instantiation with qualified name. 1696 template struct Primary<N::Arg>; 1697 )", 1698 R"( 1699 template <template <class> class T> struct Primary {}; 1700 namespace N { 1701 template <class T> struct Arg; 1702 } 1703 using namespace N; 1704 // Explicit instantiation with UNqualified name. 1705 template struct Primary<Arg>; 1706 )", 1707 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1708 EXPECT_TRUE(testStructuralMatch(t)); 1709 } 1710 1711 TEST_F( 1712 StructuralEquivalenceTemplateTest, 1713 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) { 1714 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1715 R"( 1716 template <template <class> class T> struct Primary {}; 1717 namespace N { 1718 template <class T> struct Arg { int a; }; 1719 } 1720 // Explicit instantiation with qualified name. 1721 template struct Primary<N::Arg>; 1722 )", 1723 R"( 1724 template <template <class> class T> struct Primary {}; 1725 namespace N { 1726 // This template is not equivalent with the other in the prev TU. 1727 template <class T> struct Arg { double b; }; // -- Field mismatch. 1728 } 1729 using namespace N; 1730 // Explicit instantiation with UNqualified name. 1731 template struct Primary<Arg>; 1732 )", 1733 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1734 EXPECT_FALSE(testStructuralMatch(t)); 1735 } 1736 1737 TEST_F(StructuralEquivalenceTemplateTest, 1738 IgnoreTemplateParmDepthAtTemplateTypeParmDecl) { 1739 auto Decls = makeDecls<ClassTemplateDecl>( 1740 R"( 1741 template<class> struct A; 1742 )", 1743 R"( 1744 template<class> struct S { 1745 template<class> friend struct A; 1746 }; 1747 )", 1748 Lang_CXX03, classTemplateDecl(hasName("A")), 1749 classTemplateDecl(hasName("A"))); 1750 EXPECT_TRUE(testStructuralMatch(Decls)); 1751 EXPECT_TRUE(testStructuralMatch(Decls, true)); 1752 } 1753 1754 TEST_F(StructuralEquivalenceTemplateTest, 1755 IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) { 1756 auto Decls = makeDecls<ClassTemplateDecl>( 1757 R"( 1758 template<class T, T U> struct A; 1759 )", 1760 R"( 1761 template<class T> struct S { 1762 template<class P, P Q> friend struct A; 1763 }; 1764 )", 1765 Lang_CXX03, classTemplateDecl(hasName("A")), 1766 classTemplateDecl(hasName("A"))); 1767 EXPECT_FALSE(testStructuralMatch(Decls)); 1768 EXPECT_TRUE(testStructuralMatch(Decls, /*IgnoreTemplateParmDepth=*/true)); 1769 } 1770 1771 TEST_F( 1772 StructuralEquivalenceTemplateTest, 1773 ClassTemplSpecWithInequivalentShadowedTemplArg) { 1774 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1775 R"( 1776 template <template <class> class T> struct Primary {}; 1777 template <class T> struct Arg { int a; }; 1778 // Explicit instantiation with ::Arg 1779 template struct Primary<Arg>; 1780 )", 1781 R"( 1782 template <template <class> class T> struct Primary {}; 1783 template <class T> struct Arg { int a; }; 1784 namespace N { 1785 // This template is not equivalent with the other in the global scope. 1786 template <class T> struct Arg { double b; }; // -- Field mismatch. 1787 // Explicit instantiation with N::Arg which shadows ::Arg 1788 template struct Primary<Arg>; 1789 } 1790 )", 1791 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1792 EXPECT_FALSE(testStructuralMatch(t)); 1793 } 1794 struct StructuralEquivalenceCacheTest : public StructuralEquivalenceTest { 1795 StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls; 1796 1797 template <typename NodeType, typename MatcherType> 1798 std::pair<NodeType *, NodeType *> 1799 findDeclPair(std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> TU, 1800 MatcherType M) { 1801 NodeType *D0 = FirstDeclMatcher<NodeType>().match(get<0>(TU), M); 1802 NodeType *D1 = FirstDeclMatcher<NodeType>().match(get<1>(TU), M); 1803 return {D0, D1}; 1804 } 1805 1806 template <typename NodeType> 1807 bool isInNonEqCache(std::pair<NodeType *, NodeType *> D, 1808 bool IgnoreTemplateParmDepth = false) { 1809 return NonEquivalentDecls.count( 1810 std::make_tuple(D.first, D.second, IgnoreTemplateParmDepth)) > 0; 1811 } 1812 }; 1813 1814 TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) { 1815 auto TU = makeTuDecls( 1816 R"( 1817 class A {}; 1818 class B {}; 1819 void x(A, A); 1820 )", 1821 R"( 1822 class A {}; 1823 class B {}; 1824 void x(A, B); 1825 )", 1826 Lang_CXX03); 1827 1828 StructuralEquivalenceContext Ctx( 1829 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1830 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1831 1832 auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x"))); 1833 EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second)); 1834 1835 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1836 TU, cxxRecordDecl(hasName("A"), unless(isImplicit()))))); 1837 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1838 TU, cxxRecordDecl(hasName("B"), unless(isImplicit()))))); 1839 } 1840 1841 TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) { 1842 auto TU = makeTuDecls( 1843 R"( 1844 bool x() { return true; } 1845 )", 1846 R"( 1847 bool x() { return false; } 1848 )", 1849 Lang_CXX03); 1850 1851 StructuralEquivalenceContext Ctx( 1852 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1853 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1854 1855 auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x"))); 1856 EXPECT_FALSE(Ctx.IsEquivalent(X.first->getBody(), X.second->getBody())); 1857 1858 } 1859 1860 TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) { 1861 auto TU = makeTuDecls( 1862 R"( 1863 int p; 1864 )", 1865 R"( 1866 int q; 1867 )", 1868 Lang_CXX03); 1869 1870 StructuralEquivalenceContext Ctx( 1871 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1872 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1873 1874 auto Var = findDeclPair<VarDecl>(TU, varDecl()); 1875 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second)); 1876 } 1877 1878 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) { 1879 auto TU = makeTuDecls( 1880 R"( 1881 int p; 1882 )", 1883 R"( 1884 static int p; 1885 )", 1886 Lang_CXX03); 1887 1888 StructuralEquivalenceContext Ctx( 1889 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1890 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1891 1892 auto Var = findDeclPair<VarDecl>(TU, varDecl()); 1893 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second)); 1894 } 1895 1896 TEST_F(StructuralEquivalenceCacheTest, 1897 NonTypeTemplateParmWithDifferentPositionNoEq) { 1898 auto TU = makeTuDecls( 1899 R"( 1900 template<int T> 1901 struct A { 1902 template<int U> 1903 void foo() {} 1904 }; 1905 )", 1906 R"( 1907 template<int U> 1908 struct A { 1909 template<int V, int T> 1910 void foo() {} 1911 }; 1912 )", 1913 Lang_CXX03); 1914 1915 StructuralEquivalenceContext Ctx( 1916 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1917 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1918 1919 auto NTTP = findDeclPair<NonTypeTemplateParmDecl>( 1920 TU, nonTypeTemplateParmDecl(hasName("T"))); 1921 EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second)); 1922 } 1923 1924 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) { 1925 auto TU = makeTuDecls( 1926 R"( 1927 int p = 1; 1928 )", 1929 R"( 1930 int p = 2; 1931 )", 1932 Lang_CXX03); 1933 1934 StructuralEquivalenceContext Ctx( 1935 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1936 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1937 1938 auto Var = findDeclPair<VarDecl>(TU, varDecl()); 1939 EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second)); 1940 } 1941 1942 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) { 1943 auto TU = makeTuDecls( 1944 R"( 1945 class A {}; 1946 class B { int i; }; 1947 void x(A *); 1948 void y(A *); 1949 class C { 1950 friend void x(A *); 1951 friend void y(A *); 1952 }; 1953 )", 1954 R"( 1955 class A {}; 1956 class B { int i; }; 1957 void x(A *); 1958 void y(B *); 1959 class C { 1960 friend void x(A *); 1961 friend void y(B *); 1962 }; 1963 )", 1964 Lang_CXX03); 1965 1966 StructuralEquivalenceContext Ctx( 1967 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1968 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1969 1970 auto C = findDeclPair<CXXRecordDecl>( 1971 TU, cxxRecordDecl(hasName("C"), unless(isImplicit()))); 1972 EXPECT_FALSE(Ctx.IsEquivalent(C.first, C.second)); 1973 1974 EXPECT_FALSE(isInNonEqCache(C)); 1975 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1976 TU, cxxRecordDecl(hasName("A"), unless(isImplicit()))))); 1977 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1978 TU, cxxRecordDecl(hasName("B"), unless(isImplicit()))))); 1979 EXPECT_FALSE(isInNonEqCache( 1980 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x"))))); 1981 EXPECT_FALSE(isInNonEqCache( 1982 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("y"))))); 1983 } 1984 1985 TEST_F(StructuralEquivalenceCacheTest, Cycle) { 1986 auto TU = makeTuDecls( 1987 R"( 1988 class C; 1989 class A { C *c; }; 1990 void x(A *); 1991 class C { 1992 friend void x(A *); 1993 }; 1994 )", 1995 R"( 1996 class C; 1997 class A { C *c; }; 1998 void x(A *); 1999 class C { 2000 friend void x(A *); 2001 }; 2002 )", 2003 Lang_CXX03); 2004 2005 StructuralEquivalenceContext Ctx( 2006 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 2007 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 2008 2009 auto C = findDeclPair<CXXRecordDecl>( 2010 TU, cxxRecordDecl(hasName("C"), unless(isImplicit()))); 2011 EXPECT_TRUE(Ctx.IsEquivalent(C.first, C.second)); 2012 2013 EXPECT_FALSE(isInNonEqCache(C)); 2014 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 2015 TU, cxxRecordDecl(hasName("A"), unless(isImplicit()))))); 2016 EXPECT_FALSE(isInNonEqCache( 2017 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x"))))); 2018 } 2019 2020 TEST_F(StructuralEquivalenceCacheTest, TemplateParmDepth) { 2021 // In 'friend struct Y' ClassTemplateDecl has the TU as parent context. 2022 // This declaration has template depth 1 (it is already inside a template). 2023 // It has not a previous declaration and is an "undeclared" friend. 2024 // 2025 // Second TU has a specialization of 'struct X'. 2026 // In this case 'friend struct Y' has the ClassTemplateSpecializationDecl as 2027 // parent. It has template depth 0 (it is in the specialization). It has the 2028 // first 'struct Y' declaration as previous declaration and canonical 2029 // declaration. 2030 // 2031 // When these two 'friend struct Y' are compared, only the template depth is 2032 // different. 2033 // FIXME: Structural equivalence checks the depth only in types, not in 2034 // TemplateParmDecl. For this reason the second 'A1' argument is needed (as a 2035 // type) in the template to make the check fail. 2036 auto TU = makeTuDecls( 2037 R"( 2038 template <class A1, A1> 2039 struct Y; 2040 2041 template <class A> 2042 struct X { 2043 template <class A1, A1> 2044 friend struct Y; 2045 }; 2046 )", 2047 R"( 2048 template <class A1, A1> 2049 struct Y; 2050 2051 template <class A> 2052 struct X { 2053 template <class A1, A1> 2054 friend struct Y; 2055 }; 2056 2057 X<int> x; 2058 )", 2059 Lang_CXX03); 2060 2061 auto *D0 = LastDeclMatcher<ClassTemplateDecl>().match( 2062 get<0>(TU), classTemplateDecl(hasName("Y"), unless(isImplicit()))); 2063 auto *D1 = LastDeclMatcher<ClassTemplateDecl>().match( 2064 get<1>(TU), classTemplateDecl(hasName("Y"), unless(isImplicit()))); 2065 ASSERT_EQ(D0->getTemplateDepth(), 1u); 2066 ASSERT_EQ(D1->getTemplateDepth(), 0u); 2067 2068 StructuralEquivalenceContext Ctx_NoIgnoreTemplateParmDepth( 2069 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 2070 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false, 2071 false, false); 2072 2073 EXPECT_FALSE(Ctx_NoIgnoreTemplateParmDepth.IsEquivalent(D0, D1)); 2074 2075 Decl *NonEqDecl0 = 2076 D0->getCanonicalDecl()->getTemplateParameters()->getParam(1); 2077 Decl *NonEqDecl1 = 2078 D1->getCanonicalDecl()->getTemplateParameters()->getParam(1); 2079 EXPECT_TRUE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), false)); 2080 EXPECT_FALSE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), true)); 2081 2082 StructuralEquivalenceContext Ctx_IgnoreTemplateParmDepth( 2083 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 2084 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false, 2085 false, true); 2086 2087 EXPECT_TRUE(Ctx_IgnoreTemplateParmDepth.IsEquivalent(D0, D1)); 2088 2089 EXPECT_FALSE(isInNonEqCache(std::make_pair(NonEqDecl0, NonEqDecl1), true)); 2090 } 2091 2092 struct StructuralEquivalenceStmtTest : StructuralEquivalenceTest {}; 2093 2094 /// Fallback matcher to be used only when there is no specific matcher for a 2095 /// Expr subclass. Remove this once all Expr subclasses have their own matcher. 2096 static auto &fallbackExprMatcher = expr; 2097 2098 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExpr) { 2099 auto t = makeWrappedStmts("lbl: &&lbl;", "lbl: &&lbl;", Lang_CXX03, 2100 addrLabelExpr()); 2101 EXPECT_TRUE(testStructuralMatch(t)); 2102 } 2103 2104 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExprDifferentLabel) { 2105 auto t = makeWrappedStmts("lbl1: lbl2: &&lbl1;", "lbl1: lbl2: &&lbl2;", 2106 Lang_CXX03, addrLabelExpr()); 2107 // FIXME: Should be false. LabelDecl are incorrectly matched. 2108 EXPECT_TRUE(testStructuralMatch(t)); 2109 } 2110 2111 static const std::string MemoryOrderSrc = R"( 2112 enum memory_order { 2113 memory_order_relaxed, 2114 memory_order_consume, 2115 memory_order_acquire, 2116 memory_order_release, 2117 memory_order_acq_rel, 2118 memory_order_seq_cst 2119 }; 2120 )"; 2121 2122 TEST_F(StructuralEquivalenceStmtTest, AtomicExpr) { 2123 std::string Prefix = "char a, b; " + MemoryOrderSrc; 2124 auto t = makeStmts( 2125 Prefix + 2126 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }", 2127 Prefix + 2128 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }", 2129 Lang_CXX03, atomicExpr()); 2130 EXPECT_TRUE(testStructuralMatch(t)); 2131 } 2132 2133 TEST_F(StructuralEquivalenceStmtTest, AtomicExprDifferentOp) { 2134 std::string Prefix = "char a, b; " + MemoryOrderSrc; 2135 auto t = makeStmts( 2136 Prefix + 2137 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }", 2138 Prefix + 2139 "void wrapped() { __atomic_store(&a, &b, memory_order_seq_cst); }", 2140 Lang_CXX03, atomicExpr()); 2141 EXPECT_FALSE(testStructuralMatch(t)); 2142 } 2143 2144 TEST_F(StructuralEquivalenceStmtTest, BinaryOperator) { 2145 auto t = makeWrappedStmts("1 + 1", "1 + 1", Lang_CXX03, binaryOperator()); 2146 EXPECT_TRUE(testStructuralMatch(t)); 2147 } 2148 2149 TEST_F(StructuralEquivalenceStmtTest, BinaryOperatorDifferentOps) { 2150 auto t = makeWrappedStmts("1 + 1", "1 - 1", Lang_CXX03, binaryOperator()); 2151 EXPECT_FALSE(testStructuralMatch(t)); 2152 } 2153 2154 TEST_F(StructuralEquivalenceStmtTest, CallExpr) { 2155 std::string Src = "int call(); int wrapped() { call(); }"; 2156 auto t = makeStmts(Src, Src, Lang_CXX03, callExpr()); 2157 EXPECT_TRUE(testStructuralMatch(t)); 2158 } 2159 2160 TEST_F(StructuralEquivalenceStmtTest, CallExprDifferentCallee) { 2161 std::string FunctionSrc = "int func1(); int func2();\n"; 2162 auto t = makeStmts(FunctionSrc + "void wrapper() { func1(); }", 2163 FunctionSrc + "void wrapper() { func2(); }", Lang_CXX03, 2164 callExpr()); 2165 EXPECT_FALSE(testStructuralMatch(t)); 2166 } 2167 2168 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteral) { 2169 auto t = makeWrappedStmts("'a'", "'a'", Lang_CXX03, characterLiteral()); 2170 EXPECT_TRUE(testStructuralMatch(t)); 2171 } 2172 2173 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteralDifferentValues) { 2174 auto t = makeWrappedStmts("'a'", "'b'", Lang_CXX03, characterLiteral()); 2175 EXPECT_FALSE(testStructuralMatch(t)); 2176 } 2177 2178 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExpr) { 2179 auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_lvalue_expr(1)", 2180 Lang_CXX03, fallbackExprMatcher()); 2181 EXPECT_TRUE(testStructuralMatch(t)); 2182 } 2183 2184 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExprDifferentKind) { 2185 auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_rvalue_expr(1)", 2186 Lang_CXX03, fallbackExprMatcher()); 2187 EXPECT_FALSE(testStructuralMatch(t)); 2188 } 2189 2190 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteral) { 2191 auto t = makeWrappedStmts("1.0", "1.0", Lang_CXX03, fallbackExprMatcher()); 2192 EXPECT_TRUE(testStructuralMatch(t)); 2193 } 2194 2195 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentSpelling) { 2196 auto t = makeWrappedStmts("0x10.1p0", "16.0625", Lang_CXX17, 2197 fallbackExprMatcher()); 2198 // Same value but with different spelling is equivalent. 2199 EXPECT_TRUE(testStructuralMatch(t)); 2200 } 2201 2202 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentType) { 2203 auto t = makeWrappedStmts("1.0", "1.0f", Lang_CXX03, fallbackExprMatcher()); 2204 EXPECT_FALSE(testStructuralMatch(t)); 2205 } 2206 2207 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentValue) { 2208 auto t = makeWrappedStmts("1.01", "1.0", Lang_CXX03, fallbackExprMatcher()); 2209 EXPECT_FALSE(testStructuralMatch(t)); 2210 } 2211 2212 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSame) { 2213 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)", 2214 "_Generic(0u, unsigned int: 0, float: 1)", Lang_C99, 2215 genericSelectionExpr()); 2216 EXPECT_TRUE(testStructuralMatch(t)); 2217 } 2218 2219 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSignsDiffer) { 2220 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)", 2221 "_Generic(0, int: 0, float: 1)", Lang_C99, 2222 genericSelectionExpr()); 2223 EXPECT_FALSE(testStructuralMatch(t)); 2224 } 2225 2226 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprOrderDiffers) { 2227 auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)", 2228 "_Generic(0u, float: 1, unsigned int: 0)", Lang_C99, 2229 genericSelectionExpr()); 2230 EXPECT_FALSE(testStructuralMatch(t)); 2231 } 2232 2233 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) { 2234 auto t = makeStmts( 2235 R"( 2236 template <typename T> 2237 void f() { 2238 T x; 2239 (void)_Generic(x, int: 0, float: 1); 2240 } 2241 void g() { f<int>(); } 2242 )", 2243 R"( 2244 template <typename T> 2245 void f() { 2246 T x; 2247 (void)_Generic(x, int: 0, float: 1); 2248 } 2249 void g() { f<int>(); } 2250 )", 2251 Lang_CXX03, genericSelectionExpr()); 2252 EXPECT_TRUE(testStructuralMatch(t)); 2253 } 2254 2255 TEST_F(StructuralEquivalenceStmtTest, 2256 GenericSelectionExprDependentResultOrderDiffers) { 2257 auto t = makeStmts( 2258 R"( 2259 template <typename T> 2260 void f() { 2261 T x; 2262 (void)_Generic(x, float: 1, int: 0); 2263 } 2264 void g() { f<int>(); } 2265 )", 2266 R"( 2267 template <typename T> 2268 void f() { 2269 T x; 2270 (void)_Generic(x, int: 0, float: 1); 2271 } 2272 void g() { f<int>(); } 2273 )", 2274 Lang_CXX03, genericSelectionExpr()); 2275 2276 EXPECT_FALSE(testStructuralMatch(t)); 2277 } 2278 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteral) { 2279 auto t = makeWrappedStmts("1", "1", Lang_CXX03, integerLiteral()); 2280 EXPECT_TRUE(testStructuralMatch(t)); 2281 } 2282 2283 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentSpelling) { 2284 auto t = makeWrappedStmts("1", "0x1", Lang_CXX03, integerLiteral()); 2285 // Same value but with different spelling is equivalent. 2286 EXPECT_TRUE(testStructuralMatch(t)); 2287 } 2288 2289 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentValue) { 2290 auto t = makeWrappedStmts("1", "2", Lang_CXX03, integerLiteral()); 2291 EXPECT_FALSE(testStructuralMatch(t)); 2292 } 2293 2294 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentTypes) { 2295 auto t = makeWrappedStmts("1", "1L", Lang_CXX03, integerLiteral()); 2296 EXPECT_FALSE(testStructuralMatch(t)); 2297 } 2298 2299 TEST_F(StructuralEquivalenceStmtTest, MemberExpr) { 2300 std::string ClassSrc = "struct C { int a; int b; };"; 2301 auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }", 2302 ClassSrc + "int wrapper() { C c; return c.a; }", 2303 Lang_CXX03, memberExpr()); 2304 EXPECT_TRUE(testStructuralMatch(t)); 2305 } 2306 2307 TEST_F(StructuralEquivalenceStmtTest, MemberExprDifferentMember) { 2308 std::string ClassSrc = "struct C { int a; int b; };"; 2309 auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }", 2310 ClassSrc + "int wrapper() { C c; return c.b; }", 2311 Lang_CXX03, memberExpr()); 2312 EXPECT_FALSE(testStructuralMatch(t)); 2313 } 2314 2315 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteral) { 2316 auto t = 2317 makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX, fallbackExprMatcher()); 2318 EXPECT_TRUE(testStructuralMatch(t)); 2319 } 2320 2321 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteralDifferentContent) { 2322 auto t = 2323 makeWrappedStmts("@\"a\"", "@\"b\"", Lang_OBJCXX, fallbackExprMatcher()); 2324 EXPECT_FALSE(testStructuralMatch(t)); 2325 } 2326 2327 TEST_F(StructuralEquivalenceStmtTest, StringLiteral) { 2328 auto t = makeWrappedStmts("\"a\"", "\"a\"", Lang_CXX03, stringLiteral()); 2329 EXPECT_TRUE(testStructuralMatch(t)); 2330 } 2331 2332 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentContent) { 2333 auto t = makeWrappedStmts("\"a\"", "\"b\"", Lang_CXX03, stringLiteral()); 2334 EXPECT_FALSE(testStructuralMatch(t)); 2335 } 2336 2337 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentLength) { 2338 auto t = makeWrappedStmts("\"a\"", "\"aa\"", Lang_CXX03, stringLiteral()); 2339 EXPECT_FALSE(testStructuralMatch(t)); 2340 } 2341 2342 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExpr) { 2343 auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(int)", Lang_CXX03, 2344 fallbackExprMatcher()); 2345 EXPECT_TRUE(testStructuralMatch(t)); 2346 } 2347 2348 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentType) { 2349 auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(long)", Lang_CXX03, 2350 fallbackExprMatcher()); 2351 EXPECT_FALSE(testStructuralMatch(t)); 2352 } 2353 2354 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTrait) { 2355 auto t = makeWrappedStmts( 2356 "__is_pod(int)", "__is_trivially_constructible(int)", Lang_CXX03, expr()); 2357 EXPECT_FALSE(testStructuralMatch(t)); 2358 } 2359 2360 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTraits) { 2361 auto t = makeWrappedStmts("__is_constructible(int)", 2362 "__is_constructible(int, int)", Lang_CXX03, expr()); 2363 EXPECT_FALSE(testStructuralMatch(t)); 2364 } 2365 2366 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExpr) { 2367 auto t = makeWrappedStmts("sizeof(int)", "sizeof(int)", Lang_CXX03, 2368 unaryExprOrTypeTraitExpr()); 2369 EXPECT_TRUE(testStructuralMatch(t)); 2370 } 2371 2372 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentKind) { 2373 auto t = makeWrappedStmts("sizeof(int)", "alignof(long)", Lang_CXX11, 2374 unaryExprOrTypeTraitExpr()); 2375 EXPECT_FALSE(testStructuralMatch(t)); 2376 } 2377 2378 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentType) { 2379 auto t = makeWrappedStmts("sizeof(int)", "sizeof(long)", Lang_CXX03, 2380 unaryExprOrTypeTraitExpr()); 2381 EXPECT_FALSE(testStructuralMatch(t)); 2382 } 2383 2384 TEST_F(StructuralEquivalenceStmtTest, UnaryOperator) { 2385 auto t = makeWrappedStmts("+1", "+1", Lang_CXX03, unaryOperator()); 2386 EXPECT_TRUE(testStructuralMatch(t)); 2387 } 2388 2389 TEST_F(StructuralEquivalenceStmtTest, UnaryOperatorDifferentOps) { 2390 auto t = makeWrappedStmts("+1", "-1", Lang_CXX03, unaryOperator()); 2391 EXPECT_FALSE(testStructuralMatch(t)); 2392 } 2393 2394 TEST_F(StructuralEquivalenceStmtTest, 2395 CXXOperatorCallExprVsUnaryBinaryOperator) { 2396 auto t = makeNamedDecls( 2397 R"( 2398 template <typename T, T x> 2399 class A; 2400 template <typename T, T x, T y> 2401 void foo( 2402 A<T, x + y>, 2403 A<T, x - y>, 2404 A<T, -x>, 2405 A<T, x * y>, 2406 A<T, *x>, 2407 A<T, x / y>, 2408 A<T, x % y>, 2409 A<T, x ^ y>, 2410 A<T, x & y>, 2411 A<T, &x>, 2412 A<T, x | y>, 2413 A<T, ~x>, 2414 A<T, !x>, 2415 A<T, x < y>, 2416 A<T, (x > y)>, 2417 A<T, x << y>, 2418 A<T, (x >> y)>, 2419 A<T, x == y>, 2420 A<T, x != y>, 2421 A<T, x <= y>, 2422 A<T, x >= y>, 2423 A<T, x <=> y>, 2424 A<T, x && y>, 2425 A<T, x || y>, 2426 A<T, ++x>, 2427 A<T, --x>, 2428 A<T, (x , y)>, 2429 A<T, x ->* y>, 2430 A<T, x -> y> 2431 ); 2432 )", 2433 R"( 2434 struct Bar { 2435 Bar& operator=(Bar&); 2436 Bar& operator->(); 2437 }; 2438 2439 Bar& operator+(Bar&, Bar&); 2440 Bar& operator+(Bar&); 2441 Bar& operator-(Bar&, Bar&); 2442 Bar& operator-(Bar&); 2443 Bar& operator*(Bar&, Bar&); 2444 Bar& operator*(Bar&); 2445 Bar& operator/(Bar&, Bar&); 2446 Bar& operator%(Bar&, Bar&); 2447 Bar& operator^(Bar&, Bar&); 2448 Bar& operator&(Bar&, Bar&); 2449 Bar& operator&(Bar&); 2450 Bar& operator|(Bar&, Bar&); 2451 Bar& operator~(Bar&); 2452 Bar& operator!(Bar&); 2453 Bar& operator<(Bar&, Bar&); 2454 Bar& operator>(Bar&, Bar&); 2455 Bar& operator+=(Bar&, Bar&); 2456 Bar& operator-=(Bar&, Bar&); 2457 Bar& operator*=(Bar&, Bar&); 2458 Bar& operator/=(Bar&, Bar&); 2459 Bar& operator%=(Bar&, Bar&); 2460 Bar& operator^=(Bar&, Bar&); 2461 Bar& operator&=(Bar&, Bar&); 2462 Bar& operator|=(Bar&, Bar&); 2463 Bar& operator<<(Bar&, Bar&); 2464 Bar& operator>>(Bar&, Bar&); 2465 Bar& operator<<=(Bar&, Bar&); 2466 Bar& operator>>=(Bar&, Bar&); 2467 Bar& operator==(Bar&, Bar&); 2468 Bar& operator!=(Bar&, Bar&); 2469 Bar& operator<=(Bar&, Bar&); 2470 Bar& operator>=(Bar&, Bar&); 2471 Bar& operator<=>(Bar&, Bar&); 2472 Bar& operator&&(Bar&, Bar&); 2473 Bar& operator||(Bar&, Bar&); 2474 Bar& operator++(Bar&); 2475 Bar& operator--(Bar&); 2476 Bar& operator,(Bar&, Bar&); 2477 Bar& operator->*(Bar&, Bar&); 2478 2479 template <typename T, T x> 2480 class A; 2481 template <typename T, T x, T y> 2482 void foo( 2483 A<T, x + y>, 2484 A<T, x - y>, 2485 A<T, -x>, 2486 A<T, x * y>, 2487 A<T, *x>, 2488 A<T, x / y>, 2489 A<T, x % y>, 2490 A<T, x ^ y>, 2491 A<T, x & y>, 2492 A<T, &x>, 2493 A<T, x | y>, 2494 A<T, ~x>, 2495 A<T, !x>, 2496 A<T, x < y>, 2497 A<T, (x > y)>, 2498 A<T, x << y>, 2499 A<T, (x >> y)>, 2500 A<T, x == y>, 2501 A<T, x != y>, 2502 A<T, x <= y>, 2503 A<T, x >= y>, 2504 A<T, x <=> y>, 2505 A<T, x && y>, 2506 A<T, x || y>, 2507 A<T, ++x>, 2508 A<T, --x>, 2509 A<T, (x , y)>, 2510 A<T, x ->* y>, 2511 A<T, x -> y> 2512 ); 2513 )", 2514 Lang_CXX20); 2515 EXPECT_TRUE(testStructuralMatch(t)); 2516 } 2517 2518 TEST_F(StructuralEquivalenceStmtTest, 2519 CXXOperatorCallExprVsUnaryBinaryOperatorNe) { 2520 auto t = makeNamedDecls( 2521 R"( 2522 template <typename T, T x> 2523 class A; 2524 template <typename T, T x, T y> 2525 void foo( 2526 A<T, x + y> 2527 ); 2528 )", 2529 R"( 2530 struct Bar; 2531 2532 Bar& operator-(Bar&, Bar&); 2533 2534 template <typename T, T x> 2535 class A; 2536 template <typename T, T x, T y> 2537 void foo( 2538 A<T, x - y> 2539 ); 2540 )", 2541 Lang_CXX11); 2542 EXPECT_FALSE(testStructuralMatch(t)); 2543 } 2544 2545 TEST_F(StructuralEquivalenceStmtTest, NonTypeTemplateParm) { 2546 auto t = makeNamedDecls( 2547 R"( 2548 template <typename T, T x> 2549 class A; 2550 template <typename T, T x, T y> 2551 void foo(A<T, x>); 2552 )", 2553 R"( 2554 template <typename T, T x> 2555 class A; 2556 template <typename T, T x, T y> 2557 void foo(A<T, y>); 2558 )", 2559 Lang_CXX11); 2560 EXPECT_FALSE(testStructuralMatch(t)); 2561 } 2562 2563 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) { 2564 auto t = makeStmts( 2565 R"( 2566 void f1(int); 2567 template <typename T> 2568 void f(T t) { 2569 f1(t); 2570 } 2571 void g() { f<int>(1); } 2572 )", 2573 R"( 2574 void f2(int); 2575 template <typename T> 2576 void f(T t) { 2577 f2(t); 2578 } 2579 void g() { f<int>(1); } 2580 )", 2581 Lang_CXX03, unresolvedLookupExpr()); 2582 EXPECT_FALSE(testStructuralMatch(t)); 2583 } 2584 2585 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentQualifier) { 2586 auto t = makeStmts( 2587 R"( 2588 struct X { 2589 static void g(int); 2590 static void g(char); 2591 }; 2592 2593 template <typename T> 2594 void f(T t) { 2595 X::g(t); 2596 } 2597 2598 void g() { f<int>(1); } 2599 )", 2600 R"( 2601 struct Y { 2602 static void g(int); 2603 static void g(char); 2604 }; 2605 2606 template <typename T> 2607 void f(T t) { 2608 Y::g(t); 2609 } 2610 2611 void g() { f<int>(1); } 2612 )", 2613 Lang_CXX03, unresolvedLookupExpr()); 2614 EXPECT_FALSE(testStructuralMatch(t)); 2615 } 2616 2617 TEST_F(StructuralEquivalenceStmtTest, 2618 UnresolvedLookupDifferentTemplateArgument) { 2619 auto t = makeStmts( 2620 R"( 2621 struct A {}; 2622 template<typename T1, typename T2> 2623 void g() {} 2624 2625 template <typename T> 2626 void f() { 2627 g<A, T>(); 2628 } 2629 2630 void h() { f<int>(); } 2631 )", 2632 R"( 2633 struct B {}; 2634 template<typename T1, typename T2> 2635 void g() {} 2636 2637 template <typename T> 2638 void f() { 2639 g<B, T>(); 2640 } 2641 2642 void h() { f<int>(); } 2643 )", 2644 Lang_CXX03, unresolvedLookupExpr()); 2645 EXPECT_FALSE(testStructuralMatch(t)); 2646 } 2647 2648 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) { 2649 auto t = makeStmts( 2650 R"( 2651 struct A {}; 2652 struct B { 2653 template<typename T1, typename T2> 2654 static void g(int) {}; 2655 template<typename T1, typename T2> 2656 static void g(char) {}; 2657 }; 2658 2659 template <typename T1, typename T2> 2660 void f(T2 x) { 2661 B::g<A, T1>(x); 2662 } 2663 2664 void g() { f<char, int>(1); } 2665 )", 2666 R"( 2667 struct A {}; 2668 struct B { 2669 template<typename T1, typename T2> 2670 static void g(int) {}; 2671 template<typename T1, typename T2> 2672 static void g(char) {}; 2673 }; 2674 2675 template <typename T1, typename T2> 2676 void f(T2 x) { 2677 B::g<A, T1>(x); 2678 } 2679 2680 void g() { f<char, int>(1); } 2681 )", 2682 Lang_CXX03, unresolvedLookupExpr()); 2683 EXPECT_TRUE(testStructuralMatch(t)); 2684 } 2685 2686 TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) { 2687 auto S = makeStmts( 2688 R"( 2689 void foo() { 2690 goto L1; 2691 L1: foo(); 2692 } 2693 )", 2694 R"( 2695 void foo() { 2696 goto L2; 2697 L2: foo(); 2698 } 2699 )", 2700 Lang_CXX03, gotoStmt()); 2701 EXPECT_FALSE(testStructuralMatch(S)); 2702 } 2703 2704 TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) { 2705 std::string Prefix = "enum Test { AAA, BBB };"; 2706 auto t = makeStmts( 2707 Prefix + "void foo(int i) {if (i > 0) {i = AAA;} else {i = BBB;}}", 2708 Prefix + "void foo(int i) {if (i > 0) {i = BBB;} else {i = AAA;}}", 2709 Lang_CXX03, ifStmt()); 2710 EXPECT_FALSE(testStructuralMatch(t)); 2711 } 2712 2713 TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) { 2714 auto S = makeStmts( 2715 R"( 2716 template <class T> 2717 void foo() { 2718 (void)T().x; 2719 } 2720 struct A { int x; }; 2721 void bar() { 2722 foo<A>(); 2723 } 2724 )", 2725 R"( 2726 template <class T> 2727 void foo() { 2728 (void)T().y; 2729 } 2730 struct A { int y; }; 2731 void bar() { 2732 foo<A>(); 2733 } 2734 )", 2735 Lang_CXX11, cxxDependentScopeMemberExpr()); 2736 EXPECT_FALSE(testStructuralMatch(S)); 2737 } 2738 2739 } // end namespace ast_matchers 2740 } // end namespace clang 2741