clang  12.0.0git
Transformer.cpp
Go to the documentation of this file.
1 //===--- Transformer.cpp - Transformer library implementation ---*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
14 #include "llvm/Support/Error.h"
15 #include <map>
16 #include <utility>
17 #include <vector>
18 
19 using namespace clang;
20 using namespace tooling;
21 
23 
25  for (auto &Matcher : transformer::detail::buildMatchers(Rule))
26  MatchFinder->addDynamicMatcher(Matcher, this);
27 }
28 
30  if (Result.Context->getDiagnostics().hasErrorOccurred())
31  return;
32 
35  auto Transformations = Case.Edits(Result);
36  if (!Transformations) {
37  Consumer(Transformations.takeError());
38  return;
39  }
40 
41  if (Transformations->empty()) {
42  // No rewrite applied (but no error encountered either).
44  llvm::errs() << "note: skipping match at loc ", *Result.SourceManager);
45  llvm::errs() << "\n";
46  return;
47  }
48 
49  // Group the transformations, by file, into AtomicChanges, each anchored by
50  // the location of the first change in that file.
51  std::map<FileID, AtomicChange> ChangesByFileID;
52  for (const auto &T : *Transformations) {
53  auto ID = Result.SourceManager->getFileID(T.Range.getBegin());
54  auto Iter = ChangesByFileID
55  .emplace(ID, AtomicChange(*Result.SourceManager,
56  T.Range.getBegin(), T.Metadata))
57  .first;
58  auto &AC = Iter->second;
59  if (auto Err = AC.replace(*Result.SourceManager, T.Range, T.Replacement)) {
60  Consumer(std::move(Err));
61  return;
62  }
63  }
64 
65  for (auto &IDChangePair : ChangesByFileID) {
66  auto &AC = IDChangePair.second;
67  // FIXME: this will add includes to *all* changed files, which may not be
68  // the intent. We should upgrade the representation to allow associating
69  // headers with specific edits.
70  for (const auto &I : Case.AddedIncludes) {
71  auto &Header = I.first;
72  switch (I.second) {
74  AC.addHeader(Header);
75  break;
77  AC.addHeader((llvm::Twine("<") + Header + ">").str());
78  break;
79  }
80  }
81 
82  Consumer(std::move(AC));
83  }
84 }
A class to allow finding matches over the Clang AST.
bool hasErrorOccurred() const
Definition: Diagnostic.h:757
DiagnosticsEngine & getDiagnostics() const
void run(const ast_matchers::MatchFinder::MatchResult &Result) override
Not called directly by users – called by the framework, via base class pointer.
Definition: Transformer.cpp:29
void print(raw_ostream &OS, const SourceManager &SM) const
std::vector< std::pair< std::string, IncludeFormat > > AddedIncludes
Definition: RewriteRule.h:143
void registerMatchers(ast_matchers::MatchFinder *MatchFinder)
N.B.
Definition: Transformer.cpp:24
const RewriteRule::Case & findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result, const RewriteRule &Rule)
Returns the Case of Rule that was selected in the match result.
Contains all information for a given match.
std::vector< ast_matchers::internal::DynTypedMatcher > buildMatchers(const RewriteRule &Rule)
Builds a set of matchers that cover the rule.
clang::ASTContext *const Context
Utilities for interpreting the matched AST structures.
Dataflow Directional Tag Classes.
SourceLocation getRuleMatchLoc(const ast_matchers::MatchFinder::MatchResult &Result)
Gets the beginning location of the source matched by a rewrite rule.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
Defines the clang::SourceLocation class and associated facilities.
An atomic change is used to create and group a set of source edits, e.g.
Definition: AtomicChange.h:37
clang::SourceManager *const SourceManager
bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.