blob: b189b4b51d658f6d4fbe62889e058bf2a1b24093 [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 Dunbar9119e7e2009-11-16 22:38:48 +000019#include "clang/Basic/Diagnostic.h"
Daniel Dunbar775bee72009-11-11 10:07:22 +000020#include "clang/Basic/FileManager.h"
21#include "clang/Basic/SourceManager.h"
22#include "clang/Basic/TargetInfo.h"
23#include "clang/Basic/Version.h"
Daniel Dunbarc88aa792009-11-30 07:18:13 +000024#include "clang/Driver/Arg.h"
25#include "clang/Driver/ArgList.h"
26#include "clang/Driver/CC1Options.h"
27#include "clang/Driver/DriverDiagnostic.h"
28#include "clang/Driver/OptTable.h"
Daniel Dunbar2a79e162009-11-13 03:51:44 +000029#include "clang/Frontend/CompilerInstance.h"
Daniel Dunbare29709f2009-11-09 20:55:08 +000030#include "clang/Frontend/CompilerInvocation.h"
Daniel Dunbar4fdba992009-11-14 10:53:49 +000031#include "clang/Frontend/FrontendActions.h"
Daniel Dunbar50f4f462009-03-12 10:14:16 +000032#include "clang/Frontend/FrontendDiagnostic.h"
Daniel Dunbard10c5b82009-11-15 00:12:04 +000033#include "clang/Frontend/FrontendPluginRegistry.h"
Daniel Dunbar9deb3132009-11-30 08:42:10 +000034#include "clang/Frontend/TextDiagnosticBuffer.h"
Daniel Dunbarc88aa792009-11-30 07:18:13 +000035#include "clang/Frontend/TextDiagnosticPrinter.h"
Daniel Dunbarf79dced2009-11-14 03:24:39 +000036#include "clang/Frontend/VerifyDiagnosticsClient.h"
Daniel Dunbar4fdba992009-11-14 10:53:49 +000037#include "llvm/LLVMContext.h"
Daniel Dunbar9119e7e2009-11-16 22:38:48 +000038#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar70121eb2009-08-10 03:40:28 +000039#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar524b86f2008-10-28 00:38:08 +000040#include "llvm/Support/ManagedStatic.h"
Zhongxing Xu20922362008-11-26 05:23:17 +000041#include "llvm/Support/PluginLoader.h"
Chris Lattner09e94a32009-03-04 21:41:39 +000042#include "llvm/Support/PrettyStackTrace.h"
Chris Lattner47099742009-02-18 01:51:21 +000043#include "llvm/Support/Timer.h"
Chris Lattner0fa0daa2009-08-24 04:11:30 +000044#include "llvm/Support/raw_ostream.h"
Daniel Dunbarefba2272009-12-03 05:11:05 +000045#include "llvm/System/DynamicLibrary.h"
Daniel Dunbare553a722008-10-02 01:21:33 +000046#include "llvm/System/Host.h"
Chris Lattnerdcaa0962008-03-03 03:16:03 +000047#include "llvm/System/Path.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000048#include "llvm/System/Signals.h"
Chris Lattner2fe11942009-06-17 17:25:50 +000049#include "llvm/Target/TargetSelect.h"
Daniel Dunbar1a506282009-11-25 10:53:00 +000050#include <cstdio>
Reid Spencer5f016e22007-07-11 17:01:13 +000051using namespace clang;
52
53//===----------------------------------------------------------------------===//
Daniel Dunbarc363cb12009-11-16 22:38:40 +000054// Main driver
Reid Spencer5f016e22007-07-11 17:01:13 +000055//===----------------------------------------------------------------------===//
56
Daniel Dunbar750156a2009-11-07 04:19:57 +000057std::string GetBuiltinIncludePath(const char *Argv0) {
58 llvm::sys::Path P =
59 llvm::sys::Path::GetMainExecutable(Argv0,
60 (void*)(intptr_t) GetBuiltinIncludePath);
Rafael Espindola1bb15a92009-10-05 13:12:17 +000061
Daniel Dunbar750156a2009-11-07 04:19:57 +000062 if (!P.isEmpty()) {
63 P.eraseComponent(); // Remove /clang from foo/bin/clang
64 P.eraseComponent(); // Remove /bin from foo/bin
Rafael Espindola1bb15a92009-10-05 13:12:17 +000065
Daniel Dunbar750156a2009-11-07 04:19:57 +000066 // Get foo/lib/clang/<version>/include
67 P.appendComponent("lib");
68 P.appendComponent("clang");
69 P.appendComponent(CLANG_VERSION_STRING);
70 P.appendComponent("include");
71 }
Rafael Espindola1bb15a92009-10-05 13:12:17 +000072
Daniel Dunbar750156a2009-11-07 04:19:57 +000073 return P.str();
Rafael Espindola1bb15a92009-10-05 13:12:17 +000074}
75
Daniel Dunbarc363cb12009-11-16 22:38:40 +000076static void LLVMErrorHandler(void *UserData, const std::string &Message) {
77 Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
78
79 Diags.Report(diag::err_fe_error_backend) << Message;
80
81 // We cannot recover from llvm errors.
82 exit(1);
83}
Reid Spencer5f016e22007-07-11 17:01:13 +000084
Daniel Dunbard10c5b82009-11-15 00:12:04 +000085static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
Daniel Dunbar9a8a83b2009-11-14 22:32:38 +000086 using namespace clang::frontend;
87
Daniel Dunbard10c5b82009-11-15 00:12:04 +000088 switch (CI.getFrontendOpts().ProgramAction) {
89 default:
90 llvm::llvm_unreachable("Invalid program action!");
91
Daniel Dunbar4fdba992009-11-14 10:53:49 +000092 case ASTDump: return new ASTDumpAction();
93 case ASTPrint: return new ASTPrintAction();
94 case ASTPrintXML: return new ASTPrintXMLAction();
95 case ASTView: return new ASTViewAction();
96 case DumpRawTokens: return new DumpRawTokensAction();
97 case DumpRecordLayouts: return new DumpRecordAction();
98 case DumpTokens: return new DumpTokensAction();
99 case EmitAssembly: return new EmitAssemblyAction();
100 case EmitBC: return new EmitBCAction();
101 case EmitHTML: return new HTMLPrintAction();
102 case EmitLLVM: return new EmitLLVMAction();
103 case EmitLLVMOnly: return new EmitLLVMOnlyAction();
104 case FixIt: return new FixItAction();
105 case GeneratePCH: return new GeneratePCHAction();
106 case GeneratePTH: return new GeneratePTHAction();
107 case InheritanceView: return new InheritanceViewAction();
108 case ParseNoop: return new ParseOnlyAction();
109 case ParsePrintCallbacks: return new PrintParseAction();
110 case ParseSyntaxOnly: return new SyntaxOnlyAction();
Daniel Dunbard10c5b82009-11-15 00:12:04 +0000111
112 case PluginAction: {
113 if (CI.getFrontendOpts().ActionName == "help") {
114 llvm::errs() << "clang-cc plugins:\n";
115 for (FrontendPluginRegistry::iterator it =
116 FrontendPluginRegistry::begin(),
117 ie = FrontendPluginRegistry::end();
118 it != ie; ++it)
119 llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n";
120 exit(1);
121 }
122
123 for (FrontendPluginRegistry::iterator it =
124 FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
125 it != ie; ++it) {
126 if (it->getName() == CI.getFrontendOpts().ActionName)
127 return it->instantiate();
128 }
129
130 CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
131 << CI.getFrontendOpts().ActionName;
132 return 0;
133 }
134
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000135 case PrintDeclContext: return new DeclContextPrintAction();
136 case PrintPreprocessedInput: return new PrintPreprocessedAction();
137 case RewriteBlocks: return new RewriteBlocksAction();
138 case RewriteMacros: return new RewriteMacrosAction();
139 case RewriteObjC: return new RewriteObjCAction();
140 case RewriteTest: return new RewriteTestAction();
141 case RunAnalysis: return new AnalysisAction();
142 case RunPreprocessorOnly: return new PreprocessOnlyAction();
Eli Friedman66d6f042009-05-18 22:20:00 +0000143 }
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +0000144}
145
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000146static bool ConstructCompilerInvocation(CompilerInvocation &Opts,
Daniel Dunbarae8e17e2009-11-30 07:18:20 +0000147 Diagnostic &Diags, const char *Argv0) {
Daniel Dunbard58c03f2009-11-15 06:48:46 +0000148 // Initialize target options.
149 InitializeTargetOptions(Opts.getTargetOpts());
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000150
Daniel Dunbard58c03f2009-11-15 06:48:46 +0000151 // Initialize frontend options.
152 InitializeFrontendOptions(Opts.getFrontendOpts());
Daniel Dunbarfcb0c3b2009-11-10 18:47:35 +0000153
Daniel Dunbarfbe2faf2009-11-13 02:06:12 +0000154 // Determine the input language, we currently require all files to match.
155 FrontendOptions::InputKind IK = Opts.getFrontendOpts().Inputs[0].first;
156 for (unsigned i = 1, e = Opts.getFrontendOpts().Inputs.size(); i != e; ++i) {
157 if (Opts.getFrontendOpts().Inputs[i].first != IK) {
158 llvm::errs() << "error: cannot have multiple input files of distinct "
159 << "language kinds without -x\n";
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000160 return false;
Daniel Dunbarfbe2faf2009-11-13 02:06:12 +0000161 }
162 }
163
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000164 // Initialize language options.
Daniel Dunbar5746f1f2009-11-12 00:24:10 +0000165 //
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000166 // FIXME: These aren't used during operations on ASTs. Split onto a separate
167 // code path to make this obvious.
Daniel Dunbarae8e17e2009-11-30 07:18:20 +0000168 if (IK != FrontendOptions::IK_AST)
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000169 InitializeLangOptions(Opts.getLangOpts(), IK);
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000170
Daniel Dunbar5746f1f2009-11-12 00:24:10 +0000171 // Initialize the static analyzer options.
172 InitializeAnalyzerOptions(Opts.getAnalyzerOpts());
173
Daniel Dunbar0e0bae82009-11-11 21:43:12 +0000174 // Initialize the dependency output options (-M...).
175 InitializeDependencyOutputOptions(Opts.getDependencyOutputOpts());
176
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000177 // Initialize the header search options.
Daniel Dunbarf7973292009-11-11 08:13:32 +0000178 InitializeHeaderSearchOptions(Opts.getHeaderSearchOpts(),
Daniel Dunbarc363cb12009-11-16 22:38:40 +0000179 GetBuiltinIncludePath(Argv0));
Daniel Dunbar5fc7d342009-11-09 23:12:31 +0000180
181 // Initialize the other preprocessor options.
182 InitializePreprocessorOptions(Opts.getPreprocessorOpts());
Daniel Dunbar36f4ec32009-11-10 16:19:45 +0000183
Daniel Dunbar29cf7462009-11-11 10:07:44 +0000184 // Initialize the preprocessed output options.
185 InitializePreprocessorOutputOptions(Opts.getPreprocessorOutputOpts());
186
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000187 // Initialize backend options.
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000188 InitializeCodeGenOptions(Opts.getCodeGenOpts(), Opts.getLangOpts());
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000189
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000190 return true;
Daniel Dunbare29709f2009-11-09 20:55:08 +0000191}
192
Daniel Dunbarc88aa792009-11-30 07:18:13 +0000193static int cc1_main(Diagnostic &Diags,
194 const char **ArgBegin, const char **ArgEnd,
195 const char *Argv0, void *MainAddr) {
196 using namespace clang::driver;
197
198 llvm::errs() << "cc1 argv:";
199 for (const char **i = ArgBegin; i != ArgEnd; ++i)
200 llvm::errs() << " \"" << *i << '"';
201 llvm::errs() << "\n";
202
203 // Parse the arguments.
204 OptTable *Opts = createCC1OptTable();
205 unsigned MissingArgIndex, MissingArgCount;
206 InputArgList *Args = Opts->ParseArgs(ArgBegin, ArgEnd,
207 MissingArgIndex, MissingArgCount);
208
209 // Check for missing argument error.
210 if (MissingArgCount)
211 Diags.Report(clang::diag::err_drv_missing_argument)
212 << Args->getArgString(MissingArgIndex) << MissingArgCount;
213
214 // Dump the parsed arguments.
215 llvm::errs() << "cc1 parsed options:\n";
216 for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
217 it != ie; ++it)
218 (*it)->dump();
219
220 // Create a compiler invocation.
221 llvm::errs() << "cc1 creating invocation.\n";
222 CompilerInvocation Invocation;
223 CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd,
224 Argv0, MainAddr, Diags);
225
226 // Convert the invocation back to argument strings.
227 std::vector<std::string> InvocationArgs;
228 Invocation.toArgs(InvocationArgs);
229
230 // Dump the converted arguments.
231 llvm::SmallVector<const char*, 32> Invocation2Args;
232 llvm::errs() << "invocation argv :";
233 for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) {
234 Invocation2Args.push_back(InvocationArgs[i].c_str());
235 llvm::errs() << " \"" << InvocationArgs[i] << '"';
236 }
237 llvm::errs() << "\n";
238
239 // Convert those arguments to another invocation, and check that we got the
240 // same thing.
241 CompilerInvocation Invocation2;
242 CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(),
243 Invocation2Args.end(), Argv0, MainAddr,
244 Diags);
245
246 // FIXME: Implement CompilerInvocation comparison.
247 if (true) {
248 //llvm::errs() << "warning: Invocations differ!\n";
249
250 std::vector<std::string> Invocation2Args;
251 Invocation2.toArgs(Invocation2Args);
252 llvm::errs() << "invocation2 argv:";
253 for (unsigned i = 0, e = Invocation2Args.size(); i != e; ++i)
254 llvm::errs() << " \"" << Invocation2Args[i] << '"';
255 llvm::errs() << "\n";
256 }
257
258 return 0;
259}
260
Reid Spencer5f016e22007-07-11 17:01:13 +0000261int main(int argc, char **argv) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000262 llvm::sys::PrintStackTraceOnErrorSignal();
Chris Lattner09e94a32009-03-04 21:41:39 +0000263 llvm::PrettyStackTraceProgram X(argc, argv);
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000264 CompilerInstance Clang(&llvm::getGlobalContext(), false);
Daniel Dunbard6970812009-09-02 23:20:15 +0000265
Daniel Dunbarc88aa792009-11-30 07:18:13 +0000266 // Run clang -cc1 test.
267 if (argc > 1 && llvm::StringRef(argv[1]) == "-cc1") {
268 TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions());
269 Diagnostic Diags(&DiagClient);
270 return cc1_main(Diags, (const char**) argv + 2, (const char**) argv + argc,
271 argv[0], (void*) (intptr_t) GetBuiltinIncludePath);
272 }
273
Daniel Dunbar4d861512009-09-03 04:54:12 +0000274 // Initialize targets first, so that --version shows registered targets.
Chris Lattner2fe11942009-06-17 17:25:50 +0000275 llvm::InitializeAllTargets();
276 llvm::InitializeAllAsmPrinters();
Daniel Dunbard6970812009-09-02 23:20:15 +0000277
Daniel Dunbar9deb3132009-11-30 08:42:10 +0000278#if 1
Daniel Dunbard6970812009-09-02 23:20:15 +0000279 llvm::cl::ParseCommandLineOptions(argc, argv,
280 "LLVM 'Clang' Compiler: http://clang.llvm.org\n");
Mike Stump1eb44332009-09-09 15:08:12 +0000281
Daniel Dunbar00e5b8d2009-11-12 06:48:31 +0000282 // Construct the diagnostic engine first, so that we can build a diagnostic
283 // client to use for any errors during option handling.
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000284 InitializeDiagnosticOptions(Clang.getDiagnosticOpts());
285 Clang.createDiagnostics(argc, argv);
Daniel Dunbar704e48a2009-11-13 08:20:57 +0000286 if (!Clang.hasDiagnostics())
Sebastian Redl63a9e0f2009-03-06 17:41:35 +0000287 return 1;
Ted Kremenek31e703b2007-12-11 23:28:38 +0000288
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000289 // Set an error handler, so that any LLVM backend diagnostics go through our
290 // error handler.
291 llvm::llvm_install_error_handler(LLVMErrorHandler,
292 static_cast<void*>(&Clang.getDiagnostics()));
Daniel Dunbar70121eb2009-08-10 03:40:28 +0000293
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000294 // Now that we have initialized the diagnostics engine, create the target and
295 // the compiler invocation object.
Daniel Dunbar227b2382009-11-09 22:45:57 +0000296 //
297 // FIXME: We should move .ast inputs to taking a separate path, they are
298 // really quite different.
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000299 if (!ConstructCompilerInvocation(Clang.getInvocation(),
Daniel Dunbarae8e17e2009-11-30 07:18:20 +0000300 Clang.getDiagnostics(), argv[0]))
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000301 return 1;
Daniel Dunbar9deb3132009-11-30 08:42:10 +0000302#else
Daniel Dunbarefba2272009-12-03 05:11:05 +0000303 // Buffer diagnostics from argument parsing so that we can output them using a
304 // well formed diagnostic object.
Daniel Dunbar9deb3132009-11-30 08:42:10 +0000305 TextDiagnosticBuffer DiagsBuffer;
306 Diagnostic Diags(&DiagsBuffer);
307
308 CompilerInvocation::CreateFromArgs(Clang.getInvocation(),
309 (const char**) argv + 1,
310 (const char**) argv + argc, argv[0],
311 (void*)(intptr_t) GetBuiltinIncludePath,
312 Diags);
313
314 // Create the actual diagnostics engine.
315 Clang.createDiagnostics(argc, argv);
316 if (!Clang.hasDiagnostics())
317 return 1;
318
319 // 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()));
323
324 DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics());
325
Daniel Dunbarefba2272009-12-03 05:11:05 +0000326 // Load any requested plugins.
327 for (unsigned i = 0,
328 e = Clang.getFrontendOpts().Plugins.size(); i != e; ++i) {
329 const std::string &Path = Clang.getFrontendOpts().Plugins[i];
330 std::string Error;
331 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
332 Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error;
333 }
334
Daniel Dunbar9deb3132009-11-30 08:42:10 +0000335 // If there were any errors in processing arguments, exit now.
336 if (Clang.getDiagnostics().getNumErrors())
337 return 1;
338#endif
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000339
340 // Create the target instance.
341 Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
342 Clang.getTargetOpts()));
Daniel Dunbar704e48a2009-11-13 08:20:57 +0000343 if (!Clang.hasTarget())
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000344 return 1;
Daniel Dunbar26266882009-11-12 23:52:32 +0000345
Daniel Dunbar33b26ea32009-11-20 16:55:31 +0000346 // Inform the target of the language options
347 //
348 // FIXME: We shouldn't need to do this, the target should be immutable once
349 // created. This complexity should be lifted elsewhere.
350 Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
351
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000352 // Validate/process some options
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000353 if (Clang.getHeaderSearchOpts().Verbose)
Daniel Dunbar1417c742009-11-12 23:52:46 +0000354 llvm::errs() << "clang-cc version " CLANG_VERSION_STRING
355 << " based upon " << PACKAGE_STRING
356 << " hosted on " << llvm::sys::getHostTriple() << "\n";
357
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000358 if (Clang.getFrontendOpts().ShowTimers)
Kovarththanan Rajaratnamf79bafa2009-11-29 09:57:35 +0000359 Clang.createFrontendTimer();
Daniel Dunbar26266882009-11-12 23:52:32 +0000360
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000361 for (unsigned i = 0, e = Clang.getFrontendOpts().Inputs.size(); i != e; ++i) {
362 const std::string &InFile = Clang.getFrontendOpts().Inputs[i].second;
Mike Stump1eb44332009-09-09 15:08:12 +0000363
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000364 // If we aren't using an AST file, setup the file and source managers and
365 // the preprocessor.
Daniel Dunbarae8e17e2009-11-30 07:18:20 +0000366 bool IsAST =
367 Clang.getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST;
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000368 if (!IsAST) {
369 if (!i) {
370 // Create a file manager object to provide access to and cache the
371 // filesystem.
372 Clang.createFileManager();
373
374 // Create the source manager.
375 Clang.createSourceManager();
376 } else {
377 // Reset the ID tables if we are reusing the SourceManager.
378 Clang.getSourceManager().clearIDTables();
379 }
380
381 // Create the preprocessor.
382 Clang.createPreprocessor();
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +0000383 }
384
Daniel Dunbard10c5b82009-11-15 00:12:04 +0000385 llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang));
386 if (!Act)
387 break;
388
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000389 if (Act->BeginSourceFile(Clang, InFile, IsAST)) {
390 Act->Execute();
391 Act->EndSourceFile();
392 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000393 }
Chris Lattner11215192008-03-14 06:12:05 +0000394
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000395 if (Clang.getDiagnosticOpts().ShowCarets)
396 if (unsigned NumDiagnostics = Clang.getDiagnostics().getNumDiagnostics())
Mike Stumpfc0fed32009-04-28 01:19:10 +0000397 fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
398 (NumDiagnostics == 1 ? "" : "s"));
Mike Stump1eb44332009-09-09 15:08:12 +0000399
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000400 if (Clang.getFrontendOpts().ShowStats) {
Daniel Dunbar16b74492009-11-13 04:12:06 +0000401 Clang.getFileManager().PrintStats();
Reid Spencer5f016e22007-07-11 17:01:13 +0000402 fprintf(stderr, "\n");
403 }
Chris Lattner75a97cb2009-04-17 21:05:01 +0000404
Daniel Dunbarf79dced2009-11-14 03:24:39 +0000405 // Return the appropriate status when verifying diagnostics.
406 //
407 // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need
408 // this.
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000409 if (Clang.getDiagnosticOpts().VerifyDiagnostics)
Daniel Dunbarf79dced2009-11-14 03:24:39 +0000410 return static_cast<VerifyDiagnosticsClient&>(
411 Clang.getDiagnosticClient()).HadErrors();
Mike Stump1eb44332009-09-09 15:08:12 +0000412
Daniel Dunbar524b86f2008-10-28 00:38:08 +0000413 // Managed static deconstruction. Useful for making things like
414 // -time-passes usable.
415 llvm::llvm_shutdown();
416
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000417 return (Clang.getDiagnostics().getNumErrors() != 0);
Reid Spencer5f016e22007-07-11 17:01:13 +0000418}
Daniel Dunbard10c5b82009-11-15 00:12:04 +0000419