17 #include "llvm/ADT/STLExtras.h" 26 return (Twine(
"Matcher<") + MatcherKind.
asStringRef() +
">").str();
36 llvm_unreachable(
"unhandled ArgKind");
48 if (!MatcherKind.
isBaseOf(To.MatcherKind, &Distance))
52 *Specificity = 100 - Distance;
57 VariantMatcher::MatcherOps::canConstructFrom(
const DynTypedMatcher &Matcher,
58 bool &IsExactMatch)
const {
59 IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
60 return Matcher.canConvertTo(NodeKind);
64 VariantMatcher::MatcherOps::constructVariadicOperator(
65 DynTypedMatcher::VariadicOperator Op,
67 std::vector<DynTypedMatcher> DynMatchers;
68 for (
const auto &InnerMatcher : InnerMatchers) {
71 if (!InnerMatcher.Value)
74 InnerMatcher.Value->getTypedMatcher(*
this);
77 DynMatchers.push_back(*Inner);
79 return DynTypedMatcher::constructVariadic(Op, NodeKind, DynMatchers);
82 VariantMatcher::Payload::~Payload() {}
93 return (Twine(
"Matcher<") + Matcher.getSupportedKind().asStringRef() +
">")
100 if (Ops.canConstructFrom(Matcher, Ignore))
106 unsigned *Specificity)
const override {
107 return ArgKind(Matcher.getSupportedKind())
112 const DynTypedMatcher Matcher;
118 : Matchers(
std::move(MatchersIn)) {}
123 if (Matchers.size() != 1)
130 for (
size_t i = 0, e = Matchers.size(); i != e; ++i) {
133 Inner += Matchers[i].getSupportedKind().asStringRef();
135 return (Twine(
"Matcher<") + Inner +
">").str();
140 bool FoundIsExact =
false;
141 const DynTypedMatcher *Found =
nullptr;
143 for (
size_t i = 0, e = Matchers.size(); i != e; ++i) {
145 if (Ops.canConstructFrom(Matchers[i], IsExactMatch)) {
148 assert(!IsExactMatch &&
"We should not have two exact matches.");
152 Found = &Matchers[i];
153 FoundIsExact = IsExactMatch;
158 if (Found && (FoundIsExact || NumFound == 1))
164 unsigned *Specificity)
const override {
165 unsigned MaxSpecificity = 0;
166 for (
const DynTypedMatcher &Matcher : Matchers) {
167 unsigned ThisSpecificity;
168 if (
ArgKind(Matcher.getSupportedKind())
170 MaxSpecificity =
std::max(MaxSpecificity, ThisSpecificity);
174 *Specificity = MaxSpecificity;
175 return MaxSpecificity > 0;
184 std::vector<VariantMatcher> Args)
185 : Op(Op), Args(
std::move(Args)) {}
193 for (
size_t i = 0, e = Args.size(); i != e; ++i) {
196 Inner += Args[i].getTypeAsString();
203 return Ops.constructVariadicOperator(Op, Args);
207 unsigned *Specificity)
const override {
209 if (!Matcher.isConvertibleTo(Kind, Specificity))
216 const DynTypedMatcher::VariadicOperator Op;
217 const std::vector<VariantMatcher> Args;
229 std::make_shared<PolymorphicPayload>(std::move(Matchers)));
233 DynTypedMatcher::VariadicOperator Op,
234 std::vector<VariantMatcher> Args) {
236 std::make_shared<VariadicOpPayload>(Op, std::move(Args)));
277 if (
this == &Other)
return *
this;
279 switch (Other.Type) {
302 void VariantValue::reset() {
308 delete Value.Matcher;
321 return Type == VT_Boolean;
326 return Value.Boolean;
332 Value.Boolean = NewValue;
336 return Type == VT_Double;
347 Value.Double = NewValue;
351 return Type == VT_Unsigned;
356 return Value.Unsigned;
362 Value.Unsigned = NewValue;
366 return Type == VT_String;
371 return *
Value.String;
377 Value.String =
new std::string(NewValue);
381 return Type == VT_Matcher;
386 return *
Value.Matcher;
426 llvm_unreachable(
"Invalid Type");
430 unsigned *Specificity)
const {
431 unsigned MaxSpecificity = 0;
433 unsigned ThisSpecificity;
436 MaxSpecificity =
std::max(MaxSpecificity, ThisSpecificity);
438 if (Specificity && MaxSpecificity > 0) {
439 *Specificity = MaxSpecificity;
441 return MaxSpecificity > 0;
446 case VT_String:
return "String";
448 case VT_Boolean:
return "Boolean";
449 case VT_Double:
return "Double";
450 case VT_Unsigned:
return "Unsigned";
451 case VT_Nothing:
return "Nothing";
453 llvm_unreachable(
"Invalid Type");
SinglePayload(const DynTypedMatcher &Matcher)
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity) const override
void setString(StringRef String)
std::string asString() const
String representation of the type.
StringRef asStringRef() const
String representation of the kind.
The base class of the type hierarchy.
llvm::Optional< DynTypedMatcher > getSingleMatcher() const
Return a single matcher, if there is no ambiguity.
VariantValue & operator=(const VariantValue &Other)
static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher)
Clones the provided matcher.
bool isBoolean() const
Boolean value functions.
bool isUnsigned() const
Unsigned value functions.
llvm::Optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
static VariantMatcher VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, std::vector< VariantMatcher > Args)
Creates a 'variadic' operator matcher.
unsigned getUnsigned() const
PolymorphicPayload(std::vector< DynTypedMatcher > MatchersIn)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
bool isConvertibleTo(ArgKind To, unsigned *Specificity) const
Determines if this type can be converted to To.
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
ArgKind(Kind K)
Constructor for non-matcher types.
VariadicOpPayload(DynTypedMatcher::VariadicOperator Op, std::vector< VariantMatcher > Args)
std::string getTypeAsString() const
String representation of the type of the value.
llvm::Optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
std::string getTypeAsString() const override
bool isDouble() const
Double value functions.
~PolymorphicPayload() override
const std::vector< DynTypedMatcher > Matchers
std::string getTypeAsString() const
String representation of the type of the value.
VariantMatcher()
A null matcher.
void setDouble(double Double)
const VariantMatcher & getMatcher() const
std::string getTypeAsString() const override
const std::string & getString() const
bool isBaseOf(ASTNodeKind Other, unsigned *Distance=nullptr) const
Returns true if this is a base kind of (or same as) Other.
std::string getTypeAsString() const override
Dataflow Directional Tag Classes.
bool isMatcher() const
Matcher value functions.
bool isConvertibleTo(ArgKind Kind, unsigned *Specificity) const
Determines if the contained value can be converted to Kind.
static VariantMatcher PolymorphicMatcher(std::vector< DynTypedMatcher > Matchers)
Clones the provided matchers.
void reset()
Makes the matcher the "null" matcher.
void setMatcher(const VariantMatcher &Matcher)
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
A variant matcher object.
llvm::Optional< DynTypedMatcher > getSingleMatcher() const override
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity) const
Determines if the contained matcher can be converted to Kind.
ast_type_traits::ASTNodeKind getMatcherKind() const
void setUnsigned(unsigned Unsigned)
void setBoolean(bool Boolean)
llvm::Optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
bool isString() const
String value functions.