blob: ddd8d3100c76146a8a25c10951a3e30bc9a2b283 [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:
11// clang --help - Output help info.
12// clang [options] - Read from stdin.
13// clang [options] file - Read from "file".
14// clang [options] file1 file2 - Read these files.
15//
16//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +000017
Daniel Dunbar0498cfc2009-11-10 19:51:53 +000018#include "Options.h"
Eli Friedman0ec78fa2009-05-19 21:10:40 +000019#include "clang/Frontend/AnalysisConsumer.h"
Eli Friedman8ceb0d92009-05-18 23:02:01 +000020#include "clang/Frontend/ASTConsumers.h"
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +000021#include "clang/Frontend/ASTUnit.h"
Daniel Dunbardbf75fe2009-11-11 08:13:24 +000022#include "clang/Frontend/ChainedDiagnosticClient.h"
Daniel Dunbare29709f2009-11-09 20:55:08 +000023#include "clang/Frontend/CompilerInvocation.h"
Daniel Dunbareace8742009-11-04 06:24:30 +000024#include "clang/Frontend/DiagnosticOptions.h"
Douglas Gregor558cb562009-04-02 01:08:08 +000025#include "clang/Frontend/FixItRewriter.h"
Daniel Dunbar50f4f462009-03-12 10:14:16 +000026#include "clang/Frontend/FrontendDiagnostic.h"
Daniel Dunbardd35ce92009-11-07 04:58:12 +000027#include "clang/Frontend/HeaderSearchOptions.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000028#include "clang/Frontend/PCHReader.h"
Daniel Dunbar8863b982009-11-07 04:20:15 +000029#include "clang/Frontend/PathDiagnosticClients.h"
30#include "clang/Frontend/PreprocessorOptions.h"
Daniel Dunbare1bd4e62009-03-02 06:16:29 +000031#include "clang/Frontend/TextDiagnosticBuffer.h"
32#include "clang/Frontend/TextDiagnosticPrinter.h"
Argyrios Kyrtzidis34d25d82009-06-23 22:01:39 +000033#include "clang/Frontend/CommandLineSourceLoc.h"
Eli Friedmanb09f6e12009-05-19 04:14:29 +000034#include "clang/Frontend/Utils.h"
Ted Kremenek88f5cde2008-03-27 06:17:42 +000035#include "clang/Analysis/PathDiagnostic.h"
Chris Lattner8ee3c032008-02-06 02:01:47 +000036#include "clang/CodeGen/ModuleBuilder.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000037#include "clang/Sema/CodeCompleteConsumer.h"
Chris Lattnere91c1342008-02-06 00:23:21 +000038#include "clang/Sema/ParseAST.h"
Chris Lattner88eccaf2009-01-29 06:55:46 +000039#include "clang/Sema/SemaDiagnostic.h"
Chris Lattner556beb72007-09-15 22:56:56 +000040#include "clang/AST/ASTConsumer.h"
Chris Lattner1266eca2009-03-28 04:31:31 +000041#include "clang/AST/ASTContext.h"
42#include "clang/AST/Decl.h"
Chris Lattner682bf922009-03-29 16:50:03 +000043#include "clang/AST/DeclGroup.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000044#include "clang/Parse/Parser.h"
45#include "clang/Lex/HeaderSearch.h"
Chris Lattnerdb766842009-02-06 04:16:41 +000046#include "clang/Lex/LexDiagnostic.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000047#include "clang/Basic/FileManager.h"
48#include "clang/Basic/SourceManager.h"
49#include "clang/Basic/TargetInfo.h"
Daniel Dunbaraa338bc2009-05-06 04:07:06 +000050#include "clang/Basic/Version.h"
Owen Anderson42253cc2009-07-01 17:00:06 +000051#include "llvm/LLVMContext.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000052#include "llvm/ADT/OwningPtr.h"
Chris Lattner8f3dab82007-12-15 23:20:07 +000053#include "llvm/ADT/SmallPtrSet.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000054#include "llvm/ADT/StringExtras.h"
Daniel Dunbar868bd0a2009-05-06 03:16:41 +000055#include "llvm/ADT/StringMap.h"
Daniel Dunbar227b2382009-11-09 22:45:57 +000056#include "llvm/ADT/StringSwitch.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000057#include "llvm/Config/config.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000058#include "llvm/Support/CommandLine.h"
Daniel Dunbar70121eb2009-08-10 03:40:28 +000059#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar524b86f2008-10-28 00:38:08 +000060#include "llvm/Support/ManagedStatic.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000061#include "llvm/Support/MemoryBuffer.h"
Zhongxing Xu20922362008-11-26 05:23:17 +000062#include "llvm/Support/PluginLoader.h"
Chris Lattner09e94a32009-03-04 21:41:39 +000063#include "llvm/Support/PrettyStackTrace.h"
Chris Lattner47099742009-02-18 01:51:21 +000064#include "llvm/Support/Timer.h"
Chris Lattner0fa0daa2009-08-24 04:11:30 +000065#include "llvm/Support/raw_ostream.h"
Daniel Dunbare553a722008-10-02 01:21:33 +000066#include "llvm/System/Host.h"
Chris Lattnerdcaa0962008-03-03 03:16:03 +000067#include "llvm/System/Path.h"
Eli Friedman66d6f042009-05-18 22:20:00 +000068#include "llvm/System/Program.h"
Chris Lattnerba0f25f2008-09-30 20:16:56 +000069#include "llvm/System/Signals.h"
Chris Lattner2fe11942009-06-17 17:25:50 +000070#include "llvm/Target/TargetSelect.h"
Douglas Gregor26df2f02009-04-02 19:05:20 +000071#include <cstdlib>
Douglas Gregor44cf08e2009-05-03 03:52:38 +000072#if HAVE_SYS_TYPES_H
Douglas Gregor68a0d782009-05-02 00:03:46 +000073# include <sys/types.h>
74#endif
Douglas Gregor26df2f02009-04-02 19:05:20 +000075
Reid Spencer5f016e22007-07-11 17:01:13 +000076using namespace clang;
77
78//===----------------------------------------------------------------------===//
Douglas Gregor26df2f02009-04-02 19:05:20 +000079// Source Location Parser
80//===----------------------------------------------------------------------===//
81
Argyrios Kyrtzidis34d25d82009-06-23 22:01:39 +000082static bool ResolveParsedLocation(ParsedSourceLocation &ParsedLoc,
83 FileManager &FileMgr,
84 RequestedSourceLocation &Result) {
85 const FileEntry *File = FileMgr.getFile(ParsedLoc.FileName);
Douglas Gregor26df2f02009-04-02 19:05:20 +000086 if (!File)
87 return true;
88
89 Result.File = File;
Argyrios Kyrtzidis34d25d82009-06-23 22:01:39 +000090 Result.Line = ParsedLoc.Line;
91 Result.Column = ParsedLoc.Column;
Douglas Gregor26df2f02009-04-02 19:05:20 +000092 return false;
93}
94
Douglas Gregor26df2f02009-04-02 19:05:20 +000095//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +000096// Global options.
97//===----------------------------------------------------------------------===//
98
Chris Lattner47099742009-02-18 01:51:21 +000099/// ClangFrontendTimer - The front-end activities should charge time to it with
100/// TimeRegion. The -ftime-report option controls whether this will do
101/// anything.
102llvm::Timer *ClangFrontendTimer = 0;
103
Reid Spencer5f016e22007-07-11 17:01:13 +0000104static llvm::cl::opt<bool>
105Verbose("v", llvm::cl::desc("Enable verbose output"));
106static llvm::cl::opt<bool>
Mike Stump1eb44332009-09-09 15:08:12 +0000107Stats("print-stats",
Nate Begemanaabbb122007-12-30 01:38:50 +0000108 llvm::cl::desc("Print performance metrics and statistics"));
Daniel Dunbard3db4012008-10-16 16:54:18 +0000109static llvm::cl::opt<bool>
110DisableFree("disable-free",
111 llvm::cl::desc("Disable freeing of memory on exit"),
112 llvm::cl::init(false));
Daniel Dunbar57cbfc02009-04-27 21:19:07 +0000113static llvm::cl::opt<bool>
Mike Stump1eb44332009-09-09 15:08:12 +0000114EmptyInputOnly("empty-input-only",
Daniel Dunbar57cbfc02009-04-27 21:19:07 +0000115 llvm::cl::desc("Force running on an empty input file"));
Reid Spencer5f016e22007-07-11 17:01:13 +0000116
117enum ProgActions {
Steve Naroffb29b4272008-04-14 22:03:09 +0000118 RewriteObjC, // ObjC->C Rewriter.
Steve Naroff13188952008-09-18 14:10:13 +0000119 RewriteBlocks, // ObjC->C Rewriter for Blocks.
Chris Lattnerb57e3d42008-05-08 06:52:13 +0000120 RewriteMacros, // Expand macros but not #includes.
Chris Lattnerb13c5ee2008-10-12 05:29:20 +0000121 RewriteTest, // Rewriter playground
Douglas Gregor558cb562009-04-02 01:08:08 +0000122 FixIt, // Fix-It Rewriter
Ted Kremenek13e479b2008-03-19 07:53:42 +0000123 HTMLTest, // HTML displayer testing stuff.
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000124 EmitAssembly, // Emit a .s file.
Reid Spencer5f016e22007-07-11 17:01:13 +0000125 EmitLLVM, // Emit a .ll file.
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +0000126 EmitBC, // Emit a .bc file.
Mike Stump1eb44332009-09-09 15:08:12 +0000127 EmitLLVMOnly, // Generate LLVM IR, but do not
Ted Kremenek6a340832008-03-18 21:19:49 +0000128 EmitHTML, // Translate input source into HTML.
Chris Lattner3b427b32007-10-11 00:18:28 +0000129 ASTPrint, // Parse ASTs and print them.
Douglas Gregoree75c052009-05-21 20:55:50 +0000130 ASTPrintXML, // Parse ASTs and print them in XML.
Chris Lattner3b427b32007-10-11 00:18:28 +0000131 ASTDump, // Parse ASTs and dump them.
132 ASTView, // Parse ASTs and view them in Graphviz.
Zhongxing Xu2d75d6f2009-01-13 01:29:24 +0000133 PrintDeclContext, // Print DeclContext and their Decls.
Anders Carlsson78762eb2009-09-24 18:54:49 +0000134 DumpRecordLayouts, // Dump record layout information.
Reid Spencer5f016e22007-07-11 17:01:13 +0000135 ParsePrintCallbacks, // Parse and print each callback.
136 ParseSyntaxOnly, // Parse and perform semantic analysis.
137 ParseNoop, // Parse with noop callbacks.
138 RunPreprocessorOnly, // Just lex, no output.
139 PrintPreprocessedInput, // -E mode.
Chris Lattnerc106c102008-10-12 05:03:36 +0000140 DumpTokens, // Dump out preprocessed tokens.
141 DumpRawTokens, // Dump out raw tokens.
Mike Stump1eb44332009-09-09 15:08:12 +0000142 RunAnalysis, // Run one or more source code analyses.
Douglas Gregorbf1bd6e2009-04-02 23:43:50 +0000143 GeneratePTH, // Generate pre-tokenized header.
Douglas Gregor2cf26342009-04-09 22:27:44 +0000144 GeneratePCH, // Generate pre-compiled header.
Ted Kremenek7cae2f62008-10-23 23:36:29 +0000145 InheritanceView // View C++ inheritance for a specified class.
Reid Spencer5f016e22007-07-11 17:01:13 +0000146};
147
Mike Stump1eb44332009-09-09 15:08:12 +0000148static llvm::cl::opt<ProgActions>
Reid Spencer5f016e22007-07-11 17:01:13 +0000149ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
150 llvm::cl::init(ParseSyntaxOnly),
151 llvm::cl::values(
152 clEnumValN(RunPreprocessorOnly, "Eonly",
153 "Just run preprocessor, no output (for timings)"),
154 clEnumValN(PrintPreprocessedInput, "E",
155 "Run preprocessor, emit preprocessed file"),
Chris Lattnerc106c102008-10-12 05:03:36 +0000156 clEnumValN(DumpRawTokens, "dump-raw-tokens",
157 "Lex file in raw mode and dump raw tokens"),
Daniel Dunbard4270232009-01-20 23:17:32 +0000158 clEnumValN(RunAnalysis, "analyze",
159 "Run static analysis engine"),
Chris Lattnerc106c102008-10-12 05:03:36 +0000160 clEnumValN(DumpTokens, "dump-tokens",
Reid Spencer5f016e22007-07-11 17:01:13 +0000161 "Run preprocessor, dump internal rep of tokens"),
162 clEnumValN(ParseNoop, "parse-noop",
163 "Run parser with noop callbacks (for timings)"),
164 clEnumValN(ParseSyntaxOnly, "fsyntax-only",
165 "Run parser and perform semantic analysis"),
166 clEnumValN(ParsePrintCallbacks, "parse-print-callbacks",
167 "Run parser and print each callback invoked"),
Ted Kremenek6a340832008-03-18 21:19:49 +0000168 clEnumValN(EmitHTML, "emit-html",
169 "Output input source as HTML"),
Chris Lattner3b427b32007-10-11 00:18:28 +0000170 clEnumValN(ASTPrint, "ast-print",
171 "Build ASTs and then pretty-print them"),
Douglas Gregoree75c052009-05-21 20:55:50 +0000172 clEnumValN(ASTPrintXML, "ast-print-xml",
173 "Build ASTs and then print them in XML format"),
Chris Lattner3b427b32007-10-11 00:18:28 +0000174 clEnumValN(ASTDump, "ast-dump",
175 "Build ASTs and then debug dump them"),
Chris Lattnerea254db2007-10-11 00:37:43 +0000176 clEnumValN(ASTView, "ast-view",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000177 "Build ASTs and view them with GraphViz"),
Zhongxing Xu2d75d6f2009-01-13 01:29:24 +0000178 clEnumValN(PrintDeclContext, "print-decl-contexts",
Ted Kremenek08478eb2009-04-01 00:23:28 +0000179 "Print DeclContexts and their Decls"),
Anders Carlsson78762eb2009-09-24 18:54:49 +0000180 clEnumValN(DumpRecordLayouts, "dump-record-layouts",
181 "Dump record layout information"),
Douglas Gregorbf1bd6e2009-04-02 23:43:50 +0000182 clEnumValN(GeneratePTH, "emit-pth",
Ted Kremenek08478eb2009-04-01 00:23:28 +0000183 "Generate pre-tokenized header file"),
Douglas Gregor2cf26342009-04-09 22:27:44 +0000184 clEnumValN(GeneratePCH, "emit-pch",
185 "Generate pre-compiled header file"),
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000186 clEnumValN(EmitAssembly, "S",
187 "Emit native assembly code"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000188 clEnumValN(EmitLLVM, "emit-llvm",
Ted Kremenek27b07c52007-09-06 21:26:58 +0000189 "Build ASTs then convert to LLVM, emit .ll file"),
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +0000190 clEnumValN(EmitBC, "emit-llvm-bc",
191 "Build ASTs then convert to LLVM, emit .bc file"),
Daniel Dunbare8e26002009-02-26 22:39:37 +0000192 clEnumValN(EmitLLVMOnly, "emit-llvm-only",
193 "Build ASTs and convert to LLVM, discarding output"),
Chris Lattnerb13c5ee2008-10-12 05:29:20 +0000194 clEnumValN(RewriteTest, "rewrite-test",
195 "Rewriter playground"),
Steve Naroffb29b4272008-04-14 22:03:09 +0000196 clEnumValN(RewriteObjC, "rewrite-objc",
Chris Lattnerb57e3d42008-05-08 06:52:13 +0000197 "Rewrite ObjC into C (code rewriter example)"),
198 clEnumValN(RewriteMacros, "rewrite-macros",
199 "Expand macros without full preprocessing"),
Steve Naroff13188952008-09-18 14:10:13 +0000200 clEnumValN(RewriteBlocks, "rewrite-blocks",
201 "Rewrite Blocks to C"),
Douglas Gregor558cb562009-04-02 01:08:08 +0000202 clEnumValN(FixIt, "fixit",
203 "Apply fix-it advice to the input source"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000204 clEnumValEnd));
205
Ted Kremenekccc76472007-12-19 19:47:59 +0000206
207static llvm::cl::opt<std::string>
208OutputFile("o",
Ted Kremenek50b56412007-12-19 19:50:41 +0000209 llvm::cl::value_desc("path"),
Douglas Gregor370187c2009-04-22 21:45:53 +0000210 llvm::cl::desc("Specify output file"));
Ted Kremenek55af98c2008-04-14 18:40:58 +0000211
Ted Kremenekc2e72992008-12-02 19:57:31 +0000212
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000213enum CodeCompletionPrinter {
214 CCP_Debug,
215 CCP_CIndex
216};
217
Douglas Gregorb657f112009-09-22 21:11:38 +0000218static llvm::cl::opt<ParsedSourceLocation>
219CodeCompletionAt("code-completion-at",
220 llvm::cl::value_desc("file:line:column"),
221 llvm::cl::desc("Dump code-completion information at a location"));
Douglas Gregor81b747b2009-09-17 21:32:03 +0000222
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000223static llvm::cl::opt<CodeCompletionPrinter>
224CodeCompletionPrinter("code-completion-printer",
225 llvm::cl::desc("Choose output type:"),
226 llvm::cl::init(CCP_Debug),
227 llvm::cl::values(
228 clEnumValN(CCP_Debug, "debug",
229 "Debug code-completion results"),
230 clEnumValN(CCP_CIndex, "cindex",
231 "Code-completion results for the CIndex library"),
232 clEnumValEnd));
233
234static llvm::cl::opt<bool>
235CodeCompletionWantsMacros("code-completion-macros",
236 llvm::cl::desc("Include macros in code-completion results"));
237
Douglas Gregor81b747b2009-09-17 21:32:03 +0000238/// \brief Buld a new code-completion consumer that prints the results of
239/// code completion to standard output.
240static CodeCompleteConsumer *BuildPrintingCodeCompleter(Sema &S, void *) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000241 switch (CodeCompletionPrinter.getValue()) {
242 case CCP_Debug:
243 return new PrintingCodeCompleteConsumer(S, CodeCompletionWantsMacros,
244 llvm::outs());
245
246 case CCP_CIndex:
247 return new CIndexCodeCompleteConsumer(S, CodeCompletionWantsMacros,
248 llvm::outs());
249 };
250
251 return 0;
Douglas Gregor81b747b2009-09-17 21:32:03 +0000252}
253
Ted Kremenekc2e72992008-12-02 19:57:31 +0000254//===----------------------------------------------------------------------===//
255// PTH.
256//===----------------------------------------------------------------------===//
257
258static llvm::cl::opt<std::string>
259TokenCache("token-cache", llvm::cl::value_desc("path"),
260 llvm::cl::desc("Use specified token cache file"));
261
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000262//===----------------------------------------------------------------------===//
Ted Kremenek55af98c2008-04-14 18:40:58 +0000263// Diagnostic Options
264//===----------------------------------------------------------------------===//
265
Ted Kremenek41193e42007-09-26 19:42:19 +0000266static llvm::cl::opt<bool>
267VerifyDiagnostics("verify",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000268 llvm::cl::desc("Verify emitted diagnostics and warnings"));
Ted Kremenek41193e42007-09-26 19:42:19 +0000269
Nico Weberfd54ebc2008-08-05 23:33:20 +0000270static llvm::cl::opt<bool>
271NoShowColumn("fno-show-column",
272 llvm::cl::desc("Do not include column number on diagnostics"));
273
274static llvm::cl::opt<bool>
Chris Lattner65f5e642009-01-30 19:01:41 +0000275NoShowLocation("fno-show-source-location",
276 llvm::cl::desc("Do not include source location information with"
277 " diagnostics"));
278
279static llvm::cl::opt<bool>
Nico Weberfd54ebc2008-08-05 23:33:20 +0000280NoCaretDiagnostics("fno-caret-diagnostics",
281 llvm::cl::desc("Do not include source line and caret with"
282 " diagnostics"));
283
Chris Lattner1fbee5d2009-03-13 01:08:23 +0000284static llvm::cl::opt<bool>
Chris Lattneraa5bf2e2009-04-19 07:44:08 +0000285NoDiagnosticsFixIt("fno-diagnostics-fixit-info",
286 llvm::cl::desc("Do not include fixit information in"
287 " diagnostics"));
288
289static llvm::cl::opt<bool>
Chris Lattner182e0922009-04-21 05:34:31 +0000290PrintSourceRangeInfo("fdiagnostics-print-source-range-info",
291 llvm::cl::desc("Print source range spans in numeric form"));
292
Chris Lattnerd51d74a2009-04-16 05:44:38 +0000293static llvm::cl::opt<bool>
294PrintDiagnosticOption("fdiagnostics-show-option",
295 llvm::cl::desc("Print diagnostic name with mappable diagnostics"));
Nico Weberfd54ebc2008-08-05 23:33:20 +0000296
Douglas Gregorfffd93f2009-05-01 21:53:04 +0000297static llvm::cl::opt<unsigned>
298MessageLength("fmessage-length",
Mike Stump1eb44332009-09-09 15:08:12 +0000299 llvm::cl::desc("Format message diagnostics so that they fit "
300 "within N columns or fewer, when possible."),
301 llvm::cl::value_desc("N"));
Douglas Gregorfffd93f2009-05-01 21:53:04 +0000302
Torok Edwin603fca72009-06-04 07:18:23 +0000303static llvm::cl::opt<bool>
Daniel Dunbar838be482009-11-04 06:24:57 +0000304PrintColorDiagnostic("fcolor-diagnostics",
305 llvm::cl::desc("Use colors in diagnostics"));
306
Reid Spencer5f016e22007-07-11 17:01:13 +0000307//===----------------------------------------------------------------------===//
Ted Kremenek7cae2f62008-10-23 23:36:29 +0000308// C++ Visualization.
309//===----------------------------------------------------------------------===//
310
311static llvm::cl::opt<std::string>
312InheritanceViewCls("cxx-inheritance-view",
313 llvm::cl::value_desc("class name"),
Daniel Dunbard77b2512009-01-14 18:56:36 +0000314 llvm::cl::desc("View C++ inheritance for a specified class"));
Ted Kremenek7cae2f62008-10-23 23:36:29 +0000315
316//===----------------------------------------------------------------------===//
Douglas Gregor3573c0c2009-02-14 20:49:29 +0000317// Builtin Options
318//===----------------------------------------------------------------------===//
Chris Lattnerb2509e12009-02-18 01:12:43 +0000319
320static llvm::cl::opt<bool>
321TimeReport("ftime-report",
322 llvm::cl::desc("Print the amount of time each "
323 "phase of compilation takes"));
324
Douglas Gregor3573c0c2009-02-14 20:49:29 +0000325//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +0000326// Language Options
327//===----------------------------------------------------------------------===//
328
Reid Spencer5f016e22007-07-11 17:01:13 +0000329static llvm::cl::opt<LangKind>
330BaseLang("x", llvm::cl::desc("Base language to compile"),
331 llvm::cl::init(langkind_unspecified),
332 llvm::cl::values(clEnumValN(langkind_c, "c", "C"),
Nate Begeman4e3629e2009-06-25 22:43:10 +0000333 clEnumValN(langkind_ocl, "cl", "OpenCL C"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000334 clEnumValN(langkind_cxx, "c++", "C++"),
335 clEnumValN(langkind_objc, "objective-c", "Objective C"),
336 clEnumValN(langkind_objcxx,"objective-c++","Objective C++"),
Daniel Dunbard2ea3862009-01-29 23:50:47 +0000337 clEnumValN(langkind_c_cpp, "cpp-output",
Reid Spencer5f016e22007-07-11 17:01:13 +0000338 "Preprocessed C"),
Chris Lattnera778d7d2008-10-22 17:29:21 +0000339 clEnumValN(langkind_asm_cpp, "assembler-with-cpp",
340 "Preprocessed asm"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000341 clEnumValN(langkind_cxx_cpp, "c++-cpp-output",
Chris Lattnerc76d8072009-02-06 06:19:20 +0000342 "Preprocessed C++"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000343 clEnumValN(langkind_objc_cpp, "objective-c-cpp-output",
344 "Preprocessed Objective C"),
Chris Lattnerc76d8072009-02-06 06:19:20 +0000345 clEnumValN(langkind_objcxx_cpp, "objective-c++-cpp-output",
Reid Spencer5f016e22007-07-11 17:01:13 +0000346 "Preprocessed Objective C++"),
Daniel Dunbar0b5b0da2009-04-01 05:09:09 +0000347 clEnumValN(langkind_c, "c-header",
348 "C header"),
349 clEnumValN(langkind_objc, "objective-c-header",
350 "Objective-C header"),
351 clEnumValN(langkind_cxx, "c++-header",
352 "C++ header"),
353 clEnumValN(langkind_objcxx, "objective-c++-header",
354 "Objective-C++ header"),
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +0000355 clEnumValN(langkind_ast, "ast",
356 "Clang AST"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000357 clEnumValEnd));
358
Daniel Dunbar7c15e712009-10-30 18:12:31 +0000359static llvm::cl::opt<std::string>
360TargetTriple("triple",
361 llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)"));
362
Daniel Dunbar56749082009-11-11 07:26:12 +0000363static llvm::cl::opt<std::string>
364TargetABI("target-abi",
365 llvm::cl::desc("Target a particular ABI type"));
Reid Spencer5f016e22007-07-11 17:01:13 +0000366
367//===----------------------------------------------------------------------===//
Chris Lattnere116ccf2009-04-21 05:40:52 +0000368// SourceManager initialization.
Reid Spencer5f016e22007-07-11 17:01:13 +0000369//===----------------------------------------------------------------------===//
370
Douglas Gregore1d918e2009-04-10 23:10:45 +0000371static bool InitializeSourceManager(Preprocessor &PP,
372 const std::string &InFile) {
373 // Figure out where to get and map in the main file.
374 SourceManager &SourceMgr = PP.getSourceManager();
375 FileManager &FileMgr = PP.getFileManager();
Daniel Dunbar57cbfc02009-04-27 21:19:07 +0000376
377 if (EmptyInputOnly) {
378 const char *EmptyStr = "";
Mike Stump1eb44332009-09-09 15:08:12 +0000379 llvm::MemoryBuffer *SB =
Daniel Dunbar57cbfc02009-04-27 21:19:07 +0000380 llvm::MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, "<empty input>");
381 SourceMgr.createMainFileIDForMemBuffer(SB);
382 } else if (InFile != "-") {
Douglas Gregore1d918e2009-04-10 23:10:45 +0000383 const FileEntry *File = FileMgr.getFile(InFile);
384 if (File) SourceMgr.createMainFileID(File, SourceLocation());
385 if (SourceMgr.getMainFileID().isInvalid()) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +0000386 PP.getDiagnostics().Report(diag::err_fe_error_reading) << InFile.c_str();
Douglas Gregore1d918e2009-04-10 23:10:45 +0000387 return true;
388 }
389 } else {
390 llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
Douglas Gregore1d918e2009-04-10 23:10:45 +0000391 SourceMgr.createMainFileIDForMemBuffer(SB);
392 if (SourceMgr.getMainFileID().isInvalid()) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +0000393 PP.getDiagnostics().Report(diag::err_fe_error_reading_stdin);
Douglas Gregore1d918e2009-04-10 23:10:45 +0000394 return true;
395 }
396 }
397
398 return false;
399}
400
Chris Lattneraa391972008-04-19 23:09:31 +0000401
Chris Lattnere116ccf2009-04-21 05:40:52 +0000402//===----------------------------------------------------------------------===//
403// Preprocessor Initialization
404//===----------------------------------------------------------------------===//
Sam Bishop1102d6b2008-04-14 14:41:57 +0000405
Chris Lattnere6113de2009-11-03 19:50:27 +0000406static llvm::cl::opt<bool>
Mike Stump1eb44332009-09-09 15:08:12 +0000407RelocatablePCH("relocatable-pch",
Douglas Gregore650c8c2009-07-07 00:12:59 +0000408 llvm::cl::desc("Whether to build a relocatable precompiled "
409 "header"));
Reid Spencer5f016e22007-07-11 17:01:13 +0000410
411//===----------------------------------------------------------------------===//
412// Preprocessor include path information.
413//===----------------------------------------------------------------------===//
414
415// This tool exports a large number of command line options to control how the
416// preprocessor searches for header files. At root, however, the Preprocessor
417// object takes a very simple interface: a list of directories to search for
Reid Spencer5f016e22007-07-11 17:01:13 +0000418
419static llvm::cl::opt<bool>
420nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories"));
421
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000422static llvm::cl::opt<bool>
Rafael Espindola8d737cc2009-10-26 13:36:57 +0000423nobuiltininc("nobuiltininc",
424 llvm::cl::desc("Disable builtin #include directories"));
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000425
Reid Spencer5f016e22007-07-11 17:01:13 +0000426// Various command line options. These four add directories to each chain.
427static llvm::cl::list<std::string>
428F_dirs("F", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
429 llvm::cl::desc("Add directory to framework include search path"));
430static llvm::cl::list<std::string>
431I_dirs("I", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
432 llvm::cl::desc("Add directory to include search path"));
433static llvm::cl::list<std::string>
434idirafter_dirs("idirafter", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
435 llvm::cl::desc("Add directory to AFTER include search path"));
436static llvm::cl::list<std::string>
437iquote_dirs("iquote", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
438 llvm::cl::desc("Add directory to QUOTE include search path"));
439static llvm::cl::list<std::string>
440isystem_dirs("isystem", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
441 llvm::cl::desc("Add directory to SYSTEM include search path"));
442
443// These handle -iprefix/-iwithprefix/-iwithprefixbefore.
444static llvm::cl::list<std::string>
445iprefix_vals("iprefix", llvm::cl::value_desc("prefix"), llvm::cl::Prefix,
446 llvm::cl::desc("Set the -iwithprefix/-iwithprefixbefore prefix"));
447static llvm::cl::list<std::string>
448iwithprefix_vals("iwithprefix", llvm::cl::value_desc("dir"), llvm::cl::Prefix,
449 llvm::cl::desc("Set directory to SYSTEM include search path with prefix"));
450static llvm::cl::list<std::string>
451iwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"),
452 llvm::cl::Prefix,
453 llvm::cl::desc("Set directory to include search path with prefix"));
454
Chris Lattner0c946412007-08-26 17:47:35 +0000455static llvm::cl::opt<std::string>
456isysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::init("/"),
457 llvm::cl::desc("Set the system root directory (usually /)"));
458
Reid Spencer5f016e22007-07-11 17:01:13 +0000459// Finally, implement the code that groks the options above.
Chris Lattner5f9eae52008-03-01 08:07:28 +0000460
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000461// Add the clang headers, which are relative to the clang binary.
Daniel Dunbar750156a2009-11-07 04:19:57 +0000462std::string GetBuiltinIncludePath(const char *Argv0) {
463 llvm::sys::Path P =
464 llvm::sys::Path::GetMainExecutable(Argv0,
465 (void*)(intptr_t) GetBuiltinIncludePath);
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000466
Daniel Dunbar750156a2009-11-07 04:19:57 +0000467 if (!P.isEmpty()) {
468 P.eraseComponent(); // Remove /clang from foo/bin/clang
469 P.eraseComponent(); // Remove /bin from foo/bin
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000470
Daniel Dunbar750156a2009-11-07 04:19:57 +0000471 // Get foo/lib/clang/<version>/include
472 P.appendComponent("lib");
473 P.appendComponent("clang");
474 P.appendComponent(CLANG_VERSION_STRING);
475 P.appendComponent("include");
476 }
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000477
Daniel Dunbar750156a2009-11-07 04:19:57 +0000478 return P.str();
Rafael Espindola1bb15a92009-10-05 13:12:17 +0000479}
480
Reid Spencer5f016e22007-07-11 17:01:13 +0000481/// InitializeIncludePaths - Process the -I options and set them in the
482/// HeaderSearch object.
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000483static void InitializeIncludePaths(HeaderSearchOptions &Opts,
484 const char *Argv0,
485 const LangOptions &Lang) {
486 Opts.Sysroot = isysroot;
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000487 Opts.Verbose = Verbose;
Nico Weber0fca0222008-08-22 09:25:22 +0000488
Ted Kremenekf3721112008-05-31 00:27:00 +0000489 // Handle -I... and -F... options, walking the lists in parallel.
490 unsigned Iidx = 0, Fidx = 0;
491 while (Iidx < I_dirs.size() && Fidx < F_dirs.size()) {
492 if (I_dirs.getPosition(Iidx) < F_dirs.getPosition(Fidx)) {
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000493 Opts.AddPath(I_dirs[Iidx], frontend::Angled, false, true, false);
Ted Kremenekf3721112008-05-31 00:27:00 +0000494 ++Iidx;
495 } else {
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000496 Opts.AddPath(F_dirs[Fidx], frontend::Angled, false, true, true);
Ted Kremenekf3721112008-05-31 00:27:00 +0000497 ++Fidx;
498 }
499 }
Mike Stump1eb44332009-09-09 15:08:12 +0000500
Ted Kremenekf3721112008-05-31 00:27:00 +0000501 // Consume what's left from whatever list was longer.
502 for (; Iidx != I_dirs.size(); ++Iidx)
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000503 Opts.AddPath(I_dirs[Iidx], frontend::Angled, false, true, false);
Ted Kremenekf3721112008-05-31 00:27:00 +0000504 for (; Fidx != F_dirs.size(); ++Fidx)
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000505 Opts.AddPath(F_dirs[Fidx], frontend::Angled, false, true, true);
Mike Stump1eb44332009-09-09 15:08:12 +0000506
Reid Spencer5f016e22007-07-11 17:01:13 +0000507 // Handle -idirafter... options.
508 for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i)
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000509 Opts.AddPath(idirafter_dirs[i], frontend::After,
Nico Weber0fca0222008-08-22 09:25:22 +0000510 false, true, false);
Mike Stump1eb44332009-09-09 15:08:12 +0000511
Reid Spencer5f016e22007-07-11 17:01:13 +0000512 // Handle -iquote... options.
513 for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i)
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000514 Opts.AddPath(iquote_dirs[i], frontend::Quoted, false, true, false);
Mike Stump1eb44332009-09-09 15:08:12 +0000515
Reid Spencer5f016e22007-07-11 17:01:13 +0000516 // Handle -isystem... options.
517 for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i)
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000518 Opts.AddPath(isystem_dirs[i], frontend::System, false, true, false);
Reid Spencer5f016e22007-07-11 17:01:13 +0000519
520 // Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in
521 // parallel, processing the values in order of occurance to get the right
522 // prefixes.
523 {
524 std::string Prefix = ""; // FIXME: this isn't the correct default prefix.
525 unsigned iprefix_idx = 0;
526 unsigned iwithprefix_idx = 0;
527 unsigned iwithprefixbefore_idx = 0;
528 bool iprefix_done = iprefix_vals.empty();
529 bool iwithprefix_done = iwithprefix_vals.empty();
530 bool iwithprefixbefore_done = iwithprefixbefore_vals.empty();
531 while (!iprefix_done || !iwithprefix_done || !iwithprefixbefore_done) {
532 if (!iprefix_done &&
Mike Stump1eb44332009-09-09 15:08:12 +0000533 (iwithprefix_done ||
534 iprefix_vals.getPosition(iprefix_idx) <
Reid Spencer5f016e22007-07-11 17:01:13 +0000535 iwithprefix_vals.getPosition(iwithprefix_idx)) &&
Mike Stump1eb44332009-09-09 15:08:12 +0000536 (iwithprefixbefore_done ||
537 iprefix_vals.getPosition(iprefix_idx) <
Reid Spencer5f016e22007-07-11 17:01:13 +0000538 iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
539 Prefix = iprefix_vals[iprefix_idx];
540 ++iprefix_idx;
541 iprefix_done = iprefix_idx == iprefix_vals.size();
542 } else if (!iwithprefix_done &&
Mike Stump1eb44332009-09-09 15:08:12 +0000543 (iwithprefixbefore_done ||
544 iwithprefix_vals.getPosition(iwithprefix_idx) <
Reid Spencer5f016e22007-07-11 17:01:13 +0000545 iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000546 Opts.AddPath(Prefix+iwithprefix_vals[iwithprefix_idx],
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000547 frontend::System, false, false, false);
Reid Spencer5f016e22007-07-11 17:01:13 +0000548 ++iwithprefix_idx;
549 iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size();
550 } else {
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000551 Opts.AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx],
Daniel Dunbar2cdafa82009-11-09 23:02:47 +0000552 frontend::Angled, false, false, false);
Reid Spencer5f016e22007-07-11 17:01:13 +0000553 ++iwithprefixbefore_idx;
Mike Stump1eb44332009-09-09 15:08:12 +0000554 iwithprefixbefore_done =
Reid Spencer5f016e22007-07-11 17:01:13 +0000555 iwithprefixbefore_idx == iwithprefixbefore_vals.size();
556 }
557 }
558 }
Chris Lattner5f9eae52008-03-01 08:07:28 +0000559
Daniel Dunbare1665822009-11-07 04:20:39 +0000560 // Add CPATH environment paths.
561 if (const char *Env = getenv("CPATH"))
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000562 Opts.EnvIncPath = Env;
Daniel Dunbare1665822009-11-07 04:20:39 +0000563
564 // Add language specific environment paths.
565 if (Lang.CPlusPlus && Lang.ObjC1) {
566 if (const char *Env = getenv("OBJCPLUS_INCLUDE_PATH"))
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000567 Opts.LangEnvIncPath = Env;
Daniel Dunbare1665822009-11-07 04:20:39 +0000568 } else if (Lang.CPlusPlus) {
569 if (const char *Env = getenv("CPLUS_INCLUDE_PATH"))
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000570 Opts.LangEnvIncPath = Env;
Daniel Dunbare1665822009-11-07 04:20:39 +0000571 } else if (Lang.ObjC1) {
572 if (const char *Env = getenv("OBJC_INCLUDE_PATH"))
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000573 Opts.LangEnvIncPath = Env;
Daniel Dunbare1665822009-11-07 04:20:39 +0000574 } else {
575 if (const char *Env = getenv("C_INCLUDE_PATH"))
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000576 Opts.LangEnvIncPath = Env;
Daniel Dunbare1665822009-11-07 04:20:39 +0000577 }
Chris Lattner5f9eae52008-03-01 08:07:28 +0000578
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000579 if (!nobuiltininc)
580 Opts.BuiltinIncludePath = GetBuiltinIncludePath(Argv0);
Daniel Dunbar750156a2009-11-07 04:19:57 +0000581
Daniel Dunbardd35ce92009-11-07 04:58:12 +0000582 Opts.UseStandardIncludes = !nostdinc;
Reid Spencer5f016e22007-07-11 17:01:13 +0000583}
584
Ted Kremeneka42cf2e2008-04-17 21:38:34 +0000585//===----------------------------------------------------------------------===//
Daniel Dunbar90b18272009-11-04 23:56:25 +0000586// Preprocessor construction
Ted Kremeneka42cf2e2008-04-17 21:38:34 +0000587//===----------------------------------------------------------------------===//
588
Daniel Dunbar90b18272009-11-04 23:56:25 +0000589static Preprocessor *
Daniel Dunbar5fc7d342009-11-09 23:12:31 +0000590CreatePreprocessor(Diagnostic &Diags, const LangOptions &LangInfo,
591 const PreprocessorOptions &PPOpts, TargetInfo &Target,
592 SourceManager &SourceMgr, HeaderSearch &HeaderInfo) {
Daniel Dunbar90b18272009-11-04 23:56:25 +0000593 PTHManager *PTHMgr = 0;
Daniel Dunbare0a95812009-11-10 22:09:38 +0000594 if (!TokenCache.empty() && !PPOpts.getImplicitPTHInclude().empty()) {
Daniel Dunbar90b18272009-11-04 23:56:25 +0000595 fprintf(stderr, "error: cannot use both -token-cache and -include-pth "
596 "options\n");
597 exit(1);
Ted Kremeneka42cf2e2008-04-17 21:38:34 +0000598 }
Daniel Dunbar90b18272009-11-04 23:56:25 +0000599
600 // Use PTH?
Daniel Dunbare0a95812009-11-10 22:09:38 +0000601 if (!TokenCache.empty() || !PPOpts.getImplicitPTHInclude().empty()) {
602 const std::string& x = TokenCache.empty() ?
603 PPOpts.getImplicitPTHInclude() : TokenCache;
Daniel Dunbar90b18272009-11-04 23:56:25 +0000604 PTHMgr = PTHManager::Create(x, &Diags,
605 TokenCache.empty() ? Diagnostic::Error
606 : Diagnostic::Warning);
607 }
608
609 if (Diags.hasErrorOccurred())
610 exit(1);
611
612 // Create the Preprocessor.
613 Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target,
614 SourceMgr, HeaderInfo, PTHMgr);
615
616 // Note that this is different then passing PTHMgr to Preprocessor's ctor.
617 // That argument is used as the IdentifierInfoLookup argument to
618 // IdentifierTable's ctor.
619 if (PTHMgr) {
620 PTHMgr->setPreprocessor(PP);
621 PP->setPTHManager(PTHMgr);
622 }
623
Daniel Dunbar5fc7d342009-11-09 23:12:31 +0000624 InitializePreprocessor(*PP, PPOpts);
Daniel Dunbar90b18272009-11-04 23:56:25 +0000625
626 return PP;
Ted Kremeneka42cf2e2008-04-17 21:38:34 +0000627}
Reid Spencer5f016e22007-07-11 17:01:13 +0000628
Reid Spencer5f016e22007-07-11 17:01:13 +0000629//===----------------------------------------------------------------------===//
630// Basic Parser driver
631//===----------------------------------------------------------------------===//
632
Chris Lattner51574ea2008-04-19 23:25:44 +0000633static void ParseFile(Preprocessor &PP, MinimalAction *PA) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000634 Parser P(PP, *PA);
Ted Kremenek95041a22007-12-19 22:51:13 +0000635 PP.EnterMainSourceFile();
Mike Stump1eb44332009-09-09 15:08:12 +0000636
Reid Spencer5f016e22007-07-11 17:01:13 +0000637 // Parsing the specified input file.
638 P.ParseTranslationUnit();
639 delete PA;
640}
641
642//===----------------------------------------------------------------------===//
Douglas Gregor26df2f02009-04-02 19:05:20 +0000643// Fix-It Options
644//===----------------------------------------------------------------------===//
645static llvm::cl::list<ParsedSourceLocation>
646FixItAtLocations("fixit-at", llvm::cl::value_desc("source-location"),
647 llvm::cl::desc("Perform Fix-It modifications at the given source location"));
648
649//===----------------------------------------------------------------------===//
Eli Friedmanc6d656e2009-05-18 22:39:16 +0000650// ObjC Rewriter Options
651//===----------------------------------------------------------------------===//
652static llvm::cl::opt<bool>
653SilenceRewriteMacroWarning("Wno-rewrite-macros", llvm::cl::init(false),
654 llvm::cl::desc("Silence ObjC rewriting warnings"));
655
656//===----------------------------------------------------------------------===//
Eli Friedman0eeb86e2009-05-19 01:17:04 +0000657// Warning Options
658//===----------------------------------------------------------------------===//
659
660// This gets all -W options, including -Werror, -W[no-]system-headers, etc. The
661// driver has stripped off -Wa,foo etc. The driver has also translated -W to
662// -Wextra, so we don't need to worry about it.
663static llvm::cl::list<std::string>
664OptWarnings("W", llvm::cl::Prefix, llvm::cl::ValueOptional);
665
666static llvm::cl::opt<bool> OptPedantic("pedantic");
667static llvm::cl::opt<bool> OptPedanticErrors("pedantic-errors");
668static llvm::cl::opt<bool> OptNoWarnings("w");
669
670//===----------------------------------------------------------------------===//
Eli Friedman12d3b1d2009-05-19 03:06:47 +0000671// Preprocessing (-E mode) Options
672//===----------------------------------------------------------------------===//
673static llvm::cl::opt<bool>
674DisableLineMarkers("P", llvm::cl::desc("Disable linemarker output in -E mode"));
675static llvm::cl::opt<bool>
676EnableCommentOutput("C", llvm::cl::desc("Enable comment output in -E mode"));
677static llvm::cl::opt<bool>
678EnableMacroCommentOutput("CC",
679 llvm::cl::desc("Enable comment output in -E mode, "
680 "even from macro expansions"));
681static llvm::cl::opt<bool>
682DumpMacros("dM", llvm::cl::desc("Print macro definitions in -E mode instead of"
683 " normal output"));
684static llvm::cl::opt<bool>
685DumpDefines("dD", llvm::cl::desc("Print macro definitions in -E mode in "
686 "addition to normal output"));
Eli Friedmanb5c8f8b2009-05-19 03:35:57 +0000687
688//===----------------------------------------------------------------------===//
689// Dependency file options
690//===----------------------------------------------------------------------===//
691static llvm::cl::opt<std::string>
692DependencyFile("dependency-file",
693 llvm::cl::desc("Filename (or -) to write dependency output to"));
694
695static llvm::cl::opt<bool>
696DependenciesIncludeSystemHeaders("sys-header-deps",
697 llvm::cl::desc("Include system headers in dependency output"));
698
699static llvm::cl::list<std::string>
700DependencyTargets("MT",
701 llvm::cl::desc("Specify target for dependency"));
702
Eli Friedmanb5c8f8b2009-05-19 03:35:57 +0000703static llvm::cl::opt<bool>
704PhonyDependencyTarget("MP",
705 llvm::cl::desc("Create phony target for each dependency "
706 "(other than main file)"));
707
Eli Friedman12d3b1d2009-05-19 03:06:47 +0000708//===----------------------------------------------------------------------===//
Eli Friedmane71b85f2009-05-19 10:18:02 +0000709// Analysis options
710//===----------------------------------------------------------------------===//
711
712static llvm::cl::list<Analyses>
713AnalysisList(llvm::cl::desc("Source Code Analysis - Checks and Analyses"),
714llvm::cl::values(
715#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
716clEnumValN(NAME, CMDFLAG, DESC),
Eli Friedman0ec78fa2009-05-19 21:10:40 +0000717#include "clang/Frontend/Analyses.def"
Eli Friedmane71b85f2009-05-19 10:18:02 +0000718clEnumValEnd));
719
Mike Stump1eb44332009-09-09 15:08:12 +0000720static llvm::cl::opt<AnalysisStores>
Eli Friedmane71b85f2009-05-19 10:18:02 +0000721AnalysisStoreOpt("analyzer-store",
722 llvm::cl::desc("Source Code Analysis - Abstract Memory Store Models"),
723 llvm::cl::init(BasicStoreModel),
724 llvm::cl::values(
725#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)\
726clEnumValN(NAME##Model, CMDFLAG, DESC),
Eli Friedman0ec78fa2009-05-19 21:10:40 +0000727#include "clang/Frontend/Analyses.def"
Eli Friedmane71b85f2009-05-19 10:18:02 +0000728clEnumValEnd));
729
Mike Stump1eb44332009-09-09 15:08:12 +0000730static llvm::cl::opt<AnalysisConstraints>
Eli Friedmane71b85f2009-05-19 10:18:02 +0000731AnalysisConstraintsOpt("analyzer-constraints",
732 llvm::cl::desc("Source Code Analysis - Symbolic Constraint Engines"),
733 llvm::cl::init(RangeConstraintsModel),
734 llvm::cl::values(
735#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)\
736clEnumValN(NAME##Model, CMDFLAG, DESC),
Eli Friedman0ec78fa2009-05-19 21:10:40 +0000737#include "clang/Frontend/Analyses.def"
Eli Friedmane71b85f2009-05-19 10:18:02 +0000738clEnumValEnd));
739
740static llvm::cl::opt<AnalysisDiagClients>
741AnalysisDiagOpt("analyzer-output",
742 llvm::cl::desc("Source Code Analysis - Output Options"),
743 llvm::cl::init(PD_HTML),
744 llvm::cl::values(
745#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE)\
746clEnumValN(PD_##NAME, CMDFLAG, DESC),
Eli Friedman0ec78fa2009-05-19 21:10:40 +0000747#include "clang/Frontend/Analyses.def"
Eli Friedmane71b85f2009-05-19 10:18:02 +0000748clEnumValEnd));
749
750static llvm::cl::opt<bool>
751VisualizeEGDot("analyzer-viz-egraph-graphviz",
752 llvm::cl::desc("Display exploded graph using GraphViz"));
753
754static llvm::cl::opt<bool>
755VisualizeEGUbi("analyzer-viz-egraph-ubigraph",
756 llvm::cl::desc("Display exploded graph using Ubigraph"));
757
758static llvm::cl::opt<bool>
759AnalyzeAll("analyzer-opt-analyze-headers",
760 llvm::cl::desc("Force the static analyzer to analyze "
761 "functions defined in header files"));
762
763static llvm::cl::opt<bool>
764AnalyzerDisplayProgress("analyzer-display-progress",
765 llvm::cl::desc("Emit verbose output about the analyzer's progress."));
766
767static llvm::cl::opt<bool>
768PurgeDead("analyzer-purge-dead",
769 llvm::cl::init(true),
770 llvm::cl::desc("Remove dead symbols, bindings, and constraints before"
771 " processing a statement."));
772
773static llvm::cl::opt<bool>
774EagerlyAssume("analyzer-eagerly-assume",
775 llvm::cl::init(false),
776 llvm::cl::desc("Eagerly assume the truth/falseness of some "
777 "symbolic constraints."));
778
779static llvm::cl::opt<std::string>
780AnalyzeSpecificFunction("analyze-function",
781 llvm::cl::desc("Run analysis on specific function"));
782
783static llvm::cl::opt<bool>
784TrimGraph("trim-egraph",
785 llvm::cl::desc("Only show error-related paths in the analysis graph"));
786
787static AnalyzerOptions ReadAnalyzerOptions() {
788 AnalyzerOptions Opts;
789 Opts.AnalysisList = AnalysisList;
790 Opts.AnalysisStoreOpt = AnalysisStoreOpt;
791 Opts.AnalysisConstraintsOpt = AnalysisConstraintsOpt;
792 Opts.AnalysisDiagOpt = AnalysisDiagOpt;
793 Opts.VisualizeEGDot = VisualizeEGDot;
794 Opts.VisualizeEGUbi = VisualizeEGUbi;
795 Opts.AnalyzeAll = AnalyzeAll;
796 Opts.AnalyzerDisplayProgress = AnalyzerDisplayProgress;
797 Opts.PurgeDead = PurgeDead;
798 Opts.EagerlyAssume = EagerlyAssume;
799 Opts.AnalyzeSpecificFunction = AnalyzeSpecificFunction;
800 Opts.TrimGraph = TrimGraph;
801 return Opts;
802}
803
804//===----------------------------------------------------------------------===//
Chris Lattner75a97cb2009-04-17 21:05:01 +0000805// -dump-build-information Stuff
806//===----------------------------------------------------------------------===//
807
808static llvm::cl::opt<std::string>
809DumpBuildInformation("dump-build-information",
810 llvm::cl::value_desc("filename"),
811 llvm::cl::desc("output a dump of some build information to a file"));
812
813static llvm::raw_ostream *BuildLogFile = 0;
814
Daniel Dunbar227b2382009-11-09 22:45:57 +0000815static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
Daniel Dunbare29709f2009-11-09 20:55:08 +0000816 unsigned argc, char **argv,
Chris Lattner75a97cb2009-04-17 21:05:01 +0000817 llvm::OwningPtr<DiagnosticClient> &DiagClient) {
Chris Lattner75a97cb2009-04-17 21:05:01 +0000818 std::string ErrorInfo;
Chris Lattner92bcc272009-08-23 02:59:41 +0000819 BuildLogFile = new llvm::raw_fd_ostream(DumpBuildInformation.c_str(),
Dan Gohmanb044c472009-08-25 15:36:09 +0000820 ErrorInfo);
Mike Stump1eb44332009-09-09 15:08:12 +0000821
Chris Lattner75a97cb2009-04-17 21:05:01 +0000822 if (!ErrorInfo.empty()) {
823 llvm::errs() << "error opening -dump-build-information file '"
824 << DumpBuildInformation << "', option ignored!\n";
825 delete BuildLogFile;
826 BuildLogFile = 0;
827 DumpBuildInformation = "";
828 return;
829 }
830
831 (*BuildLogFile) << "clang-cc command line arguments: ";
832 for (unsigned i = 0; i != argc; ++i)
833 (*BuildLogFile) << argv[i] << ' ';
834 (*BuildLogFile) << '\n';
Mike Stump1eb44332009-09-09 15:08:12 +0000835
Daniel Dunbardbf75fe2009-11-11 08:13:24 +0000836 // Chain in a diagnostic client which will log the diagnostics.
837 DiagnosticClient *Logger = new TextDiagnosticPrinter(*BuildLogFile, DiagOpts);
838 DiagClient.reset(new ChainedDiagnosticClient(DiagClient.take(), Logger));
Chris Lattner75a97cb2009-04-17 21:05:01 +0000839}
840
841
842
843//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +0000844// Main driver
845//===----------------------------------------------------------------------===//
846
Daniel Dunbare29709f2009-11-09 20:55:08 +0000847static llvm::raw_ostream *ComputeOutFile(const CompilerInvocation &CompOpts,
848 const std::string &InFile,
Chris Lattner92bcc272009-08-23 02:59:41 +0000849 const char *Extension,
Eli Friedman66d6f042009-05-18 22:20:00 +0000850 bool Binary,
851 llvm::sys::Path& OutPath) {
Chris Lattner92bcc272009-08-23 02:59:41 +0000852 llvm::raw_ostream *Ret;
Eli Friedman66d6f042009-05-18 22:20:00 +0000853 std::string OutFile;
Daniel Dunbare29709f2009-11-09 20:55:08 +0000854 if (!CompOpts.getOutputFile().empty())
855 OutFile = CompOpts.getOutputFile();
Chris Lattner92bcc272009-08-23 02:59:41 +0000856 else if (InFile == "-") {
857 OutFile = "-";
Eli Friedman66d6f042009-05-18 22:20:00 +0000858 } else if (Extension) {
859 llvm::sys::Path Path(InFile);
860 Path.eraseSuffix();
861 Path.appendSuffix(Extension);
Chris Lattnerd57a7ef2009-08-23 22:45:33 +0000862 OutFile = Path.str();
Eli Friedman66d6f042009-05-18 22:20:00 +0000863 } else {
Chris Lattner92bcc272009-08-23 02:59:41 +0000864 OutFile = "-";
Chris Lattner8a5c8092009-02-18 01:20:05 +0000865 }
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +0000866
Chris Lattner92bcc272009-08-23 02:59:41 +0000867 std::string Error;
868 Ret = new llvm::raw_fd_ostream(OutFile.c_str(), Error,
Dan Gohmanb044c472009-08-25 15:36:09 +0000869 (Binary ? llvm::raw_fd_ostream::F_Binary : 0));
Chris Lattner92bcc272009-08-23 02:59:41 +0000870 if (!Error.empty()) {
871 // FIXME: Don't fail this way.
872 llvm::errs() << "ERROR: " << Error << "\n";
873 ::exit(1);
Ted Kremenekdb094a22007-12-05 18:27:04 +0000874 }
Mike Stump1eb44332009-09-09 15:08:12 +0000875
Chris Lattner92bcc272009-08-23 02:59:41 +0000876 if (OutFile != "-")
877 OutPath = OutFile;
Eli Friedman66d6f042009-05-18 22:20:00 +0000878
879 return Ret;
Ted Kremenekdb094a22007-12-05 18:27:04 +0000880}
881
Daniel Dunbare29709f2009-11-09 20:55:08 +0000882static ASTConsumer *CreateConsumerAction(const CompilerInvocation &CompOpts,
883 Preprocessor &PP,
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000884 const std::string &InFile,
885 ProgActions PA,
886 llvm::OwningPtr<llvm::raw_ostream> &OS,
887 llvm::sys::Path &OutPath,
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000888 llvm::LLVMContext& Context) {
Ted Kremenek85888962008-10-21 00:54:44 +0000889 switch (PA) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000890 default:
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000891 return 0;
Eli Friedman66d6f042009-05-18 22:20:00 +0000892
893 case ASTPrint:
Daniel Dunbare29709f2009-11-09 20:55:08 +0000894 OS.reset(ComputeOutFile(CompOpts, InFile, 0, false, OutPath));
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000895 return CreateASTPrinter(OS.get());
Mike Stump1eb44332009-09-09 15:08:12 +0000896
Douglas Gregoree75c052009-05-21 20:55:50 +0000897 case ASTPrintXML:
Daniel Dunbare29709f2009-11-09 20:55:08 +0000898 OS.reset(ComputeOutFile(CompOpts, InFile, "xml", false, OutPath));
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000899 return CreateASTPrinterXML(OS.get());
Douglas Gregoree75c052009-05-21 20:55:50 +0000900
Eli Friedman66d6f042009-05-18 22:20:00 +0000901 case ASTDump:
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000902 return CreateASTDumper();
Eli Friedman66d6f042009-05-18 22:20:00 +0000903
Eli Friedman66d6f042009-05-18 22:20:00 +0000904 case ASTView:
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000905 return CreateASTViewer();
Eli Friedman66d6f042009-05-18 22:20:00 +0000906
Anders Carlsson78762eb2009-09-24 18:54:49 +0000907 case DumpRecordLayouts:
908 return CreateRecordLayoutDumper();
909
Eli Friedman66d6f042009-05-18 22:20:00 +0000910 case InheritanceView:
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000911 return CreateInheritanceViewer(InheritanceViewCls);
Eli Friedman66d6f042009-05-18 22:20:00 +0000912
913 case EmitAssembly:
914 case EmitLLVM:
Mike Stump1eb44332009-09-09 15:08:12 +0000915 case EmitBC:
Eli Friedman66d6f042009-05-18 22:20:00 +0000916 case EmitLLVMOnly: {
917 BackendAction Act;
918 if (ProgAction == EmitAssembly) {
919 Act = Backend_EmitAssembly;
Daniel Dunbare29709f2009-11-09 20:55:08 +0000920 OS.reset(ComputeOutFile(CompOpts, InFile, "s", true, OutPath));
Eli Friedman66d6f042009-05-18 22:20:00 +0000921 } else if (ProgAction == EmitLLVM) {
922 Act = Backend_EmitLL;
Daniel Dunbare29709f2009-11-09 20:55:08 +0000923 OS.reset(ComputeOutFile(CompOpts, InFile, "ll", true, OutPath));
Eli Friedman66d6f042009-05-18 22:20:00 +0000924 } else if (ProgAction == EmitLLVMOnly) {
925 Act = Backend_EmitNothing;
926 } else {
927 Act = Backend_EmitBC;
Daniel Dunbare29709f2009-11-09 20:55:08 +0000928 OS.reset(ComputeOutFile(CompOpts, InFile, "bc", true, OutPath));
Ted Kremenekdb094a22007-12-05 18:27:04 +0000929 }
Ted Kremenekfdfc1982007-12-19 22:24:34 +0000930
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000931 return CreateBackendConsumer(Act, PP.getDiagnostics(), PP.getLangOptions(),
Daniel Dunbar36f4ec32009-11-10 16:19:45 +0000932 CompOpts.getCompileOpts(), InFile, OS.get(),
933 Context);
Eli Friedman66d6f042009-05-18 22:20:00 +0000934 }
935
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000936 case RewriteObjC:
Daniel Dunbare29709f2009-11-09 20:55:08 +0000937 OS.reset(ComputeOutFile(CompOpts, InFile, "cpp", true, OutPath));
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000938 return CreateObjCRewriter(InFile, OS.get(), PP.getDiagnostics(),
939 PP.getLangOptions(), SilenceRewriteMacroWarning);
940
941 case RewriteBlocks:
942 return CreateBlockRewriter(InFile, PP.getDiagnostics(),
943 PP.getLangOptions());
Daniel Dunbar5ee0aa72009-11-11 00:54:56 +0000944
945 case ParseSyntaxOnly:
946 return new ASTConsumer();
947
948 case PrintDeclContext:
949 return CreateDeclContextPrinter();
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000950 }
951}
952
953/// ProcessInputFile - Process a single input file with the specified state.
954///
Daniel Dunbare29709f2009-11-09 20:55:08 +0000955static void ProcessInputFile(const CompilerInvocation &CompOpts,
956 Preprocessor &PP, const std::string &InFile,
Daniel Dunbar90b18272009-11-04 23:56:25 +0000957 ProgActions PA,
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000958 llvm::LLVMContext& Context) {
959 llvm::OwningPtr<llvm::raw_ostream> OS;
960 llvm::OwningPtr<ASTConsumer> Consumer;
961 bool ClearSourceMgr = false;
962 FixItRewriter *FixItRewrite = 0;
963 bool CompleteTranslationUnit = true;
964 llvm::sys::Path OutPath;
965
966 switch (PA) {
967 default:
Daniel Dunbare29709f2009-11-09 20:55:08 +0000968 Consumer.reset(CreateConsumerAction(CompOpts, PP, InFile, PA, OS, OutPath,
Daniel Dunbar26a0cac2009-11-09 22:46:17 +0000969 Context));
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000970
971 if (!Consumer.get()) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +0000972 PP.getDiagnostics().Report(diag::err_fe_invalid_ast_action);
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000973 return;
974 }
975
976 break;;
977
978 case EmitHTML:
Daniel Dunbare29709f2009-11-09 20:55:08 +0000979 OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
Daniel Dunbar90b18272009-11-04 23:56:25 +0000980 Consumer.reset(CreateHTMLPrinter(OS.get(), PP));
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000981 break;
982
983 case RunAnalysis:
Daniel Dunbare29709f2009-11-09 20:55:08 +0000984 Consumer.reset(CreateAnalysisConsumer(PP, CompOpts.getOutputFile(),
Daniel Dunbar0794d8d2009-09-17 00:48:00 +0000985 ReadAnalyzerOptions()));
986 break;
987
Eli Friedman66d6f042009-05-18 22:20:00 +0000988 case GeneratePCH:
Douglas Gregore650c8c2009-07-07 00:12:59 +0000989 if (RelocatablePCH.getValue() && !isysroot.getNumOccurrences()) {
990 PP.Diag(SourceLocation(), diag::err_relocatable_without_without_isysroot);
991 RelocatablePCH.setValue(false);
992 }
Mike Stump1eb44332009-09-09 15:08:12 +0000993
Daniel Dunbare29709f2009-11-09 20:55:08 +0000994 OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
Douglas Gregore650c8c2009-07-07 00:12:59 +0000995 if (RelocatablePCH.getValue())
996 Consumer.reset(CreatePCHGenerator(PP, OS.get(), isysroot.c_str()));
997 else
998 Consumer.reset(CreatePCHGenerator(PP, OS.get()));
Eli Friedman66d6f042009-05-18 22:20:00 +0000999 CompleteTranslationUnit = false;
1000 break;
1001
Chris Lattnerc106c102008-10-12 05:03:36 +00001002 case DumpRawTokens: {
Chris Lattner47099742009-02-18 01:51:21 +00001003 llvm::TimeRegion Timer(ClangFrontendTimer);
Chris Lattnerc106c102008-10-12 05:03:36 +00001004 SourceManager &SM = PP.getSourceManager();
Chris Lattnerc106c102008-10-12 05:03:36 +00001005 // Start lexing the specified input file.
Chris Lattner025c3a62009-01-17 07:35:14 +00001006 Lexer RawLex(SM.getMainFileID(), SM, PP.getLangOptions());
Chris Lattnerc106c102008-10-12 05:03:36 +00001007 RawLex.SetKeepWhitespaceMode(true);
1008
1009 Token RawTok;
Chris Lattnerc106c102008-10-12 05:03:36 +00001010 RawLex.LexFromRawLexer(RawTok);
1011 while (RawTok.isNot(tok::eof)) {
1012 PP.DumpToken(RawTok, true);
1013 fprintf(stderr, "\n");
1014 RawLex.LexFromRawLexer(RawTok);
1015 }
1016 ClearSourceMgr = true;
1017 break;
1018 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001019 case DumpTokens: { // Token dump mode.
Chris Lattner47099742009-02-18 01:51:21 +00001020 llvm::TimeRegion Timer(ClangFrontendTimer);
Chris Lattnerd2177732007-07-20 16:59:19 +00001021 Token Tok;
Chris Lattnerc106c102008-10-12 05:03:36 +00001022 // Start preprocessing the specified input file.
Ted Kremenek95041a22007-12-19 22:51:13 +00001023 PP.EnterMainSourceFile();
Reid Spencer5f016e22007-07-11 17:01:13 +00001024 do {
1025 PP.Lex(Tok);
1026 PP.DumpToken(Tok, true);
1027 fprintf(stderr, "\n");
Chris Lattner057aaf62007-10-09 18:03:42 +00001028 } while (Tok.isNot(tok::eof));
Chris Lattnerbd247762007-07-22 06:05:44 +00001029 ClearSourceMgr = true;
Reid Spencer5f016e22007-07-11 17:01:13 +00001030 break;
1031 }
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001032 case RunPreprocessorOnly:
Reid Spencer5f016e22007-07-11 17:01:13 +00001033 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001034
Douglas Gregorbf1bd6e2009-04-02 23:43:50 +00001035 case GeneratePTH: {
Chris Lattner47099742009-02-18 01:51:21 +00001036 llvm::TimeRegion Timer(ClangFrontendTimer);
Daniel Dunbare29709f2009-11-09 20:55:08 +00001037 if (CompOpts.getOutputFile().empty() || CompOpts.getOutputFile() == "-") {
Eli Friedmanf54fce82009-05-19 01:02:07 +00001038 // FIXME: Don't fail this way.
1039 // FIXME: Verify that we can actually seek in the given file.
Chris Lattner92bcc272009-08-23 02:59:41 +00001040 llvm::errs() << "ERROR: PTH requires an seekable file for output!\n";
Eli Friedmanf54fce82009-05-19 01:02:07 +00001041 ::exit(1);
1042 }
Daniel Dunbare29709f2009-11-09 20:55:08 +00001043 OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
Eli Friedmanf54fce82009-05-19 01:02:07 +00001044 CacheTokens(PP, static_cast<llvm::raw_fd_ostream*>(OS.get()));
Ted Kremenek85888962008-10-21 00:54:44 +00001045 ClearSourceMgr = true;
1046 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001047 }
Douglas Gregor6ab35242009-04-09 21:40:53 +00001048
Chris Lattnercc7dea82009-04-27 22:02:30 +00001049 case PrintPreprocessedInput:
Daniel Dunbare29709f2009-11-09 20:55:08 +00001050 OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
Reid Spencer5f016e22007-07-11 17:01:13 +00001051 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001052
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001053 case ParseNoop:
Reid Spencer5f016e22007-07-11 17:01:13 +00001054 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001055
Chris Lattner47099742009-02-18 01:51:21 +00001056 case ParsePrintCallbacks: {
1057 llvm::TimeRegion Timer(ClangFrontendTimer);
Daniel Dunbare29709f2009-11-09 20:55:08 +00001058 OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
Eli Friedmanf54fce82009-05-19 01:02:07 +00001059 ParseFile(PP, CreatePrintParserActionsAction(PP, OS.get()));
Chris Lattnerbd247762007-07-22 06:05:44 +00001060 ClearSourceMgr = true;
Reid Spencer5f016e22007-07-11 17:01:13 +00001061 break;
Chris Lattner47099742009-02-18 01:51:21 +00001062 }
1063
Chris Lattnerb57e3d42008-05-08 06:52:13 +00001064 case RewriteMacros:
Daniel Dunbare29709f2009-11-09 20:55:08 +00001065 OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
Eli Friedmanf54fce82009-05-19 01:02:07 +00001066 RewriteMacrosInInput(PP, OS.get());
Chris Lattnerb57e3d42008-05-08 06:52:13 +00001067 ClearSourceMgr = true;
1068 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001069
Eli Friedmanf54fce82009-05-19 01:02:07 +00001070 case RewriteTest:
Daniel Dunbare29709f2009-11-09 20:55:08 +00001071 OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
Eli Friedmanf54fce82009-05-19 01:02:07 +00001072 DoRewriteTest(PP, OS.get());
Chris Lattnerb13c5ee2008-10-12 05:29:20 +00001073 ClearSourceMgr = true;
1074 break;
Douglas Gregor558cb562009-04-02 01:08:08 +00001075
1076 case FixIt:
Douglas Gregor558cb562009-04-02 01:08:08 +00001077 Consumer.reset(new ASTConsumer());
Douglas Gregorde4bf6a2009-04-02 17:13:00 +00001078 FixItRewrite = new FixItRewriter(PP.getDiagnostics(),
Chris Lattner2c78b872009-04-14 23:22:57 +00001079 PP.getSourceManager(),
1080 PP.getLangOptions());
Douglas Gregor558cb562009-04-02 01:08:08 +00001081 break;
Chris Lattner47099742009-02-18 01:51:21 +00001082 }
Ted Kremenek46157b52009-01-28 04:29:29 +00001083
Chris Lattner1aee61a2009-04-27 21:25:27 +00001084 if (FixItAtLocations.size() > 0) {
1085 // Even without the "-fixit" flag, with may have some specific
1086 // locations where the user has requested fixes. Process those
1087 // locations now.
1088 if (!FixItRewrite)
1089 FixItRewrite = new FixItRewriter(PP.getDiagnostics(),
1090 PP.getSourceManager(),
1091 PP.getLangOptions());
Chris Lattner9ecd26a2009-03-28 01:37:17 +00001092
Chris Lattner1aee61a2009-04-27 21:25:27 +00001093 bool AddedFixitLocation = false;
Mike Stump1eb44332009-09-09 15:08:12 +00001094 for (unsigned Idx = 0, Last = FixItAtLocations.size();
Chris Lattner1aee61a2009-04-27 21:25:27 +00001095 Idx != Last; ++Idx) {
1096 RequestedSourceLocation Requested;
Argyrios Kyrtzidis34d25d82009-06-23 22:01:39 +00001097 if (ResolveParsedLocation(FixItAtLocations[Idx],
1098 PP.getFileManager(), Requested)) {
Chris Lattner1aee61a2009-04-27 21:25:27 +00001099 fprintf(stderr, "FIX-IT could not find file \"%s\"\n",
1100 FixItAtLocations[Idx].FileName.c_str());
1101 } else {
1102 FixItRewrite->addFixItLocation(Requested);
1103 AddedFixitLocation = true;
Douglas Gregor26df2f02009-04-02 19:05:20 +00001104 }
1105 }
1106
Chris Lattner1aee61a2009-04-27 21:25:27 +00001107 if (!AddedFixitLocation) {
1108 // All of the fix-it locations were bad. Don't fix anything.
1109 delete FixItRewrite;
1110 FixItRewrite = 0;
1111 }
1112 }
1113
1114 llvm::OwningPtr<ASTContext> ContextOwner;
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001115 if (Consumer)
Chris Lattner9ecd26a2009-03-28 01:37:17 +00001116 ContextOwner.reset(new ASTContext(PP.getLangOptions(),
1117 PP.getSourceManager(),
1118 PP.getTargetInfo(),
1119 PP.getIdentifierTable(),
1120 PP.getSelectorTable(),
Chris Lattner1b63e4f2009-06-14 01:54:56 +00001121 PP.getBuiltinInfo(),
Douglas Gregor2deaea32009-04-22 18:49:13 +00001122 /* FreeMemory = */ !DisableFree,
Chris Lattner1b63e4f2009-06-14 01:54:56 +00001123 /* size_reserve = */0));
Mike Stump1eb44332009-09-09 15:08:12 +00001124
Chris Lattnercc7dea82009-04-27 22:02:30 +00001125 llvm::OwningPtr<PCHReader> Reader;
1126 llvm::OwningPtr<ExternalASTSource> Source;
Mike Stump1eb44332009-09-09 15:08:12 +00001127
Daniel Dunbare0a95812009-11-10 22:09:38 +00001128 const std::string &ImplicitPCHInclude =
1129 CompOpts.getPreprocessorOpts().getImplicitPCHInclude();
1130 if (!ImplicitPCHInclude.empty()) {
Douglas Gregore650c8c2009-07-07 00:12:59 +00001131 // If the user specified -isysroot, it will be used for relocatable PCH
1132 // files.
1133 const char *isysrootPCH = 0;
1134 if (isysroot.getNumOccurrences() != 0)
1135 isysrootPCH = isysroot.c_str();
Mike Stump1eb44332009-09-09 15:08:12 +00001136
Douglas Gregore650c8c2009-07-07 00:12:59 +00001137 Reader.reset(new PCHReader(PP, ContextOwner.get(), isysrootPCH));
Mike Stump1eb44332009-09-09 15:08:12 +00001138
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001139 // The user has asked us to include a precompiled header. Load
1140 // the precompiled header into the AST context.
Daniel Dunbare0a95812009-11-10 22:09:38 +00001141 switch (Reader->ReadPCH(ImplicitPCHInclude)) {
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001142 case PCHReader::Success: {
Douglas Gregore721f952009-04-28 18:58:38 +00001143 // Set the predefines buffer as suggested by the PCH
1144 // reader. Typically, the predefines buffer will be empty.
1145 PP.setPredefines(Reader->getSuggestedPredefines());
1146
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001147 // Attach the PCH reader to the AST context as an external AST
1148 // source, so that declarations will be deserialized from the
1149 // PCH file as needed.
Chris Lattnercc7dea82009-04-27 22:02:30 +00001150 if (ContextOwner) {
1151 Source.reset(Reader.take());
Douglas Gregore1d918e2009-04-10 23:10:45 +00001152 ContextOwner->setExternalSource(Source);
Chris Lattnercc7dea82009-04-27 22:02:30 +00001153 }
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001154 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001155 }
1156
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001157 case PCHReader::Failure:
1158 // Unrecoverable failure: don't even try to process the input
1159 // file.
1160 return;
1161
1162 case PCHReader::IgnorePCH:
Douglas Gregor1ab86ac2009-04-28 22:01:16 +00001163 // No suitable PCH file could be found. Return an error.
1164 return;
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001165 }
1166
1167 // Finish preprocessor initialization. We do this now (rather
1168 // than earlier) because this initialization creates new source
1169 // location entries in the source manager, which must come after
1170 // the source location entries for the PCH file.
1171 if (InitializeSourceManager(PP, InFile))
1172 return;
Ted Kremenek46157b52009-01-28 04:29:29 +00001173 }
Daniel Dunbarbea5a842009-10-29 01:53:18 +00001174
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001175 // If we have an ASTConsumer, run the parser with it.
Douglas Gregor81b747b2009-09-17 21:32:03 +00001176 if (Consumer) {
1177 CodeCompleteConsumer *(*CreateCodeCompleter)(Sema &, void *) = 0;
1178 void *CreateCodeCompleterData = 0;
Daniel Dunbarbea5a842009-10-29 01:53:18 +00001179
Douglas Gregorb657f112009-09-22 21:11:38 +00001180 if (!CodeCompletionAt.FileName.empty()) {
1181 // Tell the source manager to chop off the given file at a specific
1182 // line and column.
Daniel Dunbarbea5a842009-10-29 01:53:18 +00001183 if (const FileEntry *Entry
Douglas Gregorb657f112009-09-22 21:11:38 +00001184 = PP.getFileManager().getFile(CodeCompletionAt.FileName)) {
1185 // Truncate the named file at the given line/column.
1186 PP.getSourceManager().truncateFileAt(Entry, CodeCompletionAt.Line,
1187 CodeCompletionAt.Column);
Daniel Dunbarbea5a842009-10-29 01:53:18 +00001188
Douglas Gregorb657f112009-09-22 21:11:38 +00001189 // Set up the creation routine for code-completion.
1190 CreateCodeCompleter = BuildPrintingCodeCompleter;
1191 } else {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +00001192 PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
Douglas Gregorb657f112009-09-22 21:11:38 +00001193 << CodeCompletionAt.FileName;
1194 }
Douglas Gregor81b747b2009-09-17 21:32:03 +00001195 }
1196
Mike Stump1eb44332009-09-09 15:08:12 +00001197 ParseAST(PP, Consumer.get(), *ContextOwner.get(), Stats,
Douglas Gregor81b747b2009-09-17 21:32:03 +00001198 CompleteTranslationUnit,
1199 CreateCodeCompleter, CreateCodeCompleterData);
1200 }
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001201
Daniel Dunbar593c41f2009-11-04 23:41:40 +00001202 // Perform post processing actions and actions which don't use a consumer.
1203 switch (PA) {
1204 default: break;
1205
1206 case RunPreprocessorOnly: { // Just lex as fast as we can, no output.
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001207 llvm::TimeRegion Timer(ClangFrontendTimer);
1208 Token Tok;
1209 // Start parsing the specified input file.
1210 PP.EnterMainSourceFile();
1211 do {
1212 PP.Lex(Tok);
1213 } while (Tok.isNot(tok::eof));
1214 ClearSourceMgr = true;
Daniel Dunbar593c41f2009-11-04 23:41:40 +00001215 break;
1216 }
1217
1218 case ParseNoop: {
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001219 llvm::TimeRegion Timer(ClangFrontendTimer);
1220 ParseFile(PP, new MinimalAction(PP));
1221 ClearSourceMgr = true;
Daniel Dunbar593c41f2009-11-04 23:41:40 +00001222 break;
1223 }
1224
1225 case PrintPreprocessedInput: {
Chris Lattnercc7dea82009-04-27 22:02:30 +00001226 llvm::TimeRegion Timer(ClangFrontendTimer);
Eli Friedman12d3b1d2009-05-19 03:06:47 +00001227 if (DumpMacros)
1228 DoPrintMacros(PP, OS.get());
1229 else
1230 DoPrintPreprocessedInput(PP, OS.get(), EnableCommentOutput,
1231 EnableMacroCommentOutput,
1232 DisableLineMarkers, DumpDefines);
Chris Lattnercc7dea82009-04-27 22:02:30 +00001233 ClearSourceMgr = true;
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001234 }
Mike Stump1eb44332009-09-09 15:08:12 +00001235
Daniel Dunbar593c41f2009-11-04 23:41:40 +00001236 }
1237
Chris Lattner1aee61a2009-04-27 21:25:27 +00001238 if (FixItRewrite)
Daniel Dunbare29709f2009-11-09 20:55:08 +00001239 FixItRewrite->WriteFixedFile(InFile, CompOpts.getOutputFile());
Daniel Dunbar70186ab2009-07-29 02:40:09 +00001240
1241 // Disable the consumer prior to the context, the consumer may perform actions
1242 // in its destructor which require the context.
1243 if (DisableFree)
1244 Consumer.take();
1245 else
1246 Consumer.reset();
Mike Stump1eb44332009-09-09 15:08:12 +00001247
Chris Lattner1aee61a2009-04-27 21:25:27 +00001248 // If in -disable-free mode, don't deallocate ASTContext.
1249 if (DisableFree)
1250 ContextOwner.take();
1251 else
1252 ContextOwner.reset(); // Delete ASTContext
Eli Friedman66d6f042009-05-18 22:20:00 +00001253
Daniel Dunbar879c3ea2008-10-27 22:03:52 +00001254 if (VerifyDiagnostics)
Daniel Dunbar276373d2008-10-27 22:10:13 +00001255 if (CheckDiagnostics(PP))
1256 exit(1);
Chris Lattnere66b65c2008-02-06 01:42:25 +00001257
Reid Spencer5f016e22007-07-11 17:01:13 +00001258 if (Stats) {
Ted Kremenekfdfc1982007-12-19 22:24:34 +00001259 fprintf(stderr, "\nSTATISTICS FOR '%s':\n", InFile.c_str());
Reid Spencer5f016e22007-07-11 17:01:13 +00001260 PP.PrintStats();
1261 PP.getIdentifierTable().PrintStats();
Chris Lattnerdee73592007-12-15 20:48:40 +00001262 PP.getHeaderSearchInfo().PrintStats();
Ted Kremenek1b95a652009-01-09 18:20:21 +00001263 PP.getSourceManager().PrintStats();
Reid Spencer5f016e22007-07-11 17:01:13 +00001264 fprintf(stderr, "\n");
1265 }
Chris Lattnerbd247762007-07-22 06:05:44 +00001266
Mike Stump1eb44332009-09-09 15:08:12 +00001267 // For a multi-file compilation, some things are ok with nuking the source
Chris Lattnerbd247762007-07-22 06:05:44 +00001268 // manager tables, other require stable fileid/macroid's across multiple
1269 // files.
Chris Lattnerdee73592007-12-15 20:48:40 +00001270 if (ClearSourceMgr)
1271 PP.getSourceManager().clearIDTables();
Daniel Dunbard68ba0e2008-11-11 06:35:39 +00001272
Eli Friedman66d6f042009-05-18 22:20:00 +00001273 // Always delete the output stream because we don't want to leak file
1274 // handles. Also, we don't want to try to erase an open file.
1275 OS.reset();
1276
Daniel Dunbar8cb65622009-10-29 21:05:18 +00001277 // If we had errors, try to erase the output file.
1278 if (PP.getDiagnostics().getNumErrors() && !OutPath.isEmpty())
Eli Friedman66d6f042009-05-18 22:20:00 +00001279 OutPath.eraseFromDisk();
Reid Spencer5f016e22007-07-11 17:01:13 +00001280}
1281
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001282/// ProcessInputFile - Process a single AST input file with the specified state.
1283///
Daniel Dunbare29709f2009-11-09 20:55:08 +00001284static void ProcessASTInputFile(const CompilerInvocation &CompOpts,
1285 const std::string &InFile, ProgActions PA,
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001286 Diagnostic &Diags, FileManager &FileMgr,
1287 llvm::LLVMContext& Context) {
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001288 std::string Error;
Steve Naroff36c44642009-10-19 14:34:22 +00001289 llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, &Error));
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001290 if (!AST) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +00001291 Diags.Report(diag::err_fe_invalid_ast_file) << Error;
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001292 return;
1293 }
1294
1295 Preprocessor &PP = AST->getPreprocessor();
1296
1297 llvm::OwningPtr<llvm::raw_ostream> OS;
1298 llvm::sys::Path OutPath;
Daniel Dunbare29709f2009-11-09 20:55:08 +00001299 llvm::OwningPtr<ASTConsumer> Consumer(CreateConsumerAction(CompOpts, PP,
1300 InFile, PA, OS,
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001301 OutPath, Context));
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001302
1303 if (!Consumer.get()) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +00001304 Diags.Report(diag::err_fe_invalid_ast_action);
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001305 return;
1306 }
1307
Daniel Dunbara674bf42009-09-21 03:03:56 +00001308 // Set the main file ID to an empty file.
1309 //
1310 // FIXME: We probably shouldn't need this, but for now this is the simplest
1311 // way to reuse the logic in ParseAST.
1312 const char *EmptyStr = "";
1313 llvm::MemoryBuffer *SB =
1314 llvm::MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, "<dummy input>");
1315 AST->getSourceManager().createMainFileIDForMemBuffer(SB);
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001316
Daniel Dunbara674bf42009-09-21 03:03:56 +00001317 // Stream the input AST to the consumer.
Daniel Dunbarefcbe942009-11-05 02:42:12 +00001318 Diags.getClient()->BeginSourceFile(PP.getLangOptions());
Daniel Dunbara674bf42009-09-21 03:03:56 +00001319 ParseAST(PP, Consumer.get(), AST->getASTContext(), Stats);
Daniel Dunbarefcbe942009-11-05 02:42:12 +00001320 Diags.getClient()->EndSourceFile();
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001321
1322 // Release the consumer and the AST, in that order since the consumer may
1323 // perform actions in its destructor which require the context.
1324 if (DisableFree) {
1325 Consumer.take();
1326 AST.take();
1327 } else {
1328 Consumer.reset();
1329 AST.reset();
1330 }
1331
1332 // Always delete the output stream because we don't want to leak file
1333 // handles. Also, we don't want to try to erase an open file.
1334 OS.reset();
1335
Daniel Dunbar8cb65622009-10-29 21:05:18 +00001336 // If we had errors, try to erase the output file.
1337 if (PP.getDiagnostics().getNumErrors() && !OutPath.isEmpty())
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001338 OutPath.eraseFromDisk();
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001339}
1340
Reid Spencer5f016e22007-07-11 17:01:13 +00001341static llvm::cl::list<std::string>
1342InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>"));
1343
Daniel Dunbar70121eb2009-08-10 03:40:28 +00001344static void LLVMErrorHandler(void *UserData, const std::string &Message) {
1345 Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
1346
Daniel Dunbar0f9fed72009-11-10 23:55:23 +00001347 Diags.Report(diag::err_fe_error_backend) << Message;
Daniel Dunbar70121eb2009-08-10 03:40:28 +00001348
1349 // We cannot recover from llvm errors.
1350 exit(1);
1351}
1352
Daniel Dunbar227b2382009-11-09 22:45:57 +00001353static LangKind GetLanguage() {
1354 // If -x was given, that's the language.
1355 if (BaseLang != langkind_unspecified)
1356 return BaseLang;
Daniel Dunbare29709f2009-11-09 20:55:08 +00001357
Daniel Dunbar227b2382009-11-09 22:45:57 +00001358 // Otherwise guess it from the input filenames;
1359 LangKind LK = langkind_unspecified;
1360 for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
1361 llvm::StringRef Name(InputFilenames[i]);
1362 LangKind ThisKind = llvm::StringSwitch<LangKind>(Name.rsplit('.').second)
1363 .Case("ast", langkind_ast)
1364 .Case("c", langkind_c)
1365 .Cases("S", "s", langkind_asm_cpp)
1366 .Case("i", langkind_c_cpp)
1367 .Case("ii", langkind_cxx_cpp)
1368 .Case("m", langkind_objc)
1369 .Case("mi", langkind_objc_cpp)
1370 .Cases("mm", "M", langkind_objcxx)
1371 .Case("mii", langkind_objcxx_cpp)
1372 .Case("C", langkind_cxx)
1373 .Cases("C", "cc", "cp", langkind_cxx)
1374 .Cases("cpp", "CPP", "c++", "cxx", langkind_cxx)
1375 .Case("cl", langkind_ocl)
1376 .Default(langkind_c);
1377
1378 if (LK != langkind_unspecified && ThisKind != LK) {
1379 llvm::errs() << "error: cannot have multiple input files of distinct "
1380 << "language kinds without -x\n";
1381 exit(1);
1382 }
1383
1384 LK = ThisKind;
1385 }
1386
1387 return LK;
1388}
1389
1390static void ConstructDiagnosticOptions(DiagnosticOptions &Opts) {
Daniel Dunbare29709f2009-11-09 20:55:08 +00001391 // Initialize the diagnostic options.
Daniel Dunbar227b2382009-11-09 22:45:57 +00001392 Opts.ShowColumn = !NoShowColumn;
1393 Opts.ShowLocation = !NoShowLocation;
1394 Opts.ShowCarets = !NoCaretDiagnostics;
1395 Opts.ShowFixits = !NoDiagnosticsFixIt;
1396 Opts.ShowSourceRanges = PrintSourceRangeInfo;
1397 Opts.ShowOptionNames = PrintDiagnosticOption;
1398 Opts.ShowColors = PrintColorDiagnostic;
1399 Opts.MessageLength = MessageLength;
1400}
1401
Daniel Dunbar0498cfc2009-11-10 19:51:53 +00001402static void FinalizeCompileOptions(CompileOptions &Opts,
1403 const LangOptions &Lang) {
1404 if (Lang.NoBuiltin)
1405 Opts.SimplifyLibCalls = 0;
1406 if (Lang.CPlusPlus)
1407 Opts.NoCommon = 1;
1408
1409 // Handle -ftime-report.
1410 Opts.TimePasses = TimeReport;
1411}
1412
Daniel Dunbar227b2382009-11-09 22:45:57 +00001413static void ConstructCompilerInvocation(CompilerInvocation &Opts,
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001414 const char *Argv0,
Daniel Dunbar227b2382009-11-09 22:45:57 +00001415 const DiagnosticOptions &DiagOpts,
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001416 TargetInfo &Target,
1417 LangKind LK) {
Daniel Dunbar227b2382009-11-09 22:45:57 +00001418 Opts.getDiagnosticOpts() = DiagOpts;
1419
1420 Opts.getOutputFile() = OutputFile;
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001421
1422 // Compute the feature set, which may effect the language.
1423 ComputeFeatureMap(Target, Opts.getTargetFeatures());
Daniel Dunbar36f4ec32009-11-10 16:19:45 +00001424
Daniel Dunbarfcb0c3b2009-11-10 18:47:35 +00001425 // Initialize backend options, which may also be used to key some language
1426 // options.
1427 InitializeCompileOptions(Opts.getCompileOpts(), Opts.getTargetFeatures());
1428
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001429 // Initialize language options.
1430 LangOptions LangInfo;
Daniel Dunbar36f4ec32009-11-10 16:19:45 +00001431
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001432 // FIXME: These aren't used during operations on ASTs. Split onto a separate
1433 // code path to make this obvious.
Daniel Dunbar56749082009-11-11 07:26:12 +00001434 if (LK != langkind_ast)
1435 InitializeLangOptions(Opts.getLangOpts(), LK, Target,
1436 Opts.getCompileOpts(), Opts.getTargetFeatures());
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001437
1438 // Initialize the header search options.
1439 InitializeIncludePaths(Opts.getHeaderSearchOpts(), Argv0, Opts.getLangOpts());
Daniel Dunbar5fc7d342009-11-09 23:12:31 +00001440
1441 // Initialize the other preprocessor options.
1442 InitializePreprocessorOptions(Opts.getPreprocessorOpts());
Daniel Dunbar36f4ec32009-11-10 16:19:45 +00001443
Daniel Dunbar0498cfc2009-11-10 19:51:53 +00001444 // Finalize some code generation options.
Daniel Dunbarfcb0c3b2009-11-10 18:47:35 +00001445 FinalizeCompileOptions(Opts.getCompileOpts(), Opts.getLangOpts());
Daniel Dunbare29709f2009-11-09 20:55:08 +00001446}
1447
Reid Spencer5f016e22007-07-11 17:01:13 +00001448int main(int argc, char **argv) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001449 llvm::sys::PrintStackTraceOnErrorSignal();
Chris Lattner09e94a32009-03-04 21:41:39 +00001450 llvm::PrettyStackTraceProgram X(argc, argv);
Owen Andersond7200462009-07-16 00:14:12 +00001451 llvm::LLVMContext &Context = llvm::getGlobalContext();
Daniel Dunbard6970812009-09-02 23:20:15 +00001452
Daniel Dunbar4d861512009-09-03 04:54:12 +00001453 // Initialize targets first, so that --version shows registered targets.
Chris Lattner2fe11942009-06-17 17:25:50 +00001454 llvm::InitializeAllTargets();
1455 llvm::InitializeAllAsmPrinters();
Daniel Dunbard6970812009-09-02 23:20:15 +00001456
1457 llvm::cl::ParseCommandLineOptions(argc, argv,
1458 "LLVM 'Clang' Compiler: http://clang.llvm.org\n");
Mike Stump1eb44332009-09-09 15:08:12 +00001459
Chris Lattner47099742009-02-18 01:51:21 +00001460 if (TimeReport)
1461 ClangFrontendTimer = new llvm::Timer("Clang front-end time");
Mike Stump1eb44332009-09-09 15:08:12 +00001462
Daniel Dunbar08e6dc62009-05-28 16:37:33 +00001463 if (Verbose)
Mike Stump3cbf5a02009-09-15 21:49:22 +00001464 llvm::errs() << "clang-cc version " CLANG_VERSION_STRING
1465 << " based upon " << PACKAGE_STRING
Daniel Dunbar2e30e592009-09-04 17:43:10 +00001466 << " hosted on " << llvm::sys::getHostTriple() << "\n";
Mike Stump1eb44332009-09-09 15:08:12 +00001467
Reid Spencer5f016e22007-07-11 17:01:13 +00001468 // If no input was specified, read from stdin.
1469 if (InputFilenames.empty())
1470 InputFilenames.push_back("-");
Douglas Gregor68a0d782009-05-02 00:03:46 +00001471
Daniel Dunbar227b2382009-11-09 22:45:57 +00001472 // Construct the diagnostic options first, which cannot fail, so that we can
1473 // build a diagnostic client to use for any errors during option handling.
1474 DiagnosticOptions DiagOpts;
1475 ConstructDiagnosticOptions(DiagOpts);
Daniel Dunbareace8742009-11-04 06:24:30 +00001476
Ted Kremenek31e703b2007-12-11 23:28:38 +00001477 // Create the diagnostic client for reporting errors or for
1478 // implementing -verify.
Chris Lattner409d4e72009-04-17 20:40:01 +00001479 llvm::OwningPtr<DiagnosticClient> DiagClient;
1480 if (VerifyDiagnostics) {
1481 // When checking diagnostics, just buffer them up.
1482 DiagClient.reset(new TextDiagnosticBuffer());
1483 if (InputFilenames.size() != 1) {
Daniel Dunbar227b2382009-11-09 22:45:57 +00001484 fprintf(stderr, "-verify only works on single input files.\n");
Chris Lattner409d4e72009-04-17 20:40:01 +00001485 return 1;
1486 }
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001487 } else {
Daniel Dunbar227b2382009-11-09 22:45:57 +00001488 DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), DiagOpts));
Reid Spencer5f016e22007-07-11 17:01:13 +00001489 }
Mike Stump1eb44332009-09-09 15:08:12 +00001490
Daniel Dunbarad451cc2009-11-05 02:11:37 +00001491 if (!DumpBuildInformation.empty())
Daniel Dunbar227b2382009-11-09 22:45:57 +00001492 SetUpBuildDumpLog(DiagOpts, argc, argv, DiagClient);
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001493
Reid Spencer5f016e22007-07-11 17:01:13 +00001494 // Configure our handling of diagnostics.
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001495 Diagnostic Diags(DiagClient.get());
Eli Friedman0eeb86e2009-05-19 01:17:04 +00001496 if (ProcessWarningOptions(Diags, OptWarnings, OptPedantic, OptPedanticErrors,
1497 OptNoWarnings))
Sebastian Redl63a9e0f2009-03-06 17:41:35 +00001498 return 1;
Ted Kremenek31e703b2007-12-11 23:28:38 +00001499
Daniel Dunbar70121eb2009-08-10 03:40:28 +00001500 // Set an error handler, so that any LLVM backend diagnostics go through our
1501 // error handler.
1502 llvm::llvm_install_error_handler(LLVMErrorHandler,
1503 static_cast<void*>(&Diags));
1504
Daniel Dunbar7c15e712009-10-30 18:12:31 +00001505 // Initialize base triple. If a -triple option has been specified, use
1506 // that triple. Otherwise, default to the host triple.
1507 llvm::Triple Triple(TargetTriple);
1508 if (Triple.getTriple().empty())
1509 Triple = llvm::Triple(llvm::sys::getHostTriple());
1510
Chris Lattner11215192008-03-14 06:12:05 +00001511 // Get information about the target being compiled for.
Daniel Dunbarbea5a842009-10-29 01:53:18 +00001512 llvm::OwningPtr<TargetInfo>
Chris Lattner2f60af72009-09-12 22:45:58 +00001513 Target(TargetInfo::CreateTargetInfo(Triple.getTriple()));
Mike Stump1eb44332009-09-09 15:08:12 +00001514
Chris Lattner11215192008-03-14 06:12:05 +00001515 if (Target == 0) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +00001516 Diags.Report(diag::err_fe_unknown_triple) << Triple.getTriple().c_str();
Sebastian Redlc5613db2009-03-07 12:09:25 +00001517 return 1;
Chris Lattner11215192008-03-14 06:12:05 +00001518 }
Mike Stump1eb44332009-09-09 15:08:12 +00001519
Daniel Dunbar73b79592009-09-14 00:02:12 +00001520 // Set the target ABI if specified.
1521 if (!TargetABI.empty()) {
1522 if (!Target->setABI(TargetABI)) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +00001523 Diags.Report(diag::err_fe_unknown_target_abi) << TargetABI;
Daniel Dunbar73b79592009-09-14 00:02:12 +00001524 return 1;
1525 }
1526 }
1527
Daniel Dunbard4270232009-01-20 23:17:32 +00001528 if (!InheritanceViewCls.empty()) // C++ visualization?
Ted Kremenek7cae2f62008-10-23 23:36:29 +00001529 ProgAction = InheritanceView;
Mike Stump1eb44332009-09-09 15:08:12 +00001530
Daniel Dunbar227b2382009-11-09 22:45:57 +00001531 // Infer the input language.
1532 //
1533 // FIXME: We should move .ast inputs to taking a separate path, they are
1534 // really quite different.
1535 LangKind LK = GetLanguage();
1536
1537 // Now that we have initialized the diagnostics engine and the target, finish
1538 // setting up the compiler invocation.
1539 CompilerInvocation CompOpts;
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001540 ConstructCompilerInvocation(CompOpts, argv[0], DiagOpts, *Target, LK);
Daniel Dunbar227b2382009-11-09 22:45:57 +00001541
Daniel Dunbar4cc1a252009-11-05 01:53:23 +00001542 // Create the source manager.
1543 SourceManager SourceMgr;
Mike Stump1eb44332009-09-09 15:08:12 +00001544
Chris Lattner2c78b872009-04-14 23:22:57 +00001545 // Create a file manager object to provide access to and cache the filesystem.
1546 FileManager FileMgr;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001547
Reid Spencer5f016e22007-07-11 17:01:13 +00001548 for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
Ted Kremenek31e703b2007-12-11 23:28:38 +00001549 const std::string &InFile = InputFilenames[i];
Mike Stump1eb44332009-09-09 15:08:12 +00001550
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001551 // AST inputs are handled specially.
1552 if (LK == langkind_ast) {
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001553 ProcessASTInputFile(CompOpts, InFile, ProgAction, Diags, FileMgr,
1554 Context);
Daniel Dunbaraca2ebd2009-09-17 00:48:13 +00001555 continue;
1556 }
1557
Daniel Dunbar4cc1a252009-11-05 01:53:23 +00001558 // Reset the ID tables if we are reusing the SourceManager.
1559 if (i)
1560 SourceMgr.clearIDTables();
Mike Stump1eb44332009-09-09 15:08:12 +00001561
Chris Lattnerf63aea32009-03-04 21:40:56 +00001562 // Process the -I options and set them in the HeaderInfo.
1563 HeaderSearch HeaderInfo(FileMgr);
Mike Stump1eb44332009-09-09 15:08:12 +00001564
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001565 // Apply all the options to the header search object.
1566 ApplyHeaderSearchOptions(CompOpts.getHeaderSearchOpts(), HeaderInfo,
1567 CompOpts.getLangOpts(), Triple);
Mike Stump1eb44332009-09-09 15:08:12 +00001568
Chris Lattnerf63aea32009-03-04 21:40:56 +00001569 // Set up the preprocessor with these options.
Daniel Dunbar5fc7d342009-11-09 23:12:31 +00001570 llvm::OwningPtr<Preprocessor>
1571 PP(CreatePreprocessor(Diags, CompOpts.getLangOpts(),
1572 CompOpts.getPreprocessorOpts(), *Target, SourceMgr,
1573 HeaderInfo));
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001574
Daniel Dunbar8cb65622009-10-29 21:05:18 +00001575 // Handle generating dependencies, if requested.
Eli Friedmanb5c8f8b2009-05-19 03:35:57 +00001576 if (!DependencyFile.empty()) {
Eli Friedmanb5c8f8b2009-05-19 03:35:57 +00001577 if (DependencyTargets.empty()) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +00001578 Diags.Report(diag::err_fe_dependency_file_requires_MT);
Eli Friedmanb5c8f8b2009-05-19 03:35:57 +00001579 continue;
1580 }
1581 std::string ErrStr;
Daniel Dunbar8cb65622009-10-29 21:05:18 +00001582 llvm::raw_ostream *DependencyOS =
Dan Gohmanb044c472009-08-25 15:36:09 +00001583 new llvm::raw_fd_ostream(DependencyFile.c_str(), ErrStr);
Eli Friedmanb5c8f8b2009-05-19 03:35:57 +00001584 if (!ErrStr.empty()) {
Daniel Dunbar0f9fed72009-11-10 23:55:23 +00001585 Diags.Report(diag::err_fe_error_opening) << DependencyFile << ErrStr;
Eli Friedmanb5c8f8b2009-05-19 03:35:57 +00001586 continue;
1587 }
1588
1589 AttachDependencyFileGen(PP.get(), DependencyOS, DependencyTargets,
1590 DependenciesIncludeSystemHeaders,
1591 PhonyDependencyTarget);
1592 }
1593
Daniel Dunbare0a95812009-11-10 22:09:38 +00001594 if (CompOpts.getPreprocessorOpts().getImplicitPCHInclude().empty()) {
Chris Lattner1b63e4f2009-06-14 01:54:56 +00001595 if (InitializeSourceManager(*PP.get(), InFile))
1596 continue;
Mike Stump1eb44332009-09-09 15:08:12 +00001597
Chris Lattner1b63e4f2009-06-14 01:54:56 +00001598 // Initialize builtin info.
1599 PP->getBuiltinInfo().InitializeBuiltins(PP->getIdentifierTable(),
Chris Lattner1b63e4f2009-06-14 01:54:56 +00001600 PP->getLangOptions().NoBuiltin);
1601 }
Douglas Gregor14f79002009-04-10 03:52:48 +00001602
Chris Lattnerf63aea32009-03-04 21:40:56 +00001603 // Process the source file.
Daniel Dunbar26a0cac2009-11-09 22:46:17 +00001604 Diags.getClient()->BeginSourceFile(CompOpts.getLangOpts());
1605 ProcessInputFile(CompOpts, *PP, InFile, ProgAction, Context);
Daniel Dunbar227b2382009-11-09 22:45:57 +00001606 Diags.getClient()->EndSourceFile();
Mike Stump1eb44332009-09-09 15:08:12 +00001607
Chris Lattner40469652009-04-17 20:16:08 +00001608 HeaderInfo.ClearFileInfo();
Reid Spencer5f016e22007-07-11 17:01:13 +00001609 }
Chris Lattner11215192008-03-14 06:12:05 +00001610
Daniel Dunbar9253e492009-11-10 00:46:12 +00001611 if (CompOpts.getDiagnosticOpts().ShowCarets)
Mike Stumpfc0fed32009-04-28 01:19:10 +00001612 if (unsigned NumDiagnostics = Diags.getNumDiagnostics())
1613 fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
1614 (NumDiagnostics == 1 ? "" : "s"));
Mike Stump1eb44332009-09-09 15:08:12 +00001615
Reid Spencer5f016e22007-07-11 17:01:13 +00001616 if (Stats) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001617 FileMgr.PrintStats();
1618 fprintf(stderr, "\n");
1619 }
Chris Lattner75a97cb2009-04-17 21:05:01 +00001620
1621 delete ClangFrontendTimer;
1622 delete BuildLogFile;
Mike Stump1eb44332009-09-09 15:08:12 +00001623
Daniel Dunbar276373d2008-10-27 22:10:13 +00001624 // If verifying diagnostics and we reached here, all is well.
1625 if (VerifyDiagnostics)
1626 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001627
Daniel Dunbar524b86f2008-10-28 00:38:08 +00001628 // Managed static deconstruction. Useful for making things like
1629 // -time-passes usable.
1630 llvm::llvm_shutdown();
1631
Daniel Dunbar8cb65622009-10-29 21:05:18 +00001632 return (Diags.getNumErrors() != 0);
Reid Spencer5f016e22007-07-11 17:01:13 +00001633}