16#include "llvm/ADT/STLExtras.h"
20namespace ast_matchers {
26 return (Twine(
"Matcher<") + NodeKind.
asStringRef() +
">").str();
38 llvm_unreachable(
"unhandled ArgKind");
50 if (!NodeKind.
isBaseOf(To.NodeKind, &Distance))
54 *Specificity = 100 - Distance;
59VariantMatcher::MatcherOps::canConstructFrom(
const DynTypedMatcher &Matcher,
60 bool &IsExactMatch)
const {
61 IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
62 return Matcher.canConvertTo(NodeKind);
65DynTypedMatcher VariantMatcher::MatcherOps::convertMatcher(
66 const DynTypedMatcher &Matcher)
const {
67 return Matcher.dynCastTo(NodeKind);
70std::optional<DynTypedMatcher>
71VariantMatcher::MatcherOps::constructVariadicOperator(
72 DynTypedMatcher::VariadicOperator Op,
74 std::vector<DynTypedMatcher> DynMatchers;
75 for (
const auto &InnerMatcher : InnerMatchers) {
78 if (!InnerMatcher.Value)
80 std::optional<DynTypedMatcher> Inner =
81 InnerMatcher.Value->getTypedMatcher(*
this);
84 DynMatchers.push_back(*Inner);
86 return DynTypedMatcher::constructVariadic(Op, NodeKind, DynMatchers);
89VariantMatcher::Payload::~Payload() {}
100 return (Twine(
"Matcher<") + Matcher.getSupportedKind().asStringRef() +
">")
104 std::optional<DynTypedMatcher>
107 if (Ops.canConstructFrom(Matcher, Ignore))
118 const DynTypedMatcher Matcher;
136 for (
size_t i = 0, e =
Matchers.size(); i != e; ++i) {
139 Inner +=
Matchers[i].getSupportedKind().asStringRef();
141 return (Twine(
"Matcher<") + Inner +
">").str();
144 std::optional<DynTypedMatcher>
146 bool FoundIsExact =
false;
147 const DynTypedMatcher *
Found =
nullptr;
149 for (
size_t i = 0, e =
Matchers.size(); i != e; ++i) {
151 if (Ops.canConstructFrom(
Matchers[i], IsExactMatch)) {
154 assert(!IsExactMatch &&
"We should not have two exact matches.");
159 FoundIsExact = IsExactMatch;
164 if (
Found && (FoundIsExact || NumFound == 1))
170 unsigned MaxSpecificity = 0;
171 for (
const DynTypedMatcher &Matcher :
Matchers) {
172 unsigned ThisSpecificity;
176 MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
180 *Specificity = MaxSpecificity;
181 return MaxSpecificity > 0;
190 std::vector<VariantMatcher> Args)
191 : Op(Op), Args(
std::move(Args)) {}
199 for (
size_t i = 0, e = Args.size(); i != e; ++i) {
202 Inner += Args[i].getTypeAsString();
207 std::optional<DynTypedMatcher>
209 return Ops.constructVariadicOperator(Op, Args);
214 if (!Matcher.isConvertibleTo(
Kind, Specificity))
221 const DynTypedMatcher::VariadicOperator Op;
222 const std::vector<VariantMatcher> Args;
234 std::make_shared<PolymorphicPayload>(std::move(Matchers)));
238 DynTypedMatcher::VariadicOperator Op,
239 std::vector<VariantMatcher> Args) {
241 std::make_shared<VariadicOpPayload>(Op, std::move(Args)));
245 return Value ?
Value->getSingleMatcher() : std::optional<DynTypedMatcher>();
286 if (
this == &
Other)
return *
this;
288 switch (
Other.Type) {
314void VariantValue::reset() {
320 delete Value.Matcher;
323 delete Value.NodeKind;
336 return Type == VT_Boolean;
341 return Value.Boolean;
347 Value.Boolean = NewValue;
351 return Type == VT_Double;
362 Value.Double = NewValue;
366 return Type == VT_Unsigned;
371 return Value.Unsigned;
377 Value.Unsigned = NewValue;
381 return Type == VT_String;
386 return *
Value.String;
392 Value.String =
new std::string(NewValue);
399 return *
Value.NodeKind;
409 return Type == VT_Matcher;
414 return *
Value.Matcher;
424 switch (
Kind.getArgKind()) {
459 llvm_unreachable(
"Invalid Type");
463 unsigned *Specificity)
const {
464 unsigned MaxSpecificity = 0;
466 unsigned ThisSpecificity;
469 MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
471 if (Specificity && MaxSpecificity > 0) {
472 *Specificity = MaxSpecificity;
474 return MaxSpecificity > 0;
479 case VT_String:
return "String";
481 case VT_Boolean:
return "Boolean";
482 case VT_Double:
return "Double";
483 case VT_Unsigned:
return "Unsigned";
486 case VT_Nothing:
return "Nothing";
488 llvm_unreachable(
"Invalid Type");
enum clang::sema::@1655::IndirectLocalPathEntry::EntryKind Kind
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
StringRef asStringRef() const
String representation of the kind.
bool isBaseOf(ASTNodeKind Other) const
Returns true if this is a base kind of (or same as) Other.
The base class of the type hierarchy.
static ArgKind MakeMatcherArg(ASTNodeKind MatcherKind)
Constructor for matcher types.
std::string asString() const
String representation of the type.
bool isConvertibleTo(ArgKind To, unsigned *Specificity) const
Determines if this type can be converted to To.
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const override
std::optional< DynTypedMatcher > getSingleMatcher() const override
std::optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
std::string getTypeAsString() const override
const std::vector< DynTypedMatcher > Matchers
PolymorphicPayload(std::vector< DynTypedMatcher > MatchersIn)
~PolymorphicPayload() override
SinglePayload(const DynTypedMatcher &Matcher)
std::string getTypeAsString() const override
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const override
std::optional< DynTypedMatcher > getSingleMatcher() const override
std::optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
VariadicOpPayload(DynTypedMatcher::VariadicOperator Op, std::vector< VariantMatcher > Args)
std::optional< DynTypedMatcher > getTypedMatcher(const MatcherOps &Ops) const override
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const override
std::optional< DynTypedMatcher > getSingleMatcher() const override
std::string getTypeAsString() const override
A variant matcher object.
static VariantMatcher PolymorphicMatcher(std::vector< DynTypedMatcher > Matchers)
Clones the provided matchers.
VariantMatcher()
A null matcher.
void reset()
Makes the matcher the "null" matcher.
std::optional< DynTypedMatcher > getSingleMatcher() const
Return a single matcher, if there is no ambiguity.
std::string getTypeAsString() const
String representation of the type of the value.
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const
Determines if the contained matcher can be converted to Kind.
static VariantMatcher VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, std::vector< VariantMatcher > Args)
Creates a 'variadic' operator matcher.
static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher)
Clones the provided matcher.
bool isString() const
String value functions.
void setNodeKind(ASTNodeKind NodeKind)
unsigned getUnsigned() const
void setBoolean(bool Boolean)
const ASTNodeKind & getNodeKind() const
const std::string & getString() const
bool isUnsigned() const
Unsigned value functions.
void setDouble(double Double)
std::string getTypeAsString() const
String representation of the type of the value.
bool isConvertibleTo(ArgKind Kind, unsigned *Specificity) const
Determines if the contained value can be converted to Kind.
void setString(StringRef String)
void setUnsigned(unsigned Unsigned)
const VariantMatcher & getMatcher() const
bool isMatcher() const
Matcher value functions.
bool isBoolean() const
Boolean value functions.
void setMatcher(const VariantMatcher &Matcher)
VariantValue & operator=(const VariantValue &Other)
bool isDouble() const
Double value functions.
The JSON file list parser is used to communicate input to InstallAPI.
@ Other
Other implicit parameter.