14 #include "llvm/ADT/Optional.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/Support/Errc.h" 17 #include "llvm/Support/Error.h" 23 using namespace clang;
24 using namespace transformer;
27 using ast_matchers::internal::DynTypedMatcher;
36 for (
const auto &Edit : Edits) {
39 return Range.takeError();
46 auto Replacement = Edit.Replacement->eval(Result);
48 return Replacement.takeError();
52 Transformations.push_back(std::move(T));
54 return Transformations;
70 SimpleTextGenerator(std::string S) : S(std::move(S)) {}
72 std::string *Result)
const override {
74 return llvm::Error::success();
76 std::string
toString()
const override {
77 return (llvm::Twine(
"text(\"") + S +
"\")").str();
83 return change(std::move(S), std::make_shared<SimpleTextGenerator>(
""));
89 std::move(M), std::move(Edits), std::move(Explanation), {}}}};
94 for (
auto &Case : Rule.
Cases)
95 Case.AddedIncludes.emplace_back(Header.str(), Format);
112 std::vector<DynTypedMatcher> Matchers;
113 Matchers.reserve(Cases.size());
114 for (
const auto &Case : Cases) {
115 std::string Tag = (TagBase + Twine(Case.first)).str();
117 DynTypedMatcher BoundMatcher(Case.second.Matcher);
118 BoundMatcher.setAllowBind(
true);
119 auto M = BoundMatcher.tryBind(Tag);
120 Matchers.push_back(*std::move(M));
130 for (
auto &Rule : Rules)
135 std::vector<DynTypedMatcher>
141 std::map<ASTNodeKind, SmallVector<std::pair<size_t, RewriteRule::Case>, 1>>
144 for (
int I = 0, N = Cases.size(); I < N; ++I) {
146 "Matcher must be non-(Qual)Type node matcher");
147 Buckets[Cases[I].Matcher.getSupportedKind()].emplace_back(I, Cases[I]);
150 std::vector<DynTypedMatcher> Matchers;
151 for (
const auto &Bucket : Buckets) {
152 DynTypedMatcher M = DynTypedMatcher::constructVariadic(
153 DynTypedMatcher::VO_AnyOf, Bucket.first,
155 M.setAllowBind(
true);
164 assert(Ms.size() == 1 &&
"Cases must have compatible matchers.");
169 auto &NodesMap = Result.Nodes.getMap();
171 assert(Root != NodesMap.end() &&
"Transformation failed: missing root node.");
176 return RootRange->getBegin();
179 return Result.SourceManager->getExpansionLoc(
180 Root->second.getSourceRange().getBegin());
188 if (Rule.
Cases.size() == 1)
189 return Rule.
Cases[0];
191 auto &NodesMap = Result.Nodes.getMap();
192 for (
size_t i = 0, N = Rule.
Cases.size(); i < N; ++i) {
193 std::string Tag = (
"Tag" + Twine(i)).str();
194 if (NodesMap.find(Tag) != NodesMap.end())
195 return Rule.
Cases[i];
197 llvm_unreachable(
"No tag found for this rule.");
203 return std::make_shared<SimpleTextGenerator>(std::move(M));
A class to allow finding matches over the Clang AST.
A (possibly-)qualified type.
static CharSourceRange getTokenRange(SourceRange R)
MatchFinder::MatchResult MatchResult
MatchFinder::MatchResult MatchResult
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static std::vector< DynTypedMatcher > taggedMatchers(StringRef TagBase, const SmallVectorImpl< std::pair< size_t, RewriteRule::Case >> &Cases)
Contains all information for a given match.
Encodes a location in the source.
Dataflow Directional Tag Classes.
Defines the clang::SourceLocation class and associated facilities.
static bool hasValidKind(const DynTypedMatcher &M)
Defines the RewriteRule class and related functions for creating, modifying and interpreting RewriteR...