16 #include "llvm/ADT/STLExtras.h" 25 return (Twine(
"Matcher<") + MatcherKind.
asStringRef() +
">").str();
35 llvm_unreachable(
"unhandled ArgKind");
47 if (!MatcherKind.
isBaseOf(To.MatcherKind, &Distance))
51 *Specificity = 100 - Distance;
56 VariantMatcher::MatcherOps::canConstructFrom(
const DynTypedMatcher &Matcher,
57 bool &IsExactMatch)
const {
58 IsExactMatch = Matcher.getSupportedKind().isSame(
NodeKind);
59 return Matcher.canConvertTo(
NodeKind);
63 VariantMatcher::MatcherOps::constructVariadicOperator(
64 DynTypedMatcher::VariadicOperator Op,
66 std::vector<DynTypedMatcher> DynMatchers;
67 for (
const auto &InnerMatcher : InnerMatchers) {
70 if (!InnerMatcher.Value)
73 InnerMatcher.Value->getTypedMatcher(*
this);
76 DynMatchers.push_back(*Inner);
78 return DynTypedMatcher::constructVariadic(Op,
NodeKind, DynMatchers);
81 VariantMatcher::Payload::~Payload() {}
92 return (Twine(
"Matcher<") + Matcher.getSupportedKind().asStringRef() +
">")
99 if (Ops.canConstructFrom(Matcher, Ignore))
105 unsigned *Specificity)
const override {
106 return ArgKind(Matcher.getSupportedKind())
111 const DynTypedMatcher Matcher;
117 : Matchers(
std::move(MatchersIn)) {}
122 if (Matchers.size() != 1)
129 for (
size_t i = 0, e = Matchers.size(); i != e; ++i) {
132 Inner += Matchers[i].getSupportedKind().asStringRef();
134 return (Twine(
"Matcher<") + Inner +
">").str();
139 bool FoundIsExact =
false;
140 const DynTypedMatcher *Found =
nullptr;
142 for (
size_t i = 0, e = Matchers.size(); i != e; ++i) {
144 if (Ops.canConstructFrom(Matchers[i], IsExactMatch)) {
147 assert(!IsExactMatch &&
"We should not have two exact matches.");
151 Found = &Matchers[i];
152 FoundIsExact = IsExactMatch;
157 if (Found && (FoundIsExact || NumFound == 1))
163 unsigned *Specificity)
const override {
164 unsigned MaxSpecificity = 0;
165 for (
const DynTypedMatcher &Matcher : Matchers) {
166 unsigned ThisSpecificity;
167 if (
ArgKind(Matcher.getSupportedKind())
169 MaxSpecificity =
std::max(MaxSpecificity, ThisSpecificity);
173 *Specificity = MaxSpecificity;
174 return MaxSpecificity > 0;
183 std::vector<VariantMatcher> Args)
184 : Op(Op), Args(
std::move(Args)) {}
192 for (
size_t i = 0, e = Args.size(); i != e; ++i) {
195 Inner += Args[i].getTypeAsString();
202 return Ops.constructVariadicOperator(Op, Args);
206 unsigned *Specificity)
const override {
208 if (!Matcher.isConvertibleTo(Kind, Specificity))
215 const DynTypedMatcher::VariadicOperator Op;
216 const std::vector<VariantMatcher> Args;
228 std::make_shared<PolymorphicPayload>(std::move(Matchers)));
232 DynTypedMatcher::VariadicOperator Op,
233 std::vector<VariantMatcher> Args) {
235 std::make_shared<VariadicOpPayload>(Op, std::move(Args)));
276 if (
this == &Other)
return *
this;
278 switch (Other.Type) {
301 void VariantValue::reset() {
307 delete Value.Matcher;
320 return Type == VT_Boolean;
325 return Value.Boolean;
331 Value.Boolean = NewValue;
335 return Type == VT_Double;
346 Value.Double = NewValue;
350 return Type == VT_Unsigned;
355 return Value.Unsigned;
361 Value.Unsigned = NewValue;
365 return Type == VT_String;
370 return *
Value.String;
376 Value.String =
new std::string(NewValue);
380 return Type == VT_Matcher;
385 return *
Value.Matcher;
425 llvm_unreachable(
"Invalid Type");
429 unsigned *Specificity)
const {
430 unsigned MaxSpecificity = 0;
432 unsigned ThisSpecificity;
435 MaxSpecificity =
std::max(MaxSpecificity, ThisSpecificity);
437 if (Specificity && MaxSpecificity > 0) {
438 *Specificity = MaxSpecificity;
440 return MaxSpecificity > 0;
445 case VT_String:
return "String";
447 case VT_Boolean:
return "Boolean";
448 case VT_Double:
return "Double";
449 case VT_Unsigned:
return "Unsigned";
450 case VT_Nothing:
return "Nothing";
452 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
__DEVICE__ int max(int __a, int __b)
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
NodeKind
A kind of a syntax node, used for implementing casts.
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)
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.