]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / 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/Pragma.h"
13 #include "clang/Lex/Preprocessor.h"
14 #include "clang/Parse/Parser.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Frontend/ASTConsumers.h"
17 #include "clang/Frontend/ASTUnit.h"
18 #include "clang/Frontend/CompilerInstance.h"
19 #include "clang/Frontend/FrontendDiagnostic.h"
20 #include "clang/Frontend/Utils.h"
21 #include "clang/Serialization/ASTWriter.h"
22 #include "llvm/ADT/OwningPtr.h"
23 #include "llvm/Support/MemoryBuffer.h"
24 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
26
27 //===----------------------------------------------------------------------===//
28 // Custom Actions
29 //===----------------------------------------------------------------------===//
30
31 ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
32                                                llvm::StringRef InFile) {
33   return new ASTConsumer();
34 }
35
36 void InitOnlyAction::ExecuteAction() {
37 }
38
39 //===----------------------------------------------------------------------===//
40 // AST Consumer Actions
41 //===----------------------------------------------------------------------===//
42
43 ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
44                                                llvm::StringRef InFile) {
45   if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
46     return CreateASTPrinter(OS);
47   return 0;
48 }
49
50 ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
51                                               llvm::StringRef InFile) {
52   return CreateASTDumper();
53 }
54
55 ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI,
56                                                  llvm::StringRef InFile) {
57   llvm::raw_ostream *OS;
58   if (CI.getFrontendOpts().OutputFile.empty())
59     OS = &llvm::outs();
60   else
61     OS = CI.createDefaultOutputFile(false, InFile);
62   if (!OS) return 0;
63   return CreateASTDumperXML(*OS);
64 }
65
66 ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
67                                               llvm::StringRef InFile) {
68   return CreateASTViewer();
69 }
70
71 ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
72                                                        llvm::StringRef InFile) {
73   return CreateDeclContextPrinter();
74 }
75
76 ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
77                                                   llvm::StringRef InFile) {
78   std::string Sysroot;
79   std::string OutputFile;
80   llvm::raw_ostream *OS = 0;
81   bool Chaining;
82   if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS, Chaining))
83     return 0;
84
85   const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
86                              Sysroot.c_str() : 0;  
87   return new PCHGenerator(CI.getPreprocessor(), OutputFile, Chaining, isysroot, OS);
88 }
89
90 bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
91                                                     llvm::StringRef InFile,
92                                                     std::string &Sysroot,
93                                                     std::string &OutputFile,
94                                                     llvm::raw_ostream *&OS,
95                                                     bool &Chaining) {
96   Sysroot = CI.getHeaderSearchOpts().Sysroot;
97   if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
98     CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
99     return true;
100   }
101
102   // We use createOutputFile here because this is exposed via libclang, and we
103   // must disable the RemoveFileOnSignal behavior.
104   OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
105                            /*RemoveFileOnSignal=*/false, InFile);
106   if (!OS)
107     return true;
108
109   OutputFile = CI.getFrontendOpts().OutputFile;
110   Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
111              !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
112   return false;
113 }
114
115 ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
116                                                  llvm::StringRef InFile) {
117   return new ASTConsumer();
118 }
119
120 //===----------------------------------------------------------------------===//
121 // Preprocessor Actions
122 //===----------------------------------------------------------------------===//
123
124 void DumpRawTokensAction::ExecuteAction() {
125   Preprocessor &PP = getCompilerInstance().getPreprocessor();
126   SourceManager &SM = PP.getSourceManager();
127
128   // Start lexing the specified input file.
129   const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
130   Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
131   RawLex.SetKeepWhitespaceMode(true);
132
133   Token RawTok;
134   RawLex.LexFromRawLexer(RawTok);
135   while (RawTok.isNot(tok::eof)) {
136     PP.DumpToken(RawTok, true);
137     llvm::errs() << "\n";
138     RawLex.LexFromRawLexer(RawTok);
139   }
140 }
141
142 void DumpTokensAction::ExecuteAction() {
143   Preprocessor &PP = getCompilerInstance().getPreprocessor();
144   // Start preprocessing the specified input file.
145   Token Tok;
146   PP.EnterMainSourceFile();
147   do {
148     PP.Lex(Tok);
149     PP.DumpToken(Tok, true);
150     llvm::errs() << "\n";
151   } while (Tok.isNot(tok::eof));
152 }
153
154 void GeneratePTHAction::ExecuteAction() {
155   CompilerInstance &CI = getCompilerInstance();
156   if (CI.getFrontendOpts().OutputFile.empty() ||
157       CI.getFrontendOpts().OutputFile == "-") {
158     // FIXME: Don't fail this way.
159     // FIXME: Verify that we can actually seek in the given file.
160     llvm::report_fatal_error("PTH requires a seekable file for output!");
161   }
162   llvm::raw_fd_ostream *OS =
163     CI.createDefaultOutputFile(true, getCurrentFile());
164   if (!OS) return;
165
166   CacheTokens(CI.getPreprocessor(), OS);
167 }
168
169 void PreprocessOnlyAction::ExecuteAction() {
170   Preprocessor &PP = getCompilerInstance().getPreprocessor();
171
172   // Ignore unknown pragmas.
173   PP.AddPragmaHandler(new EmptyPragmaHandler());
174
175   Token Tok;
176   // Start parsing the specified input file.
177   PP.EnterMainSourceFile();
178   do {
179     PP.Lex(Tok);
180   } while (Tok.isNot(tok::eof));
181 }
182
183 void PrintPreprocessedAction::ExecuteAction() {
184   CompilerInstance &CI = getCompilerInstance();
185   // Output file needs to be set to 'Binary', to avoid converting Unix style
186   // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
187   llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
188   if (!OS) return;
189
190   DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
191                            CI.getPreprocessorOutputOpts());
192 }
193
194 void PrintPreambleAction::ExecuteAction() {
195   switch (getCurrentFileKind()) {
196   case IK_C:
197   case IK_CXX:
198   case IK_ObjC:
199   case IK_ObjCXX:
200   case IK_OpenCL:
201   case IK_CUDA:
202     break;
203       
204   case IK_None:
205   case IK_Asm:
206   case IK_PreprocessedC:
207   case IK_PreprocessedCXX:
208   case IK_PreprocessedObjC:
209   case IK_PreprocessedObjCXX:
210   case IK_AST:
211   case IK_LLVM_IR:
212     // We can't do anything with these.
213     return;
214   }
215   
216   CompilerInstance &CI = getCompilerInstance();
217   llvm::MemoryBuffer *Buffer
218       = CI.getFileManager().getBufferForFile(getCurrentFile());
219   if (Buffer) {
220     unsigned Preamble = Lexer::ComputePreamble(Buffer).first;
221     llvm::outs().write(Buffer->getBufferStart(), Preamble);
222     delete Buffer;
223   }
224 }