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 StructuralEquivalenceEnumTest : StructuralEquivalenceTest {}; 933 934 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) { 935 auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11); 936 EXPECT_TRUE(testStructuralMatch(t)); 937 } 938 939 TEST_F(StructuralEquivalenceEnumTest, 940 FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) { 941 auto t = 942 makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11); 943 EXPECT_TRUE(testStructuralMatch(t)); 944 } 945 946 TEST_F(StructuralEquivalenceEnumTest, 947 EnumShouldBeEqualWithEnumWhichHasDefinition) { 948 auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };", 949 Lang_CXX11); 950 EXPECT_TRUE(testStructuralMatch(t)); 951 } 952 953 TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) { 954 auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };", 955 Lang_CXX11); 956 EXPECT_FALSE(testStructuralMatch(t)); 957 } 958 959 struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {}; 960 961 TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) { 962 auto t = makeNamedDecls("template <class T> struct foo;", 963 "template <class T> struct foo;", Lang_CXX03); 964 EXPECT_TRUE(testStructuralMatch(t)); 965 } 966 967 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) { 968 auto t = makeNamedDecls("template <class T> struct foo;", 969 "template <class U> struct foo;", Lang_CXX03); 970 EXPECT_TRUE(testStructuralMatch(t)); 971 } 972 973 TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) { 974 auto t = makeNamedDecls("template <class T> struct foo;", 975 "template <int T> struct foo;", Lang_CXX03); 976 EXPECT_FALSE(testStructuralMatch(t)); 977 } 978 979 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) { 980 auto Decls = makeNamedDecls( 981 "template <bool b> struct foo {explicit(b) foo(int);};", 982 "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX20); 983 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match( 984 get<0>(Decls), cxxConstructorDecl(hasName("foo<b>"))); 985 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match( 986 get<1>(Decls), cxxConstructorDecl(hasName("foo<b>"))); 987 EXPECT_TRUE(testStructuralMatch(First, Second)); 988 } 989 990 TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) { 991 auto Decls = makeNamedDecls( 992 "template <bool b> struct foo {explicit(b) foo(int);};", 993 "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX20); 994 CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match( 995 get<0>(Decls), cxxConstructorDecl(hasName("foo<b>"))); 996 CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match( 997 get<1>(Decls), cxxConstructorDecl(hasName("foo<b>"))); 998 EXPECT_FALSE(testStructuralMatch(First, Second)); 999 } 1000 1001 TEST_F(StructuralEquivalenceTemplateTest, 1002 TemplateVsSubstTemplateTemplateParmInArgEq) { 1003 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1004 R"( 1005 template <typename P1> class Arg { }; 1006 template <template <typename PP1> class P1> class Primary { }; 1007 1008 void f() { 1009 // Make specialization with simple template. 1010 Primary <Arg> A; 1011 } 1012 )", 1013 R"( 1014 template <typename P1> class Arg { }; 1015 template <template <typename PP1> class P1> class Primary { }; 1016 1017 template <template <typename PP1> class P1> class Templ { 1018 void f() { 1019 // Make specialization with substituted template template param. 1020 Primary <P1> A; 1021 }; 1022 }; 1023 1024 // Instantiate with substitution Arg into P1. 1025 template class Templ <Arg>; 1026 )", 1027 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1028 EXPECT_TRUE(testStructuralMatch(t)); 1029 } 1030 1031 TEST_F(StructuralEquivalenceTemplateTest, 1032 TemplateVsSubstTemplateTemplateParmInArgNotEq) { 1033 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1034 R"( 1035 template <typename P1> class Arg { }; 1036 template <template <typename PP1> class P1> class Primary { }; 1037 1038 void f() { 1039 // Make specialization with simple template. 1040 Primary <Arg> A; 1041 } 1042 )", 1043 R"( 1044 // Arg is different from the other, this should cause non-equivalence. 1045 template <typename P1> class Arg { int X; }; 1046 template <template <typename PP1> class P1> class Primary { }; 1047 1048 template <template <typename PP1> class P1> class Templ { 1049 void f() { 1050 // Make specialization with substituted template template param. 1051 Primary <P1> A; 1052 }; 1053 }; 1054 1055 // Instantiate with substitution Arg into P1. 1056 template class Templ <Arg>; 1057 )", 1058 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1059 EXPECT_FALSE(testStructuralMatch(t)); 1060 } 1061 1062 struct StructuralEquivalenceDependentTemplateArgsTest 1063 : StructuralEquivalenceTemplateTest {}; 1064 1065 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1066 SameStructsInDependentArgs) { 1067 std::string Code = 1068 R"( 1069 template <typename> 1070 struct S1; 1071 1072 template <typename> 1073 struct enable_if; 1074 1075 struct S 1076 { 1077 template <typename T, typename enable_if<S1<T>>::type> 1078 void f(); 1079 }; 1080 )"; 1081 auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11, 1082 functionTemplateDecl(hasName("f"))); 1083 EXPECT_TRUE(testStructuralMatch(t)); 1084 } 1085 1086 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1087 DifferentStructsInDependentArgs) { 1088 std::string Code = 1089 R"( 1090 template <typename> 1091 struct S1; 1092 1093 template <typename> 1094 struct S2; 1095 1096 template <typename> 1097 struct enable_if; 1098 )"; 1099 auto t = makeDecls<FunctionTemplateDecl>(Code + R"( 1100 struct S 1101 { 1102 template <typename T, typename enable_if<S1<T>>::type> 1103 void f(); 1104 }; 1105 )", 1106 Code + R"( 1107 struct S 1108 { 1109 template <typename T, typename enable_if<S2<T>>::type> 1110 void f(); 1111 }; 1112 )", 1113 Lang_CXX11, 1114 functionTemplateDecl(hasName("f"))); 1115 EXPECT_FALSE(testStructuralMatch(t)); 1116 } 1117 1118 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1119 SameStructsInDependentScopeDeclRefExpr) { 1120 std::string Code = 1121 R"( 1122 template <typename> 1123 struct S1; 1124 1125 template <bool> 1126 struct enable_if; 1127 1128 struct S 1129 { 1130 template <typename T, typename enable_if<S1<T>::value>::type> 1131 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^ 1132 }; 1133 )"; 1134 auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11, 1135 functionTemplateDecl(hasName("f"))); 1136 EXPECT_TRUE(testStructuralMatch(t)); 1137 } 1138 1139 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1140 DifferentStructsInDependentScopeDeclRefExpr) { 1141 std::string Code = 1142 R"( 1143 template <typename> 1144 struct S1; 1145 1146 template <typename> 1147 struct S2; 1148 1149 template <bool> 1150 struct enable_if; 1151 )"; 1152 auto t = makeDecls<FunctionTemplateDecl>(Code + R"( 1153 struct S 1154 { 1155 template <typename T, typename enable_if<S1<T>::value>::type> 1156 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^ 1157 }; 1158 )", 1159 Code + R"( 1160 struct S 1161 { 1162 template <typename T, typename enable_if<S2<T>::value>::type> 1163 void f(); 1164 }; 1165 )", 1166 Lang_CXX03, 1167 functionTemplateDecl(hasName("f"))); 1168 EXPECT_FALSE(testStructuralMatch(t)); 1169 } 1170 1171 TEST_F(StructuralEquivalenceDependentTemplateArgsTest, 1172 DifferentValueInDependentScopeDeclRefExpr) { 1173 std::string Code = 1174 R"( 1175 template <typename> 1176 struct S1; 1177 1178 template <bool> 1179 struct enable_if; 1180 )"; 1181 auto t = makeDecls<FunctionTemplateDecl>(Code + R"( 1182 struct S 1183 { 1184 template <typename T, typename enable_if<S1<T>::value1>::type> 1185 void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^ 1186 }; 1187 )", 1188 Code + R"( 1189 struct S 1190 { 1191 template <typename T, typename enable_if<S1<T>::value2>::type> 1192 void f(); 1193 }; 1194 )", 1195 Lang_CXX03, 1196 functionTemplateDecl(hasName("f"))); 1197 EXPECT_FALSE(testStructuralMatch(t)); 1198 } 1199 1200 TEST_F( 1201 StructuralEquivalenceTemplateTest, 1202 ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) { 1203 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1204 R"( 1205 template <class T> struct Primary {}; 1206 namespace N { 1207 struct Arg; 1208 } 1209 // Explicit instantiation with qualified name. 1210 template struct Primary<N::Arg>; 1211 )", 1212 R"( 1213 template <class T> struct Primary {}; 1214 namespace N { 1215 struct Arg; 1216 } 1217 using namespace N; 1218 // Explicit instantiation with UNqualified name. 1219 template struct Primary<Arg>; 1220 )", 1221 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1222 EXPECT_TRUE(testStructuralMatch(t)); 1223 } 1224 1225 TEST_F( 1226 StructuralEquivalenceTemplateTest, 1227 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) { 1228 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1229 R"( 1230 template <class T> struct Primary {}; 1231 namespace N { 1232 struct Arg { int a; }; 1233 } 1234 // Explicit instantiation with qualified name. 1235 template struct Primary<N::Arg>; 1236 )", 1237 R"( 1238 template <class T> struct Primary {}; 1239 namespace N { 1240 // This struct is not equivalent with the other in the prev TU. 1241 struct Arg { double b; }; // -- Field mismatch. 1242 } 1243 using namespace N; 1244 // Explicit instantiation with UNqualified name. 1245 template struct Primary<Arg>; 1246 )", 1247 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1248 EXPECT_FALSE(testStructuralMatch(t)); 1249 } 1250 1251 TEST_F( 1252 StructuralEquivalenceTemplateTest, 1253 ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) { 1254 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1255 R"( 1256 template <template <class> class T> struct Primary {}; 1257 namespace N { 1258 template <class T> struct Arg; 1259 } 1260 // Explicit instantiation with qualified name. 1261 template struct Primary<N::Arg>; 1262 )", 1263 R"( 1264 template <template <class> class T> struct Primary {}; 1265 namespace N { 1266 template <class T> struct Arg; 1267 } 1268 using namespace N; 1269 // Explicit instantiation with UNqualified name. 1270 template struct Primary<Arg>; 1271 )", 1272 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1273 EXPECT_TRUE(testStructuralMatch(t)); 1274 } 1275 1276 TEST_F( 1277 StructuralEquivalenceTemplateTest, 1278 ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) { 1279 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1280 R"( 1281 template <template <class> class T> struct Primary {}; 1282 namespace N { 1283 template <class T> struct Arg { int a; }; 1284 } 1285 // Explicit instantiation with qualified name. 1286 template struct Primary<N::Arg>; 1287 )", 1288 R"( 1289 template <template <class> class T> struct Primary {}; 1290 namespace N { 1291 // This template is not equivalent with the other in the prev TU. 1292 template <class T> struct Arg { double b; }; // -- Field mismatch. 1293 } 1294 using namespace N; 1295 // Explicit instantiation with UNqualified name. 1296 template struct Primary<Arg>; 1297 )", 1298 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1299 EXPECT_FALSE(testStructuralMatch(t)); 1300 } 1301 1302 TEST_F( 1303 StructuralEquivalenceTemplateTest, 1304 ClassTemplSpecWithInequivalentShadowedTemplArg) { 1305 auto t = makeDecls<ClassTemplateSpecializationDecl>( 1306 R"( 1307 template <template <class> class T> struct Primary {}; 1308 template <class T> struct Arg { int a; }; 1309 // Explicit instantiation with ::Arg 1310 template struct Primary<Arg>; 1311 )", 1312 R"( 1313 template <template <class> class T> struct Primary {}; 1314 template <class T> struct Arg { int a; }; 1315 namespace N { 1316 // This template is not equivalent with the other in the global scope. 1317 template <class T> struct Arg { double b; }; // -- Field mismatch. 1318 // Explicit instantiation with N::Arg which shadows ::Arg 1319 template struct Primary<Arg>; 1320 } 1321 )", 1322 Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary"))); 1323 EXPECT_FALSE(testStructuralMatch(t)); 1324 } 1325 struct StructuralEquivalenceCacheTest : public StructuralEquivalenceTest { 1326 llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls; 1327 1328 template <typename NodeType, typename MatcherType> 1329 std::pair<NodeType *, NodeType *> 1330 findDeclPair(std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> TU, 1331 MatcherType M) { 1332 NodeType *D0 = FirstDeclMatcher<NodeType>().match(get<0>(TU), M); 1333 NodeType *D1 = FirstDeclMatcher<NodeType>().match(get<1>(TU), M); 1334 return {D0, D1}; 1335 } 1336 1337 template <typename NodeType> 1338 bool isInNonEqCache(std::pair<NodeType *, NodeType *> D) { 1339 return NonEquivalentDecls.count(D) > 0; 1340 } 1341 }; 1342 1343 TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) { 1344 auto TU = makeTuDecls( 1345 R"( 1346 class A {}; 1347 class B {}; 1348 void x(A, A); 1349 )", 1350 R"( 1351 class A {}; 1352 class B {}; 1353 void x(A, B); 1354 )", 1355 Lang_CXX03); 1356 1357 StructuralEquivalenceContext Ctx( 1358 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1359 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1360 1361 auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x"))); 1362 EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second)); 1363 1364 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1365 TU, cxxRecordDecl(hasName("A"), unless(isImplicit()))))); 1366 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1367 TU, cxxRecordDecl(hasName("B"), unless(isImplicit()))))); 1368 } 1369 1370 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) { 1371 auto TU = makeTuDecls( 1372 R"( 1373 class A {}; 1374 class B { int i; }; 1375 void x(A *); 1376 void y(A *); 1377 class C { 1378 friend void x(A *); 1379 friend void y(A *); 1380 }; 1381 )", 1382 R"( 1383 class A {}; 1384 class B { int i; }; 1385 void x(A *); 1386 void y(B *); 1387 class C { 1388 friend void x(A *); 1389 friend void y(B *); 1390 }; 1391 )", 1392 Lang_CXX03); 1393 1394 StructuralEquivalenceContext Ctx( 1395 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1396 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1397 1398 auto C = findDeclPair<CXXRecordDecl>( 1399 TU, cxxRecordDecl(hasName("C"), unless(isImplicit()))); 1400 EXPECT_FALSE(Ctx.IsEquivalent(C.first, C.second)); 1401 1402 EXPECT_FALSE(isInNonEqCache(C)); 1403 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1404 TU, cxxRecordDecl(hasName("A"), unless(isImplicit()))))); 1405 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1406 TU, cxxRecordDecl(hasName("B"), unless(isImplicit()))))); 1407 EXPECT_FALSE(isInNonEqCache( 1408 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x"))))); 1409 EXPECT_FALSE(isInNonEqCache( 1410 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("y"))))); 1411 } 1412 1413 TEST_F(StructuralEquivalenceCacheTest, Cycle) { 1414 auto TU = makeTuDecls( 1415 R"( 1416 class C; 1417 class A { C *c; }; 1418 void x(A *); 1419 class C { 1420 friend void x(A *); 1421 }; 1422 )", 1423 R"( 1424 class C; 1425 class A { C *c; }; 1426 void x(A *); 1427 class C { 1428 friend void x(A *); 1429 }; 1430 )", 1431 Lang_CXX03); 1432 1433 StructuralEquivalenceContext Ctx( 1434 get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(), 1435 NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false); 1436 1437 auto C = findDeclPair<CXXRecordDecl>( 1438 TU, cxxRecordDecl(hasName("C"), unless(isImplicit()))); 1439 EXPECT_TRUE(Ctx.IsEquivalent(C.first, C.second)); 1440 1441 EXPECT_FALSE(isInNonEqCache(C)); 1442 EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>( 1443 TU, cxxRecordDecl(hasName("A"), unless(isImplicit()))))); 1444 EXPECT_FALSE(isInNonEqCache( 1445 findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x"))))); 1446 } 1447 1448 struct StructuralEquivalenceStmtTest : StructuralEquivalenceTest {}; 1449 1450 /// Fallback matcher to be used only when there is no specific matcher for a 1451 /// Expr subclass. Remove this once all Expr subclasses have their own matcher. 1452 static auto &fallbackExprMatcher = expr; 1453 1454 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExpr) { 1455 auto t = makeWrappedStmts("lbl: &&lbl;", "lbl: &&lbl;", Lang_CXX03, 1456 addrLabelExpr()); 1457 EXPECT_TRUE(testStructuralMatch(t)); 1458 } 1459 1460 TEST_F(StructuralEquivalenceStmtTest, AddrLabelExprDifferentLabel) { 1461 auto t = makeWrappedStmts("lbl1: lbl2: &&lbl1;", "lbl1: lbl2: &&lbl2;", 1462 Lang_CXX03, addrLabelExpr()); 1463 // FIXME: Should be false. LabelDecl are incorrectly matched. 1464 EXPECT_TRUE(testStructuralMatch(t)); 1465 } 1466 1467 static const std::string MemoryOrderSrc = R"( 1468 enum memory_order { 1469 memory_order_relaxed, 1470 memory_order_consume, 1471 memory_order_acquire, 1472 memory_order_release, 1473 memory_order_acq_rel, 1474 memory_order_seq_cst 1475 }; 1476 )"; 1477 1478 TEST_F(StructuralEquivalenceStmtTest, AtomicExpr) { 1479 std::string Prefix = "char a, b; " + MemoryOrderSrc; 1480 auto t = makeStmts( 1481 Prefix + 1482 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }", 1483 Prefix + 1484 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }", 1485 Lang_CXX03, atomicExpr()); 1486 EXPECT_TRUE(testStructuralMatch(t)); 1487 } 1488 1489 TEST_F(StructuralEquivalenceStmtTest, AtomicExprDifferentOp) { 1490 std::string Prefix = "char a, b; " + MemoryOrderSrc; 1491 auto t = makeStmts( 1492 Prefix + 1493 "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }", 1494 Prefix + 1495 "void wrapped() { __atomic_store(&a, &b, memory_order_seq_cst); }", 1496 Lang_CXX03, atomicExpr()); 1497 EXPECT_FALSE(testStructuralMatch(t)); 1498 } 1499 1500 TEST_F(StructuralEquivalenceStmtTest, BinaryOperator) { 1501 auto t = makeWrappedStmts("1 + 1", "1 + 1", Lang_CXX03, binaryOperator()); 1502 EXPECT_TRUE(testStructuralMatch(t)); 1503 } 1504 1505 TEST_F(StructuralEquivalenceStmtTest, BinaryOperatorDifferentOps) { 1506 auto t = makeWrappedStmts("1 + 1", "1 - 1", Lang_CXX03, binaryOperator()); 1507 EXPECT_FALSE(testStructuralMatch(t)); 1508 } 1509 1510 TEST_F(StructuralEquivalenceStmtTest, CallExpr) { 1511 std::string Src = "int call(); int wrapped() { call(); }"; 1512 auto t = makeStmts(Src, Src, Lang_CXX03, callExpr()); 1513 EXPECT_TRUE(testStructuralMatch(t)); 1514 } 1515 1516 TEST_F(StructuralEquivalenceStmtTest, CallExprDifferentCallee) { 1517 std::string FunctionSrc = "int func1(); int func2();\n"; 1518 auto t = makeStmts(FunctionSrc + "void wrapper() { func1(); }", 1519 FunctionSrc + "void wrapper() { func2(); }", Lang_CXX03, 1520 callExpr()); 1521 EXPECT_FALSE(testStructuralMatch(t)); 1522 } 1523 1524 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteral) { 1525 auto t = makeWrappedStmts("'a'", "'a'", Lang_CXX03, characterLiteral()); 1526 EXPECT_TRUE(testStructuralMatch(t)); 1527 } 1528 1529 TEST_F(StructuralEquivalenceStmtTest, CharacterLiteralDifferentValues) { 1530 auto t = makeWrappedStmts("'a'", "'b'", Lang_CXX03, characterLiteral()); 1531 EXPECT_FALSE(testStructuralMatch(t)); 1532 } 1533 1534 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExpr) { 1535 auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_lvalue_expr(1)", 1536 Lang_CXX03, fallbackExprMatcher()); 1537 EXPECT_TRUE(testStructuralMatch(t)); 1538 } 1539 1540 TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExprDifferentKind) { 1541 auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_rvalue_expr(1)", 1542 Lang_CXX03, fallbackExprMatcher()); 1543 EXPECT_FALSE(testStructuralMatch(t)); 1544 } 1545 1546 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteral) { 1547 auto t = makeWrappedStmts("1.0", "1.0", Lang_CXX03, fallbackExprMatcher()); 1548 EXPECT_TRUE(testStructuralMatch(t)); 1549 } 1550 1551 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentSpelling) { 1552 auto t = makeWrappedStmts("0x10.1p0", "16.0625", Lang_CXX17, 1553 fallbackExprMatcher()); 1554 // Same value but with different spelling is equivalent. 1555 EXPECT_TRUE(testStructuralMatch(t)); 1556 } 1557 1558 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentType) { 1559 auto t = makeWrappedStmts("1.0", "1.0f", Lang_CXX03, fallbackExprMatcher()); 1560 EXPECT_FALSE(testStructuralMatch(t)); 1561 } 1562 1563 TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentValue) { 1564 auto t = makeWrappedStmts("1.01", "1.0", Lang_CXX03, fallbackExprMatcher()); 1565 EXPECT_FALSE(testStructuralMatch(t)); 1566 } 1567 1568 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteral) { 1569 auto t = makeWrappedStmts("1", "1", Lang_CXX03, integerLiteral()); 1570 EXPECT_TRUE(testStructuralMatch(t)); 1571 } 1572 1573 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentSpelling) { 1574 auto t = makeWrappedStmts("1", "0x1", Lang_CXX03, integerLiteral()); 1575 // Same value but with different spelling is equivalent. 1576 EXPECT_TRUE(testStructuralMatch(t)); 1577 } 1578 1579 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentValue) { 1580 auto t = makeWrappedStmts("1", "2", Lang_CXX03, integerLiteral()); 1581 EXPECT_FALSE(testStructuralMatch(t)); 1582 } 1583 1584 TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentTypes) { 1585 auto t = makeWrappedStmts("1", "1L", Lang_CXX03, integerLiteral()); 1586 EXPECT_FALSE(testStructuralMatch(t)); 1587 } 1588 1589 TEST_F(StructuralEquivalenceStmtTest, MemberExpr) { 1590 std::string ClassSrc = "struct C { int a; int b; };"; 1591 auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }", 1592 ClassSrc + "int wrapper() { C c; return c.a; }", 1593 Lang_CXX03, memberExpr()); 1594 EXPECT_TRUE(testStructuralMatch(t)); 1595 } 1596 1597 TEST_F(StructuralEquivalenceStmtTest, MemberExprDifferentMember) { 1598 std::string ClassSrc = "struct C { int a; int b; };"; 1599 auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }", 1600 ClassSrc + "int wrapper() { C c; return c.b; }", 1601 Lang_CXX03, memberExpr()); 1602 EXPECT_FALSE(testStructuralMatch(t)); 1603 } 1604 1605 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteral) { 1606 auto t = 1607 makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX, fallbackExprMatcher()); 1608 EXPECT_TRUE(testStructuralMatch(t)); 1609 } 1610 1611 TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteralDifferentContent) { 1612 auto t = 1613 makeWrappedStmts("@\"a\"", "@\"b\"", Lang_OBJCXX, fallbackExprMatcher()); 1614 EXPECT_FALSE(testStructuralMatch(t)); 1615 } 1616 1617 TEST_F(StructuralEquivalenceStmtTest, StringLiteral) { 1618 auto t = makeWrappedStmts("\"a\"", "\"a\"", Lang_CXX03, stringLiteral()); 1619 EXPECT_TRUE(testStructuralMatch(t)); 1620 } 1621 1622 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentContent) { 1623 auto t = makeWrappedStmts("\"a\"", "\"b\"", Lang_CXX03, stringLiteral()); 1624 EXPECT_FALSE(testStructuralMatch(t)); 1625 } 1626 1627 TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentLength) { 1628 auto t = makeWrappedStmts("\"a\"", "\"aa\"", Lang_CXX03, stringLiteral()); 1629 EXPECT_FALSE(testStructuralMatch(t)); 1630 } 1631 1632 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExpr) { 1633 auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(int)", Lang_CXX03, 1634 fallbackExprMatcher()); 1635 EXPECT_TRUE(testStructuralMatch(t)); 1636 } 1637 1638 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentType) { 1639 auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(long)", Lang_CXX03, 1640 fallbackExprMatcher()); 1641 EXPECT_FALSE(testStructuralMatch(t)); 1642 } 1643 1644 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTrait) { 1645 auto t = makeWrappedStmts( 1646 "__is_pod(int)", "__is_trivially_constructible(int)", Lang_CXX03, expr()); 1647 EXPECT_FALSE(testStructuralMatch(t)); 1648 } 1649 1650 TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTraits) { 1651 auto t = makeWrappedStmts("__is_constructible(int)", 1652 "__is_constructible(int, int)", Lang_CXX03, expr()); 1653 EXPECT_FALSE(testStructuralMatch(t)); 1654 } 1655 1656 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExpr) { 1657 auto t = makeWrappedStmts("sizeof(int)", "sizeof(int)", Lang_CXX03, 1658 unaryExprOrTypeTraitExpr()); 1659 EXPECT_TRUE(testStructuralMatch(t)); 1660 } 1661 1662 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentKind) { 1663 auto t = makeWrappedStmts("sizeof(int)", "alignof(long)", Lang_CXX11, 1664 unaryExprOrTypeTraitExpr()); 1665 EXPECT_FALSE(testStructuralMatch(t)); 1666 } 1667 1668 TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentType) { 1669 auto t = makeWrappedStmts("sizeof(int)", "sizeof(long)", Lang_CXX03, 1670 unaryExprOrTypeTraitExpr()); 1671 EXPECT_FALSE(testStructuralMatch(t)); 1672 } 1673 1674 TEST_F(StructuralEquivalenceStmtTest, UnaryOperator) { 1675 auto t = makeWrappedStmts("+1", "+1", Lang_CXX03, unaryOperator()); 1676 EXPECT_TRUE(testStructuralMatch(t)); 1677 } 1678 1679 TEST_F(StructuralEquivalenceStmtTest, UnaryOperatorDifferentOps) { 1680 auto t = makeWrappedStmts("+1", "-1", Lang_CXX03, unaryOperator()); 1681 EXPECT_FALSE(testStructuralMatch(t)); 1682 } 1683 1684 } // end namespace ast_matchers 1685 } // end namespace clang 1686