13#include "clang/Config/config.h"
26#include "llvm/ADT/DenseSet.h"
27#include "llvm/Support/CrashRecoveryContext.h"
28#include "llvm/Support/FileSystem.h"
29#include "llvm/Support/Path.h"
30#include "llvm/Support/raw_ostream.h"
40std::unique_ptr<ASTConsumer>
42 if (std::unique_ptr<raw_ostream> OS =
51std::unique_ptr<ASTConsumer>
53 return std::make_unique<ASTConsumer>();
59 FixItRewriteInPlace() { InPlace =
true; }
61 std::string RewriteFilename(
const std::string &
Filename,
int &fd)
override {
62 llvm_unreachable(
"don't call RewriteFilename for inplace rewrites");
67 std::string NewSuffix;
70 FixItActionSuffixInserter(std::string NewSuffix,
bool FixWhatYouCan)
71 : NewSuffix(
std::move(NewSuffix)) {
72 this->FixWhatYouCan = FixWhatYouCan;
75 std::string RewriteFilename(
const std::string &
Filename,
int &fd)
override {
78 llvm::sys::path::replace_extension(
Path,
79 NewSuffix + llvm::sys::path::extension(
Path));
80 return std::string(
Path);
86 std::string RewriteFilename(
const std::string &
Filename,
int &fd)
override {
88 llvm::sys::fs::createTemporaryFile(llvm::sys::path::filename(
Filename),
89 llvm::sys::path::extension(
Filename).drop_front(), fd,
91 return std::string(
Path);
102 FixItOpts.reset(
new FixItRewriteInPlace);
117 std::vector<std::pair<std::string, std::string> > RewrittenFiles;
122 if (FixAction->BeginSourceFile(CI, FEOpts.
Inputs[0])) {
123 std::unique_ptr<FixItOptions> FixItOpts;
125 FixItOpts.reset(
new FixItRewriteToTemp());
127 FixItOpts.reset(
new FixItRewriteInPlace());
128 FixItOpts->Silent =
true;
133 if (llvm::Error Err = FixAction->Execute()) {
135 consumeError(std::move(Err));
139 err =
Rewriter.WriteFixedFiles(&RewrittenFiles);
141 FixAction->EndSourceFile();
155 RewrittenFiles.begin(), RewrittenFiles.end());
161#if CLANG_ENABLE_OBJC_REWRITER
163std::unique_ptr<ASTConsumer>
165 if (std::unique_ptr<raw_ostream> OS =
172 llvm::codegenoptions::NoDebugInfo));
188 std::unique_ptr<raw_ostream> OS =
197 std::unique_ptr<raw_ostream> OS =
206 std::weak_ptr<raw_ostream> Out;
208 llvm::DenseSet<const FileEntry*> Rewritten;
212 : CI(CI), Out(Out) {}
217 assert(
File &&
"missing file for loaded module?");
220 if (!Rewritten.insert(*File).second)
225 assert(MF &&
"missing module file for loaded module?");
231 auto OS = Out.lock();
232 assert(OS &&
"loaded module file after finishing rewrite action?");
234 (*OS) <<
"#pragma clang module build ";
247 Instance.setInvocation(
249 Instance.createDiagnostics(
253 Instance.getFrontendOpts().DisableFree =
false;
254 Instance.getFrontendOpts().Inputs.clear();
255 Instance.getFrontendOpts().Inputs.emplace_back(
257 Instance.getFrontendOpts().ModuleFiles.clear();
258 Instance.getFrontendOpts().ModuleMapFiles.clear();
260 Instance.getPreprocessorOutputOpts().RewriteImports =
false;
262 llvm::CrashRecoveryContext().RunSafelyOnThread([&]() {
264 Action.OutputStream = OS;
265 Instance.ExecuteAction(Action);
268 (*OS) <<
"#pragma clang module endbuild /*" << MF->
ModuleName <<
"*/\n";
280 auto &OS = *OutputStream;
286 if (Input.isFile()) {
288 OS.write_escaped(Input.getFile());
292 OS <<
"#pragma clang module contents\n";
300 std::make_unique<RewriteImportsListener>(CI, OutputStream));