17 #include "llvm/ADT/STLExtras.h"
20 namespace ast_matchers {
26 return (Twine(
"Matcher<") + MatcherKind.
asStringRef() +
">").str();
32 llvm_unreachable(
"unhandled ArgKind");
44 if (!MatcherKind.
isBaseOf(To.MatcherKind, &Distance))
48 *Specificity = 100 - Distance;
53 VariantMatcher::MatcherOps::canConstructFrom(
const DynTypedMatcher &
Matcher,
54 bool &IsExactMatch)
const {
55 IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
56 return Matcher.canConvertTo(NodeKind);
60 VariantMatcher::MatcherOps::constructVariadicOperator(
61 DynTypedMatcher::VariadicOperator Op,
63 std::vector<DynTypedMatcher> DynMatchers;
73 DynMatchers.push_back(*Inner);
75 return DynTypedMatcher::constructVariadic(Op, DynMatchers);
78 VariantMatcher::Payload::~Payload() {}
89 return (Twine(
"Matcher<") + Matcher.getSupportedKind().asStringRef() +
">")
96 if (Ops.canConstructFrom(Matcher, Ignore))
102 unsigned *Specificity)
const override {
103 return ArgKind(Matcher.getSupportedKind())
108 const DynTypedMatcher Matcher;
114 :
Matchers(std::move(MatchersIn)) {}
126 for (
size_t i = 0, e =
Matchers.size(); i != e; ++i) {
129 Inner +=
Matchers[i].getSupportedKind().asStringRef();
131 return (Twine(
"Matcher<") + Inner +
">").str();
136 bool FoundIsExact =
false;
137 const DynTypedMatcher *Found =
nullptr;
139 for (
size_t i = 0, e =
Matchers.size(); i != e; ++i) {
141 if (Ops.canConstructFrom(
Matchers[i], IsExactMatch)) {
144 assert(!IsExactMatch &&
"We should not have two exact matches.");
149 FoundIsExact = IsExactMatch;
154 if (Found && (FoundIsExact || NumFound == 1))
160 unsigned *Specificity)
const override {
161 unsigned MaxSpecificity = 0;
162 for (
const DynTypedMatcher &Matcher :
Matchers) {
163 unsigned ThisSpecificity;
164 if (
ArgKind(Matcher.getSupportedKind())
166 MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
170 *Specificity = MaxSpecificity;
171 return MaxSpecificity > 0;
180 std::vector<VariantMatcher> Args)
181 : Op(Op), Args(std::move(Args)) {}
189 for (
size_t i = 0, e = Args.size(); i != e; ++i) {
192 Inner += Args[i].getTypeAsString();
199 return Ops.constructVariadicOperator(Op, Args);
203 unsigned *Specificity)
const override {
205 if (!Matcher.isConvertibleTo(Kind, Specificity))
212 const DynTypedMatcher::VariadicOperator Op;
213 const std::vector<VariantMatcher> Args;
228 DynTypedMatcher::VariadicOperator Op,
229 std::vector<VariantMatcher> Args) {
263 if (
this == &Other)
return *
this;
265 switch (Other.Type) {
282 void VariantValue::reset() {
288 delete Value.Matcher;
299 return Type == VT_Unsigned;
304 return Value.Unsigned;
310 Value.Unsigned = NewValue;
314 return Type == VT_String;
319 return *
Value.String;
325 Value.String =
new std::string(NewValue);
329 return Type == VT_Matcher;
334 return *
Value.Matcher;
362 llvm_unreachable(
"Invalid Type");
366 unsigned *Specificity)
const {
367 unsigned MaxSpecificity = 0;
369 unsigned ThisSpecificity;
372 MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
374 if (Specificity && MaxSpecificity > 0) {
375 *Specificity = MaxSpecificity;
377 return MaxSpecificity > 0;
382 case VT_String:
return "String";
384 case VT_Unsigned:
return "Unsigned";
385 case VT_Nothing:
return "Nothing";
387 llvm_unreachable(
"Invalid Type");
const MatchFinder::MatchersByType * Matchers
bool isMatcher() const
Matcher value functions.
SinglePayload(const DynTypedMatcher &Matcher)
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity) const override
void setString(StringRef String)
std::string getTypeAsString() const
String representation of the type of the value.
const DynTypedMatcher *const Matcher
VariantValue & operator=(const VariantValue &Other)
static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher)
Clones the provided matcher.
llvm::Optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
static VariantMatcher VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, std::vector< VariantMatcher > Args)
Creates a 'variadic' operator matcher.
bool isUnsigned() const
Unsigned value functions.
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity) const
Determines if the contained matcher can be converted to Kind.
bool isBaseOf(ASTNodeKind Other, unsigned *Distance=nullptr) const
Returns true if this is a base kind of (or same as) Other.
std::vector< DynTypedMatcher > InnerMatchers
PolymorphicPayload(std::vector< DynTypedMatcher > MatchersIn)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
const IntrusiveRefCntPtr< DynMatcherInterface > InnerMatcher
ast_type_traits::ASTNodeKind getMatcherKind() const
llvm::Optional< DynTypedMatcher > getSingleMatcher() const override
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity) const override
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity) const override
llvm::Optional< DynTypedMatcher > getSingleMatcher() const override
VariadicOpPayload(DynTypedMatcher::VariadicOperator Op, std::vector< VariantMatcher > Args)
llvm::Optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
std::string getTypeAsString() const override
~PolymorphicPayload() override
std::string asString() const
String representation of the type.
const std::vector< DynTypedMatcher > Matchers
bool isConvertibleTo(ArgKind To, unsigned *Specificity) const
Determines if this type can be converted to To.
VariantMatcher()
A null matcher.
StringRef asStringRef() const
String representation of the kind.
std::string getTypeAsString() const override
std::string getTypeAsString() const
String representation of the type of the value.
std::string getTypeAsString() const override
static VariantMatcher PolymorphicMatcher(std::vector< DynTypedMatcher > Matchers)
Clones the provided matchers.
void reset()
Makes the matcher the "null" matcher.
void setMatcher(const VariantMatcher &Matcher)
bool isString() const
String value functions.
A variant matcher object.
llvm::Optional< DynTypedMatcher > getSingleMatcher() const override
bool isConvertibleTo(ArgKind Kind, unsigned *Specificity) const
Determines if the contained value can be converted to Kind.
const std::string & getString() const
void setUnsigned(unsigned Unsigned)
llvm::Optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
const VariantMatcher & getMatcher() const
unsigned getUnsigned() const
llvm::Optional< DynTypedMatcher > getSingleMatcher() const
Return a single matcher, if there is no ambiguity.