blob: 35ae4b023460e2c9727070d44a38f50eb2289e6b [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- clang.cpp - C-Language Front-end ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This utility may be invoked in the following manner:
Daniel Dunbar4fdba992009-11-14 10:53:49 +000011// clang-cc --help - Output help info.
12// clang-cc [options] - Read from stdin.
13// clang-cc [options] file - Read from "file".
14// clang-cc [options] file1 file2 - Read these files.
Reid Spencer5f016e22007-07-11 17:01:13 +000015//
16//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +000017
Daniel Dunbar0498cfc2009-11-10 19:51:53 +000018#include "Options.h"
Daniel Dunbar775bee72009-11-11 10:07:22 +000019#include "clang/Basic/FileManager.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Version.h"
Daniel Dunbar2a79e162009-11-13 03:51:44 +000023#include "clang/Frontend/CompilerInstance.h"
Daniel Dunbare29709f2009-11-09 20:55:08 +000024#include "clang/Frontend/CompilerInvocation.h"
Daniel Dunbar4fdba992009-11-14 10:53:49 +000025#include "clang/Frontend/FrontendActions.h"
Daniel Dunbar50f4f462009-03-12 10:14:16 +000026#include "clang/Frontend/FrontendDiagnostic.h"
Daniel Dunbar8863b982009-11-07 04:20:15 +000027#include "clang/Frontend/PathDiagnosticClients.h"
28#include "clang/Frontend/PreprocessorOptions.h"
Daniel Dunbar775bee72009-11-11 10:07:22 +000029#include "clang/Frontend/PreprocessorOutputOptions.h"
Daniel Dunbarf79dced2009-11-14 03:24:39 +000030#include "clang/Frontend/VerifyDiagnosticsClient.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000031#include "llvm/ADT/OwningPtr.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000032#include "llvm/Config/config.h"
Daniel Dunbar4fdba992009-11-14 10:53:49 +000033#include "llvm/LLVMContext.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000034#include "llvm/Support/CommandLine.h"
Daniel Dunbar70121eb2009-08-10 03:40:28 +000035#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar524b86f2008-10-28 00:38:08 +000036#include "llvm/Support/ManagedStatic.h"
Zhongxing Xu20922362008-11-26 05:23:17 +000037#include "llvm/Support/PluginLoader.h"
Chris Lattner09e94a32009-03-04 21:41:39 +000038#include "llvm/Support/PrettyStackTrace.h"
Chris Lattner47099742009-02-18 01:51:21 +000039#include "llvm/Support/Timer.h"
Chris Lattner0fa0daa2009-08-24 04:11:30 +000040#include "llvm/Support/raw_ostream.h"
Daniel Dunbare553a722008-10-02 01:21:33 +000041#include "llvm/System/Host.h"
Chris Lattnerdcaa0962008-03-03 03:16:03 +000042#include "llvm/System/Path.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000043#include "llvm/System/Signals.h"
Chris Lattner2fe11942009-06-17 17:25:50 +000044#include "llvm/Target/TargetSelect.h"
Douglas Gregor26df2f02009-04-02 19:05:20 +000045#include <cstdlib>
Douglas Gregor44cf08e2009-05-03 03:52:38 +000046#if HAVE_SYS_TYPES_H
Douglas Gregor68a0d782009-05-02 00:03:46 +000047# include <sys/types.h>
48#endif
Douglas Gregor26df2f02009-04-02 19:05:20 +000049
Reid Spencer5f016e22007-07-11 17:01:13 +000050using namespace clang;
51
52//===----------------------------------------------------------------------===//
Daniel Dunbaraa576142009-11-12 15:23:20 +000053// Frontend Actions
54//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +000055
56enum ProgActions {
Steve Naroffb29b4272008-04-14 22:03:09 +000057 RewriteObjC, // ObjC->C Rewriter.
Steve Naroff13188952008-09-18 14:10:13 +000058 RewriteBlocks, // ObjC->C Rewriter for Blocks.
Chris Lattnerb57e3d42008-05-08 06:52:13 +000059 RewriteMacros, // Expand macros but not #includes.
Chris Lattnerb13c5ee2008-10-12 05:29:20 +000060 RewriteTest, // Rewriter playground
Ted Kremenek13e479b2008-03-19 07:53:42 +000061 HTMLTest, // HTML displayer testing stuff.
Daniel Dunbard69bacc2008-10-21 23:49:24 +000062 EmitAssembly, // Emit a .s file.
Reid Spencer5f016e22007-07-11 17:01:13 +000063 EmitLLVM, // Emit a .ll file.
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +000064 EmitBC, // Emit a .bc file.
Mike Stump1eb44332009-09-09 15:08:12 +000065 EmitLLVMOnly, // Generate LLVM IR, but do not
Ted Kremenek6a340832008-03-18 21:19:49 +000066 EmitHTML, // Translate input source into HTML.
Chris Lattner3b427b32007-10-11 00:18:28 +000067 ASTPrint, // Parse ASTs and print them.
Douglas Gregoree75c052009-05-21 20:55:50 +000068 ASTPrintXML, // Parse ASTs and print them in XML.
Chris Lattner3b427b32007-10-11 00:18:28 +000069 ASTDump, // Parse ASTs and dump them.
70 ASTView, // Parse ASTs and view them in Graphviz.
Zhongxing Xu2d75d6f2009-01-13 01:29:24 +000071 PrintDeclContext, // Print DeclContext and their Decls.
Anders Carlsson78762eb2009-09-24 18:54:49 +000072 DumpRecordLayouts, // Dump record layout information.
Reid Spencer5f016e22007-07-11 17:01:13 +000073 ParsePrintCallbacks, // Parse and print each callback.
74 ParseSyntaxOnly, // Parse and perform semantic analysis.
Daniel Dunbar79b55f92009-11-14 04:39:29 +000075 FixIt, // Parse and apply any fixits to the source.
Reid Spencer5f016e22007-07-11 17:01:13 +000076 ParseNoop, // Parse with noop callbacks.
77 RunPreprocessorOnly, // Just lex, no output.
78 PrintPreprocessedInput, // -E mode.
Chris Lattnerc106c102008-10-12 05:03:36 +000079 DumpTokens, // Dump out preprocessed tokens.
80 DumpRawTokens, // Dump out raw tokens.
Mike Stump1eb44332009-09-09 15:08:12 +000081 RunAnalysis, // Run one or more source code analyses.
Douglas Gregorbf1bd6e2009-04-02 23:43:50 +000082 GeneratePTH, // Generate pre-tokenized header.
Douglas Gregor2cf26342009-04-09 22:27:44 +000083 GeneratePCH, // Generate pre-compiled header.
Ted Kremenek7cae2f62008-10-23 23:36:29 +000084 InheritanceView // View C++ inheritance for a specified class.
Reid Spencer5f016e22007-07-11 17:01:13 +000085};
86
Mike Stump1eb44332009-09-09 15:08:12 +000087static llvm::cl::opt<ProgActions>
Reid Spencer5f016e22007-07-11 17:01:13 +000088ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
89 llvm::cl::init(ParseSyntaxOnly),
90 llvm::cl::values(
91 clEnumValN(RunPreprocessorOnly, "Eonly",
92 "Just run preprocessor, no output (for timings)"),
93 clEnumValN(PrintPreprocessedInput, "E",
94 "Run preprocessor, emit preprocessed file"),
Chris Lattnerc106c102008-10-12 05:03:36 +000095 clEnumValN(DumpRawTokens, "dump-raw-tokens",
96 "Lex file in raw mode and dump raw tokens"),
Daniel Dunbard4270232009-01-20 23:17:32 +000097 clEnumValN(RunAnalysis, "analyze",
98 "Run static analysis engine"),
Chris Lattnerc106c102008-10-12 05:03:36 +000099 clEnumValN(DumpTokens, "dump-tokens",
Reid Spencer5f016e22007-07-11 17:01:13 +0000100 "Run preprocessor, dump internal rep of tokens"),
101 clEnumValN(ParseNoop, "parse-noop",
102 "Run parser with noop callbacks (for timings)"),
103 clEnumValN(ParseSyntaxOnly, "fsyntax-only",
104 "Run parser and perform semantic analysis"),
Daniel Dunbar79b55f92009-11-14 04:39:29 +0000105 clEnumValN(FixIt, "fixit",
106 "Apply fix-it advice to the input source"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000107 clEnumValN(ParsePrintCallbacks, "parse-print-callbacks",
108 "Run parser and print each callback invoked"),
Ted Kremenek6a340832008-03-18 21:19:49 +0000109 clEnumValN(EmitHTML, "emit-html",
110 "Output input source as HTML"),
Chris Lattner3b427b32007-10-11 00:18:28 +0000111 clEnumValN(ASTPrint, "ast-print",
112 "Build ASTs and then pretty-print them"),
Douglas Gregoree75c052009-05-21 20:55:50 +0000113 clEnumValN(ASTPrintXML, "ast-print-xml",
114 "Build ASTs and then print them in XML format"),
Chris Lattner3b427b32007-10-11 00:18:28 +0000115 clEnumValN(ASTDump, "ast-dump",
116 "Build ASTs and then debug dump them"),
Chris Lattnerea254db2007-10-11 00:37:43 +0000117 clEnumValN(ASTView, "ast-view",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000118 "Build ASTs and view them with GraphViz"),
Zhongxing Xu2d75d6f2009-01-13 01:29:24 +0000119 clEnumValN(PrintDeclContext, "print-decl-contexts",
Ted Kremenek08478eb2009-04-01 00:23:28 +0000120 "Print DeclContexts and their Decls"),
Anders Carlsson78762eb2009-09-24 18:54:49 +0000121 clEnumValN(DumpRecordLayouts, "dump-record-layouts",
122 "Dump record layout information"),
Douglas Gregorbf1bd6e2009-04-02 23:43:50 +0000123 clEnumValN(GeneratePTH, "emit-pth",
Ted Kremenek08478eb2009-04-01 00:23:28 +0000124 "Generate pre-tokenized header file"),
Douglas Gregor2cf26342009-04-09 22:27:44 +0000125 clEnumValN(GeneratePCH, "emit-pch",
126 "Generate pre-compiled header file"),
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000127 clEnumValN(EmitAssembly, "S",
128 "Emit native assembly code"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000129 clEnumValN(EmitLLVM, "emit-llvm",
Ted Kremenek27b07c52007-09-06 21:26:58 +0000130 "Build ASTs then convert to LLVM, emit .ll file"),
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +0000131 clEnumValN(EmitBC, "emit-llvm-bc",
132 "Build ASTs then convert to LLVM, emit .bc file"),
Daniel Dunbare8e26002009-02-26 22:39:37 +0000133 clEnumValN(EmitLLVMOnly, "emit-llvm-only",
134 "Build ASTs and convert to LLVM, discarding output"),
Chris Lattnerb13c5ee2008-10-12 05:29:20 +0000135 clEnumValN(RewriteTest, "rewrite-test",
136 "Rewriter playground"),
Steve Naroffb29b4272008-04-14 22:03:09 +0000137 clEnumValN(RewriteObjC, "rewrite-objc",
Chris Lattnerb57e3d42008-05-08 06:52:13 +0000138 "Rewrite ObjC into C (code rewriter example)"),
139 clEnumValN(RewriteMacros, "rewrite-macros",
140 "Expand macros without full preprocessing"),
Steve Naroff13188952008-09-18 14:10:13 +0000141 clEnumValN(RewriteBlocks, "rewrite-blocks",
142 "Rewrite Blocks to C"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000143 clEnumValEnd));
144
Daniel Dunbaraa576142009-11-12 15:23:20 +0000145//===----------------------------------------------------------------------===//
Daniel Dunbar914474c2009-11-13 01:02:10 +0000146// Utility Methods
Reid Spencer5f016e22007-07-11 17:01:13 +0000147//===----------------------------------------------------------------------===//
148
Daniel Dunbar750156a2009-11-07 04:19:57 +0000149std::string GetBuiltinIncludePath(const char *Argv0) {
150 llvm::sys::Path P =
151 llvm::sys::Path::GetMainExecutable(Argv0,
152 (void*)(intptr_t) GetBuiltinIncludePath);
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000153
Daniel Dunbar750156a2009-11-07 04:19:57 +0000154 if (!P.isEmpty()) {
155 P.eraseComponent(); // Remove /clang from foo/bin/clang
156 P.eraseComponent(); // Remove /bin from foo/bin
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000157
Daniel Dunbar750156a2009-11-07 04:19:57 +0000158 // Get foo/lib/clang/<version>/include
159 P.appendComponent("lib");
160 P.appendComponent("clang");
161 P.appendComponent(CLANG_VERSION_STRING);
162 P.appendComponent("include");
163 }
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000164
Daniel Dunbar750156a2009-11-07 04:19:57 +0000165 return P.str();
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000166}
167
Reid Spencer5f016e22007-07-11 17:01:13 +0000168//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +0000169// Main driver
170//===----------------------------------------------------------------------===//
171
Daniel Dunbaraa576142009-11-12 15:23:20 +0000172/// ClangFrontendTimer - The front-end activities should charge time to it with
173/// TimeRegion. The -ftime-report option controls whether this will do
174/// anything.
175llvm::Timer *ClangFrontendTimer = 0;
176
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000177static FrontendAction *CreateFrontendAction(ProgActions PA) {
Ted Kremenek85888962008-10-21 00:54:44 +0000178 switch (PA) {
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000179 default: return 0;
180 case ASTDump: return new ASTDumpAction();
181 case ASTPrint: return new ASTPrintAction();
182 case ASTPrintXML: return new ASTPrintXMLAction();
183 case ASTView: return new ASTViewAction();
184 case DumpRawTokens: return new DumpRawTokensAction();
185 case DumpRecordLayouts: return new DumpRecordAction();
186 case DumpTokens: return new DumpTokensAction();
187 case EmitAssembly: return new EmitAssemblyAction();
188 case EmitBC: return new EmitBCAction();
189 case EmitHTML: return new HTMLPrintAction();
190 case EmitLLVM: return new EmitLLVMAction();
191 case EmitLLVMOnly: return new EmitLLVMOnlyAction();
192 case FixIt: return new FixItAction();
193 case GeneratePCH: return new GeneratePCHAction();
194 case GeneratePTH: return new GeneratePTHAction();
195 case InheritanceView: return new InheritanceViewAction();
196 case ParseNoop: return new ParseOnlyAction();
197 case ParsePrintCallbacks: return new PrintParseAction();
198 case ParseSyntaxOnly: return new SyntaxOnlyAction();
199 case PrintDeclContext: return new DeclContextPrintAction();
200 case PrintPreprocessedInput: return new PrintPreprocessedAction();
201 case RewriteBlocks: return new RewriteBlocksAction();
202 case RewriteMacros: return new RewriteMacrosAction();
203 case RewriteObjC: return new RewriteObjCAction();
204 case RewriteTest: return new RewriteTestAction();
205 case RunAnalysis: return new AnalysisAction();
206 case RunPreprocessorOnly: return new PreprocessOnlyAction();
Eli Friedman66d6f042009-05-18 22:20:00 +0000207 }
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +0000208}
209
Daniel Dunbar70121eb2009-08-10 03:40:28 +0000210static void LLVMErrorHandler(void *UserData, const std::string &Message) {
211 Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
212
Daniel Dunbar0f9fed72009-11-10 23:55:23 +0000213 Diags.Report(diag::err_fe_error_backend) << Message;
Daniel Dunbar70121eb2009-08-10 03:40:28 +0000214
215 // We cannot recover from llvm errors.
216 exit(1);
217}
218
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000219static TargetInfo *
220ConstructCompilerInvocation(CompilerInvocation &Opts, Diagnostic &Diags,
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000221 const char *Argv0, bool &IsAST) {
Daniel Dunbar26266882009-11-12 23:52:32 +0000222 // Initialize frontend options.
223 InitializeFrontendOptions(Opts.getFrontendOpts());
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000224
Daniel Dunbarf819b252009-11-13 05:52:19 +0000225 // FIXME: The target information in frontend options should be split out into
226 // TargetOptions, and the target options in codegen options should move there
227 // as well. Then we could properly initialize in layering order.
228
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000229 // Initialize base triple. If a -triple option has been specified, use
230 // that triple. Otherwise, default to the host triple.
231 llvm::Triple Triple(Opts.getFrontendOpts().TargetTriple);
232 if (Triple.getTriple().empty())
233 Triple = llvm::Triple(llvm::sys::getHostTriple());
234
235 // Get information about the target being compiled for.
236 TargetInfo *Target = TargetInfo::CreateTargetInfo(Triple.getTriple());
237 if (!Target) {
238 Diags.Report(diag::err_fe_unknown_triple) << Triple.getTriple().c_str();
239 return 0;
240 }
241
242 // Set the target ABI if specified.
243 if (!Opts.getFrontendOpts().TargetABI.empty() &&
244 !Target->setABI(Opts.getFrontendOpts().TargetABI)) {
245 Diags.Report(diag::err_fe_unknown_target_abi)
246 << Opts.getFrontendOpts().TargetABI;
247 return 0;
248 }
249
Daniel Dunbarfcb0c3b2009-11-10 18:47:35 +0000250 // Initialize backend options, which may also be used to key some language
251 // options.
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000252 InitializeCodeGenOptions(Opts.getCodeGenOpts(), *Target);
Daniel Dunbarfcb0c3b2009-11-10 18:47:35 +0000253
Daniel Dunbarfbe2faf2009-11-13 02:06:12 +0000254 // Determine the input language, we currently require all files to match.
255 FrontendOptions::InputKind IK = Opts.getFrontendOpts().Inputs[0].first;
256 for (unsigned i = 1, e = Opts.getFrontendOpts().Inputs.size(); i != e; ++i) {
257 if (Opts.getFrontendOpts().Inputs[i].first != IK) {
258 llvm::errs() << "error: cannot have multiple input files of distinct "
259 << "language kinds without -x\n";
260 return 0;
261 }
262 }
263
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000264 // Initialize language options.
Daniel Dunbar5746f1f2009-11-12 00:24:10 +0000265 //
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000266 // FIXME: These aren't used during operations on ASTs. Split onto a separate
267 // code path to make this obvious.
Daniel Dunbarfbe2faf2009-11-13 02:06:12 +0000268 IsAST = (IK == FrontendOptions::IK_AST);
Daniel Dunbar26266882009-11-12 23:52:32 +0000269 if (!IsAST)
Daniel Dunbarfbe2faf2009-11-13 02:06:12 +0000270 InitializeLangOptions(Opts.getLangOpts(), IK, *Target,
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000271 Opts.getCodeGenOpts());
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000272
Daniel Dunbar5746f1f2009-11-12 00:24:10 +0000273 // Initialize the static analyzer options.
274 InitializeAnalyzerOptions(Opts.getAnalyzerOpts());
275
Daniel Dunbar0e0bae82009-11-11 21:43:12 +0000276 // Initialize the dependency output options (-M...).
277 InitializeDependencyOutputOptions(Opts.getDependencyOutputOpts());
278
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000279 // Initialize the header search options.
Daniel Dunbarf7973292009-11-11 08:13:32 +0000280 InitializeHeaderSearchOptions(Opts.getHeaderSearchOpts(),
281 GetBuiltinIncludePath(Argv0),
Daniel Dunbarf7973292009-11-11 08:13:32 +0000282 Opts.getLangOpts());
Daniel Dunbar5fc7d342009-11-09 23:12:31 +0000283
284 // Initialize the other preprocessor options.
285 InitializePreprocessorOptions(Opts.getPreprocessorOpts());
Daniel Dunbar36f4ec32009-11-10 16:19:45 +0000286
Daniel Dunbar29cf7462009-11-11 10:07:44 +0000287 // Initialize the preprocessed output options.
288 InitializePreprocessorOutputOptions(Opts.getPreprocessorOutputOpts());
289
Daniel Dunbar26266882009-11-12 23:52:32 +0000290 // Finalize some code generation options which are derived from other places.
291 if (Opts.getLangOpts().NoBuiltin)
292 Opts.getCodeGenOpts().SimplifyLibCalls = 0;
293 if (Opts.getLangOpts().CPlusPlus)
294 Opts.getCodeGenOpts().NoCommon = 1;
295 Opts.getCodeGenOpts().TimePasses = Opts.getFrontendOpts().ShowTimers;
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000296
297 return Target;
Daniel Dunbare29709f2009-11-09 20:55:08 +0000298}
299
Reid Spencer5f016e22007-07-11 17:01:13 +0000300int main(int argc, char **argv) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000301 llvm::sys::PrintStackTraceOnErrorSignal();
Chris Lattner09e94a32009-03-04 21:41:39 +0000302 llvm::PrettyStackTraceProgram X(argc, argv);
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000303 CompilerInstance Clang(&llvm::getGlobalContext(), false);
Daniel Dunbard6970812009-09-02 23:20:15 +0000304
Daniel Dunbar4d861512009-09-03 04:54:12 +0000305 // Initialize targets first, so that --version shows registered targets.
Chris Lattner2fe11942009-06-17 17:25:50 +0000306 llvm::InitializeAllTargets();
307 llvm::InitializeAllAsmPrinters();
Daniel Dunbard6970812009-09-02 23:20:15 +0000308
309 llvm::cl::ParseCommandLineOptions(argc, argv,
310 "LLVM 'Clang' Compiler: http://clang.llvm.org\n");
Mike Stump1eb44332009-09-09 15:08:12 +0000311
Daniel Dunbar00e5b8d2009-11-12 06:48:31 +0000312 // Construct the diagnostic engine first, so that we can build a diagnostic
313 // client to use for any errors during option handling.
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000314 InitializeDiagnosticOptions(Clang.getDiagnosticOpts());
315 Clang.createDiagnostics(argc, argv);
Daniel Dunbar704e48a2009-11-13 08:20:57 +0000316 if (!Clang.hasDiagnostics())
Sebastian Redl63a9e0f2009-03-06 17:41:35 +0000317 return 1;
Ted Kremenek31e703b2007-12-11 23:28:38 +0000318
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000319 // Set an error handler, so that any LLVM backend diagnostics go through our
320 // error handler.
321 llvm::llvm_install_error_handler(LLVMErrorHandler,
322 static_cast<void*>(&Clang.getDiagnostics()));
Daniel Dunbar70121eb2009-08-10 03:40:28 +0000323
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000324 // Now that we have initialized the diagnostics engine, create the target and
325 // the compiler invocation object.
Daniel Dunbar227b2382009-11-09 22:45:57 +0000326 //
327 // FIXME: We should move .ast inputs to taking a separate path, they are
328 // really quite different.
Daniel Dunbar26266882009-11-12 23:52:32 +0000329 bool IsAST;
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000330 Clang.setTarget(
331 ConstructCompilerInvocation(Clang.getInvocation(), Clang.getDiagnostics(),
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000332 argv[0], IsAST));
Daniel Dunbar704e48a2009-11-13 08:20:57 +0000333 if (!Clang.hasTarget())
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000334 return 1;
Daniel Dunbar26266882009-11-12 23:52:32 +0000335
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000336 // Validate/process some options
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000337 if (Clang.getHeaderSearchOpts().Verbose)
Daniel Dunbar1417c742009-11-12 23:52:46 +0000338 llvm::errs() << "clang-cc version " CLANG_VERSION_STRING
339 << " based upon " << PACKAGE_STRING
340 << " hosted on " << llvm::sys::getHostTriple() << "\n";
341
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000342 if (Clang.getFrontendOpts().ShowTimers)
Daniel Dunbar26266882009-11-12 23:52:32 +0000343 ClangFrontendTimer = new llvm::Timer("Clang front-end time");
344
Daniel Dunbar79b55f92009-11-14 04:39:29 +0000345 // Enforce certain implications.
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000346 if (!Clang.getFrontendOpts().ViewClassInheritance.empty())
Daniel Dunbar26266882009-11-12 23:52:32 +0000347 ProgAction = InheritanceView;
Daniel Dunbar79b55f92009-11-14 04:39:29 +0000348 if (!Clang.getFrontendOpts().FixItLocations.empty())
349 ProgAction = FixIt;
Daniel Dunbar227b2382009-11-09 22:45:57 +0000350
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000351 for (unsigned i = 0, e = Clang.getFrontendOpts().Inputs.size(); i != e; ++i) {
352 const std::string &InFile = Clang.getFrontendOpts().Inputs[i].second;
Mike Stump1eb44332009-09-09 15:08:12 +0000353
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000354 // If we aren't using an AST file, setup the file and source managers and
355 // the preprocessor.
356 if (!IsAST) {
357 if (!i) {
358 // Create a file manager object to provide access to and cache the
359 // filesystem.
360 Clang.createFileManager();
361
362 // Create the source manager.
363 Clang.createSourceManager();
364 } else {
365 // Reset the ID tables if we are reusing the SourceManager.
366 Clang.getSourceManager().clearIDTables();
367 }
368
369 // Create the preprocessor.
370 Clang.createPreprocessor();
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +0000371 }
372
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000373 llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(ProgAction));
374 assert(Act && "Invalid program action!");
375 Act->setCurrentTimer(ClangFrontendTimer);
376 if (Act->BeginSourceFile(Clang, InFile, IsAST)) {
377 Act->Execute();
378 Act->EndSourceFile();
379 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000380 }
Chris Lattner11215192008-03-14 06:12:05 +0000381
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000382 if (Clang.getDiagnosticOpts().ShowCarets)
383 if (unsigned NumDiagnostics = Clang.getDiagnostics().getNumDiagnostics())
Mike Stumpfc0fed32009-04-28 01:19:10 +0000384 fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
385 (NumDiagnostics == 1 ? "" : "s"));
Mike Stump1eb44332009-09-09 15:08:12 +0000386
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000387 if (Clang.getFrontendOpts().ShowStats) {
Daniel Dunbar16b74492009-11-13 04:12:06 +0000388 Clang.getFileManager().PrintStats();
Reid Spencer5f016e22007-07-11 17:01:13 +0000389 fprintf(stderr, "\n");
390 }
Chris Lattner75a97cb2009-04-17 21:05:01 +0000391
392 delete ClangFrontendTimer;
Mike Stump1eb44332009-09-09 15:08:12 +0000393
Daniel Dunbarf79dced2009-11-14 03:24:39 +0000394 // Return the appropriate status when verifying diagnostics.
395 //
396 // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need
397 // this.
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000398 if (Clang.getDiagnosticOpts().VerifyDiagnostics)
Daniel Dunbarf79dced2009-11-14 03:24:39 +0000399 return static_cast<VerifyDiagnosticsClient&>(
400 Clang.getDiagnosticClient()).HadErrors();
Mike Stump1eb44332009-09-09 15:08:12 +0000401
Daniel Dunbar524b86f2008-10-28 00:38:08 +0000402 // Managed static deconstruction. Useful for making things like
403 // -time-passes usable.
404 llvm::llvm_shutdown();
405
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000406 return (Clang.getDiagnostics().getNumErrors() != 0);
Reid Spencer5f016e22007-07-11 17:01:13 +0000407}