clang  3.9.0
Frontend/Rewrite/FrontendActions.cpp
Go to the documentation of this file.
1 //===--- FrontendActions.cpp ----------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 #include "clang/AST/ASTConsumer.h"
16 #include "clang/Frontend/Utils.h"
17 #include "clang/Lex/Preprocessor.h"
18 #include "clang/Parse/Parser.h"
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/Path.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include <memory>
26 #include <utility>
27 
28 using namespace clang;
29 
30 //===----------------------------------------------------------------------===//
31 // AST Consumer Actions
32 //===----------------------------------------------------------------------===//
33 
34 std::unique_ptr<ASTConsumer>
36  if (std::unique_ptr<raw_ostream> OS =
37  CI.createDefaultOutputFile(false, InFile))
38  return CreateHTMLPrinter(std::move(OS), CI.getPreprocessor());
39  return nullptr;
40 }
41 
44 
45 std::unique_ptr<ASTConsumer>
47  return llvm::make_unique<ASTConsumer>();
48 }
49 
50 namespace {
51 class FixItRewriteInPlace : public FixItOptions {
52 public:
53  FixItRewriteInPlace() { InPlace = true; }
54 
55  std::string RewriteFilename(const std::string &Filename, int &fd) override {
56  llvm_unreachable("don't call RewriteFilename for inplace rewrites");
57  }
58 };
59 
60 class FixItActionSuffixInserter : public FixItOptions {
61  std::string NewSuffix;
62 
63 public:
64  FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan)
65  : NewSuffix(std::move(NewSuffix)) {
66  this->FixWhatYouCan = FixWhatYouCan;
67  }
68 
69  std::string RewriteFilename(const std::string &Filename, int &fd) override {
70  fd = -1;
71  SmallString<128> Path(Filename);
72  llvm::sys::path::replace_extension(Path,
73  NewSuffix + llvm::sys::path::extension(Path));
74  return Path.str();
75  }
76 };
77 
78 class FixItRewriteToTemp : public FixItOptions {
79 public:
80  std::string RewriteFilename(const std::string &Filename, int &fd) override {
81  SmallString<128> Path;
82  llvm::sys::fs::createTemporaryFile(llvm::sys::path::filename(Filename),
83  llvm::sys::path::extension(Filename).drop_front(), fd,
84  Path);
85  return Path.str();
86  }
87 };
88 } // end anonymous namespace
89 
91  StringRef Filename) {
93  if (!FEOpts.FixItSuffix.empty()) {
94  FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix,
95  FEOpts.FixWhatYouCan));
96  } else {
97  FixItOpts.reset(new FixItRewriteInPlace);
98  FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
99  }
101  CI.getLangOpts(), FixItOpts.get()));
102  return true;
103 }
104 
106  // Otherwise rewrite all files.
107  Rewriter->WriteFixedFiles();
108 }
109 
111 
112  std::vector<std::pair<std::string, std::string> > RewrittenFiles;
113  bool err = false;
114  {
115  const FrontendOptions &FEOpts = CI.getFrontendOpts();
116  std::unique_ptr<FrontendAction> FixAction(new SyntaxOnlyAction());
117  if (FixAction->BeginSourceFile(CI, FEOpts.Inputs[0])) {
118  std::unique_ptr<FixItOptions> FixItOpts;
119  if (FEOpts.FixToTemporaries)
120  FixItOpts.reset(new FixItRewriteToTemp());
121  else
122  FixItOpts.reset(new FixItRewriteInPlace());
123  FixItOpts->Silent = true;
124  FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
125  FixItOpts->FixOnlyWarnings = FEOpts.FixOnlyWarnings;
127  CI.getLangOpts(), FixItOpts.get());
128  FixAction->Execute();
129 
130  err = Rewriter.WriteFixedFiles(&RewrittenFiles);
131 
132  FixAction->EndSourceFile();
133  CI.setSourceManager(nullptr);
134  CI.setFileManager(nullptr);
135  } else {
136  err = true;
137  }
138  }
139  if (err)
140  return false;
141  CI.getDiagnosticClient().clear();
142  CI.getDiagnostics().Reset();
143 
145  PPOpts.RemappedFiles.insert(PPOpts.RemappedFiles.end(),
146  RewrittenFiles.begin(), RewrittenFiles.end());
147  PPOpts.RemappedFilesKeepOriginalName = false;
148 
149  return true;
150 }
151 
152 #ifdef CLANG_ENABLE_OBJC_REWRITER
153 
154 std::unique_ptr<ASTConsumer>
156  if (std::unique_ptr<raw_ostream> OS =
157  CI.createDefaultOutputFile(false, InFile, "cpp")) {
160  InFile, std::move(OS), CI.getDiagnostics(), CI.getLangOpts(),
161  CI.getDiagnosticOpts().NoRewriteMacros,
162  (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo));
163  return CreateObjCRewriter(InFile, std::move(OS), CI.getDiagnostics(),
164  CI.getLangOpts(),
165  CI.getDiagnosticOpts().NoRewriteMacros);
166  }
167  return nullptr;
168 }
169 
170 #endif
171 
172 //===----------------------------------------------------------------------===//
173 // Preprocessor Actions
174 //===----------------------------------------------------------------------===//
175 
178  std::unique_ptr<raw_ostream> OS =
180  if (!OS) return;
181 
182  RewriteMacrosInInput(CI.getPreprocessor(), OS.get());
183 }
184 
187  std::unique_ptr<raw_ostream> OS =
189  if (!OS) return;
190 
191  DoRewriteTest(CI.getPreprocessor(), OS.get());
192 }
193 
196  std::unique_ptr<raw_ostream> OS =
198  if (!OS) return;
199 
202 }
LangOptions & getLangOpts()
PreprocessorOptions & getPreprocessorOpts()
std::unique_ptr< FixItOptions > FixItOpts
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
bool RemappedFilesKeepOriginalName
True if the SourceManager should report the original file name for contents of files that were remapp...
Defines the clang::FileManager interface and associated types.
CompilerInstance & getCompilerInstance() const
DiagnosticOptions & getDiagnosticOpts()
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
void setSourceManager(SourceManager *Value)
setSourceManager - Replace the current source manager.
SourceManager & getSourceManager() const
Return the current source manager.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
std::string FixItSuffix
If given, the new suffix for fix-it rewritten files.
std::unique_ptr< ASTConsumer > CreateHTMLPrinter(std::unique_ptr< raw_ostream > OS, Preprocessor &PP, bool SyntaxHighlight=true, bool HighlightMacros=true)
CreateHTMLPrinter - Create an AST consumer which rewrites source code to HTML with syntax highlightin...
Definition: HTMLPrint.cpp:51
CodeGenOptions & getCodeGenOpts()
FrontendOptions & getFrontendOpts()
DiagnosticConsumer & getDiagnosticClient() const
PreprocessorOutputOptions & getPreprocessorOutputOpts()
std::unique_ptr< ASTConsumer > CreateObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning)
unsigned FixWhatYouCan
Apply fixes even if there are unfixable errors.
void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS)
RewriteMacrosInInput - Implement -rewrite-macros mode.
void setFileManager(FileManager *Value)
Replace the current file manager and virtual file system.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
void Reset()
Reset the state of the diagnostic object to its initial configuration.
Definition: Diagnostic.cpp:115
Preprocessor & getPreprocessor() const
Return the current preprocessor.
StringRef Filename
Definition: Format.cpp:1194
Defines the clang::Preprocessor interface.
clang::ObjCRuntime ObjCRuntime
Definition: LangOptions.h:93
unsigned FixOnlyWarnings
Apply fixes only for warnings.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
void EndSourceFileAction() override
Callback at the end of processing a single input.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Definition: ObjCRuntime.h:80
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
bool BeginInvocation(CompilerInstance &CI) override
Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...
std::vector< FrontendInputFile > Inputs
The input files and their types.
const StringRef getCurrentFile() const
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
unsigned FixToTemporaries
Apply fixes to temporary files.
void RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
RewriteIncludesInInput - Implement -frewrite-includes mode.
bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override
Callback at the start of processing a single input.
FrontendOptions - Options for controlling the behavior of the frontend.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
void DoRewriteTest(Preprocessor &PP, raw_ostream *OS)
DoRewriteTest - A simple test for the TokenRewriter class.
Definition: RewriteTest.cpp:19
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="")
Create the default output file (from the invocation's options) and add it to the list of tracked outp...
Rewriter - This is the main interface to the rewrite buffers.
Definition: Rewriter.h:31
std::vector< std::pair< std::string, std::string > > RemappedFiles
The set of file remappings, which take existing files on the system (the first part of each pair) and...