blob: 3df2edc4caeb090d859f75d0b309899bcabe7570 [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 Dunbard10c5b82009-11-15 00:12:04 +000027#include "clang/Frontend/FrontendPluginRegistry.h"
Daniel Dunbar8863b982009-11-07 04:20:15 +000028#include "clang/Frontend/PathDiagnosticClients.h"
29#include "clang/Frontend/PreprocessorOptions.h"
Daniel Dunbar775bee72009-11-11 10:07:22 +000030#include "clang/Frontend/PreprocessorOutputOptions.h"
Daniel Dunbarf79dced2009-11-14 03:24:39 +000031#include "clang/Frontend/VerifyDiagnosticsClient.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000032#include "llvm/ADT/OwningPtr.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000033#include "llvm/Config/config.h"
Daniel Dunbar4fdba992009-11-14 10:53:49 +000034#include "llvm/LLVMContext.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000035#include "llvm/Support/CommandLine.h"
Daniel Dunbar70121eb2009-08-10 03:40:28 +000036#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar524b86f2008-10-28 00:38:08 +000037#include "llvm/Support/ManagedStatic.h"
Zhongxing Xu20922362008-11-26 05:23:17 +000038#include "llvm/Support/PluginLoader.h"
Chris Lattner09e94a32009-03-04 21:41:39 +000039#include "llvm/Support/PrettyStackTrace.h"
Daniel Dunbard10c5b82009-11-15 00:12:04 +000040#include "llvm/Support/Registry.h"
Chris Lattner47099742009-02-18 01:51:21 +000041#include "llvm/Support/Timer.h"
Chris Lattner0fa0daa2009-08-24 04:11:30 +000042#include "llvm/Support/raw_ostream.h"
Daniel Dunbare553a722008-10-02 01:21:33 +000043#include "llvm/System/Host.h"
Chris Lattnerdcaa0962008-03-03 03:16:03 +000044#include "llvm/System/Path.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000045#include "llvm/System/Signals.h"
Chris Lattner2fe11942009-06-17 17:25:50 +000046#include "llvm/Target/TargetSelect.h"
Douglas Gregor26df2f02009-04-02 19:05:20 +000047#include <cstdlib>
Douglas Gregor44cf08e2009-05-03 03:52:38 +000048#if HAVE_SYS_TYPES_H
Douglas Gregor68a0d782009-05-02 00:03:46 +000049# include <sys/types.h>
50#endif
Douglas Gregor26df2f02009-04-02 19:05:20 +000051
Reid Spencer5f016e22007-07-11 17:01:13 +000052using namespace clang;
53
54//===----------------------------------------------------------------------===//
Daniel Dunbar914474c2009-11-13 01:02:10 +000055// Utility Methods
Reid Spencer5f016e22007-07-11 17:01:13 +000056//===----------------------------------------------------------------------===//
57
Daniel Dunbar750156a2009-11-07 04:19:57 +000058std::string GetBuiltinIncludePath(const char *Argv0) {
59 llvm::sys::Path P =
60 llvm::sys::Path::GetMainExecutable(Argv0,
61 (void*)(intptr_t) GetBuiltinIncludePath);
Rafael Espindola1bb15a92009-10-05 13:12:17 +000062
Daniel Dunbar750156a2009-11-07 04:19:57 +000063 if (!P.isEmpty()) {
64 P.eraseComponent(); // Remove /clang from foo/bin/clang
65 P.eraseComponent(); // Remove /bin from foo/bin
Rafael Espindola1bb15a92009-10-05 13:12:17 +000066
Daniel Dunbar750156a2009-11-07 04:19:57 +000067 // Get foo/lib/clang/<version>/include
68 P.appendComponent("lib");
69 P.appendComponent("clang");
70 P.appendComponent(CLANG_VERSION_STRING);
71 P.appendComponent("include");
72 }
Rafael Espindola1bb15a92009-10-05 13:12:17 +000073
Daniel Dunbar750156a2009-11-07 04:19:57 +000074 return P.str();
Rafael Espindola1bb15a92009-10-05 13:12:17 +000075}
76
Reid Spencer5f016e22007-07-11 17:01:13 +000077//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +000078// Main driver
79//===----------------------------------------------------------------------===//
80
Daniel Dunbaraa576142009-11-12 15:23:20 +000081/// ClangFrontendTimer - The front-end activities should charge time to it with
82/// TimeRegion. The -ftime-report option controls whether this will do
83/// anything.
84llvm::Timer *ClangFrontendTimer = 0;
85
Daniel Dunbard10c5b82009-11-15 00:12:04 +000086static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
Daniel Dunbar9a8a83b2009-11-14 22:32:38 +000087 using namespace clang::frontend;
88
Daniel Dunbard10c5b82009-11-15 00:12:04 +000089 switch (CI.getFrontendOpts().ProgramAction) {
90 default:
91 llvm::llvm_unreachable("Invalid program action!");
92
Daniel Dunbar4fdba992009-11-14 10:53:49 +000093 case ASTDump: return new ASTDumpAction();
94 case ASTPrint: return new ASTPrintAction();
95 case ASTPrintXML: return new ASTPrintXMLAction();
96 case ASTView: return new ASTViewAction();
97 case DumpRawTokens: return new DumpRawTokensAction();
98 case DumpRecordLayouts: return new DumpRecordAction();
99 case DumpTokens: return new DumpTokensAction();
100 case EmitAssembly: return new EmitAssemblyAction();
101 case EmitBC: return new EmitBCAction();
102 case EmitHTML: return new HTMLPrintAction();
103 case EmitLLVM: return new EmitLLVMAction();
104 case EmitLLVMOnly: return new EmitLLVMOnlyAction();
105 case FixIt: return new FixItAction();
106 case GeneratePCH: return new GeneratePCHAction();
107 case GeneratePTH: return new GeneratePTHAction();
108 case InheritanceView: return new InheritanceViewAction();
109 case ParseNoop: return new ParseOnlyAction();
110 case ParsePrintCallbacks: return new PrintParseAction();
111 case ParseSyntaxOnly: return new SyntaxOnlyAction();
Daniel Dunbard10c5b82009-11-15 00:12:04 +0000112
113 case PluginAction: {
114 if (CI.getFrontendOpts().ActionName == "help") {
115 llvm::errs() << "clang-cc plugins:\n";
116 for (FrontendPluginRegistry::iterator it =
117 FrontendPluginRegistry::begin(),
118 ie = FrontendPluginRegistry::end();
119 it != ie; ++it)
120 llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n";
121 exit(1);
122 }
123
124 for (FrontendPluginRegistry::iterator it =
125 FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
126 it != ie; ++it) {
127 if (it->getName() == CI.getFrontendOpts().ActionName)
128 return it->instantiate();
129 }
130
131 CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
132 << CI.getFrontendOpts().ActionName;
133 return 0;
134 }
135
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000136 case PrintDeclContext: return new DeclContextPrintAction();
137 case PrintPreprocessedInput: return new PrintPreprocessedAction();
138 case RewriteBlocks: return new RewriteBlocksAction();
139 case RewriteMacros: return new RewriteMacrosAction();
140 case RewriteObjC: return new RewriteObjCAction();
141 case RewriteTest: return new RewriteTestAction();
142 case RunAnalysis: return new AnalysisAction();
143 case RunPreprocessorOnly: return new PreprocessOnlyAction();
Eli Friedman66d6f042009-05-18 22:20:00 +0000144 }
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +0000145}
146
Daniel Dunbar70121eb2009-08-10 03:40:28 +0000147static void LLVMErrorHandler(void *UserData, const std::string &Message) {
148 Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
149
Daniel Dunbar0f9fed72009-11-10 23:55:23 +0000150 Diags.Report(diag::err_fe_error_backend) << Message;
Daniel Dunbar70121eb2009-08-10 03:40:28 +0000151
152 // We cannot recover from llvm errors.
153 exit(1);
154}
155
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000156static TargetInfo *
157ConstructCompilerInvocation(CompilerInvocation &Opts, Diagnostic &Diags,
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000158 const char *Argv0, bool &IsAST) {
Daniel Dunbar26266882009-11-12 23:52:32 +0000159 // Initialize frontend options.
160 InitializeFrontendOptions(Opts.getFrontendOpts());
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000161
Daniel Dunbarf819b252009-11-13 05:52:19 +0000162 // FIXME: The target information in frontend options should be split out into
163 // TargetOptions, and the target options in codegen options should move there
164 // as well. Then we could properly initialize in layering order.
165
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000166 // Initialize base triple. If a -triple option has been specified, use
167 // that triple. Otherwise, default to the host triple.
168 llvm::Triple Triple(Opts.getFrontendOpts().TargetTriple);
169 if (Triple.getTriple().empty())
170 Triple = llvm::Triple(llvm::sys::getHostTriple());
171
172 // Get information about the target being compiled for.
173 TargetInfo *Target = TargetInfo::CreateTargetInfo(Triple.getTriple());
174 if (!Target) {
175 Diags.Report(diag::err_fe_unknown_triple) << Triple.getTriple().c_str();
176 return 0;
177 }
178
179 // Set the target ABI if specified.
180 if (!Opts.getFrontendOpts().TargetABI.empty() &&
181 !Target->setABI(Opts.getFrontendOpts().TargetABI)) {
182 Diags.Report(diag::err_fe_unknown_target_abi)
183 << Opts.getFrontendOpts().TargetABI;
184 return 0;
185 }
186
Daniel Dunbarfcb0c3b2009-11-10 18:47:35 +0000187 // Initialize backend options, which may also be used to key some language
188 // options.
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000189 InitializeCodeGenOptions(Opts.getCodeGenOpts(), *Target);
Daniel Dunbarfcb0c3b2009-11-10 18:47:35 +0000190
Daniel Dunbarfbe2faf2009-11-13 02:06:12 +0000191 // Determine the input language, we currently require all files to match.
192 FrontendOptions::InputKind IK = Opts.getFrontendOpts().Inputs[0].first;
193 for (unsigned i = 1, e = Opts.getFrontendOpts().Inputs.size(); i != e; ++i) {
194 if (Opts.getFrontendOpts().Inputs[i].first != IK) {
195 llvm::errs() << "error: cannot have multiple input files of distinct "
196 << "language kinds without -x\n";
197 return 0;
198 }
199 }
200
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000201 // Initialize language options.
Daniel Dunbar5746f1f2009-11-12 00:24:10 +0000202 //
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000203 // FIXME: These aren't used during operations on ASTs. Split onto a separate
204 // code path to make this obvious.
Daniel Dunbarfbe2faf2009-11-13 02:06:12 +0000205 IsAST = (IK == FrontendOptions::IK_AST);
Daniel Dunbar26266882009-11-12 23:52:32 +0000206 if (!IsAST)
Daniel Dunbarfbe2faf2009-11-13 02:06:12 +0000207 InitializeLangOptions(Opts.getLangOpts(), IK, *Target,
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000208 Opts.getCodeGenOpts());
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000209
Daniel Dunbar5746f1f2009-11-12 00:24:10 +0000210 // Initialize the static analyzer options.
211 InitializeAnalyzerOptions(Opts.getAnalyzerOpts());
212
Daniel Dunbar0e0bae82009-11-11 21:43:12 +0000213 // Initialize the dependency output options (-M...).
214 InitializeDependencyOutputOptions(Opts.getDependencyOutputOpts());
215
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000216 // Initialize the header search options.
Daniel Dunbarf7973292009-11-11 08:13:32 +0000217 InitializeHeaderSearchOptions(Opts.getHeaderSearchOpts(),
218 GetBuiltinIncludePath(Argv0),
Daniel Dunbarf7973292009-11-11 08:13:32 +0000219 Opts.getLangOpts());
Daniel Dunbar5fc7d342009-11-09 23:12:31 +0000220
221 // Initialize the other preprocessor options.
222 InitializePreprocessorOptions(Opts.getPreprocessorOpts());
Daniel Dunbar36f4ec32009-11-10 16:19:45 +0000223
Daniel Dunbar29cf7462009-11-11 10:07:44 +0000224 // Initialize the preprocessed output options.
225 InitializePreprocessorOutputOptions(Opts.getPreprocessorOutputOpts());
226
Daniel Dunbar26266882009-11-12 23:52:32 +0000227 // Finalize some code generation options which are derived from other places.
228 if (Opts.getLangOpts().NoBuiltin)
229 Opts.getCodeGenOpts().SimplifyLibCalls = 0;
230 if (Opts.getLangOpts().CPlusPlus)
231 Opts.getCodeGenOpts().NoCommon = 1;
232 Opts.getCodeGenOpts().TimePasses = Opts.getFrontendOpts().ShowTimers;
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000233
234 return Target;
Daniel Dunbare29709f2009-11-09 20:55:08 +0000235}
236
Reid Spencer5f016e22007-07-11 17:01:13 +0000237int main(int argc, char **argv) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000238 llvm::sys::PrintStackTraceOnErrorSignal();
Chris Lattner09e94a32009-03-04 21:41:39 +0000239 llvm::PrettyStackTraceProgram X(argc, argv);
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000240 CompilerInstance Clang(&llvm::getGlobalContext(), false);
Daniel Dunbard6970812009-09-02 23:20:15 +0000241
Daniel Dunbar4d861512009-09-03 04:54:12 +0000242 // Initialize targets first, so that --version shows registered targets.
Chris Lattner2fe11942009-06-17 17:25:50 +0000243 llvm::InitializeAllTargets();
244 llvm::InitializeAllAsmPrinters();
Daniel Dunbard6970812009-09-02 23:20:15 +0000245
246 llvm::cl::ParseCommandLineOptions(argc, argv,
247 "LLVM 'Clang' Compiler: http://clang.llvm.org\n");
Mike Stump1eb44332009-09-09 15:08:12 +0000248
Daniel Dunbar00e5b8d2009-11-12 06:48:31 +0000249 // Construct the diagnostic engine first, so that we can build a diagnostic
250 // client to use for any errors during option handling.
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000251 InitializeDiagnosticOptions(Clang.getDiagnosticOpts());
252 Clang.createDiagnostics(argc, argv);
Daniel Dunbar704e48a2009-11-13 08:20:57 +0000253 if (!Clang.hasDiagnostics())
Sebastian Redl63a9e0f2009-03-06 17:41:35 +0000254 return 1;
Ted Kremenek31e703b2007-12-11 23:28:38 +0000255
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000256 // Set an error handler, so that any LLVM backend diagnostics go through our
257 // error handler.
258 llvm::llvm_install_error_handler(LLVMErrorHandler,
259 static_cast<void*>(&Clang.getDiagnostics()));
Daniel Dunbar70121eb2009-08-10 03:40:28 +0000260
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000261 // Now that we have initialized the diagnostics engine, create the target and
262 // the compiler invocation object.
Daniel Dunbar227b2382009-11-09 22:45:57 +0000263 //
264 // FIXME: We should move .ast inputs to taking a separate path, they are
265 // really quite different.
Daniel Dunbar26266882009-11-12 23:52:32 +0000266 bool IsAST;
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000267 Clang.setTarget(
268 ConstructCompilerInvocation(Clang.getInvocation(), Clang.getDiagnostics(),
Daniel Dunbar0fbb3d92009-11-13 05:52:34 +0000269 argv[0], IsAST));
Daniel Dunbar704e48a2009-11-13 08:20:57 +0000270 if (!Clang.hasTarget())
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000271 return 1;
Daniel Dunbar26266882009-11-12 23:52:32 +0000272
Daniel Dunbar21dac5e2009-11-13 01:02:19 +0000273 // Validate/process some options
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000274 if (Clang.getHeaderSearchOpts().Verbose)
Daniel Dunbar1417c742009-11-12 23:52:46 +0000275 llvm::errs() << "clang-cc version " CLANG_VERSION_STRING
276 << " based upon " << PACKAGE_STRING
277 << " hosted on " << llvm::sys::getHostTriple() << "\n";
278
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000279 if (Clang.getFrontendOpts().ShowTimers)
Daniel Dunbar26266882009-11-12 23:52:32 +0000280 ClangFrontendTimer = new llvm::Timer("Clang front-end time");
281
Daniel Dunbar79b55f92009-11-14 04:39:29 +0000282 // Enforce certain implications.
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000283 if (!Clang.getFrontendOpts().ViewClassInheritance.empty())
Daniel Dunbar9a8a83b2009-11-14 22:32:38 +0000284 Clang.getFrontendOpts().ProgramAction = frontend::InheritanceView;
Daniel Dunbar79b55f92009-11-14 04:39:29 +0000285 if (!Clang.getFrontendOpts().FixItLocations.empty())
Daniel Dunbar9a8a83b2009-11-14 22:32:38 +0000286 Clang.getFrontendOpts().ProgramAction = frontend::FixIt;
Daniel Dunbar227b2382009-11-09 22:45:57 +0000287
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000288 for (unsigned i = 0, e = Clang.getFrontendOpts().Inputs.size(); i != e; ++i) {
289 const std::string &InFile = Clang.getFrontendOpts().Inputs[i].second;
Mike Stump1eb44332009-09-09 15:08:12 +0000290
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000291 // If we aren't using an AST file, setup the file and source managers and
292 // the preprocessor.
293 if (!IsAST) {
294 if (!i) {
295 // Create a file manager object to provide access to and cache the
296 // filesystem.
297 Clang.createFileManager();
298
299 // Create the source manager.
300 Clang.createSourceManager();
301 } else {
302 // Reset the ID tables if we are reusing the SourceManager.
303 Clang.getSourceManager().clearIDTables();
304 }
305
306 // Create the preprocessor.
307 Clang.createPreprocessor();
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +0000308 }
309
Daniel Dunbard10c5b82009-11-15 00:12:04 +0000310 llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang));
311 if (!Act)
312 break;
313
Daniel Dunbar4fdba992009-11-14 10:53:49 +0000314 Act->setCurrentTimer(ClangFrontendTimer);
315 if (Act->BeginSourceFile(Clang, InFile, IsAST)) {
316 Act->Execute();
317 Act->EndSourceFile();
318 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000319 }
Chris Lattner11215192008-03-14 06:12:05 +0000320
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000321 if (Clang.getDiagnosticOpts().ShowCarets)
322 if (unsigned NumDiagnostics = Clang.getDiagnostics().getNumDiagnostics())
Mike Stumpfc0fed32009-04-28 01:19:10 +0000323 fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
324 (NumDiagnostics == 1 ? "" : "s"));
Mike Stump1eb44332009-09-09 15:08:12 +0000325
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000326 if (Clang.getFrontendOpts().ShowStats) {
Daniel Dunbar16b74492009-11-13 04:12:06 +0000327 Clang.getFileManager().PrintStats();
Reid Spencer5f016e22007-07-11 17:01:13 +0000328 fprintf(stderr, "\n");
329 }
Chris Lattner75a97cb2009-04-17 21:05:01 +0000330
331 delete ClangFrontendTimer;
Mike Stump1eb44332009-09-09 15:08:12 +0000332
Daniel Dunbarf79dced2009-11-14 03:24:39 +0000333 // Return the appropriate status when verifying diagnostics.
334 //
335 // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need
336 // this.
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000337 if (Clang.getDiagnosticOpts().VerifyDiagnostics)
Daniel Dunbarf79dced2009-11-14 03:24:39 +0000338 return static_cast<VerifyDiagnosticsClient&>(
339 Clang.getDiagnosticClient()).HadErrors();
Mike Stump1eb44332009-09-09 15:08:12 +0000340
Daniel Dunbar524b86f2008-10-28 00:38:08 +0000341 // Managed static deconstruction. Useful for making things like
342 // -time-passes usable.
343 llvm::llvm_shutdown();
344
Daniel Dunbar2a79e162009-11-13 03:51:44 +0000345 return (Clang.getDiagnostics().getNumErrors() != 0);
Reid Spencer5f016e22007-07-11 17:01:13 +0000346}
Daniel Dunbard10c5b82009-11-15 00:12:04 +0000347