aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/ASTMatchers/Dynamic')
-rw-r--r--contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp11
-rw-r--r--contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h208
-rw-r--r--contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp11
-rw-r--r--contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp30
4 files changed, 220 insertions, 40 deletions
diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
index 989ee0fa75cd..f6fdbe868e2d 100644
--- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
+++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
@@ -89,8 +89,9 @@ llvm::Optional<std::string>
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
clang::OpenMPClauseKind>::getBestGuess(const VariantValue &Value) {
static constexpr llvm::StringRef Allowed[] = {
-#define OMP_CLAUSE_CLASS(Enum, Str, Class) #Enum,
-#include "llvm/Frontend/OpenMP/OMPKinds.def"
+#define GEN_CLANG_CLAUSE_CLASS
+#define CLAUSE_CLASS(Enum, Str, Class) #Enum,
+#include "llvm/Frontend/OpenMP/OMP.inc"
};
if (Value.isString())
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
@@ -120,7 +121,8 @@ static constexpr std::pair<llvm::StringRef, llvm::Regex::RegexFlags>
{"BasicRegex", llvm::Regex::RegexFlags::BasicRegex},
};
-llvm::Optional<llvm::Regex::RegexFlags> getRegexFlag(llvm::StringRef Flag) {
+static llvm::Optional<llvm::Regex::RegexFlags>
+getRegexFlag(llvm::StringRef Flag) {
for (const auto &StringFlag : RegexMap) {
if (Flag == StringFlag.first)
return StringFlag.second;
@@ -128,7 +130,8 @@ llvm::Optional<llvm::Regex::RegexFlags> getRegexFlag(llvm::StringRef Flag) {
return llvm::None;
}
-llvm::Optional<llvm::StringRef> getCloseRegexMatch(llvm::StringRef Flag) {
+static llvm::Optional<llvm::StringRef>
+getCloseRegexMatch(llvm::StringRef Flag) {
for (const auto &StringFlag : RegexMap) {
if (Flag.edit_distance(StringFlag.first) < 3)
return StringFlag.first;
diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h
index 33f6d1e4155c..690b52162e2b 100644
--- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -58,7 +58,10 @@ template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
};
template <> struct ArgTypeTraits<std::string> {
- static bool is(const VariantValue &Value) { return Value.isString(); }
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isString();
+ }
+ static bool hasCorrectValue(const VariantValue &Value) { return true; }
static const std::string &get(const VariantValue &Value) {
return Value.getString();
@@ -78,8 +81,11 @@ struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
};
template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> {
- static bool is(const VariantValue &Value) {
- return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
+ static bool hasCorrectType(const VariantValue& Value) {
+ return Value.isMatcher();
+ }
+ static bool hasCorrectValue(const VariantValue &Value) {
+ return Value.getMatcher().hasTypedMatcher<T>();
}
static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
@@ -96,7 +102,10 @@ template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> {
};
template <> struct ArgTypeTraits<bool> {
- static bool is(const VariantValue &Value) { return Value.isBoolean(); }
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isBoolean();
+ }
+ static bool hasCorrectValue(const VariantValue &Value) { return true; }
static bool get(const VariantValue &Value) {
return Value.getBoolean();
@@ -112,7 +121,10 @@ template <> struct ArgTypeTraits<bool> {
};
template <> struct ArgTypeTraits<double> {
- static bool is(const VariantValue &Value) { return Value.isDouble(); }
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isDouble();
+ }
+ static bool hasCorrectValue(const VariantValue &Value) { return true; }
static double get(const VariantValue &Value) {
return Value.getDouble();
@@ -128,7 +140,10 @@ template <> struct ArgTypeTraits<double> {
};
template <> struct ArgTypeTraits<unsigned> {
- static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isUnsigned();
+ }
+ static bool hasCorrectValue(const VariantValue &Value) { return true; }
static unsigned get(const VariantValue &Value) {
return Value.getUnsigned();
@@ -146,15 +161,20 @@ template <> struct ArgTypeTraits<unsigned> {
template <> struct ArgTypeTraits<attr::Kind> {
private:
static Optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) {
+ if (!AttrKind.consume_front("attr::"))
+ return llvm::None;
return llvm::StringSwitch<Optional<attr::Kind>>(AttrKind)
-#define ATTR(X) .Case("attr::" #X, attr:: X)
+#define ATTR(X) .Case(#X, attr::X)
#include "clang/Basic/AttrList.inc"
.Default(llvm::None);
}
public:
- static bool is(const VariantValue &Value) {
- return Value.isString() && getAttrKind(Value.getString());
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isString();
+ }
+ static bool hasCorrectValue(const VariantValue& Value) {
+ return getAttrKind(Value.getString()).hasValue();
}
static attr::Kind get(const VariantValue &Value) {
@@ -171,15 +191,20 @@ public:
template <> struct ArgTypeTraits<CastKind> {
private:
static Optional<CastKind> getCastKind(llvm::StringRef AttrKind) {
+ if (!AttrKind.consume_front("CK_"))
+ return llvm::None;
return llvm::StringSwitch<Optional<CastKind>>(AttrKind)
-#define CAST_OPERATION(Name) .Case("CK_" #Name, CK_##Name)
+#define CAST_OPERATION(Name) .Case(#Name, CK_##Name)
#include "clang/AST/OperationKinds.def"
.Default(llvm::None);
}
public:
- static bool is(const VariantValue &Value) {
- return Value.isString() && getCastKind(Value.getString());
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isString();
+ }
+ static bool hasCorrectValue(const VariantValue& Value) {
+ return getCastKind(Value.getString()).hasValue();
}
static CastKind get(const VariantValue &Value) {
@@ -198,8 +223,11 @@ private:
static Optional<llvm::Regex::RegexFlags> getFlags(llvm::StringRef Flags);
public:
- static bool is(const VariantValue &Value) {
- return Value.isString() && getFlags(Value.getString());
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isString();
+ }
+ static bool hasCorrectValue(const VariantValue& Value) {
+ return getFlags(Value.getString()).hasValue();
}
static llvm::Regex::RegexFlags get(const VariantValue &Value) {
@@ -215,14 +243,18 @@ template <> struct ArgTypeTraits<OpenMPClauseKind> {
private:
static Optional<OpenMPClauseKind> getClauseKind(llvm::StringRef ClauseKind) {
return llvm::StringSwitch<Optional<OpenMPClauseKind>>(ClauseKind)
-#define OMP_CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum)
-#include "llvm/Frontend/OpenMP/OMPKinds.def"
+#define GEN_CLANG_CLAUSE_CLASS
+#define CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum)
+#include "llvm/Frontend/OpenMP/OMP.inc"
.Default(llvm::None);
}
public:
- static bool is(const VariantValue &Value) {
- return Value.isString() && getClauseKind(Value.getString());
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isString();
+ }
+ static bool hasCorrectValue(const VariantValue& Value) {
+ return getClauseKind(Value.getString()).hasValue();
}
static OpenMPClauseKind get(const VariantValue &Value) {
@@ -238,18 +270,22 @@ template <> struct ArgTypeTraits<UnaryExprOrTypeTrait> {
private:
static Optional<UnaryExprOrTypeTrait>
getUnaryOrTypeTraitKind(llvm::StringRef ClauseKind) {
+ if (!ClauseKind.consume_front("UETT_"))
+ return llvm::None;
return llvm::StringSwitch<Optional<UnaryExprOrTypeTrait>>(ClauseKind)
-#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \
- .Case("UETT_" #Name, UETT_##Name)
+#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) .Case(#Name, UETT_##Name)
#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \
- .Case("UETT_" #Name, UETT_##Name)
+ .Case(#Name, UETT_##Name)
#include "clang/Basic/TokenKinds.def"
.Default(llvm::None);
}
public:
- static bool is(const VariantValue &Value) {
- return Value.isString() && getUnaryOrTypeTraitKind(Value.getString());
+ static bool hasCorrectType(const VariantValue &Value) {
+ return Value.isString();
+ }
+ static bool hasCorrectValue(const VariantValue& Value) {
+ return getUnaryOrTypeTraitKind(Value.getString()).hasValue();
}
static UnaryExprOrTypeTrait get(const VariantValue &Value) {
@@ -453,12 +489,31 @@ variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
const ParserValue &Arg = Args[i];
const VariantValue &Value = Arg.Value;
- if (!ArgTraits::is(Value)) {
+ if (!ArgTraits::hasCorrectType(Value)) {
Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
<< (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
HasError = true;
break;
}
+ if (!ArgTraits::hasCorrectValue(Value)) {
+ if (llvm::Optional<std::string> BestGuess =
+ ArgTraits::getBestGuess(Value)) {
+ Error->addError(Arg.Range, Error->ET_RegistryUnknownEnumWithReplace)
+ << i + 1 << Value.getString() << *BestGuess;
+ } else if (Value.isString()) {
+ Error->addError(Arg.Range, Error->ET_RegistryValueNotFound)
+ << Value.getString();
+ } else {
+ // This isn't ideal, but it's better than reporting an empty string as
+ // the error in this case.
+ Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
+ << (i + 1) << ArgTraits::getKind().asString()
+ << Value.getTypeAsString();
+ }
+ HasError = true;
+ break;
+ }
+
InnerArgs[i] = new ArgT(ArgTraits::get(Value));
}
@@ -568,16 +623,21 @@ private:
}
#define CHECK_ARG_TYPE(index, type) \
- if (!ArgTypeTraits<type>::is(Args[index].Value)) { \
+ if (!ArgTypeTraits<type>::hasCorrectType(Args[index].Value)) { \
+ Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
+ << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
+ << Args[index].Value.getTypeAsString(); \
+ return VariantMatcher(); \
+ } \
+ if (!ArgTypeTraits<type>::hasCorrectValue(Args[index].Value)) { \
if (llvm::Optional<std::string> BestGuess = \
ArgTypeTraits<type>::getBestGuess(Args[index].Value)) { \
Error->addError(Args[index].Range, \
Error->ET_RegistryUnknownEnumWithReplace) \
<< index + 1 << Args[index].Value.getString() << *BestGuess; \
- } else { \
- Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
- << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
- << Args[index].Value.getTypeAsString(); \
+ } else if (Args[index].Value.isString()) { \
+ Error->addError(Args[index].Range, Error->ET_RegistryValueNotFound) \
+ << Args[index].Value.getString(); \
} \
return VariantMatcher(); \
}
@@ -761,7 +821,7 @@ public:
<< "1 or 2" << Args.size();
return VariantMatcher();
}
- if (!ArgTypeTraits<StringRef>::is(Args[0].Value)) {
+ if (!ArgTypeTraits<StringRef>::hasCorrectType(Args[0].Value)) {
Error->addError(Args[0].Range, Error->ET_RegistryWrongArgType)
<< 1 << ArgTypeTraits<StringRef>::getKind().asString()
<< Args[0].Value.getTypeAsString();
@@ -771,16 +831,23 @@ public:
return outvalueToVariantMatcher(
NoFlags(ArgTypeTraits<StringRef>::get(Args[0].Value)));
}
- if (!ArgTypeTraits<llvm::Regex::RegexFlags>::is(Args[1].Value)) {
+ if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectType(
+ Args[1].Value)) {
+ Error->addError(Args[1].Range, Error->ET_RegistryWrongArgType)
+ << 2 << ArgTypeTraits<llvm::Regex::RegexFlags>::getKind().asString()
+ << Args[1].Value.getTypeAsString();
+ return VariantMatcher();
+ }
+ if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectValue(
+ Args[1].Value)) {
if (llvm::Optional<std::string> BestGuess =
ArgTypeTraits<llvm::Regex::RegexFlags>::getBestGuess(
Args[1].Value)) {
Error->addError(Args[1].Range, Error->ET_RegistryUnknownEnumWithReplace)
<< 2 << Args[1].Value.getString() << *BestGuess;
} else {
- Error->addError(Args[1].Range, Error->ET_RegistryWrongArgType)
- << 2 << ArgTypeTraits<llvm::Regex::RegexFlags>::getKind().asString()
- << Args[1].Value.getTypeAsString();
+ Error->addError(Args[1].Range, Error->ET_RegistryValueNotFound)
+ << Args[1].Value.getString();
}
return VariantMatcher();
}
@@ -858,6 +925,70 @@ private:
const StringRef MatcherName;
};
+class MapAnyOfMatcherDescriptor : public MatcherDescriptor {
+ ASTNodeKind CladeNodeKind;
+ std::vector<ASTNodeKind> NodeKinds;
+
+public:
+ MapAnyOfMatcherDescriptor(ASTNodeKind CladeNodeKind,
+ std::vector<ASTNodeKind> NodeKinds)
+ : CladeNodeKind(CladeNodeKind), NodeKinds(NodeKinds) {}
+
+ VariantMatcher create(SourceRange NameRange, ArrayRef<ParserValue> Args,
+ Diagnostics *Error) const override {
+
+ std::vector<DynTypedMatcher> NodeArgs;
+
+ for (auto NK : NodeKinds) {
+ std::vector<DynTypedMatcher> InnerArgs;
+
+ for (const auto &Arg : Args) {
+ if (!Arg.Value.isMatcher())
+ return {};
+ const VariantMatcher &VM = Arg.Value.getMatcher();
+ if (VM.hasTypedMatcher(NK)) {
+ auto DM = VM.getTypedMatcher(NK);
+ InnerArgs.push_back(DM);
+ }
+ }
+
+ if (InnerArgs.empty()) {
+ NodeArgs.push_back(
+ DynTypedMatcher::trueMatcher(NK).dynCastTo(CladeNodeKind));
+ } else {
+ NodeArgs.push_back(
+ DynTypedMatcher::constructVariadic(
+ ast_matchers::internal::DynTypedMatcher::VO_AllOf, NK,
+ InnerArgs)
+ .dynCastTo(CladeNodeKind));
+ }
+ }
+
+ auto Result = DynTypedMatcher::constructVariadic(
+ ast_matchers::internal::DynTypedMatcher::VO_AnyOf, CladeNodeKind,
+ NodeArgs);
+ Result.setAllowBind(true);
+ return VariantMatcher::SingleMatcher(Result);
+ }
+
+ bool isVariadic() const override { return true; }
+ unsigned getNumArgs() const override { return 0; }
+
+ void getArgKinds(ASTNodeKind ThisKind, unsigned,
+ std::vector<ArgKind> &Kinds) const override {
+ Kinds.push_back(ThisKind);
+ }
+
+ bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
+ ASTNodeKind *LeastDerivedKind) const override {
+ if (Specificity)
+ *Specificity = 1;
+ if (LeastDerivedKind)
+ *LeastDerivedKind = CladeNodeKind;
+ return true;
+ }
+};
+
/// Helper functions to select the appropriate marshaller functions.
/// They detect the number of arguments, arguments types and return type.
@@ -962,6 +1093,15 @@ std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
MinCount, MaxCount, Func.Op, MatcherName);
}
+template <typename CladeType, typename... MatcherT>
+std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
+ ast_matchers::internal::MapAnyOfMatcherImpl<CladeType, MatcherT...>,
+ StringRef MatcherName) {
+ return std::make_unique<MapAnyOfMatcherDescriptor>(
+ ASTNodeKind::getFromNodeKind<CladeType>(),
+ std::vector<ASTNodeKind>{ASTNodeKind::getFromNodeKind<MatcherT>()...});
+}
+
} // namespace internal
} // namespace dynamic
} // namespace ast_matchers
diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index ec2215804c09..00a7c74a0b90 100644
--- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -31,8 +31,6 @@
#include <utility>
#include <vector>
-using namespace clang::ast_type_traits;
-
namespace clang {
namespace ast_matchers {
namespace dynamic {
@@ -145,6 +143,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(autoreleasePoolStmt)
REGISTER_MATCHER(binaryConditionalOperator);
REGISTER_MATCHER(binaryOperator);
+ REGISTER_MATCHER(binaryOperation);
REGISTER_MATCHER(blockDecl);
REGISTER_MATCHER(blockExpr);
REGISTER_MATCHER(blockPointerType);
@@ -193,6 +192,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(cxxOperatorCallExpr);
REGISTER_MATCHER(cxxRecordDecl);
REGISTER_MATCHER(cxxReinterpretCastExpr);
+ REGISTER_MATCHER(cxxRewrittenBinaryOperator);
REGISTER_MATCHER(cxxStaticCastExpr);
REGISTER_MATCHER(cxxStdInitializerListExpr);
REGISTER_MATCHER(cxxTemporaryObjectExpr);
@@ -202,6 +202,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(cxxUnresolvedConstructExpr);
REGISTER_MATCHER(decayedType);
REGISTER_MATCHER(decl);
+ REGISTER_MATCHER(decompositionDecl);
REGISTER_MATCHER(declCountIs);
REGISTER_MATCHER(declRefExpr);
REGISTER_MATCHER(declStmt);
@@ -227,6 +228,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(floatLiteral);
REGISTER_MATCHER(forEach);
REGISTER_MATCHER(forEachArgumentWithParam);
+ REGISTER_MATCHER(forEachArgumentWithParamType);
REGISTER_MATCHER(forEachConstructorInitializer);
REGISTER_MATCHER(forEachDescendant);
REGISTER_MATCHER(forEachOverridden);
@@ -239,6 +241,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(functionProtoType);
REGISTER_MATCHER(functionTemplateDecl);
REGISTER_MATCHER(functionType);
+ REGISTER_MATCHER(genericSelectionExpr);
REGISTER_MATCHER(gnuNullExpr);
REGISTER_MATCHER(gotoStmt);
REGISTER_MATCHER(has);
@@ -300,6 +303,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasLocalStorage);
REGISTER_MATCHER(hasLoopInit);
REGISTER_MATCHER(hasLoopVariable);
+ REGISTER_MATCHER(hasMemberName);
REGISTER_MATCHER(hasMethod);
REGISTER_MATCHER(hasName);
REGISTER_MATCHER(hasNullSelector);
@@ -431,6 +435,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isVirtual);
REGISTER_MATCHER(isVirtualAsWritten);
REGISTER_MATCHER(isVolatileQualified);
+ REGISTER_MATCHER(isWeak);
REGISTER_MATCHER(isWritten);
REGISTER_MATCHER(lValueReferenceType);
REGISTER_MATCHER(labelDecl);
@@ -440,6 +445,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(materializeTemporaryExpr);
REGISTER_MATCHER(member);
REGISTER_MATCHER(memberExpr);
+ REGISTER_MATCHER(memberHasSameNameAsBoundNode);
REGISTER_MATCHER(memberPointerType);
REGISTER_MATCHER(namedDecl);
REGISTER_MATCHER(namesType);
@@ -514,6 +520,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(templateArgumentCountIs);
REGISTER_MATCHER(templateName);
REGISTER_MATCHER(templateSpecializationType);
+ REGISTER_MATCHER(templateTemplateParmDecl);
REGISTER_MATCHER(templateTypeParmDecl);
REGISTER_MATCHER(templateTypeParmType);
REGISTER_MATCHER(throughUsingDecl);
diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 866e2d0e3491..d1ecb1e00b91 100644
--- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -59,6 +59,11 @@ VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher,
return Matcher.canConvertTo(NodeKind);
}
+DynTypedMatcher VariantMatcher::MatcherOps::convertMatcher(
+ const DynTypedMatcher &Matcher) const {
+ return Matcher.dynCastTo(NodeKind);
+}
+
llvm::Optional<DynTypedMatcher>
VariantMatcher::MatcherOps::constructVariadicOperator(
DynTypedMatcher::VariadicOperator Op,
@@ -263,6 +268,10 @@ VariantValue::VariantValue(StringRef String) : Type(VT_Nothing) {
setString(String);
}
+VariantValue::VariantValue(ASTNodeKind NodeKind) : Type(VT_Nothing) {
+ setNodeKind(NodeKind);
+}
+
VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
setMatcher(Matcher);
}
@@ -285,6 +294,9 @@ VariantValue &VariantValue::operator=(const VariantValue &Other) {
case VT_String:
setString(Other.getString());
break;
+ case VT_NodeKind:
+ setNodeKind(Other.getNodeKind());
+ break;
case VT_Matcher:
setMatcher(Other.getMatcher());
break;
@@ -303,6 +315,9 @@ void VariantValue::reset() {
case VT_Matcher:
delete Value.Matcher;
break;
+ case VT_NodeKind:
+ delete Value.NodeKind;
+ break;
// Cases that do nothing.
case VT_Boolean:
case VT_Double:
@@ -373,6 +388,19 @@ void VariantValue::setString(StringRef NewValue) {
Value.String = new std::string(NewValue);
}
+bool VariantValue::isNodeKind() const { return Type == VT_NodeKind; }
+
+const ASTNodeKind &VariantValue::getNodeKind() const {
+ assert(isNodeKind());
+ return *Value.NodeKind;
+}
+
+void VariantValue::setNodeKind(ASTNodeKind NewValue) {
+ reset();
+ Type = VT_NodeKind;
+ Value.NodeKind = new ASTNodeKind(NewValue);
+}
+
bool VariantValue::isMatcher() const {
return Type == VT_Matcher;
}
@@ -444,6 +472,8 @@ std::string VariantValue::getTypeAsString() const {
case VT_Boolean: return "Boolean";
case VT_Double: return "Double";
case VT_Unsigned: return "Unsigned";
+ case VT_NodeKind:
+ return getNodeKind().asStringRef().str();
case VT_Nothing: return "Nothing";
}
llvm_unreachable("Invalid Type");