Remove the OpenMP clause information from the OMPKinds.def file and use the information from the new OMP.td file. There is now a single source of truth for the directives and clauses. To avoid generate lots of specific small code from tablegen, the macros previously used in OMPKinds.def are generated almost as identical. This can be polished and possibly removed in a further patch. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D92955
176 lines
5.5 KiB
C++
176 lines
5.5 KiB
C++
//===--- Marshallers.cpp ----------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Marshallers.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/Optional.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/Regex.h"
|
|
#include <string>
|
|
|
|
static llvm::Optional<std::string>
|
|
getBestGuess(llvm::StringRef Search, llvm::ArrayRef<llvm::StringRef> Allowed,
|
|
llvm::StringRef DropPrefix = "", unsigned MaxEditDistance = 3) {
|
|
if (MaxEditDistance != ~0U)
|
|
++MaxEditDistance;
|
|
llvm::StringRef Res;
|
|
for (const llvm::StringRef &Item : Allowed) {
|
|
if (Item.equals_lower(Search)) {
|
|
assert(!Item.equals(Search) && "This should be handled earlier on.");
|
|
MaxEditDistance = 1;
|
|
Res = Item;
|
|
continue;
|
|
}
|
|
unsigned Distance = Item.edit_distance(Search);
|
|
if (Distance < MaxEditDistance) {
|
|
MaxEditDistance = Distance;
|
|
Res = Item;
|
|
}
|
|
}
|
|
if (!Res.empty())
|
|
return Res.str();
|
|
if (!DropPrefix.empty()) {
|
|
--MaxEditDistance; // Treat dropping the prefix as 1 edit
|
|
for (const llvm::StringRef &Item : Allowed) {
|
|
auto NoPrefix = Item;
|
|
if (!NoPrefix.consume_front(DropPrefix))
|
|
continue;
|
|
if (NoPrefix.equals_lower(Search)) {
|
|
if (NoPrefix.equals(Search))
|
|
return Item.str();
|
|
MaxEditDistance = 1;
|
|
Res = Item;
|
|
continue;
|
|
}
|
|
unsigned Distance = NoPrefix.edit_distance(Search);
|
|
if (Distance < MaxEditDistance) {
|
|
MaxEditDistance = Distance;
|
|
Res = Item;
|
|
}
|
|
}
|
|
if (!Res.empty())
|
|
return Res.str();
|
|
}
|
|
return llvm::None;
|
|
}
|
|
|
|
llvm::Optional<std::string>
|
|
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
|
|
clang::attr::Kind>::getBestGuess(const VariantValue &Value) {
|
|
static constexpr llvm::StringRef Allowed[] = {
|
|
#define ATTR(X) "attr::" #X,
|
|
#include "clang/Basic/AttrList.inc"
|
|
};
|
|
if (Value.isString())
|
|
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
|
|
"attr::");
|
|
return llvm::None;
|
|
}
|
|
|
|
llvm::Optional<std::string>
|
|
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
|
|
clang::CastKind>::getBestGuess(const VariantValue &Value) {
|
|
static constexpr llvm::StringRef Allowed[] = {
|
|
#define CAST_OPERATION(Name) "CK_" #Name,
|
|
#include "clang/AST/OperationKinds.def"
|
|
};
|
|
if (Value.isString())
|
|
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
|
|
"CK_");
|
|
return llvm::None;
|
|
}
|
|
|
|
llvm::Optional<std::string>
|
|
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
|
|
clang::OpenMPClauseKind>::getBestGuess(const VariantValue &Value) {
|
|
static constexpr llvm::StringRef Allowed[] = {
|
|
#define GEN_CLANG_CLAUSE_CLASS
|
|
#define CLAUSE_CLASS(Enum, Str, Class) #Enum,
|
|
#include "llvm/Frontend/OpenMP/OMP.inc"
|
|
};
|
|
if (Value.isString())
|
|
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
|
|
"OMPC_");
|
|
return llvm::None;
|
|
}
|
|
|
|
llvm::Optional<std::string>
|
|
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
|
|
clang::UnaryExprOrTypeTrait>::getBestGuess(const VariantValue &Value) {
|
|
static constexpr llvm::StringRef Allowed[] = {
|
|
#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) "UETT_" #Name,
|
|
#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) "UETT_" #Name,
|
|
#include "clang/Basic/TokenKinds.def"
|
|
};
|
|
if (Value.isString())
|
|
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
|
|
"UETT_");
|
|
return llvm::None;
|
|
}
|
|
|
|
static constexpr std::pair<llvm::StringRef, llvm::Regex::RegexFlags>
|
|
RegexMap[] = {
|
|
{"NoFlags", llvm::Regex::RegexFlags::NoFlags},
|
|
{"IgnoreCase", llvm::Regex::RegexFlags::IgnoreCase},
|
|
{"Newline", llvm::Regex::RegexFlags::Newline},
|
|
{"BasicRegex", llvm::Regex::RegexFlags::BasicRegex},
|
|
};
|
|
|
|
static llvm::Optional<llvm::Regex::RegexFlags>
|
|
getRegexFlag(llvm::StringRef Flag) {
|
|
for (const auto &StringFlag : RegexMap) {
|
|
if (Flag == StringFlag.first)
|
|
return StringFlag.second;
|
|
}
|
|
return llvm::None;
|
|
}
|
|
|
|
static llvm::Optional<llvm::StringRef>
|
|
getCloseRegexMatch(llvm::StringRef Flag) {
|
|
for (const auto &StringFlag : RegexMap) {
|
|
if (Flag.edit_distance(StringFlag.first) < 3)
|
|
return StringFlag.first;
|
|
}
|
|
return llvm::None;
|
|
}
|
|
|
|
llvm::Optional<llvm::Regex::RegexFlags>
|
|
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
|
|
llvm::Regex::RegexFlags>::getFlags(llvm::StringRef Flags) {
|
|
llvm::Optional<llvm::Regex::RegexFlags> Flag;
|
|
SmallVector<StringRef, 4> Split;
|
|
Flags.split(Split, '|', -1, false);
|
|
for (StringRef OrFlag : Split) {
|
|
if (llvm::Optional<llvm::Regex::RegexFlags> NextFlag =
|
|
getRegexFlag(OrFlag.trim()))
|
|
Flag = Flag.getValueOr(llvm::Regex::NoFlags) | *NextFlag;
|
|
else
|
|
return None;
|
|
}
|
|
return Flag;
|
|
}
|
|
|
|
llvm::Optional<std::string>
|
|
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
|
|
llvm::Regex::RegexFlags>::getBestGuess(const VariantValue &Value) {
|
|
if (!Value.isString())
|
|
return llvm::None;
|
|
SmallVector<StringRef, 4> Split;
|
|
llvm::StringRef(Value.getString()).split(Split, '|', -1, false);
|
|
for (llvm::StringRef &Flag : Split) {
|
|
if (llvm::Optional<llvm::StringRef> BestGuess =
|
|
getCloseRegexMatch(Flag.trim()))
|
|
Flag = *BestGuess;
|
|
else
|
|
return None;
|
|
}
|
|
if (Split.empty())
|
|
return None;
|
|
return llvm::join(Split, " | ");
|
|
}
|