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