[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG1f65f42dd37a: Make `hasTypeLoc` matcher support more node types. (authored by SilensAngelusNex, committed by stephenkelly). Changed prior to commit: https://reviews.llvm.org/D101572?vs=343219=343782#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/ASTMatchers/ASTMatchersInternal.h clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp === --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -11,6 +11,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Host.h" #include "gtest/gtest.h" @@ -375,15 +376,104 @@ typedefNameDecl(hasType(asString("foo")), hasName("bar"; } -TEST(HasTypeLoc, MatchesDeclaratorDecls) { +TEST(HasTypeLoc, MatchesBlockDecl) { + EXPECT_TRUE(matchesConditionally( + "auto x = ^int (int a, int b) { return a + b; };", + blockDecl(hasTypeLoc(loc(asString("int (int, int)", true, + {"-fblocks"})); +} + +TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) { + llvm::StringRef code = R"cpp( + class Foo {}; + class Bar : public Foo { +Bar() : Foo() {} + }; + )cpp"; + + EXPECT_TRUE(matches( + code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("class Foo"))); + EXPECT_TRUE(matches( + code, cxxCtorInitializer(hasTypeLoc(loc(asString("class Foo")); +} + +TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) { + EXPECT_TRUE(matches("auto x = int(3);", + cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesCXXNewExpr) { + EXPECT_TRUE(matches("auto* x = new int(3);", + cxxNewExpr(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();", + cxxNewExpr(hasTypeLoc(loc(asString("class Foo")); +} + +TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) { + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);", + cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("struct Foo")); +} + +TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) { + EXPECT_TRUE( + matches("template T make() { return T(); }", + cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T")); +} + +TEST(HasTypeLoc, MatchesClassTemplateSpecializationDecl) { + EXPECT_TRUE(matches( + "template class Foo; template <> class Foo {};", + classTemplateSpecializationDecl(hasTypeLoc(loc(asString("Foo")); +} + +TEST(HasTypeLoc, MatchesCompoundLiteralExpr) { + EXPECT_TRUE( + matches("int* x = (int [2]) { 0, 1 };", + compoundLiteralExpr(hasTypeLoc(loc(asString("int [2]")); +} + +TEST(HasTypeLoc, MatchesDeclaratorDecl) { EXPECT_TRUE(matches("int x;", varDecl(hasName("x"), hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("int x(3);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("int")); + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; Foo x(1, 2);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("struct Foo")); // Make sure we don't crash on implicit constructors. EXPECT_TRUE(notMatches("class X {}; X x;", declaratorDecl(hasTypeLoc(loc(asString("int")); } +TEST(HasTypeLoc, MatchesExplicitCastExpr) { + EXPECT_TRUE(matches("auto x = (int) 3;", + explicitCastExpr(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("auto x = static_cast(3);", + explicitCastExpr(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesObjCPropertyDecl) { + EXPECT_TRUE(matchesObjC(R"objc( + @interface Foo + @property int enabled; + @end +)objc", + objcPropertyDecl(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesTemplateArgumentLoc) { + EXPECT_TRUE(matches("template class Foo {}; Foo x;", + templateArgumentLoc(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesTypedefNameDecl) { + EXPECT_TRUE(matches("typedef int X;", + typedefNameDecl(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("using X = int;", + typedefNameDecl(hasTypeLoc(loc(asString("int")); +} TEST(Callee,
[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
SilensAngelusNex added a comment. I don't have commit access; you can go ahead and submit it. Thanks for the review! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
steveire accepted this revision. steveire added a comment. This revision is now accepted and ready to land. This looks good to me. I tried running it in clang-query, which crashes with a matcher like m binaryOperator(hasEitherOperand(hasTypeLoc(loc(asString("int") but it also crashes before your change, so it must be unrelated. Do you have a commit account or will I commit this for you with the name/email in your github commit? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
SilensAngelusNex added a comment. Here's my branch on Github: https://github.com/SilensAngelusNex/llvm-project/tree/has-type-info Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:138-150 +template struct disjunction; +template struct disjunction : public T {}; +template struct disjunction { + using type = + typename std::conditional>::type; + static constexpr bool value = type::value; +}; steveire wrote: > SilensAngelusNex wrote: > > Is there a better way to express this? I was originally using > > > > ``` > > template struct is_one_of { > > template > > static constexpr bool value = (std::is_base_of_v || ...); > > }; > > ``` > > but that didn't compile because `is_base_of_v` and fold expressions are > > C++17 features. > > > > Maybe it would be better to just explicitly write out an overload of > > `GetTypeSourceInfo` for each type? > > I like your c++17 solution too, but given that we have > `TypeListContainsSuperOf` in this file used for this kind of thing, I think > it makes sense to use that. I think this will work: > > ``` > templatestd::enable_if_t ast_matchers::internal::TypeList< > CXXBaseSpecifier, CXXCtorInitializer, CXXTemporaryObjectExpr, > CXXUnresolvedConstructExpr, CompoundLiteralExpr, DeclaratorDecl, > ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl>, > T>::value> > * = nullptr> > ``` > Perfect, thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
SilensAngelusNex updated this revision to Diff 343219. SilensAngelusNex marked 2 inline comments as done. SilensAngelusNex added a comment. Regenerate docs and replace `is_one_of` with `TypeListContainsSuperOf`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/ASTMatchers/ASTMatchersInternal.h clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp === --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -11,6 +11,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Host.h" #include "gtest/gtest.h" @@ -375,15 +376,104 @@ typedefNameDecl(hasType(asString("foo")), hasName("bar"; } -TEST(HasTypeLoc, MatchesDeclaratorDecls) { +TEST(HasTypeLoc, MatchesBlockDecl) { + EXPECT_TRUE(matchesConditionally( + "auto x = ^int (int a, int b) { return a + b; };", + blockDecl(hasTypeLoc(loc(asString("int (int, int)", true, + {"-fblocks"})); +} + +TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) { + llvm::StringRef code = R"cpp( + class Foo {}; + class Bar : public Foo { +Bar() : Foo() {} + }; + )cpp"; + + EXPECT_TRUE(matches( + code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("class Foo"))); + EXPECT_TRUE(matches( + code, cxxCtorInitializer(hasTypeLoc(loc(asString("class Foo")); +} + +TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) { + EXPECT_TRUE(matches("auto x = int(3);", + cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesCXXNewExpr) { + EXPECT_TRUE(matches("auto* x = new int(3);", + cxxNewExpr(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();", + cxxNewExpr(hasTypeLoc(loc(asString("class Foo")); +} + +TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) { + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);", + cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("struct Foo")); +} + +TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) { + EXPECT_TRUE( + matches("template T make() { return T(); }", + cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T")); +} + +TEST(HasTypeLoc, MatchesClassTemplateSpecializationDecl) { + EXPECT_TRUE(matches( + "template class Foo; template <> class Foo {};", + classTemplateSpecializationDecl(hasTypeLoc(loc(asString("Foo")); +} + +TEST(HasTypeLoc, MatchesCompoundLiteralExpr) { + EXPECT_TRUE( + matches("int* x = (int [2]) { 0, 1 };", + compoundLiteralExpr(hasTypeLoc(loc(asString("int [2]")); +} + +TEST(HasTypeLoc, MatchesDeclaratorDecl) { EXPECT_TRUE(matches("int x;", varDecl(hasName("x"), hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("int x(3);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("int")); + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; Foo x(1, 2);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("struct Foo")); // Make sure we don't crash on implicit constructors. EXPECT_TRUE(notMatches("class X {}; X x;", declaratorDecl(hasTypeLoc(loc(asString("int")); } +TEST(HasTypeLoc, MatchesExplicitCastExpr) { + EXPECT_TRUE(matches("auto x = (int) 3;", + explicitCastExpr(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("auto x = static_cast(3);", + explicitCastExpr(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesObjCPropertyDecl) { + EXPECT_TRUE(matchesObjC(R"objc( + @interface Foo + @property int enabled; + @end +)objc", + objcPropertyDecl(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesTemplateArgumentLoc) { + EXPECT_TRUE(matches("template class Foo {}; Foo x;", + templateArgumentLoc(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesTypedefNameDecl) { + EXPECT_TRUE(matches("typedef int X;", + typedefNameDecl(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("using X = int;", + typedefNameDecl(hasTypeLoc(loc(asString("int")); +} TEST(Callee, MatchesDeclarations) { StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"; Index:
[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
steveire added a comment. Please run `llvm-project/clang/docs/tools/dump_ast_matchers.py` to generate updated documentation for this (there is a `urlopen(url)` which slows things down, so I usually comment that out when running it). Do you have this on a git clone somewhere? It's easier to take a patch and try it out from a git repo than phab. Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:3919 +/// cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo" +/// matches Foo(1, 2) +AST_POLYMORPHIC_MATCHER_P( This should somehow document the types it works with. You don't have to add examples for all of the nodes though. `hasDeclaration` is another example of a matcher supporting many different nodes. It has `Usable as:` at the bottom of its docs which gets parsed by `dump_ast_matchers.py`. Please make a similar change here to verify that the script generates docs for each type. Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:138-150 +template struct disjunction; +template struct disjunction : public T {}; +template struct disjunction { + using type = + typename std::conditional>::type; + static constexpr bool value = type::value; +}; SilensAngelusNex wrote: > Is there a better way to express this? I was originally using > > ``` > template struct is_one_of { > template > static constexpr bool value = (std::is_base_of_v || ...); > }; > ``` > but that didn't compile because `is_base_of_v` and fold expressions are C++17 > features. > > Maybe it would be better to just explicitly write out an overload of > `GetTypeSourceInfo` for each type? I like your c++17 solution too, but given that we have `TypeListContainsSuperOf` in this file used for this kind of thing, I think it makes sense to use that. I think this will work: ``` template , T>::value> * = nullptr> ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
SilensAngelusNex updated this revision to Diff 343106. SilensAngelusNex added a comment. Rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 Files: clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/ASTMatchers/ASTMatchersInternal.h clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp === --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -11,6 +11,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Host.h" #include "gtest/gtest.h" @@ -375,15 +376,104 @@ typedefNameDecl(hasType(asString("foo")), hasName("bar"; } -TEST(HasTypeLoc, MatchesDeclaratorDecls) { +TEST(HasTypeLoc, MatchesBlockDecl) { + EXPECT_TRUE(matchesConditionally( + "auto x = ^int (int a, int b) { return a + b; };", + blockDecl(hasTypeLoc(loc(asString("int (int, int)", true, + {"-fblocks"})); +} + +TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) { + llvm::StringRef code = R"cpp( + class Foo {}; + class Bar : public Foo { +Bar() : Foo() {} + }; + )cpp"; + + EXPECT_TRUE(matches( + code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("class Foo"))); + EXPECT_TRUE(matches( + code, cxxCtorInitializer(hasTypeLoc(loc(asString("class Foo")); +} + +TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) { + EXPECT_TRUE(matches("auto x = int(3);", + cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesCXXNewExpr) { + EXPECT_TRUE(matches("auto* x = new int(3);", + cxxNewExpr(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();", + cxxNewExpr(hasTypeLoc(loc(asString("class Foo")); +} + +TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) { + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);", + cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("struct Foo")); +} + +TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) { + EXPECT_TRUE( + matches("template T make() { return T(); }", + cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T")); +} + +TEST(HasTypeLoc, MatchesClassTemplateSpecializationDecl) { + EXPECT_TRUE(matches( + "template class Foo; template <> class Foo {};", + classTemplateSpecializationDecl(hasTypeLoc(loc(asString("Foo")); +} + +TEST(HasTypeLoc, MatchesCompoundLiteralExpr) { + EXPECT_TRUE( + matches("int* x = (int [2]) { 0, 1 };", + compoundLiteralExpr(hasTypeLoc(loc(asString("int [2]")); +} + +TEST(HasTypeLoc, MatchesDeclaratorDecl) { EXPECT_TRUE(matches("int x;", varDecl(hasName("x"), hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("int x(3);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("int")); + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; Foo x(1, 2);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("struct Foo")); // Make sure we don't crash on implicit constructors. EXPECT_TRUE(notMatches("class X {}; X x;", declaratorDecl(hasTypeLoc(loc(asString("int")); } +TEST(HasTypeLoc, MatchesExplicitCastExpr) { + EXPECT_TRUE(matches("auto x = (int) 3;", + explicitCastExpr(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("auto x = static_cast(3);", + explicitCastExpr(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesObjCPropertyDecl) { + EXPECT_TRUE(matchesObjC(R"objc( + @interface Foo + @property int enabled; + @end +)objc", + objcPropertyDecl(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesTemplateArgumentLoc) { + EXPECT_TRUE(matches("template class Foo {}; Foo x;", + templateArgumentLoc(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesTypedefNameDecl) { + EXPECT_TRUE(matches("typedef int X;", + typedefNameDecl(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("using X = int;", + typedefNameDecl(hasTypeLoc(loc(asString("int")); +} TEST(Callee, MatchesDeclarations) { StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"; Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h === --- clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++
[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
SilensAngelusNex added inline comments. Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:138-150 +template struct disjunction; +template struct disjunction : public T {}; +template struct disjunction { + using type = + typename std::conditional>::type; + static constexpr bool value = type::value; +}; Is there a better way to express this? I was originally using ``` template struct is_one_of { template static constexpr bool value = (std::is_base_of_v || ...); }; ``` but that didn't compile because `is_base_of_v` and fold expressions are C++17 features. Maybe it would be better to just explicitly write out an overload of `GetTypeSourceInfo` for each type? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D101572: Make `hasTypeLoc` matcher support more node types.
SilensAngelusNex updated this revision to Diff 342790. SilensAngelusNex retitled this revision from "Make `hasTypeLoc` matcher support nodes of type `CXXFunctionalCastExpr` and `CXXTemporaryObjectExpr`." to "Make `hasTypeLoc` matcher support more node types.". SilensAngelusNex added a comment. Added support for node types in groups #1 and #3. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D101572/new/ https://reviews.llvm.org/D101572 Files: clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/ASTMatchers/ASTMatchersInternal.h clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp === --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -11,6 +11,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Host.h" #include "gtest/gtest.h" @@ -375,15 +376,104 @@ typedefNameDecl(hasType(asString("foo")), hasName("bar"; } -TEST(HasTypeLoc, MatchesDeclaratorDecls) { +TEST(HasTypeLoc, MatchesBlockDecl) { + EXPECT_TRUE(matchesConditionally( + "auto x = ^int (int a, int b) { return a + b; };", + blockDecl(hasTypeLoc(loc(asString("int (int, int)", true, + {"-fblocks"})); +} + +TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) { + llvm::StringRef code = R"cpp( + class Foo {}; + class Bar : public Foo { +Bar() : Foo() {} + }; + )cpp"; + + EXPECT_TRUE(matches( + code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("class Foo"))); + EXPECT_TRUE(matches( + code, cxxCtorInitializer(hasTypeLoc(loc(asString("class Foo")); +} + +TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) { + EXPECT_TRUE(matches("auto x = int(3);", + cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesCXXNewExpr) { + EXPECT_TRUE(matches("auto* x = new int(3);", + cxxNewExpr(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();", + cxxNewExpr(hasTypeLoc(loc(asString("class Foo")); +} + +TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) { + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);", + cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("struct Foo")); +} + +TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) { + EXPECT_TRUE( + matches("template T make() { return T(); }", + cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T")); +} + +TEST(HasTypeLoc, MatchesClassTemplateSpecializationDecl) { + EXPECT_TRUE(matches( + "template class Foo; template <> class Foo {};", + classTemplateSpecializationDecl(hasTypeLoc(loc(asString("Foo")); +} + +TEST(HasTypeLoc, MatchesCompoundLiteralExpr) { + EXPECT_TRUE( + matches("int* x = (int [2]) { 0, 1 };", + compoundLiteralExpr(hasTypeLoc(loc(asString("int [2]")); +} + +TEST(HasTypeLoc, MatchesDeclaratorDecl) { EXPECT_TRUE(matches("int x;", varDecl(hasName("x"), hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("int x(3);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("int")); + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; Foo x(1, 2);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("struct Foo")); // Make sure we don't crash on implicit constructors. EXPECT_TRUE(notMatches("class X {}; X x;", declaratorDecl(hasTypeLoc(loc(asString("int")); } +TEST(HasTypeLoc, MatchesExplicitCastExpr) { + EXPECT_TRUE(matches("auto x = (int) 3;", + explicitCastExpr(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("auto x = static_cast(3);", + explicitCastExpr(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesObjCPropertyDecl) { + EXPECT_TRUE(matchesObjC(R"objc( + @interface Foo + @property int enabled; + @end +)objc", + objcPropertyDecl(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesTemplateArgumentLoc) { + EXPECT_TRUE(matches("template class Foo {}; Foo x;", + templateArgumentLoc(hasTypeLoc(loc(asString("int")); +} + +TEST(HasTypeLoc, MatchesTypedefNameDecl) { + EXPECT_TRUE(matches("typedef int X;", + typedefNameDecl(hasTypeLoc(loc(asString("int")); + EXPECT_TRUE(matches("using X = int;", + typedefNameDecl(hasTypeLoc(loc(asString("int")); +} TEST(Callee, MatchesDeclarations) { StatementMatcher CallMethodX =