Author: Nathan James Date: 2020-04-09T14:33:04+01:00 New Revision: bf968e28ee82efce6a34a4dffd904c3c5df4eae4
URL: https://github.com/llvm/llvm-project/commit/bf968e28ee82efce6a34a4dffd904c3c5df4eae4 DIFF: https://github.com/llvm/llvm-project/commit/bf968e28ee82efce6a34a4dffd904c3c5df4eae4.diff LOG: [ASTMatchers] Add support for dynamic matching of ofKind narrowing matcher Summary: Adds support for using the ofKind in clang-query and other dynamic matcher use cases Reviewers: klimek, aaron.ballman, jdoerfert Reviewed By: aaron.ballman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77791 Added: Modified: clang/lib/ASTMatchers/Dynamic/Marshallers.cpp clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp Removed: ################################################################################ diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp b/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp index 46312284e088..de1a97814e42 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp @@ -95,3 +95,17 @@ clang::ast_matchers::dynamic::internal::ArgTypeTraits< "OMPC_"); return llvm::None; } + +llvm::Optional<std::string> +clang::ast_matchers::dynamic::internal::ArgTypeTraits< + clang::UnaryExprOrTypeTrait>::getBestGuess(const VariantValue &Value) { + static constexpr llvm::StringRef Allowed[] = { + "UETT_SizeOf", "UETT_AlignOf", + "UETT_VecStep", "UETT_OpenMPRequiredSimdAlign", + "UETT_PreferredAlignOf", + }; + if (Value.isString()) + return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed), + "UETT_"); + return llvm::None; +} diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 3d36ed6ea187..288155217d5c 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -27,6 +27,7 @@ #include "clang/Basic/AttrKinds.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/TypeTraits.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" @@ -214,6 +215,35 @@ template <> struct ArgTypeTraits<OpenMPClauseKind> { static llvm::Optional<std::string> getBestGuess(const VariantValue &Value); }; +template <> struct ArgTypeTraits<UnaryExprOrTypeTrait> { +private: + static Optional<UnaryExprOrTypeTrait> + getUnaryOrTypeTraitKind(llvm::StringRef ClauseKind) { + // FIXME: Type traits should probably be in a `.def` to make less error + // prone. + return llvm::StringSwitch<Optional<UnaryExprOrTypeTrait>>(ClauseKind) + .Case("UETT_SizeOf", UETT_SizeOf) + .Case("UETT_AlignOf", UETT_AlignOf) + .Case("UETT_VecStep", UETT_VecStep) + .Case("UETT_OpenMPRequiredSimdAlign", UETT_OpenMPRequiredSimdAlign) + .Case("UETT_PreferredAlignOf", UETT_PreferredAlignOf) + .Default(llvm::None); + } + +public: + static bool is(const VariantValue &Value) { + return Value.isString() && getUnaryOrTypeTraitKind(Value.getString()); + } + + static UnaryExprOrTypeTrait get(const VariantValue &Value) { + return *getUnaryOrTypeTraitKind(Value.getString()); + } + + static ArgKind getKind() { return ArgKind(ArgKind::AK_String); } + + static llvm::Optional<std::string> getBestGuess(const VariantValue &Value); +}; + /// Matcher descriptor interface. /// /// Provides a \c create() method that constructs the matcher from the provided diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 259b81ab19f0..e7659feaf1e9 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -95,9 +95,6 @@ void RegistryMaps::registerMatcher( RegistryMaps::RegistryMaps() { // TODO: Here is the list of the missing matchers, grouped by reason. // - // Need Variant/Parser fixes: - // ofKind - // // Polymorphic + argument overload: // findAll // @@ -458,6 +455,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(objcThrowStmt); REGISTER_MATCHER(objcTryStmt); REGISTER_MATCHER(ofClass); + REGISTER_MATCHER(ofKind); REGISTER_MATCHER(ompDefaultClause); REGISTER_MATCHER(ompExecutableDirective); REGISTER_MATCHER(on); diff --git a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp index 71c2e3e5addf..1b553ffe73ed 100644 --- a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp +++ b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp @@ -242,6 +242,14 @@ TEST(ParserTest, FullParserTest) { EXPECT_TRUE(matches("void f(int a, int x);", M)); EXPECT_FALSE(matches("void f(int x, int a);", M)); + Code = "unaryExprOrTypeTraitExpr(ofKind(\"UETT_SizeOf\"))"; + llvm::Optional<DynTypedMatcher> UnaryExprSizeOf( + Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error)); + EXPECT_EQ("", Error.toStringFull()); + Matcher<Stmt> MStmt = UnaryExprSizeOf->unconditionalConvertTo<Stmt>(); + EXPECT_TRUE(matches("unsigned X = sizeof(int);", MStmt)); + EXPECT_FALSE(matches("unsigned X = alignof(int);", MStmt)); + Code = "hasInitializer(\n binaryOperator(hasLHS(\"A\")))"; EXPECT_TRUE(!Parser::parseMatcherExpression(Code, &Error).hasValue()); EXPECT_EQ("1:1: Error parsing argument 1 for matcher hasInitializer.\n" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits