10#include "llvm/ADT/ArrayRef.h"
11#include "llvm/ADT/StringRef.h"
12#include "llvm/Support/Regex.h"
21 std::vector<ast_matchers::internal::DynTypedMatcher> InnerMatchers;
22 InnerMatchers.reserve(Args.size());
23 for (
size_t I = 0; I != Args.size(); ++I) {
34 .dynCastTo(DerivedKind));
37 ast_matchers::internal::DynTypedMatcher
Result =
39 ? ast_matchers::internal::DynTypedMatcher::trueMatcher(DerivedKind)
40 : InnerMatchers.size() == 1
41 ? InnerMatchers.front()
42 : ast_matchers::internal::DynTypedMatcher::constructVariadic(
43 ast_matchers::internal::DynTypedMatcher::VO_AllOf, DerivedKind,
44 std::move(InnerMatchers));
60 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
69static std::optional<std::string>
71 llvm::StringRef DropPrefix =
"",
unsigned MaxEditDistance = 3) {
72 if (MaxEditDistance != ~0
U)
75 for (
const llvm::StringRef &Item : Allowed) {
76 if (Item.equals_insensitive(Search)) {
77 assert(Item != Search &&
"This should be handled earlier on.");
82 unsigned Distance = Item.edit_distance(Search);
83 if (Distance < MaxEditDistance) {
84 MaxEditDistance = Distance;
90 if (!DropPrefix.empty()) {
92 for (
const llvm::StringRef &Item : Allowed) {
94 if (!NoPrefix.consume_front(DropPrefix))
96 if (NoPrefix.equals_insensitive(Search)) {
97 if (NoPrefix == Search)
103 unsigned Distance = NoPrefix.edit_distance(Search);
104 if (Distance < MaxEditDistance) {
105 MaxEditDistance = Distance;
115std::optional<std::string>
116clang::ast_matchers::dynamic::internal::ArgTypeTraits<
118 static constexpr llvm::StringRef Allowed[] = {
119#define ATTR(X) "attr::" #X,
120#include "clang/Basic/AttrList.inc"
122 if (
Value.isString())
123 return ::getBestGuess(
Value.getString(), llvm::ArrayRef(Allowed),
"attr::");
127std::optional<std::string>
128clang::ast_matchers::dynamic::internal::ArgTypeTraits<
130 static constexpr llvm::StringRef Allowed[] = {
131#define CAST_OPERATION(Name) "CK_" #Name,
132#include "clang/AST/OperationKinds.def"
134 if (
Value.isString())
135 return ::getBestGuess(
Value.getString(), llvm::ArrayRef(Allowed),
"CK_");
139std::optional<std::string>
140clang::ast_matchers::dynamic::internal::ArgTypeTraits<
142 static constexpr llvm::StringRef Allowed[] = {
143#define GEN_CLANG_CLAUSE_CLASS
144#define CLAUSE_CLASS(Enum, Str, Class) #Enum,
145#include "llvm/Frontend/OpenMP/OMP.inc"
147 if (
Value.isString())
148 return ::getBestGuess(
Value.getString(), llvm::ArrayRef(Allowed),
"OMPC_");
152std::optional<std::string>
153clang::ast_matchers::dynamic::internal::ArgTypeTraits<
155 static constexpr llvm::StringRef Allowed[] = {
156#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) "UETT_" #Name,
157#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) "UETT_" #Name,
158#include "clang/Basic/BuiltinTraits.inc"
160 if (
Value.isString())
161 return ::getBestGuess(
Value.getString(), llvm::ArrayRef(Allowed),
"UETT_");
165static constexpr std::pair<llvm::StringRef, llvm::Regex::RegexFlags>
167 {
"NoFlags", llvm::Regex::RegexFlags::NoFlags},
168 {
"IgnoreCase", llvm::Regex::RegexFlags::IgnoreCase},
169 {
"Newline", llvm::Regex::RegexFlags::Newline},
170 {
"BasicRegex", llvm::Regex::RegexFlags::BasicRegex},
173static std::optional<llvm::Regex::RegexFlags>
175 for (
const auto &StringFlag :
RegexMap) {
176 if (Flag == StringFlag.first)
177 return StringFlag.second;
183 for (
const auto &StringFlag :
RegexMap) {
184 if (Flag.edit_distance(StringFlag.first) < 3)
185 return StringFlag.first;
190std::optional<llvm::Regex::RegexFlags>
191clang::ast_matchers::dynamic::internal::ArgTypeTraits<
192 llvm::Regex::RegexFlags>::getFlags(llvm::StringRef Flags) {
193 std::optional<llvm::Regex::RegexFlags> Flag;
194 SmallVector<StringRef, 4>
Split;
195 Flags.split(Split,
'|', -1,
false);
196 for (StringRef OrFlag : Split) {
197 if (std::optional<llvm::Regex::RegexFlags> NextFlag =
199 Flag = Flag.value_or(llvm::Regex::NoFlags) | *NextFlag;
206std::optional<std::string>
207clang::ast_matchers::dynamic::internal::ArgTypeTraits<
209 if (!
Value.isString())
212 llvm::StringRef(
Value.getString()).split(Split,
'|', -1,
false);
213 for (llvm::StringRef &Flag : Split) {
214 if (std::optional<llvm::StringRef> BestGuess =
222 return llvm::join(Split,
" | ");
static std::optional< llvm::StringRef > getCloseRegexMatch(llvm::StringRef Flag)
static constexpr std::pair< llvm::StringRef, llvm::Regex::RegexFlags > RegexMap[]
static std::optional< llvm::Regex::RegexFlags > getRegexFlag(llvm::StringRef Flag)
static std::optional< std::string > getBestGuess(llvm::StringRef Search, llvm::ArrayRef< llvm::StringRef > Allowed, llvm::StringRef DropPrefix="", unsigned MaxEditDistance=3)
Functions templates and classes to wrap matcher construct functions.
static ArgKind MakeMatcherArg(ASTNodeKind MatcherKind)
Constructor for matcher types.
Helper class to manage error messages.
A variant matcher object.
ast_matchers::internal::Matcher< T > getTypedMatcher() const
Return this matcher as a Matcher<T>.
bool hasTypedMatcher() const
Determines if the contained matcher can be converted to Matcher<T>.
static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher)
Clones the provided matcher.
std::string getTypeAsString() const
String representation of the type of the value.
const VariantMatcher & getMatcher() const
bool isMatcher() const
Matcher value functions.
VariantMatcher create(SourceRange NameRange, ArrayRef< ParserValue > Args, Diagnostics *Error) const override
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, ASTNodeKind *LeastDerivedKind) const override
Returns whether this matcher is convertible to the given type.
bool isRetKindConvertibleTo(ArrayRef< ASTNodeKind > RetKinds, ASTNodeKind Kind, unsigned *Specificity, ASTNodeKind *LeastDerivedKind)
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
A VariantValue instance annotated with its parser context.