]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Frontend/FrontendActions.cpp
Update clang to 97654.
[FreeBSD/FreeBSD.git] / lib / Frontend / FrontendActions.cpp
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
10 #include "clang/Frontend/FrontendActions.h"
11 #include "clang/AST/ASTConsumer.h"
12 #include "clang/Lex/Preprocessor.h"
13 #include "clang/Parse/Parser.h"
14 #include "clang/Basic/FileManager.h"
15 #include "clang/Frontend/AnalysisConsumer.h"
16 #include "clang/Frontend/ASTConsumers.h"
17 #include "clang/Frontend/ASTUnit.h"
18 #include "clang/Frontend/CompilerInstance.h"
19 #include "clang/Frontend/FixItRewriter.h"
20 #include "clang/Frontend/FrontendDiagnostic.h"
21 #include "clang/Frontend/Utils.h"
22 #include "llvm/Support/raw_ostream.h"
23 using namespace clang;
24
25 //===----------------------------------------------------------------------===//
26 // AST Consumer Actions
27 //===----------------------------------------------------------------------===//
28
29 ASTConsumer *AnalysisAction::CreateASTConsumer(CompilerInstance &CI,
30                                                llvm::StringRef InFile) {
31   return CreateAnalysisConsumer(CI.getPreprocessor(),
32                                 CI.getFrontendOpts().OutputFile,
33                                 CI.getAnalyzerOpts());
34 }
35
36 ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
37                                                llvm::StringRef InFile) {
38   if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
39     return CreateASTPrinter(OS);
40   return 0;
41 }
42
43 ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI,
44                                                   llvm::StringRef InFile) {
45   if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml"))
46     return CreateASTPrinterXML(OS);
47   return 0;
48 }
49
50 ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
51                                               llvm::StringRef InFile) {
52   return CreateASTDumper();
53 }
54
55 ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
56                                               llvm::StringRef InFile) {
57   return CreateASTViewer();
58 }
59
60 ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
61                                                        llvm::StringRef InFile) {
62   return CreateDeclContextPrinter();
63 }
64
65 ASTConsumer *DumpRecordAction::CreateASTConsumer(CompilerInstance &CI,
66                                                  llvm::StringRef InFile) {
67   return CreateRecordLayoutDumper();
68 }
69
70 ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
71                                                   llvm::StringRef InFile) {
72   const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
73   if (CI.getFrontendOpts().RelocatablePCH &&
74       Sysroot.empty()) {
75     CI.getDiagnostics().Report(diag::err_relocatable_without_without_isysroot);
76     return 0;
77   }
78
79   llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, InFile);
80   if (!OS)
81     return 0;
82
83   if (CI.getFrontendOpts().RelocatablePCH)
84     return CreatePCHGenerator(CI.getPreprocessor(), OS, Sysroot.c_str());
85
86   return CreatePCHGenerator(CI.getPreprocessor(), OS);
87 }
88
89 ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI,
90                                                 llvm::StringRef InFile) {
91   if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
92     return CreateHTMLPrinter(OS, CI.getPreprocessor());
93   return 0;
94 }
95
96 ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
97                                                       llvm::StringRef InFile) {
98   return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance);
99 }
100
101 FixItAction::FixItAction() {}
102 FixItAction::~FixItAction() {}
103
104 ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI,
105                                             llvm::StringRef InFile) {
106   return new ASTConsumer();
107 }
108
109 /// AddFixItLocations - Add any individual user specified "fix-it" locations,
110 /// and return true on success.
111 static bool AddFixItLocations(CompilerInstance &CI,
112                               FixItRewriter &FixItRewrite) {
113   const std::vector<ParsedSourceLocation> &Locs =
114     CI.getFrontendOpts().FixItLocations;
115   for (unsigned i = 0, e = Locs.size(); i != e; ++i) {
116     const FileEntry *File = CI.getFileManager().getFile(Locs[i].FileName);
117     if (!File) {
118       CI.getDiagnostics().Report(diag::err_fe_unable_to_find_fixit_file)
119         << Locs[i].FileName;
120       return false;
121     }
122
123     RequestedSourceLocation Requested;
124     Requested.File = File;
125     Requested.Line = Locs[i].Line;
126     Requested.Column = Locs[i].Column;
127     FixItRewrite.addFixItLocation(Requested);
128   }
129
130   return true;
131 }
132
133 bool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
134                                         llvm::StringRef Filename) {
135   Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
136                                    CI.getLangOpts()));
137   if (!AddFixItLocations(CI, *Rewriter))
138     return false;
139
140   return true;
141 }
142
143 void FixItAction::EndSourceFileAction() {
144   const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
145   Rewriter->WriteFixedFile(getCurrentFile(), FEOpts.OutputFile);
146 }
147
148 ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,
149                                                   llvm::StringRef InFile) {
150   if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp"))
151     return CreateObjCRewriter(InFile, OS,
152                               CI.getDiagnostics(), CI.getLangOpts(),
153                               CI.getDiagnosticOpts().NoRewriteMacros);
154   return 0;
155 }
156
157 ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
158                                                  llvm::StringRef InFile) {
159   return new ASTConsumer();
160 }
161
162 //===----------------------------------------------------------------------===//
163 // Preprocessor Actions
164 //===----------------------------------------------------------------------===//
165
166 void DumpRawTokensAction::ExecuteAction() {
167   Preprocessor &PP = getCompilerInstance().getPreprocessor();
168   SourceManager &SM = PP.getSourceManager();
169
170   // Start lexing the specified input file.
171   const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
172   Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
173   RawLex.SetKeepWhitespaceMode(true);
174
175   Token RawTok;
176   RawLex.LexFromRawLexer(RawTok);
177   while (RawTok.isNot(tok::eof)) {
178     PP.DumpToken(RawTok, true);
179     llvm::errs() << "\n";
180     RawLex.LexFromRawLexer(RawTok);
181   }
182 }
183
184 void DumpTokensAction::ExecuteAction() {
185   Preprocessor &PP = getCompilerInstance().getPreprocessor();
186   // Start preprocessing the specified input file.
187   Token Tok;
188   PP.EnterMainSourceFile();
189   do {
190     PP.Lex(Tok);
191     PP.DumpToken(Tok, true);
192     llvm::errs() << "\n";
193   } while (Tok.isNot(tok::eof));
194 }
195
196 void GeneratePTHAction::ExecuteAction() {
197   CompilerInstance &CI = getCompilerInstance();
198   if (CI.getFrontendOpts().OutputFile.empty() ||
199       CI.getFrontendOpts().OutputFile == "-") {
200     // FIXME: Don't fail this way.
201     // FIXME: Verify that we can actually seek in the given file.
202     llvm::llvm_report_error("PTH requires a seekable file for output!");
203   }
204   llvm::raw_fd_ostream *OS =
205     CI.createDefaultOutputFile(true, getCurrentFile());
206   if (!OS) return;
207
208   CacheTokens(CI.getPreprocessor(), OS);
209 }
210
211 void ParseOnlyAction::ExecuteAction() {
212   Preprocessor &PP = getCompilerInstance().getPreprocessor();
213   llvm::OwningPtr<Action> PA(new MinimalAction(PP));
214
215   Parser P(PP, *PA);
216   PP.EnterMainSourceFile();
217   P.ParseTranslationUnit();
218 }
219
220 void PreprocessOnlyAction::ExecuteAction() {
221   Preprocessor &PP = getCompilerInstance().getPreprocessor();
222
223   Token Tok;
224   // Start parsing the specified input file.
225   PP.EnterMainSourceFile();
226   do {
227     PP.Lex(Tok);
228   } while (Tok.isNot(tok::eof));
229 }
230
231 void PrintParseAction::ExecuteAction() {
232   CompilerInstance &CI = getCompilerInstance();
233   Preprocessor &PP = getCompilerInstance().getPreprocessor();
234   llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
235   if (!OS) return;
236
237   llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS));
238
239   Parser P(PP, *PA);
240   PP.EnterMainSourceFile();
241   P.ParseTranslationUnit();
242 }
243
244 void PrintPreprocessedAction::ExecuteAction() {
245   CompilerInstance &CI = getCompilerInstance();
246   // Output file needs to be set to 'Binary', to avoid converting Unix style
247   // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
248   llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
249   if (!OS) return;
250
251   DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
252                            CI.getPreprocessorOutputOpts());
253 }
254
255 void RewriteMacrosAction::ExecuteAction() {
256   CompilerInstance &CI = getCompilerInstance();
257   llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
258   if (!OS) return;
259
260   RewriteMacrosInInput(CI.getPreprocessor(), OS);
261 }
262
263 void RewriteTestAction::ExecuteAction() {
264   CompilerInstance &CI = getCompilerInstance();
265   llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
266   if (!OS) return;
267
268   DoRewriteTest(CI.getPreprocessor(), OS);
269 }