1 //===--- FrontendActions.cpp ----------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
;
27 //===----------------------------------------------------------------------===//
29 //===----------------------------------------------------------------------===//
31 ASTConsumer
*InitOnlyAction::CreateASTConsumer(CompilerInstance
&CI
,
32 llvm::StringRef InFile
) {
33 return new ASTConsumer();
36 void InitOnlyAction::ExecuteAction() {
39 //===----------------------------------------------------------------------===//
40 // AST Consumer Actions
41 //===----------------------------------------------------------------------===//
43 ASTConsumer
*ASTPrintAction::CreateASTConsumer(CompilerInstance
&CI
,
44 llvm::StringRef InFile
) {
45 if (llvm::raw_ostream
*OS
= CI
.createDefaultOutputFile(false, InFile
))
46 return CreateASTPrinter(OS
);
50 ASTConsumer
*ASTDumpAction::CreateASTConsumer(CompilerInstance
&CI
,
51 llvm::StringRef InFile
) {
52 return CreateASTDumper();
55 ASTConsumer
*ASTDumpXMLAction::CreateASTConsumer(CompilerInstance
&CI
,
56 llvm::StringRef InFile
) {
57 llvm::raw_ostream
*OS
;
58 if (CI
.getFrontendOpts().OutputFile
.empty())
61 OS
= CI
.createDefaultOutputFile(false, InFile
);
63 return CreateASTDumperXML(*OS
);
66 ASTConsumer
*ASTViewAction::CreateASTConsumer(CompilerInstance
&CI
,
67 llvm::StringRef InFile
) {
68 return CreateASTViewer();
71 ASTConsumer
*DeclContextPrintAction::CreateASTConsumer(CompilerInstance
&CI
,
72 llvm::StringRef InFile
) {
73 return CreateDeclContextPrinter();
76 ASTConsumer
*GeneratePCHAction::CreateASTConsumer(CompilerInstance
&CI
,
77 llvm::StringRef InFile
) {
79 std::string OutputFile
;
80 llvm::raw_ostream
*OS
= 0;
82 if (ComputeASTConsumerArguments(CI
, InFile
, Sysroot
, OutputFile
, OS
, Chaining
))
85 const char *isysroot
= CI
.getFrontendOpts().RelocatablePCH
?
87 return new PCHGenerator(CI
.getPreprocessor(), OutputFile
, Chaining
, isysroot
, OS
);
90 bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance
&CI
,
91 llvm::StringRef InFile
,
93 std::string
&OutputFile
,
94 llvm::raw_ostream
*&OS
,
96 Sysroot
= CI
.getHeaderSearchOpts().Sysroot
;
97 if (CI
.getFrontendOpts().RelocatablePCH
&& Sysroot
.empty()) {
98 CI
.getDiagnostics().Report(diag::err_relocatable_without_isysroot
);
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
);
109 OutputFile
= CI
.getFrontendOpts().OutputFile
;
110 Chaining
= CI
.getInvocation().getFrontendOpts().ChainedPCH
&&
111 !CI
.getPreprocessorOpts().ImplicitPCHInclude
.empty();
115 ASTConsumer
*SyntaxOnlyAction::CreateASTConsumer(CompilerInstance
&CI
,
116 llvm::StringRef InFile
) {
117 return new ASTConsumer();
120 //===----------------------------------------------------------------------===//
121 // Preprocessor Actions
122 //===----------------------------------------------------------------------===//
124 void DumpRawTokensAction::ExecuteAction() {
125 Preprocessor
&PP
= getCompilerInstance().getPreprocessor();
126 SourceManager
&SM
= PP
.getSourceManager();
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);
134 RawLex
.LexFromRawLexer(RawTok
);
135 while (RawTok
.isNot(tok::eof
)) {
136 PP
.DumpToken(RawTok
, true);
137 llvm::errs() << "\n";
138 RawLex
.LexFromRawLexer(RawTok
);
142 void DumpTokensAction::ExecuteAction() {
143 Preprocessor
&PP
= getCompilerInstance().getPreprocessor();
144 // Start preprocessing the specified input file.
146 PP
.EnterMainSourceFile();
149 PP
.DumpToken(Tok
, true);
150 llvm::errs() << "\n";
151 } while (Tok
.isNot(tok::eof
));
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!");
162 llvm::raw_fd_ostream
*OS
=
163 CI
.createDefaultOutputFile(true, getCurrentFile());
166 CacheTokens(CI
.getPreprocessor(), OS
);
169 void PreprocessOnlyAction::ExecuteAction() {
170 Preprocessor
&PP
= getCompilerInstance().getPreprocessor();
172 // Ignore unknown pragmas.
173 PP
.AddPragmaHandler(new EmptyPragmaHandler());
176 // Start parsing the specified input file.
177 PP
.EnterMainSourceFile();
180 } while (Tok
.isNot(tok::eof
));
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());
190 DoPrintPreprocessedInput(CI
.getPreprocessor(), OS
,
191 CI
.getPreprocessorOutputOpts());
194 void PrintPreambleAction::ExecuteAction() {
195 switch (getCurrentFileKind()) {
206 case IK_PreprocessedC
:
207 case IK_PreprocessedCXX
:
208 case IK_PreprocessedObjC
:
209 case IK_PreprocessedObjCXX
:
212 // We can't do anything with these.
216 CompilerInstance
&CI
= getCompilerInstance();
217 llvm::MemoryBuffer
*Buffer
218 = CI
.getFileManager().getBufferForFile(getCurrentFile());
220 unsigned Preamble
= Lexer::ComputePreamble(Buffer
).first
;
221 llvm::outs().write(Buffer
->getBufferStart(), Preamble
);