clang  3.7.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 
27 using namespace clang;
28 
29 //===----------------------------------------------------------------------===//
30 // AST Consumer Actions
31 //===----------------------------------------------------------------------===//
32 
33 std::unique_ptr<ASTConsumer>
35  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
36  return CreateHTMLPrinter(OS, CI.getPreprocessor());
37  return nullptr;
38 }
39 
42 
43 std::unique_ptr<ASTConsumer>
45  return llvm::make_unique<ASTConsumer>();
46 }
47 
48 namespace {
49 class FixItRewriteInPlace : public FixItOptions {
50 public:
51  FixItRewriteInPlace() { InPlace = true; }
52 
53  std::string RewriteFilename(const std::string &Filename, int &fd) override {
54  llvm_unreachable("don't call RewriteFilename for inplace rewrites");
55  }
56 };
57 
58 class FixItActionSuffixInserter : public FixItOptions {
59  std::string NewSuffix;
60 
61 public:
62  FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan)
63  : NewSuffix(NewSuffix) {
64  this->FixWhatYouCan = FixWhatYouCan;
65  }
66 
67  std::string RewriteFilename(const std::string &Filename, int &fd) override {
68  fd = -1;
69  SmallString<128> Path(Filename);
70  llvm::sys::path::replace_extension(Path,
71  NewSuffix + llvm::sys::path::extension(Path));
72  return Path.str();
73  }
74 };
75 
76 class FixItRewriteToTemp : public FixItOptions {
77 public:
78  std::string RewriteFilename(const std::string &Filename, int &fd) override {
79  SmallString<128> Path;
80  llvm::sys::fs::createTemporaryFile(llvm::sys::path::filename(Filename),
81  llvm::sys::path::extension(Filename), fd,
82  Path);
83  return Path.str();
84  }
85 };
86 } // end anonymous namespace
87 
89  StringRef Filename) {
91  if (!FEOpts.FixItSuffix.empty()) {
92  FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix,
93  FEOpts.FixWhatYouCan));
94  } else {
95  FixItOpts.reset(new FixItRewriteInPlace);
96  FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
97  }
99  CI.getLangOpts(), FixItOpts.get()));
100  return true;
101 }
102 
104  // Otherwise rewrite all files.
105  Rewriter->WriteFixedFiles();
106 }
107 
109 
110  std::vector<std::pair<std::string, std::string> > RewrittenFiles;
111  bool err = false;
112  {
113  const FrontendOptions &FEOpts = CI.getFrontendOpts();
114  std::unique_ptr<FrontendAction> FixAction(new SyntaxOnlyAction());
115  if (FixAction->BeginSourceFile(CI, FEOpts.Inputs[0])) {
116  std::unique_ptr<FixItOptions> FixItOpts;
117  if (FEOpts.FixToTemporaries)
118  FixItOpts.reset(new FixItRewriteToTemp());
119  else
120  FixItOpts.reset(new FixItRewriteInPlace());
121  FixItOpts->Silent = true;
122  FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
123  FixItOpts->FixOnlyWarnings = FEOpts.FixOnlyWarnings;
125  CI.getLangOpts(), FixItOpts.get());
126  FixAction->Execute();
127 
128  err = Rewriter.WriteFixedFiles(&RewrittenFiles);
129 
130  FixAction->EndSourceFile();
131  CI.setSourceManager(nullptr);
132  CI.setFileManager(nullptr);
133  } else {
134  err = true;
135  }
136  }
137  if (err)
138  return false;
139  CI.getDiagnosticClient().clear();
140  CI.getDiagnostics().Reset();
141 
143  PPOpts.RemappedFiles.insert(PPOpts.RemappedFiles.end(),
144  RewrittenFiles.begin(), RewrittenFiles.end());
145  PPOpts.RemappedFilesKeepOriginalName = false;
146 
147  return true;
148 }
149 
150 #ifdef CLANG_ENABLE_OBJC_REWRITER
151 
152 std::unique_ptr<ASTConsumer>
154  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) {
156  return CreateModernObjCRewriter(InFile, OS,
157  CI.getDiagnostics(), CI.getLangOpts(),
158  CI.getDiagnosticOpts().NoRewriteMacros,
159  (CI.getCodeGenOpts().getDebugInfo() !=
161  return CreateObjCRewriter(InFile, OS,
162  CI.getDiagnostics(), CI.getLangOpts(),
163  CI.getDiagnosticOpts().NoRewriteMacros);
164  }
165  return nullptr;
166 }
167 
168 #endif
169 
170 //===----------------------------------------------------------------------===//
171 // Preprocessor Actions
172 //===----------------------------------------------------------------------===//
173 
176  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
177  if (!OS) return;
178 
180 }
181 
184  raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
185  if (!OS) return;
186 
187  DoRewriteTest(CI.getPreprocessor(), OS);
188 }
189 
192  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
193  if (!OS) return;
194 
197 }
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.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, raw_ostream *OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
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.
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.
CodeGenOptions & getCodeGenOpts()
FrontendOptions & getFrontendOpts()
DiagnosticConsumer & getDiagnosticClient() const
PreprocessorOutputOptions & getPreprocessorOutputOpts()
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:114
Preprocessor & getPreprocessor() const
Return the current preprocessor.
Defines the clang::Preprocessor interface.
clang::ObjCRuntime ObjCRuntime
Definition: LangOptions.h:85
unsigned FixOnlyWarnings
Apply fixes only for warnings.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
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:76
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.
std::unique_ptr< ASTConsumer > CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning)
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.
std::unique_ptr< ASTConsumer > CreateHTMLPrinter(raw_ostream *OS, Preprocessor &PP, bool SyntaxHighlight=true, bool HighlightMacros=true)
Definition: HTMLPrint.cpp:50
void DoRewriteTest(Preprocessor &PP, raw_ostream *OS)
DoRewriteTest - A simple test for the TokenRewriter class.
Definition: RewriteTest.cpp:19
raw_pwrite_stream * createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="")
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...