blob: f0b86a9214af7e209538365d72248a013098dd48 [file] [log] [blame]
Daniel Dunbar8305d012009-11-14 10:42:46 +00001//===--- 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"
Daniel Dunbarc72cc502010-06-11 20:10:12 +000012#include "clang/Lex/Pragma.h"
Daniel Dunbar5f3b9972009-11-14 10:42:57 +000013#include "clang/Lex/Preprocessor.h"
14#include "clang/Parse/Parser.h"
Daniel Dunbar8305d012009-11-14 10:42:46 +000015#include "clang/Basic/FileManager.h"
Daniel Dunbar8305d012009-11-14 10:42:46 +000016#include "clang/Frontend/ASTConsumers.h"
17#include "clang/Frontend/ASTUnit.h"
18#include "clang/Frontend/CompilerInstance.h"
Daniel Dunbar8305d012009-11-14 10:42:46 +000019#include "clang/Frontend/FrontendDiagnostic.h"
20#include "clang/Frontend/Utils.h"
Nick Lewyckyba5f6ec2010-04-24 01:30:46 +000021#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar8305d012009-11-14 10:42:46 +000022#include "llvm/Support/raw_ostream.h"
23using namespace clang;
24
Daniel Dunbar5f3b9972009-11-14 10:42:57 +000025//===----------------------------------------------------------------------===//
Daniel Dunbar27585952010-03-19 19:44:04 +000026// Custom Actions
27//===----------------------------------------------------------------------===//
28
29ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
30 llvm::StringRef InFile) {
31 return new ASTConsumer();
32}
33
34void InitOnlyAction::ExecuteAction() {
35}
36
37//===----------------------------------------------------------------------===//
Daniel Dunbar5f3b9972009-11-14 10:42:57 +000038// AST Consumer Actions
39//===----------------------------------------------------------------------===//
40
Daniel Dunbar8305d012009-11-14 10:42:46 +000041ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
42 llvm::StringRef InFile) {
Daniel Dunbar36043592009-12-03 09:13:30 +000043 if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
44 return CreateASTPrinter(OS);
45 return 0;
Daniel Dunbar8305d012009-11-14 10:42:46 +000046}
47
48ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI,
49 llvm::StringRef InFile) {
Daniel Dunbar36043592009-12-03 09:13:30 +000050 if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml"))
51 return CreateASTPrinterXML(OS);
52 return 0;
Daniel Dunbar8305d012009-11-14 10:42:46 +000053}
54
55ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
56 llvm::StringRef InFile) {
57 return CreateASTDumper();
58}
59
60ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
61 llvm::StringRef InFile) {
62 return CreateASTViewer();
63}
64
65ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
66 llvm::StringRef InFile) {
67 return CreateDeclContextPrinter();
68}
69
Daniel Dunbar8305d012009-11-14 10:42:46 +000070ASTConsumer *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);
Daniel Dunbar36043592009-12-03 09:13:30 +000080 if (!OS)
81 return 0;
82
Daniel Dunbar8305d012009-11-14 10:42:46 +000083 if (CI.getFrontendOpts().RelocatablePCH)
84 return CreatePCHGenerator(CI.getPreprocessor(), OS, Sysroot.c_str());
85
86 return CreatePCHGenerator(CI.getPreprocessor(), OS);
87}
88
Daniel Dunbar8305d012009-11-14 10:42:46 +000089ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
90 llvm::StringRef InFile) {
91 return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance);
92}
93
Daniel Dunbar8305d012009-11-14 10:42:46 +000094ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
95 llvm::StringRef InFile) {
96 return new ASTConsumer();
97}
98
Daniel Dunbar5f3b9972009-11-14 10:42:57 +000099//===----------------------------------------------------------------------===//
100// Preprocessor Actions
101//===----------------------------------------------------------------------===//
102
103void DumpRawTokensAction::ExecuteAction() {
104 Preprocessor &PP = getCompilerInstance().getPreprocessor();
105 SourceManager &SM = PP.getSourceManager();
106
107 // Start lexing the specified input file.
Chris Lattner6e290142009-11-30 04:18:44 +0000108 const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
109 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000110 RawLex.SetKeepWhitespaceMode(true);
111
112 Token RawTok;
113 RawLex.LexFromRawLexer(RawTok);
114 while (RawTok.isNot(tok::eof)) {
115 PP.DumpToken(RawTok, true);
Daniel Dunbar33f57f82009-11-25 10:27:48 +0000116 llvm::errs() << "\n";
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000117 RawLex.LexFromRawLexer(RawTok);
118 }
119}
120
121void DumpTokensAction::ExecuteAction() {
122 Preprocessor &PP = getCompilerInstance().getPreprocessor();
123 // Start preprocessing the specified input file.
124 Token Tok;
Chris Lattnere127a0d2010-04-20 20:35:58 +0000125 PP.EnterMainSourceFile();
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000126 do {
127 PP.Lex(Tok);
128 PP.DumpToken(Tok, true);
Daniel Dunbar33f57f82009-11-25 10:27:48 +0000129 llvm::errs() << "\n";
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000130 } while (Tok.isNot(tok::eof));
131}
132
133void GeneratePTHAction::ExecuteAction() {
134 CompilerInstance &CI = getCompilerInstance();
135 if (CI.getFrontendOpts().OutputFile.empty() ||
136 CI.getFrontendOpts().OutputFile == "-") {
137 // FIXME: Don't fail this way.
138 // FIXME: Verify that we can actually seek in the given file.
Chris Lattner83e7a782010-04-07 22:58:06 +0000139 llvm::report_fatal_error("PTH requires a seekable file for output!");
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000140 }
141 llvm::raw_fd_ostream *OS =
142 CI.createDefaultOutputFile(true, getCurrentFile());
Daniel Dunbar36043592009-12-03 09:13:30 +0000143 if (!OS) return;
144
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000145 CacheTokens(CI.getPreprocessor(), OS);
146}
147
148void ParseOnlyAction::ExecuteAction() {
149 Preprocessor &PP = getCompilerInstance().getPreprocessor();
150 llvm::OwningPtr<Action> PA(new MinimalAction(PP));
151
152 Parser P(PP, *PA);
Chris Lattnere127a0d2010-04-20 20:35:58 +0000153 PP.EnterMainSourceFile();
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000154 P.ParseTranslationUnit();
155}
156
157void PreprocessOnlyAction::ExecuteAction() {
158 Preprocessor &PP = getCompilerInstance().getPreprocessor();
159
Daniel Dunbarc72cc502010-06-11 20:10:12 +0000160 // Ignore unknown pragmas.
161 PP.AddPragmaHandler(0, new EmptyPragmaHandler());
162
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000163 Token Tok;
164 // Start parsing the specified input file.
Chris Lattnere127a0d2010-04-20 20:35:58 +0000165 PP.EnterMainSourceFile();
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000166 do {
167 PP.Lex(Tok);
168 } while (Tok.isNot(tok::eof));
169}
170
171void PrintParseAction::ExecuteAction() {
172 CompilerInstance &CI = getCompilerInstance();
173 Preprocessor &PP = getCompilerInstance().getPreprocessor();
174 llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
Daniel Dunbar36043592009-12-03 09:13:30 +0000175 if (!OS) return;
176
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000177 llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS));
178
179 Parser P(PP, *PA);
Chris Lattnere127a0d2010-04-20 20:35:58 +0000180 PP.EnterMainSourceFile();
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000181 P.ParseTranslationUnit();
182}
183
184void PrintPreprocessedAction::ExecuteAction() {
185 CompilerInstance &CI = getCompilerInstance();
Steve Naroffd57d7c02010-01-05 17:33:23 +0000186 // Output file needs to be set to 'Binary', to avoid converting Unix style
187 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
188 llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
Daniel Dunbar36043592009-12-03 09:13:30 +0000189 if (!OS) return;
190
Daniel Dunbar5f3b9972009-11-14 10:42:57 +0000191 DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
192 CI.getPreprocessorOutputOpts());
193}