25 return (Twine(
"Matcher<") + NodeKind.asStringRef() +
">").str();
27 return NodeKind.asStringRef().str();
37 llvm_unreachable(
"unhandled ArgKind");
49 if (!NodeKind.isBaseOf(To.NodeKind, &Distance))
53 *Specificity = 100 - Distance;
58VariantMatcher::MatcherOps::canConstructFrom(
const DynTypedMatcher &Matcher,
59 bool &IsExactMatch)
const {
60 IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
61 return Matcher.canConvertTo(NodeKind);
64DynTypedMatcher VariantMatcher::MatcherOps::convertMatcher(
65 const DynTypedMatcher &Matcher)
const {
66 return Matcher.dynCastTo(NodeKind);
69std::optional<DynTypedMatcher>
70VariantMatcher::MatcherOps::constructVariadicOperator(
71 DynTypedMatcher::VariadicOperator Op,
73 std::vector<DynTypedMatcher> DynMatchers;
74 for (
const auto &InnerMatcher : InnerMatchers) {
77 if (!InnerMatcher.Value)
79 std::optional<DynTypedMatcher> Inner =
80 InnerMatcher.Value->getTypedMatcher(*
this);
83 DynMatchers.push_back(*Inner);
85 return DynTypedMatcher::constructVariadic(Op, NodeKind, DynMatchers);
88VariantMatcher::Payload::~Payload() {}
99 return (Twine(
"Matcher<") + Matcher.getSupportedKind().asStringRef() +
">")
103 std::optional<DynTypedMatcher>
106 if (Ops.canConstructFrom(Matcher, Ignore))
117 const DynTypedMatcher Matcher;
135 for (
size_t i = 0, e =
Matchers.size(); i != e; ++i) {
138 Inner +=
Matchers[i].getSupportedKind().asStringRef();
140 return (Twine(
"Matcher<") + Inner +
">").str();
143 std::optional<DynTypedMatcher>
145 bool FoundIsExact =
false;
146 const DynTypedMatcher *
Found =
nullptr;
148 for (
size_t i = 0, e =
Matchers.size(); i != e; ++i) {
150 if (Ops.canConstructFrom(
Matchers[i], IsExactMatch)) {
153 assert(!IsExactMatch &&
"We should not have two exact matches.");
158 FoundIsExact = IsExactMatch;
163 if (
Found && (FoundIsExact || NumFound == 1))
169 unsigned MaxSpecificity = 0;
170 for (
const DynTypedMatcher &Matcher :
Matchers) {
171 unsigned ThisSpecificity;
175 MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
179 *Specificity = MaxSpecificity;
180 return MaxSpecificity > 0;
189 std::vector<VariantMatcher> Args)
190 : Op(Op), Args(
std::move(Args)) {}
198 for (
size_t i = 0, e = Args.size(); i != e; ++i) {
201 Inner += Args[i].getTypeAsString();
206 std::optional<DynTypedMatcher>
208 return Ops.constructVariadicOperator(Op, Args);
213 if (!Matcher.isConvertibleTo(Kind, Specificity))
220 const DynTypedMatcher::VariadicOperator Op;
221 const std::vector<VariantMatcher> Args;
233 std::make_shared<PolymorphicPayload>(std::move(Matchers)));
237 DynTypedMatcher::VariadicOperator Op,
238 std::vector<VariantMatcher> Args) {
240 std::make_shared<VariadicOpPayload>(Op, std::move(Args)));
244 return Value ? Value->getSingleMatcher() : std::optional<DynTypedMatcher>();
250 if (Value)
return Value->getTypeAsString();
285 if (
this == &
Other)
return *
this;
287 switch (
Other.Type) {
313void VariantValue::reset() {
319 delete Value.Matcher;
322 delete Value.NodeKind;
335 return Type == VT_Boolean;
340 return Value.Boolean;
346 Value.Boolean = NewValue;
350 return Type == VT_Double;
361 Value.Double = NewValue;
365 return Type == VT_Unsigned;
370 return Value.Unsigned;
376 Value.Unsigned = NewValue;
380 return Type == VT_String;
385 return *Value.String;
391 Value.String =
new std::string(NewValue);
398 return *Value.NodeKind;
408 return Type == VT_Matcher;
413 return *Value.Matcher;
423 switch (Kind.getArgKind()) {
458 llvm_unreachable(
"Invalid Type");
462 unsigned *Specificity)
const {
463 unsigned MaxSpecificity = 0;
464 for (
const ArgKind& Kind : Kinds) {
465 unsigned ThisSpecificity;
468 MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
470 if (Specificity && MaxSpecificity > 0) {
471 *Specificity = MaxSpecificity;
473 return MaxSpecificity > 0;
478 case VT_String:
return "String";
480 case VT_Boolean:
return "Boolean";
481 case VT_Double:
return "Double";
482 case VT_Unsigned:
return "Unsigned";
485 case VT_Nothing:
return "Nothing";
487 llvm_unreachable(
"Invalid Type");
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
StringRef asStringRef() const
String representation of the kind.
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.
ArgKind(Kind K)
Constructor for non-matcher types.
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.