blob: 8bafbd50789812d154ea9d290df6ec5e58ff7c00 [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//===----------------------------------------------------------------------===//
17//
18// TODO: Options to support:
19//
20// -ffatal-errors
21// -ftabstop=width
22//
23//===----------------------------------------------------------------------===//
24
25#include "clang.h"
Chris Lattner97e8b6f2007-10-07 06:04:32 +000026#include "ASTConsumers.h"
Ted Kremenek88f5cde2008-03-27 06:17:42 +000027#include "HTMLDiagnostics.h"
Nico Weberfd54ebc2008-08-05 23:33:20 +000028#include "clang/Driver/TextDiagnosticBuffer.h"
29#include "clang/Driver/TextDiagnosticPrinter.h"
Ted Kremenek88f5cde2008-03-27 06:17:42 +000030#include "clang/Analysis/PathDiagnostic.h"
Ted Kremenek77cda502007-12-18 21:34:28 +000031#include "clang/AST/TranslationUnit.h"
Chris Lattner8ee3c032008-02-06 02:01:47 +000032#include "clang/CodeGen/ModuleBuilder.h"
Chris Lattnere91c1342008-02-06 00:23:21 +000033#include "clang/Sema/ParseAST.h"
Chris Lattner556beb72007-09-15 22:56:56 +000034#include "clang/AST/ASTConsumer.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000035#include "clang/Parse/Parser.h"
36#include "clang/Lex/HeaderSearch.h"
37#include "clang/Basic/FileManager.h"
38#include "clang/Basic/SourceManager.h"
39#include "clang/Basic/TargetInfo.h"
Chris Lattner8f3dab82007-12-15 23:20:07 +000040#include "llvm/ADT/SmallPtrSet.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000041#include "llvm/Support/CommandLine.h"
42#include "llvm/Support/MemoryBuffer.h"
43#include "llvm/System/Signals.h"
Ted Kremenekae360762007-12-03 22:06:55 +000044#include "llvm/Config/config.h"
Ted Kremenekee533642007-12-20 19:47:16 +000045#include "llvm/ADT/OwningPtr.h"
Chris Lattnerdcaa0962008-03-03 03:16:03 +000046#include "llvm/System/Path.h"
Ted Kremenek57134332008-08-07 18:14:04 +000047
Reid Spencer5f016e22007-07-11 17:01:13 +000048using namespace clang;
49
50//===----------------------------------------------------------------------===//
51// Global options.
52//===----------------------------------------------------------------------===//
53
54static llvm::cl::opt<bool>
55Verbose("v", llvm::cl::desc("Enable verbose output"));
56static llvm::cl::opt<bool>
Nate Begemanaabbb122007-12-30 01:38:50 +000057Stats("print-stats",
58 llvm::cl::desc("Print performance metrics and statistics"));
Reid Spencer5f016e22007-07-11 17:01:13 +000059
60enum ProgActions {
Steve Naroffb29b4272008-04-14 22:03:09 +000061 RewriteObjC, // ObjC->C Rewriter.
Chris Lattnerb57e3d42008-05-08 06:52:13 +000062 RewriteMacros, // Expand macros but not #includes.
Ted Kremenek13e479b2008-03-19 07:53:42 +000063 HTMLTest, // HTML displayer testing stuff.
Reid Spencer5f016e22007-07-11 17:01:13 +000064 EmitLLVM, // Emit a .ll file.
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +000065 EmitBC, // Emit a .bc file.
Ted Kremeneka1fa3a12007-12-13 00:37:31 +000066 SerializeAST, // Emit a .ast file.
Ted Kremenek6a340832008-03-18 21:19:49 +000067 EmitHTML, // Translate input source into HTML.
Chris Lattner3b427b32007-10-11 00:18:28 +000068 ASTPrint, // Parse ASTs and print them.
69 ASTDump, // Parse ASTs and dump them.
70 ASTView, // Parse ASTs and view them in Graphviz.
Ted Kremenekbfa82c42007-10-16 23:37:27 +000071 TestSerialization, // Run experimental serialization code.
Reid Spencer5f016e22007-07-11 17:01:13 +000072 ParsePrintCallbacks, // Parse and print each callback.
73 ParseSyntaxOnly, // Parse and perform semantic analysis.
74 ParseNoop, // Parse with noop callbacks.
75 RunPreprocessorOnly, // Just lex, no output.
76 PrintPreprocessedInput, // -E mode.
Ted Kremenekf4381fd2008-07-02 00:03:09 +000077 DumpTokens, // Token dump mode.
78 RunAnalysis // Run one or more source code analyses.
Reid Spencer5f016e22007-07-11 17:01:13 +000079};
80
81static llvm::cl::opt<ProgActions>
82ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
83 llvm::cl::init(ParseSyntaxOnly),
84 llvm::cl::values(
85 clEnumValN(RunPreprocessorOnly, "Eonly",
86 "Just run preprocessor, no output (for timings)"),
87 clEnumValN(PrintPreprocessedInput, "E",
88 "Run preprocessor, emit preprocessed file"),
89 clEnumValN(DumpTokens, "dumptokens",
90 "Run preprocessor, dump internal rep of tokens"),
91 clEnumValN(ParseNoop, "parse-noop",
92 "Run parser with noop callbacks (for timings)"),
93 clEnumValN(ParseSyntaxOnly, "fsyntax-only",
94 "Run parser and perform semantic analysis"),
95 clEnumValN(ParsePrintCallbacks, "parse-print-callbacks",
96 "Run parser and print each callback invoked"),
Ted Kremenek6a340832008-03-18 21:19:49 +000097 clEnumValN(EmitHTML, "emit-html",
98 "Output input source as HTML"),
Chris Lattner3b427b32007-10-11 00:18:28 +000099 clEnumValN(ASTPrint, "ast-print",
100 "Build ASTs and then pretty-print them"),
101 clEnumValN(ASTDump, "ast-dump",
102 "Build ASTs and then debug dump them"),
Chris Lattnerea254db2007-10-11 00:37:43 +0000103 clEnumValN(ASTView, "ast-view",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000104 "Build ASTs and view them with GraphViz"),
Ted Kremenekbfa82c42007-10-16 23:37:27 +0000105 clEnumValN(TestSerialization, "test-pickling",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000106 "Run prototype serialization code"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000107 clEnumValN(EmitLLVM, "emit-llvm",
Ted Kremenek27b07c52007-09-06 21:26:58 +0000108 "Build ASTs then convert to LLVM, emit .ll file"),
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +0000109 clEnumValN(EmitBC, "emit-llvm-bc",
110 "Build ASTs then convert to LLVM, emit .bc file"),
Ted Kremenekccc76472007-12-19 19:47:59 +0000111 clEnumValN(SerializeAST, "serialize",
Ted Kremeneka1fa3a12007-12-13 00:37:31 +0000112 "Build ASTs and emit .ast file"),
Steve Naroffb29b4272008-04-14 22:03:09 +0000113 clEnumValN(RewriteObjC, "rewrite-objc",
Chris Lattnerb57e3d42008-05-08 06:52:13 +0000114 "Rewrite ObjC into C (code rewriter example)"),
115 clEnumValN(RewriteMacros, "rewrite-macros",
116 "Expand macros without full preprocessing"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000117 clEnumValEnd));
118
Ted Kremenekccc76472007-12-19 19:47:59 +0000119
120static llvm::cl::opt<std::string>
121OutputFile("o",
Ted Kremenek50b56412007-12-19 19:50:41 +0000122 llvm::cl::value_desc("path"),
Ted Kremenekccc76472007-12-19 19:47:59 +0000123 llvm::cl::desc("Specify output file (for --serialize, this is a directory)"));
Ted Kremenek55af98c2008-04-14 18:40:58 +0000124
125//===----------------------------------------------------------------------===//
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000126// Code Generator Options
127//===----------------------------------------------------------------------===//
128static llvm::cl::opt<bool>
129GenerateDebugInfo("g",
130 llvm::cl::desc("Generate source level debug information"));
131
132//===----------------------------------------------------------------------===//
Ted Kremenek55af98c2008-04-14 18:40:58 +0000133// Diagnostic Options
134//===----------------------------------------------------------------------===//
135
Ted Kremenek41193e42007-09-26 19:42:19 +0000136static llvm::cl::opt<bool>
137VerifyDiagnostics("verify",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000138 llvm::cl::desc("Verify emitted diagnostics and warnings"));
Ted Kremenek41193e42007-09-26 19:42:19 +0000139
Ted Kremenek88f5cde2008-03-27 06:17:42 +0000140static llvm::cl::opt<std::string>
141HTMLDiag("html-diags",
142 llvm::cl::desc("Generate HTML to report diagnostics"),
143 llvm::cl::value_desc("HTML directory"));
144
Nico Weberfd54ebc2008-08-05 23:33:20 +0000145static llvm::cl::opt<bool>
146NoShowColumn("fno-show-column",
147 llvm::cl::desc("Do not include column number on diagnostics"));
148
149static llvm::cl::opt<bool>
150NoCaretDiagnostics("fno-caret-diagnostics",
151 llvm::cl::desc("Do not include source line and caret with"
152 " diagnostics"));
153
154
Reid Spencer5f016e22007-07-11 17:01:13 +0000155//===----------------------------------------------------------------------===//
Ted Kremenek55af98c2008-04-14 18:40:58 +0000156// Analyzer Options
157//===----------------------------------------------------------------------===//
158
159static llvm::cl::opt<bool>
160VisualizeEG("visualize-egraph",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000161 llvm::cl::desc("Display static analysis Exploded Graph"));
Ted Kremenek55af98c2008-04-14 18:40:58 +0000162
163static llvm::cl::opt<bool>
164AnalyzeAll("checker-opt-analyze-headers",
165 llvm::cl::desc("Force the static analyzer to analyze "
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000166 "functions defined in header files"));
Ted Kremenek55af98c2008-04-14 18:40:58 +0000167
Ted Kremenekf4381fd2008-07-02 00:03:09 +0000168static llvm::cl::list<Analyses>
169AnalysisList(llvm::cl::desc("Available Source Code Analyses:"),
170llvm::cl::values(
Ted Kremenekf7f3c202008-07-15 00:46:02 +0000171#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
Ted Kremenekfb9a48c2008-07-14 23:41:13 +0000172clEnumValN(NAME, CMDFLAG, DESC),
173#include "Analyses.def"
174clEnumValEnd));
Ted Kremenekf4381fd2008-07-02 00:03:09 +0000175
Ted Kremenek55af98c2008-04-14 18:40:58 +0000176//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +0000177// Language Options
178//===----------------------------------------------------------------------===//
179
180enum LangKind {
181 langkind_unspecified,
182 langkind_c,
183 langkind_c_cpp,
184 langkind_cxx,
185 langkind_cxx_cpp,
186 langkind_objc,
187 langkind_objc_cpp,
188 langkind_objcxx,
189 langkind_objcxx_cpp
190};
191
192/* TODO: GCC also accepts:
193 c-header c++-header objective-c-header objective-c++-header
194 assembler assembler-with-cpp
195 ada, f77*, ratfor (!), f95, java, treelang
196 */
197static llvm::cl::opt<LangKind>
198BaseLang("x", llvm::cl::desc("Base language to compile"),
199 llvm::cl::init(langkind_unspecified),
200 llvm::cl::values(clEnumValN(langkind_c, "c", "C"),
201 clEnumValN(langkind_cxx, "c++", "C++"),
202 clEnumValN(langkind_objc, "objective-c", "Objective C"),
203 clEnumValN(langkind_objcxx,"objective-c++","Objective C++"),
204 clEnumValN(langkind_c_cpp, "c-cpp-output",
205 "Preprocessed C"),
206 clEnumValN(langkind_cxx_cpp, "c++-cpp-output",
207 "Preprocessed C++"),
208 clEnumValN(langkind_objc_cpp, "objective-c-cpp-output",
209 "Preprocessed Objective C"),
210 clEnumValN(langkind_objcxx_cpp,"objective-c++-cpp-output",
211 "Preprocessed Objective C++"),
212 clEnumValEnd));
213
214static llvm::cl::opt<bool>
215LangObjC("ObjC", llvm::cl::desc("Set base language to Objective-C"),
216 llvm::cl::Hidden);
217static llvm::cl::opt<bool>
218LangObjCXX("ObjC++", llvm::cl::desc("Set base language to Objective-C++"),
219 llvm::cl::Hidden);
220
Ted Kremenek8904f152007-12-05 23:49:08 +0000221/// InitializeBaseLanguage - Handle the -x foo options.
222static void InitializeBaseLanguage() {
223 if (LangObjC)
224 BaseLang = langkind_objc;
225 else if (LangObjCXX)
226 BaseLang = langkind_objcxx;
227}
228
229static LangKind GetLanguage(const std::string &Filename) {
230 if (BaseLang != langkind_unspecified)
231 return BaseLang;
232
233 std::string::size_type DotPos = Filename.rfind('.');
234
235 if (DotPos == std::string::npos) {
236 BaseLang = langkind_c; // Default to C if no extension.
Chris Lattner9b2f6c42008-01-04 19:12:28 +0000237 return langkind_c;
Reid Spencer5f016e22007-07-11 17:01:13 +0000238 }
239
Ted Kremenek8904f152007-12-05 23:49:08 +0000240 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
241 // C header: .h
242 // C++ header: .hh or .H;
243 // assembler no preprocessing: .s
244 // assembler: .S
245 if (Ext == "c")
246 return langkind_c;
247 else if (Ext == "i")
248 return langkind_c_cpp;
249 else if (Ext == "ii")
250 return langkind_cxx_cpp;
251 else if (Ext == "m")
252 return langkind_objc;
253 else if (Ext == "mi")
254 return langkind_objc_cpp;
255 else if (Ext == "mm" || Ext == "M")
256 return langkind_objcxx;
257 else if (Ext == "mii")
258 return langkind_objcxx_cpp;
259 else if (Ext == "C" || Ext == "cc" || Ext == "cpp" || Ext == "CPP" ||
260 Ext == "c++" || Ext == "cp" || Ext == "cxx")
261 return langkind_cxx;
262 else
263 return langkind_c;
264}
265
266
267static void InitializeLangOptions(LangOptions &Options, LangKind LK) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000268 // FIXME: implement -fpreprocessed mode.
269 bool NoPreprocess = false;
270
Ted Kremenek8904f152007-12-05 23:49:08 +0000271 switch (LK) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000272 default: assert(0 && "Unknown language kind!");
273 case langkind_c_cpp:
274 NoPreprocess = true;
275 // FALLTHROUGH
276 case langkind_c:
277 break;
278 case langkind_cxx_cpp:
279 NoPreprocess = true;
280 // FALLTHROUGH
281 case langkind_cxx:
282 Options.CPlusPlus = 1;
283 break;
284 case langkind_objc_cpp:
285 NoPreprocess = true;
286 // FALLTHROUGH
287 case langkind_objc:
Ted Kremenek01d9dbf2008-04-29 04:37:03 +0000288 Options.ObjC1 = Options.ObjC2 = 1;
Reid Spencer5f016e22007-07-11 17:01:13 +0000289 break;
290 case langkind_objcxx_cpp:
291 NoPreprocess = true;
292 // FALLTHROUGH
293 case langkind_objcxx:
294 Options.ObjC1 = Options.ObjC2 = 1;
295 Options.CPlusPlus = 1;
296 break;
297 }
298}
299
300/// LangStds - Language standards we support.
301enum LangStds {
302 lang_unspecified,
303 lang_c89, lang_c94, lang_c99,
304 lang_gnu89, lang_gnu99,
Chris Lattnerd4b80f12007-07-16 04:18:29 +0000305 lang_cxx98, lang_gnucxx98,
306 lang_cxx0x, lang_gnucxx0x
Reid Spencer5f016e22007-07-11 17:01:13 +0000307};
308
309static llvm::cl::opt<LangStds>
310LangStd("std", llvm::cl::desc("Language standard to compile for"),
311 llvm::cl::init(lang_unspecified),
312 llvm::cl::values(clEnumValN(lang_c89, "c89", "ISO C 1990"),
313 clEnumValN(lang_c89, "c90", "ISO C 1990"),
314 clEnumValN(lang_c89, "iso9899:1990", "ISO C 1990"),
315 clEnumValN(lang_c94, "iso9899:199409",
316 "ISO C 1990 with amendment 1"),
317 clEnumValN(lang_c99, "c99", "ISO C 1999"),
318// clEnumValN(lang_c99, "c9x", "ISO C 1999"),
319 clEnumValN(lang_c99, "iso9899:1999", "ISO C 1999"),
320// clEnumValN(lang_c99, "iso9899:199x", "ISO C 1999"),
321 clEnumValN(lang_gnu89, "gnu89",
322 "ISO C 1990 with GNU extensions (default for C)"),
323 clEnumValN(lang_gnu99, "gnu99",
324 "ISO C 1999 with GNU extensions"),
325 clEnumValN(lang_gnu99, "gnu9x",
326 "ISO C 1999 with GNU extensions"),
327 clEnumValN(lang_cxx98, "c++98",
328 "ISO C++ 1998 with amendments"),
329 clEnumValN(lang_gnucxx98, "gnu++98",
330 "ISO C++ 1998 with amendments and GNU "
331 "extensions (default for C++)"),
Chris Lattnerd4b80f12007-07-16 04:18:29 +0000332 clEnumValN(lang_cxx0x, "c++0x",
333 "Upcoming ISO C++ 200x with amendments"),
334 clEnumValN(lang_gnucxx0x, "gnu++0x",
335 "Upcoming ISO C++ 200x with amendments and GNU "
336 "extensions (default for C++)"),
Reid Spencer5f016e22007-07-11 17:01:13 +0000337 clEnumValEnd));
338
339static llvm::cl::opt<bool>
340NoOperatorNames("fno-operator-names",
341 llvm::cl::desc("Do not treat C++ operator name keywords as "
342 "synonyms for operators"));
343
Anders Carlssonee98ac52007-10-15 02:50:23 +0000344static llvm::cl::opt<bool>
345PascalStrings("fpascal-strings",
346 llvm::cl::desc("Recognize and construct Pascal-style "
347 "string literals"));
Steve Naroffd62701b2008-02-07 03:50:06 +0000348
349static llvm::cl::opt<bool>
350MSExtensions("fms-extensions",
351 llvm::cl::desc("Accept some non-standard constructs used in "
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000352 "Microsoft header files "));
Chris Lattner45e8cbd2007-11-28 05:34:05 +0000353
354static llvm::cl::opt<bool>
355WritableStrings("fwritable-strings",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000356 llvm::cl::desc("Store string literals as writable data"));
Anders Carlsson695dbb62007-11-30 04:21:22 +0000357
358static llvm::cl::opt<bool>
359LaxVectorConversions("flax-vector-conversions",
360 llvm::cl::desc("Allow implicit conversions between vectors"
361 " with a different number of elements or "
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000362 "different element types"));
Ted Kremenek01d9dbf2008-04-29 04:37:03 +0000363
Reid Spencer5f016e22007-07-11 17:01:13 +0000364// FIXME: add:
365// -ansi
366// -trigraphs
367// -fdollars-in-identifiers
Anders Carlssonee98ac52007-10-15 02:50:23 +0000368// -fpascal-strings
Ted Kremenek8904f152007-12-05 23:49:08 +0000369static void InitializeLanguageStandard(LangOptions &Options, LangKind LK) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000370 if (LangStd == lang_unspecified) {
371 // Based on the base language, pick one.
Ted Kremenek8904f152007-12-05 23:49:08 +0000372 switch (LK) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000373 default: assert(0 && "Unknown base language");
374 case langkind_c:
375 case langkind_c_cpp:
376 case langkind_objc:
377 case langkind_objc_cpp:
378 LangStd = lang_gnu99;
379 break;
380 case langkind_cxx:
381 case langkind_cxx_cpp:
382 case langkind_objcxx:
383 case langkind_objcxx_cpp:
384 LangStd = lang_gnucxx98;
385 break;
386 }
387 }
388
389 switch (LangStd) {
390 default: assert(0 && "Unknown language standard!");
391
392 // Fall through from newer standards to older ones. This isn't really right.
393 // FIXME: Enable specifically the right features based on the language stds.
Chris Lattnerd4b80f12007-07-16 04:18:29 +0000394 case lang_gnucxx0x:
395 case lang_cxx0x:
396 Options.CPlusPlus0x = 1;
397 // FALL THROUGH
Reid Spencer5f016e22007-07-11 17:01:13 +0000398 case lang_gnucxx98:
399 case lang_cxx98:
400 Options.CPlusPlus = 1;
401 Options.CXXOperatorNames = !NoOperatorNames;
Nate Begeman8aebcb72007-11-15 07:30:50 +0000402 Options.Boolean = 1;
Reid Spencer5f016e22007-07-11 17:01:13 +0000403 // FALL THROUGH.
404 case lang_gnu99:
405 case lang_c99:
Reid Spencer5f016e22007-07-11 17:01:13 +0000406 Options.C99 = 1;
407 Options.HexFloats = 1;
408 // FALL THROUGH.
409 case lang_gnu89:
410 Options.BCPLComment = 1; // Only for C99/C++.
411 // FALL THROUGH.
412 case lang_c94:
Chris Lattner3426b9b2008-02-25 04:01:39 +0000413 Options.Digraphs = 1; // C94, C99, C++.
414 // FALL THROUGH.
Reid Spencer5f016e22007-07-11 17:01:13 +0000415 case lang_c89:
416 break;
417 }
418
Chris Lattnerd658b562008-04-05 06:32:51 +0000419 if (LangStd == lang_c89 || LangStd == lang_c94 || LangStd == lang_gnu89)
420 Options.ImplicitInt = 1;
421 else
422 Options.ImplicitInt = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000423 Options.Trigraphs = 1; // -trigraphs or -ansi
424 Options.DollarIdents = 1; // FIXME: Really a target property.
Anders Carlssonee98ac52007-10-15 02:50:23 +0000425 Options.PascalStrings = PascalStrings;
Steve Naroffd62701b2008-02-07 03:50:06 +0000426 Options.Microsoft = MSExtensions;
Chris Lattner45e8cbd2007-11-28 05:34:05 +0000427 Options.WritableStrings = WritableStrings;
Anders Carlsson695dbb62007-11-30 04:21:22 +0000428 Options.LaxVectorConversions = LaxVectorConversions;
Reid Spencer5f016e22007-07-11 17:01:13 +0000429}
430
Ted Kremenek01d9dbf2008-04-29 04:37:03 +0000431static llvm::cl::opt<bool>
432ObjCExclusiveGC("fobjc-gc-only",
433 llvm::cl::desc("Use GC exclusively for Objective-C related "
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000434 "memory management"));
Ted Kremenek01d9dbf2008-04-29 04:37:03 +0000435
436static llvm::cl::opt<bool>
437ObjCEnableGC("fobjc-gc",
Nico Weberfd54ebc2008-08-05 23:33:20 +0000438 llvm::cl::desc("Enable Objective-C garbage collection"));
Ted Kremenek01d9dbf2008-04-29 04:37:03 +0000439
440void InitializeGCMode(LangOptions &Options) {
441 if (ObjCExclusiveGC)
442 Options.setGCMode(LangOptions::GCOnly);
443 else if (ObjCEnableGC)
444 Options.setGCMode(LangOptions::HybridGC);
445}
446
447
Reid Spencer5f016e22007-07-11 17:01:13 +0000448//===----------------------------------------------------------------------===//
449// Our DiagnosticClient implementation
450//===----------------------------------------------------------------------===//
451
452// FIXME: Werror should take a list of things, -Werror=foo,bar
453static llvm::cl::opt<bool>
454WarningsAsErrors("Werror", llvm::cl::desc("Treat all warnings as errors"));
455
456static llvm::cl::opt<bool>
Chris Lattner5b4681c2008-05-29 15:36:45 +0000457SilenceWarnings("w", llvm::cl::desc("Do not emit any warnings"));
458
459static llvm::cl::opt<bool>
Reid Spencer5f016e22007-07-11 17:01:13 +0000460WarnOnExtensions("pedantic", llvm::cl::init(false),
461 llvm::cl::desc("Issue a warning on uses of GCC extensions"));
462
463static llvm::cl::opt<bool>
464ErrorOnExtensions("pedantic-errors",
465 llvm::cl::desc("Issue an error on uses of GCC extensions"));
466
467static llvm::cl::opt<bool>
468WarnUnusedMacros("Wunused_macros",
469 llvm::cl::desc("Warn for unused macros in the main translation unit"));
470
Ted Kremenekdb87bca2007-11-13 18:37:02 +0000471static llvm::cl::opt<bool>
472WarnFloatEqual("Wfloat-equal",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000473 llvm::cl::desc("Warn about equality comparisons of floating point values"));
Ted Kremenekdb87bca2007-11-13 18:37:02 +0000474
Ted Kremenek73da5902007-12-17 17:50:07 +0000475static llvm::cl::opt<bool>
476WarnNoFormatNonLiteral("Wno-format-nonliteral",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000477 llvm::cl::desc("Do not warn about non-literal format strings"));
Ted Kremenek73da5902007-12-17 17:50:07 +0000478
Chris Lattner116a4b12008-01-23 17:19:46 +0000479static llvm::cl::opt<bool>
480WarnUndefMacros("Wundef",
481 llvm::cl::desc("Warn on use of undefined macros in #if's"));
482
Chris Lattner37d10842008-05-05 21:18:06 +0000483static llvm::cl::opt<bool>
Ted Kremenek358256d2008-05-30 16:42:02 +0000484WarnImplicitFunctionDeclaration("Wimplicit-function-declaration",
485 llvm::cl::desc("Warn about uses of implicitly defined functions"));
Chris Lattner116a4b12008-01-23 17:19:46 +0000486
Reid Spencer5f016e22007-07-11 17:01:13 +0000487/// InitializeDiagnostics - Initialize the diagnostic object, based on the
488/// current command line option settings.
489static void InitializeDiagnostics(Diagnostic &Diags) {
Chris Lattner5b4681c2008-05-29 15:36:45 +0000490 Diags.setIgnoreAllWarnings(SilenceWarnings);
Reid Spencer5f016e22007-07-11 17:01:13 +0000491 Diags.setWarningsAsErrors(WarningsAsErrors);
492 Diags.setWarnOnExtensions(WarnOnExtensions);
493 Diags.setErrorOnExtensions(ErrorOnExtensions);
494
495 // Silence the "macro is not used" warning unless requested.
496 if (!WarnUnusedMacros)
497 Diags.setDiagnosticMapping(diag::pp_macro_not_used, diag::MAP_IGNORE);
Ted Kremenekdb87bca2007-11-13 18:37:02 +0000498
499 // Silence "floating point comparison" warnings unless requested.
500 if (!WarnFloatEqual)
501 Diags.setDiagnosticMapping(diag::warn_floatingpoint_eq, diag::MAP_IGNORE);
Ted Kremenek73da5902007-12-17 17:50:07 +0000502
503 // Silence "format string is not a string literal" warnings if requested
504 if (WarnNoFormatNonLiteral)
Ted Kremenek7c1d3df2007-12-17 17:50:39 +0000505 Diags.setDiagnosticMapping(diag::warn_printf_not_string_constant,
506 diag::MAP_IGNORE);
Chris Lattner116a4b12008-01-23 17:19:46 +0000507 if (!WarnUndefMacros)
508 Diags.setDiagnosticMapping(diag::warn_pp_undef_identifier,diag::MAP_IGNORE);
Steve Naroffe7a37302008-02-11 22:40:08 +0000509
Chris Lattner37d10842008-05-05 21:18:06 +0000510 if (!WarnImplicitFunctionDeclaration)
511 Diags.setDiagnosticMapping(diag::warn_implicit_function_decl,
512 diag::MAP_IGNORE);
513
Steve Naroffe7a37302008-02-11 22:40:08 +0000514 if (MSExtensions) // MS allows unnamed struct/union fields.
515 Diags.setDiagnosticMapping(diag::w_no_declarators, diag::MAP_IGNORE);
Chris Lattner8aedf192008-05-04 23:52:02 +0000516
517 // If -pedantic-errors is set, turn extensions that warn by default into
518 // errors.
519 if (ErrorOnExtensions) {
520 Diags.setDiagnosticMapping(diag::warn_hex_escape_too_large,
521 diag::MAP_ERROR);
522 Diags.setDiagnosticMapping(diag::warn_octal_escape_too_large,
523 diag::MAP_ERROR);
524 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000525}
526
527//===----------------------------------------------------------------------===//
Ted Kremenekcb330932008-02-18 21:21:23 +0000528// Analysis-specific options.
529//===----------------------------------------------------------------------===//
530
531static llvm::cl::opt<std::string>
532AnalyzeSpecificFunction("analyze-function",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000533 llvm::cl::desc("Run analysis on specific function"));
Ted Kremenekcb330932008-02-18 21:21:23 +0000534
Ted Kremenekffe0f432008-03-07 22:58:01 +0000535static llvm::cl::opt<bool>
Ted Kremenekd71ed262008-04-10 22:16:52 +0000536TrimGraph("trim-egraph",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000537 llvm::cl::desc("Only show error-related paths in the analysis graph"));
Ted Kremenekffe0f432008-03-07 22:58:01 +0000538
Ted Kremenekcb330932008-02-18 21:21:23 +0000539//===----------------------------------------------------------------------===//
Ted Kremenekae360762007-12-03 22:06:55 +0000540// Target Triple Processing.
541//===----------------------------------------------------------------------===//
542
543static llvm::cl::opt<std::string>
544TargetTriple("triple",
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000545 llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)"));
Ted Kremenekae360762007-12-03 22:06:55 +0000546
Chris Lattner42e67372008-03-05 01:18:20 +0000547static llvm::cl::opt<std::string>
Sanjiv Gupta56cf96b2008-05-08 08:28:14 +0000548Arch("arch", llvm::cl::desc("Specify target architecture (e.g. i686)"));
Ted Kremenekae360762007-12-03 22:06:55 +0000549
Chris Lattner6fd9fa12008-03-09 01:35:13 +0000550static std::string CreateTargetTriple() {
Ted Kremenekae360762007-12-03 22:06:55 +0000551 // Initialize base triple. If a -triple option has been specified, use
552 // that triple. Otherwise, default to the host triple.
Chris Lattner6590d212007-12-12 05:01:48 +0000553 std::string Triple = TargetTriple;
554 if (Triple.empty()) Triple = LLVM_HOSTTRIPLE;
Ted Kremenekae360762007-12-03 22:06:55 +0000555
Chris Lattner6fd9fa12008-03-09 01:35:13 +0000556 // If -arch foo was specified, remove the architecture from the triple we have
557 // so far and replace it with the specified one.
558 if (Arch.empty())
559 return Triple;
560
Ted Kremenekae360762007-12-03 22:06:55 +0000561 // Decompose the base triple into "arch" and suffix.
Chris Lattner6fd9fa12008-03-09 01:35:13 +0000562 std::string::size_type FirstDashIdx = Triple.find("-");
Ted Kremenekae360762007-12-03 22:06:55 +0000563
Chris Lattner6fd9fa12008-03-09 01:35:13 +0000564 if (FirstDashIdx == std::string::npos) {
Ted Kremenek9b4ebc22007-12-03 22:11:31 +0000565 fprintf(stderr,
566 "Malformed target triple: \"%s\" ('-' could not be found).\n",
Chris Lattner6590d212007-12-12 05:01:48 +0000567 Triple.c_str());
568 exit(1);
Ted Kremenek9b4ebc22007-12-03 22:11:31 +0000569 }
Ted Kremenekae360762007-12-03 22:06:55 +0000570
Chris Lattner6fd9fa12008-03-09 01:35:13 +0000571 return Arch + std::string(Triple.begin()+FirstDashIdx, Triple.end());
Ted Kremenekae360762007-12-03 22:06:55 +0000572}
573
574//===----------------------------------------------------------------------===//
Reid Spencer5f016e22007-07-11 17:01:13 +0000575// Preprocessor Initialization
576//===----------------------------------------------------------------------===//
577
578// FIXME: Preprocessor builtins to support.
579// -A... - Play with #assertions
580// -undef - Undefine all predefined macros
581
582static llvm::cl::list<std::string>
583D_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix,
584 llvm::cl::desc("Predefine the specified macro"));
585static llvm::cl::list<std::string>
586U_macros("U", llvm::cl::value_desc("macro"), llvm::cl::Prefix,
587 llvm::cl::desc("Undefine the specified macro"));
588
Chris Lattner64299f82008-01-10 01:53:41 +0000589static llvm::cl::list<std::string>
590ImplicitIncludes("include", llvm::cl::value_desc("file"),
591 llvm::cl::desc("Include file before parsing"));
592
593
Reid Spencer5f016e22007-07-11 17:01:13 +0000594// Append a #define line to Buf for Macro. Macro should be of the form XXX,
595// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
596// "#define XXX Y z W". To get a #define with no value, use "XXX=".
597static void DefineBuiltinMacro(std::vector<char> &Buf, const char *Macro,
598 const char *Command = "#define ") {
599 Buf.insert(Buf.end(), Command, Command+strlen(Command));
600 if (const char *Equal = strchr(Macro, '=')) {
601 // Turn the = into ' '.
602 Buf.insert(Buf.end(), Macro, Equal);
603 Buf.push_back(' ');
604 Buf.insert(Buf.end(), Equal+1, Equal+strlen(Equal));
605 } else {
606 // Push "macroname 1".
607 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
608 Buf.push_back(' ');
609 Buf.push_back('1');
610 }
611 Buf.push_back('\n');
612}
613
Chris Lattner64299f82008-01-10 01:53:41 +0000614/// AddImplicitInclude - Add an implicit #include of the specified file to the
615/// predefines buffer.
616static void AddImplicitInclude(std::vector<char> &Buf, const std::string &File){
617 const char *Inc = "#include \"";
618 Buf.insert(Buf.end(), Inc, Inc+strlen(Inc));
619 Buf.insert(Buf.end(), File.begin(), File.end());
620 Buf.push_back('"');
621 Buf.push_back('\n');
622}
623
Reid Spencer5f016e22007-07-11 17:01:13 +0000624
Chris Lattner53b0dab2007-10-09 22:10:18 +0000625/// InitializePreprocessor - Initialize the preprocessor getting it and the
Chris Lattner51574ea2008-04-19 23:25:44 +0000626/// environment ready to process a single file. This returns true on error.
Chris Lattner53b0dab2007-10-09 22:10:18 +0000627///
Chris Lattner51574ea2008-04-19 23:25:44 +0000628static bool InitializePreprocessor(Preprocessor &PP,
629 bool InitializeSourceMgr,
630 const std::string &InFile) {
Chris Lattnerdee73592007-12-15 20:48:40 +0000631 FileManager &FileMgr = PP.getFileManager();
Reid Spencer5f016e22007-07-11 17:01:13 +0000632
Chris Lattner53b0dab2007-10-09 22:10:18 +0000633 // Figure out where to get and map in the main file.
Chris Lattnerdee73592007-12-15 20:48:40 +0000634 SourceManager &SourceMgr = PP.getSourceManager();
Ted Kremenek339b9c22008-04-17 22:31:54 +0000635
636 if (InitializeSourceMgr) {
637 if (InFile != "-") {
638 const FileEntry *File = FileMgr.getFile(InFile);
639 if (File) SourceMgr.createMainFileID(File, SourceLocation());
640 if (SourceMgr.getMainFileID() == 0) {
641 fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
Chris Lattner51574ea2008-04-19 23:25:44 +0000642 return true;
Ted Kremenek339b9c22008-04-17 22:31:54 +0000643 }
644 } else {
645 llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
646 if (SB) SourceMgr.createMainFileIDForMemBuffer(SB);
647 if (SourceMgr.getMainFileID() == 0) {
648 fprintf(stderr, "Error reading standard input! Empty?\n");
Chris Lattner51574ea2008-04-19 23:25:44 +0000649 return true;
Ted Kremenek339b9c22008-04-17 22:31:54 +0000650 }
Chris Lattner53b0dab2007-10-09 22:10:18 +0000651 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000652 }
Sam Bishop1102d6b2008-04-14 14:41:57 +0000653
Chris Lattneraa391972008-04-19 23:09:31 +0000654 std::vector<char> PredefineBuffer;
655
Reid Spencer5f016e22007-07-11 17:01:13 +0000656 // Add macros from the command line.
Sam Bishop1102d6b2008-04-14 14:41:57 +0000657 unsigned d = 0, D = D_macros.size();
658 unsigned u = 0, U = U_macros.size();
659 while (d < D || u < U) {
660 if (u == U || (d < D && D_macros.getPosition(d) < U_macros.getPosition(u)))
661 DefineBuiltinMacro(PredefineBuffer, D_macros[d++].c_str());
662 else
663 DefineBuiltinMacro(PredefineBuffer, U_macros[u++].c_str(), "#undef ");
664 }
665
Chris Lattner64299f82008-01-10 01:53:41 +0000666 // FIXME: Read any files specified by -imacros.
667
668 // Add implicit #includes from -include.
669 for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i)
670 AddImplicitInclude(PredefineBuffer, ImplicitIncludes[i]);
Chris Lattner53b0dab2007-10-09 22:10:18 +0000671
Chris Lattneraa391972008-04-19 23:09:31 +0000672 // Null terminate PredefinedBuffer and add it.
Chris Lattner53b0dab2007-10-09 22:10:18 +0000673 PredefineBuffer.push_back(0);
Chris Lattneraa391972008-04-19 23:09:31 +0000674 PP.setPredefines(&PredefineBuffer[0]);
Chris Lattner53b0dab2007-10-09 22:10:18 +0000675
676 // Once we've read this, we're done.
Chris Lattner51574ea2008-04-19 23:25:44 +0000677 return false;
Reid Spencer5f016e22007-07-11 17:01:13 +0000678}
679
680//===----------------------------------------------------------------------===//
681// Preprocessor include path information.
682//===----------------------------------------------------------------------===//
683
684// This tool exports a large number of command line options to control how the
685// preprocessor searches for header files. At root, however, the Preprocessor
686// object takes a very simple interface: a list of directories to search for
687//
688// FIXME: -nostdinc,-nostdinc++
Chris Lattner0c946412007-08-26 17:47:35 +0000689// FIXME: -imultilib
Reid Spencer5f016e22007-07-11 17:01:13 +0000690//
Chris Lattner64299f82008-01-10 01:53:41 +0000691// FIXME: -imacros
Reid Spencer5f016e22007-07-11 17:01:13 +0000692
693static llvm::cl::opt<bool>
694nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories"));
695
696// Various command line options. These four add directories to each chain.
697static llvm::cl::list<std::string>
698F_dirs("F", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
699 llvm::cl::desc("Add directory to framework include search path"));
700static llvm::cl::list<std::string>
701I_dirs("I", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
702 llvm::cl::desc("Add directory to include search path"));
703static llvm::cl::list<std::string>
704idirafter_dirs("idirafter", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
705 llvm::cl::desc("Add directory to AFTER include search path"));
706static llvm::cl::list<std::string>
707iquote_dirs("iquote", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
708 llvm::cl::desc("Add directory to QUOTE include search path"));
709static llvm::cl::list<std::string>
710isystem_dirs("isystem", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
711 llvm::cl::desc("Add directory to SYSTEM include search path"));
712
713// These handle -iprefix/-iwithprefix/-iwithprefixbefore.
714static llvm::cl::list<std::string>
715iprefix_vals("iprefix", llvm::cl::value_desc("prefix"), llvm::cl::Prefix,
716 llvm::cl::desc("Set the -iwithprefix/-iwithprefixbefore prefix"));
717static llvm::cl::list<std::string>
718iwithprefix_vals("iwithprefix", llvm::cl::value_desc("dir"), llvm::cl::Prefix,
719 llvm::cl::desc("Set directory to SYSTEM include search path with prefix"));
720static llvm::cl::list<std::string>
721iwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"),
722 llvm::cl::Prefix,
723 llvm::cl::desc("Set directory to include search path with prefix"));
724
Chris Lattner0c946412007-08-26 17:47:35 +0000725static llvm::cl::opt<std::string>
726isysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::init("/"),
727 llvm::cl::desc("Set the system root directory (usually /)"));
728
Reid Spencer5f016e22007-07-11 17:01:13 +0000729// Finally, implement the code that groks the options above.
730enum IncludeDirGroup {
731 Quoted = 0,
732 Angled,
733 System,
734 After
735};
736
737static std::vector<DirectoryLookup> IncludeGroup[4];
738
739/// AddPath - Add the specified path to the specified group list.
740///
741static void AddPath(const std::string &Path, IncludeDirGroup Group,
742 bool isCXXAware, bool isUserSupplied,
Chris Lattner822da612007-12-17 06:36:45 +0000743 bool isFramework, HeaderSearch &HS) {
Chris Lattnerb3de9e72007-12-09 00:39:55 +0000744 assert(!Path.empty() && "can't handle empty path here");
Chris Lattner822da612007-12-17 06:36:45 +0000745 FileManager &FM = HS.getFileMgr();
Chris Lattnerb3de9e72007-12-09 00:39:55 +0000746
Chris Lattnerd6655272007-12-17 05:59:27 +0000747 // Compute the actual path, taking into consideration -isysroot.
748 llvm::SmallString<256> MappedPath;
Chris Lattner0c946412007-08-26 17:47:35 +0000749
Chris Lattnerd6655272007-12-17 05:59:27 +0000750 // Handle isysroot.
751 if (Group == System) {
Chris Lattner60e4e2b2007-12-17 06:51:34 +0000752 // FIXME: Portability. This should be a sys::Path interface, this doesn't
753 // handle things like C:\ right, nor win32 \\network\device\blah.
Chris Lattnerd6655272007-12-17 05:59:27 +0000754 if (isysroot.size() != 1 || isysroot[0] != '/') // Add isysroot if present.
755 MappedPath.append(isysroot.begin(), isysroot.end());
Reid Spencer5f016e22007-07-11 17:01:13 +0000756 }
757
Chris Lattnerd6655272007-12-17 05:59:27 +0000758 MappedPath.append(Path.begin(), Path.end());
759
760 // Compute the DirectoryLookup type.
Reid Spencer5f016e22007-07-11 17:01:13 +0000761 DirectoryLookup::DirType Type;
762 if (Group == Quoted || Group == Angled)
763 Type = DirectoryLookup::NormalHeaderDir;
764 else if (isCXXAware)
765 Type = DirectoryLookup::SystemHeaderDir;
766 else
767 Type = DirectoryLookup::ExternCSystemHeaderDir;
768
Chris Lattnerd6655272007-12-17 05:59:27 +0000769
770 // If the directory exists, add it.
771 if (const DirectoryEntry *DE = FM.getDirectory(&MappedPath[0],
772 &MappedPath[0]+
773 MappedPath.size())) {
774 IncludeGroup[Group].push_back(DirectoryLookup(DE, Type, isUserSupplied,
775 isFramework));
776 return;
777 }
778
Chris Lattnerdf772332007-12-17 07:52:39 +0000779 // Check to see if this is an apple-style headermap (which are not allowed to
780 // be frameworks).
781 if (!isFramework) {
782 if (const FileEntry *FE = FM.getFile(&MappedPath[0],
783 &MappedPath[0]+MappedPath.size())) {
Chris Lattner1bfd4a62007-12-17 18:34:53 +0000784 if (const HeaderMap *HM = HS.CreateHeaderMap(FE)) {
785 // It is a headermap, add it to the search path.
Chris Lattnerdf772332007-12-17 07:52:39 +0000786 IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied));
787 return;
788 }
Chris Lattner822da612007-12-17 06:36:45 +0000789 }
790 }
791
Chris Lattnerd6655272007-12-17 05:59:27 +0000792 if (Verbose)
793 fprintf(stderr, "ignoring nonexistent directory \"%s\"\n", Path.c_str());
Reid Spencer5f016e22007-07-11 17:01:13 +0000794}
795
796/// RemoveDuplicates - If there are duplicate directory entries in the specified
797/// search list, remove the later (dead) ones.
798static void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList) {
Chris Lattner8f3dab82007-12-15 23:20:07 +0000799 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
Chris Lattnerdf772332007-12-17 07:52:39 +0000800 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
Chris Lattnerb94c7072007-12-17 06:44:29 +0000801 llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
Reid Spencer5f016e22007-07-11 17:01:13 +0000802 for (unsigned i = 0; i != SearchList.size(); ++i) {
Chris Lattnerb94c7072007-12-17 06:44:29 +0000803 if (SearchList[i].isNormalDir()) {
804 // If this isn't the first time we've seen this dir, remove it.
805 if (SeenDirs.insert(SearchList[i].getDir()))
806 continue;
807
Reid Spencer5f016e22007-07-11 17:01:13 +0000808 if (Verbose)
809 fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
810 SearchList[i].getDir()->getName());
Chris Lattnerdf772332007-12-17 07:52:39 +0000811 } else if (SearchList[i].isFramework()) {
812 // If this isn't the first time we've seen this framework dir, remove it.
813 if (SeenFrameworkDirs.insert(SearchList[i].getFrameworkDir()))
814 continue;
815
816 if (Verbose)
817 fprintf(stderr, "ignoring duplicate framework \"%s\"\n",
818 SearchList[i].getFrameworkDir()->getName());
819
Chris Lattnerb94c7072007-12-17 06:44:29 +0000820 } else {
821 assert(SearchList[i].isHeaderMap() && "Not a headermap or normal dir?");
822 // If this isn't the first time we've seen this headermap, remove it.
823 if (SeenHeaderMaps.insert(SearchList[i].getHeaderMap()))
824 continue;
825
826 if (Verbose)
827 fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
828 SearchList[i].getDir()->getName());
Reid Spencer5f016e22007-07-11 17:01:13 +0000829 }
Chris Lattnerb94c7072007-12-17 06:44:29 +0000830
831 // This is reached if the current entry is a duplicate.
832 SearchList.erase(SearchList.begin()+i);
833 --i;
Reid Spencer5f016e22007-07-11 17:01:13 +0000834 }
835}
836
Chris Lattner5f9eae52008-03-01 08:07:28 +0000837// AddEnvVarPaths - Add a list of paths from an environment variable to a
838// header search list.
839//
840static void AddEnvVarPaths(const char *Name, HeaderSearch &Headers) {
841 const char* at = getenv(Name);
842 if (!at)
843 return;
844
845 const char* delim = strchr(at, llvm::sys::PathSeparator);
846 while (delim != 0) {
847 if (delim-at == 0)
848 AddPath(".", Angled, false, true, false, Headers);
849 else
850 AddPath(std::string(at, std::string::size_type(delim-at)), Angled, false,
851 true, false, Headers);
852 at = delim + 1;
853 delim = strchr(at, llvm::sys::PathSeparator);
854 }
855 if (*at == 0)
856 AddPath(".", Angled, false, true, false, Headers);
857 else
858 AddPath(at, Angled, false, true, false, Headers);
859}
860
Reid Spencer5f016e22007-07-11 17:01:13 +0000861/// InitializeIncludePaths - Process the -I options and set them in the
862/// HeaderSearch object.
Chris Lattnerdcaa0962008-03-03 03:16:03 +0000863static void InitializeIncludePaths(const char *Argv0, HeaderSearch &Headers,
864 FileManager &FM, const LangOptions &Lang) {
Ted Kremenekf3721112008-05-31 00:27:00 +0000865 // Handle -I... and -F... options, walking the lists in parallel.
866 unsigned Iidx = 0, Fidx = 0;
867 while (Iidx < I_dirs.size() && Fidx < F_dirs.size()) {
868 if (I_dirs.getPosition(Iidx) < F_dirs.getPosition(Fidx)) {
869 AddPath(I_dirs[Iidx], Angled, false, true, false, Headers);
870 ++Iidx;
871 } else {
872 AddPath(F_dirs[Fidx], Angled, false, true, true, Headers);
873 ++Fidx;
874 }
875 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000876
Ted Kremenekf3721112008-05-31 00:27:00 +0000877 // Consume what's left from whatever list was longer.
878 for (; Iidx != I_dirs.size(); ++Iidx)
879 AddPath(I_dirs[Iidx], Angled, false, true, false, Headers);
880 for (; Fidx != F_dirs.size(); ++Fidx)
881 AddPath(F_dirs[Fidx], Angled, false, true, true, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +0000882
883 // Handle -idirafter... options.
884 for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i)
Chris Lattner822da612007-12-17 06:36:45 +0000885 AddPath(idirafter_dirs[i], After, false, true, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +0000886
887 // Handle -iquote... options.
888 for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i)
Chris Lattner822da612007-12-17 06:36:45 +0000889 AddPath(iquote_dirs[i], Quoted, false, true, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +0000890
891 // Handle -isystem... options.
892 for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i)
Chris Lattner822da612007-12-17 06:36:45 +0000893 AddPath(isystem_dirs[i], System, false, true, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +0000894
895 // Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in
896 // parallel, processing the values in order of occurance to get the right
897 // prefixes.
898 {
899 std::string Prefix = ""; // FIXME: this isn't the correct default prefix.
900 unsigned iprefix_idx = 0;
901 unsigned iwithprefix_idx = 0;
902 unsigned iwithprefixbefore_idx = 0;
903 bool iprefix_done = iprefix_vals.empty();
904 bool iwithprefix_done = iwithprefix_vals.empty();
905 bool iwithprefixbefore_done = iwithprefixbefore_vals.empty();
906 while (!iprefix_done || !iwithprefix_done || !iwithprefixbefore_done) {
907 if (!iprefix_done &&
908 (iwithprefix_done ||
909 iprefix_vals.getPosition(iprefix_idx) <
910 iwithprefix_vals.getPosition(iwithprefix_idx)) &&
911 (iwithprefixbefore_done ||
912 iprefix_vals.getPosition(iprefix_idx) <
913 iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
914 Prefix = iprefix_vals[iprefix_idx];
915 ++iprefix_idx;
916 iprefix_done = iprefix_idx == iprefix_vals.size();
917 } else if (!iwithprefix_done &&
918 (iwithprefixbefore_done ||
919 iwithprefix_vals.getPosition(iwithprefix_idx) <
920 iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
921 AddPath(Prefix+iwithprefix_vals[iwithprefix_idx],
Chris Lattner822da612007-12-17 06:36:45 +0000922 System, false, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +0000923 ++iwithprefix_idx;
924 iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size();
925 } else {
926 AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx],
Chris Lattner822da612007-12-17 06:36:45 +0000927 Angled, false, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +0000928 ++iwithprefixbefore_idx;
929 iwithprefixbefore_done =
930 iwithprefixbefore_idx == iwithprefixbefore_vals.size();
931 }
932 }
933 }
Chris Lattner5f9eae52008-03-01 08:07:28 +0000934
935 AddEnvVarPaths("CPATH", Headers);
936 if (Lang.CPlusPlus && Lang.ObjC1)
937 AddEnvVarPaths("OBJCPLUS_INCLUDE_PATH", Headers);
938 else if (Lang.CPlusPlus)
939 AddEnvVarPaths("CPLUS_INCLUDE_PATH", Headers);
940 else if (Lang.ObjC1)
941 AddEnvVarPaths("OBJC_INCLUDE_PATH", Headers);
942 else
943 AddEnvVarPaths("C_INCLUDE_PATH", Headers);
944
Chris Lattnerdcaa0962008-03-03 03:16:03 +0000945 // Add the clang headers, which are relative to the clang driver.
946 llvm::sys::Path MainExecutablePath =
Chris Lattner985e1822008-03-03 05:57:43 +0000947 llvm::sys::Path::GetMainExecutable(Argv0,
948 (void*)(intptr_t)InitializeIncludePaths);
Chris Lattnerdcaa0962008-03-03 03:16:03 +0000949 if (!MainExecutablePath.isEmpty()) {
950 MainExecutablePath.eraseComponent(); // Remove /clang from foo/bin/clang
951 MainExecutablePath.eraseComponent(); // Remove /bin from foo/bin
952 MainExecutablePath.appendComponent("Headers"); // Get foo/Headers
953 AddPath(MainExecutablePath.c_str(), System, false, false, false, Headers);
954 }
955
Reid Spencer5f016e22007-07-11 17:01:13 +0000956 // FIXME: temporary hack: hard-coded paths.
957 // FIXME: get these from the target?
958 if (!nostdinc) {
959 if (Lang.CPlusPlus) {
Ted Kremenek1d3cce32008-05-22 15:26:22 +0000960 AddPath("/usr/include/c++/4.2.1", System, true, false, false, Headers);
961 AddPath("/usr/include/c++/4.2.1/i686-apple-darwin10", System, true, false,
962 false, Headers);
963 AddPath("/usr/include/c++/4.2.1/backward", System, true, false, false,
964 Headers);
965
Chris Lattner822da612007-12-17 06:36:45 +0000966 AddPath("/usr/include/c++/4.0.0", System, true, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +0000967 AddPath("/usr/include/c++/4.0.0/i686-apple-darwin8", System, true, false,
Chris Lattner822da612007-12-17 06:36:45 +0000968 false, Headers);
969 AddPath("/usr/include/c++/4.0.0/backward", System, true, false, false,
970 Headers);
Lauro Ramos Venancioa6743492008-02-15 22:36:38 +0000971
972 // Ubuntu 7.10 - Gutsy Gibbon
973 AddPath("/usr/include/c++/4.1.3", System, true, false, false, Headers);
974 AddPath("/usr/include/c++/4.1.3/i486-linux-gnu", System, true, false,
975 false, Headers);
976 AddPath("/usr/include/c++/4.1.3/backward", System, true, false, false,
977 Headers);
Chris Lattner04421082008-04-08 04:40:51 +0000978
979 // Fedora 8
980 AddPath("/usr/include/c++/4.1.2", System, true, false, false, Headers);
Chris Lattner8ac661c2008-04-16 05:21:09 +0000981 AddPath("/usr/include/c++/4.1.2/i386-redhat-linux", System, true, false,
982 false, Headers);
983 AddPath("/usr/include/c++/4.1.2/backward", System, true, false, false,
984 Headers);
Ted Kremenekd88fb6c2008-06-24 03:33:47 +0000985
Ted Kremenek16833602008-07-24 03:49:15 +0000986 // Fedora 9
987 AddPath("/usr/include/c++/4.3.0", System, true, false, false, Headers);
988 AddPath("/usr/include/c++/4.3.0/i386-redhat-linux", System, true, false,
989 false, Headers);
990 AddPath("/usr/include/c++/4.3.0/backward", System, true, false, false,
991 Headers);
992
Ted Kremenekd88fb6c2008-06-24 03:33:47 +0000993 // Arch Linux 2008-06-24
994 AddPath("/usr/include/c++/4.3.1", System, true, false, false, Headers);
995 AddPath("/usr/include/c++/4.3.1/i686-pc-linux-gnu", System, true, false,
996 false, Headers);
997 AddPath("/usr/include/c++/4.3.1/backward", System, true, false, false,
998 Headers);
999 AddPath("/usr/include/c++/4.3.1/x86_64-unknown-linux-gnu", System, true,
1000 false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +00001001 }
1002
Chris Lattner822da612007-12-17 06:36:45 +00001003 AddPath("/usr/local/include", System, false, false, false, Headers);
Ted Kremenek1d3cce32008-05-22 15:26:22 +00001004
1005 AddPath("/usr/lib/gcc/i686-apple-darwin10/4.2.1/include", System,
1006 false, false, false, Headers);
1007 AddPath("/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/include",
1008 System, false, false, false, Headers);
1009
Reid Spencer5f016e22007-07-11 17:01:13 +00001010 // leopard
1011 AddPath("/usr/lib/gcc/i686-apple-darwin9/4.0.1/include", System,
Chris Lattner822da612007-12-17 06:36:45 +00001012 false, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +00001013 AddPath("/usr/lib/gcc/powerpc-apple-darwin9/4.0.1/include",
Chris Lattner822da612007-12-17 06:36:45 +00001014 System, false, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +00001015 AddPath("/usr/lib/gcc/powerpc-apple-darwin9/"
1016 "4.0.1/../../../../powerpc-apple-darwin0/include",
Chris Lattner822da612007-12-17 06:36:45 +00001017 System, false, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +00001018
1019 // tiger
1020 AddPath("/usr/lib/gcc/i686-apple-darwin8/4.0.1/include", System,
Chris Lattner822da612007-12-17 06:36:45 +00001021 false, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +00001022 AddPath("/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/include",
Chris Lattner822da612007-12-17 06:36:45 +00001023 System, false, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +00001024 AddPath("/usr/lib/gcc/powerpc-apple-darwin8/"
1025 "4.0.1/../../../../powerpc-apple-darwin8/include",
Chris Lattner822da612007-12-17 06:36:45 +00001026 System, false, false, false, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +00001027
Lauro Ramos Venancio397cbf22008-01-21 23:08:35 +00001028 // Ubuntu 7.10 - Gutsy Gibbon
1029 AddPath("/usr/lib/gcc/i486-linux-gnu/4.1.3/include", System,
Chris Lattnerc81c8142008-02-25 21:04:36 +00001030 false, false, false, Headers);
Lauro Ramos Venancio397cbf22008-01-21 23:08:35 +00001031
Chris Lattner04421082008-04-08 04:40:51 +00001032 // Fedora 8
1033 AddPath("/usr/lib/gcc/i386-redhat-linux/4.1.2/include", System,
1034 false, false, false, Headers);
1035
Ted Kremenek16833602008-07-24 03:49:15 +00001036 // Fedora 9
1037 AddPath("/usr/lib/gcc/i386-redhat-linux/4.3.0/include", System,
1038 false, false, false, Headers);
1039
Andrew Lenharth92d56b72008-03-24 21:25:48 +00001040 //Debian testing/lenny x86
1041 AddPath("/usr/lib/gcc/i486-linux-gnu/4.2.3/include", System,
1042 false, false, false, Headers);
Andrew Lenharthf24964c2008-03-24 21:39:05 +00001043
1044 //Debian testing/lenny amd64
1045 AddPath("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include", System,
1046 false, false, false, Headers);
Andrew Lenharth92d56b72008-03-24 21:25:48 +00001047
Ted Kremenekd88fb6c2008-06-24 03:33:47 +00001048 // Arch Linux 2008-06-24
1049 AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.3.1/include", System,
1050 false, false, false, Headers);
1051 AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.3.1/include-fixed", System,
1052 false, false, false, Headers);
1053 AddPath("/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/include", System,
1054 false, false, false, Headers);
1055 AddPath("/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/include-fixed",
1056 System, false, false, false, Headers);
1057
Matthijs Kooijmane9484fc2008-06-26 08:39:30 +00001058 // Debian testing/lenny ppc32
1059 AddPath("/usr/lib/gcc/powerpc-linux-gnu/4.2.3/include", System,
1060 false, false, false, Headers);
1061
Nuno Lopes68bf3872008-07-05 17:15:18 +00001062 // Gentoo x86 stable
1063 AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include", System,
1064 false, false, false, Headers);
1065
Chris Lattner822da612007-12-17 06:36:45 +00001066 AddPath("/usr/include", System, false, false, false, Headers);
1067 AddPath("/System/Library/Frameworks", System, true, false, true, Headers);
1068 AddPath("/Library/Frameworks", System, true, false, true, Headers);
Reid Spencer5f016e22007-07-11 17:01:13 +00001069 }
1070
1071 // Now that we have collected all of the include paths, merge them all
1072 // together and tell the preprocessor about them.
1073
1074 // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
1075 std::vector<DirectoryLookup> SearchList;
1076 SearchList = IncludeGroup[Angled];
1077 SearchList.insert(SearchList.end(), IncludeGroup[System].begin(),
1078 IncludeGroup[System].end());
1079 SearchList.insert(SearchList.end(), IncludeGroup[After].begin(),
1080 IncludeGroup[After].end());
1081 RemoveDuplicates(SearchList);
1082 RemoveDuplicates(IncludeGroup[Quoted]);
1083
1084 // Prepend QUOTED list on the search list.
1085 SearchList.insert(SearchList.begin(), IncludeGroup[Quoted].begin(),
1086 IncludeGroup[Quoted].end());
1087
1088
1089 bool DontSearchCurDir = false; // TODO: set to true if -I- is set?
1090 Headers.SetSearchPaths(SearchList, IncludeGroup[Quoted].size(),
1091 DontSearchCurDir);
1092
1093 // If verbose, print the list of directories that will be searched.
1094 if (Verbose) {
1095 fprintf(stderr, "#include \"...\" search starts here:\n");
1096 unsigned QuotedIdx = IncludeGroup[Quoted].size();
1097 for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
1098 if (i == QuotedIdx)
1099 fprintf(stderr, "#include <...> search starts here:\n");
Chris Lattner3af66a92007-12-17 17:57:27 +00001100 const char *Name = SearchList[i].getName();
1101 const char *Suffix;
Chris Lattner0048b512007-12-17 17:42:26 +00001102 if (SearchList[i].isNormalDir())
Chris Lattner3af66a92007-12-17 17:57:27 +00001103 Suffix = "";
Chris Lattner0048b512007-12-17 17:42:26 +00001104 else if (SearchList[i].isFramework())
Chris Lattner3af66a92007-12-17 17:57:27 +00001105 Suffix = " (framework directory)";
Chris Lattner0048b512007-12-17 17:42:26 +00001106 else {
1107 assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
Chris Lattner3af66a92007-12-17 17:57:27 +00001108 Suffix = " (headermap)";
Chris Lattner0048b512007-12-17 17:42:26 +00001109 }
Chris Lattner3af66a92007-12-17 17:57:27 +00001110 fprintf(stderr, " %s%s\n", Name, Suffix);
Reid Spencer5f016e22007-07-11 17:01:13 +00001111 }
Chris Lattner80e17152007-12-15 23:11:06 +00001112 fprintf(stderr, "End of search list.\n");
Reid Spencer5f016e22007-07-11 17:01:13 +00001113 }
1114}
1115
Ted Kremeneka42cf2e2008-04-17 21:38:34 +00001116//===----------------------------------------------------------------------===//
1117// Driver PreprocessorFactory - For lazily generating preprocessors ...
1118//===----------------------------------------------------------------------===//
1119
1120namespace {
1121class VISIBILITY_HIDDEN DriverPreprocessorFactory : public PreprocessorFactory {
Ted Kremenek339b9c22008-04-17 22:31:54 +00001122 const std::string &InFile;
Ted Kremeneka42cf2e2008-04-17 21:38:34 +00001123 Diagnostic &Diags;
1124 const LangOptions &LangInfo;
1125 TargetInfo &Target;
1126 SourceManager &SourceMgr;
1127 HeaderSearch &HeaderInfo;
Ted Kremenek339b9c22008-04-17 22:31:54 +00001128 bool InitializeSourceMgr;
1129
Ted Kremeneka42cf2e2008-04-17 21:38:34 +00001130public:
Ted Kremenek339b9c22008-04-17 22:31:54 +00001131 DriverPreprocessorFactory(const std::string &infile,
1132 Diagnostic &diags, const LangOptions &opts,
Ted Kremeneka42cf2e2008-04-17 21:38:34 +00001133 TargetInfo &target, SourceManager &SM,
1134 HeaderSearch &Headers)
Ted Kremenek339b9c22008-04-17 22:31:54 +00001135 : InFile(infile), Diags(diags), LangInfo(opts), Target(target),
1136 SourceMgr(SM), HeaderInfo(Headers), InitializeSourceMgr(true) {}
1137
Ted Kremeneka42cf2e2008-04-17 21:38:34 +00001138
1139 virtual ~DriverPreprocessorFactory() {}
1140
1141 virtual Preprocessor* CreatePreprocessor() {
Ted Kremenek339b9c22008-04-17 22:31:54 +00001142 Preprocessor* PP = new Preprocessor(Diags, LangInfo, Target,
1143 SourceMgr, HeaderInfo);
1144
Chris Lattner51574ea2008-04-19 23:25:44 +00001145 if (InitializePreprocessor(*PP, InitializeSourceMgr, InFile)) {
Ted Kremenek339b9c22008-04-17 22:31:54 +00001146 delete PP;
1147 return NULL;
1148 }
1149
1150 InitializeSourceMgr = false;
Ted Kremenek339b9c22008-04-17 22:31:54 +00001151 return PP;
Ted Kremeneka42cf2e2008-04-17 21:38:34 +00001152 }
1153};
1154}
Reid Spencer5f016e22007-07-11 17:01:13 +00001155
Reid Spencer5f016e22007-07-11 17:01:13 +00001156//===----------------------------------------------------------------------===//
1157// Basic Parser driver
1158//===----------------------------------------------------------------------===//
1159
Chris Lattner51574ea2008-04-19 23:25:44 +00001160static void ParseFile(Preprocessor &PP, MinimalAction *PA) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001161 Parser P(PP, *PA);
Ted Kremenek95041a22007-12-19 22:51:13 +00001162 PP.EnterMainSourceFile();
Reid Spencer5f016e22007-07-11 17:01:13 +00001163
1164 // Parsing the specified input file.
1165 P.ParseTranslationUnit();
1166 delete PA;
Argyrios Kyrtzidis14d41402008-06-13 12:15:34 +00001167
1168 if (VerifyDiagnostics)
1169 exit(CheckDiagnostics(PP));
Reid Spencer5f016e22007-07-11 17:01:13 +00001170}
1171
1172//===----------------------------------------------------------------------===//
1173// Main driver
1174//===----------------------------------------------------------------------===//
1175
Ted Kremenekdb094a22007-12-05 18:27:04 +00001176/// CreateASTConsumer - Create the ASTConsumer for the corresponding program
1177/// action. These consumers can operate on both ASTs that are freshly
1178/// parsed from source files as well as those deserialized from Bitcode.
Ted Kremenekfdfc1982007-12-19 22:24:34 +00001179static ASTConsumer* CreateASTConsumer(const std::string& InFile,
Ted Kremeneka1fa3a12007-12-13 00:37:31 +00001180 Diagnostic& Diag, FileManager& FileMgr,
Chris Lattnere66b65c2008-02-06 01:42:25 +00001181 const LangOptions& LangOpts,
Chris Lattner3245a0a2008-04-16 06:11:58 +00001182 Preprocessor *PP,
Ted Kremenek815c78f2008-08-05 18:50:11 +00001183 PreprocessorFactory *PPF) {
Ted Kremenekdb094a22007-12-05 18:27:04 +00001184 switch (ProgAction) {
1185 default:
1186 return NULL;
1187
1188 case ASTPrint:
1189 return CreateASTPrinter();
1190
1191 case ASTDump:
1192 return CreateASTDumper();
1193
1194 case ASTView:
Ted Kremenek6a340832008-03-18 21:19:49 +00001195 return CreateASTViewer();
1196
1197 case EmitHTML:
Ted Kremenek339b9c22008-04-17 22:31:54 +00001198 return CreateHTMLPrinter(OutputFile, Diag, PP, PPF);
Ted Kremenek902141f2008-07-02 18:23:21 +00001199
Ted Kremenekdb094a22007-12-05 18:27:04 +00001200 case TestSerialization:
Ted Kremeneke7d07d12008-06-04 15:55:15 +00001201 return CreateSerializationTest(Diag, FileMgr);
Ted Kremenekdb094a22007-12-05 18:27:04 +00001202
1203 case EmitLLVM:
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +00001204 case EmitBC:
Ted Kremenek815c78f2008-08-05 18:50:11 +00001205 return CreateLLVMCodeGenWriter(ProgAction == EmitBC, Diag, LangOpts,
1206 InFile, OutputFile, GenerateDebugInfo);
Seo Sanghyeonfe947ad2007-12-24 01:52:34 +00001207
Ted Kremenek3910c7c2007-12-19 17:25:59 +00001208 case SerializeAST:
Ted Kremeneka1fa3a12007-12-13 00:37:31 +00001209 // FIXME: Allow user to tailor where the file is written.
Ted Kremeneke7d07d12008-06-04 15:55:15 +00001210 return CreateASTSerializer(InFile, OutputFile, Diag);
Ted Kremeneka1fa3a12007-12-13 00:37:31 +00001211
Steve Naroffb29b4272008-04-14 22:03:09 +00001212 case RewriteObjC:
Chris Lattnerc68ab772008-03-22 00:08:40 +00001213 return CreateCodeRewriterTest(InFile, OutputFile, Diag, LangOpts);
Ted Kremenekf4381fd2008-07-02 00:03:09 +00001214
1215 case RunAnalysis:
1216 assert (!AnalysisList.empty());
1217 return CreateAnalysisConsumer(&AnalysisList[0],
1218 &AnalysisList[0]+AnalysisList.size(),
1219 Diag, PP, PPF, LangOpts,
1220 AnalyzeSpecificFunction,
1221 OutputFile, VisualizeEG, TrimGraph,
1222 AnalyzeAll);
Ted Kremenekdb094a22007-12-05 18:27:04 +00001223 }
1224}
1225
Reid Spencer5f016e22007-07-11 17:01:13 +00001226/// ProcessInputFile - Process a single input file with the specified state.
1227///
Ted Kremenek339b9c22008-04-17 22:31:54 +00001228static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
1229 const std::string &InFile) {
Ted Kremenekd39bcd82007-09-26 18:39:29 +00001230
Ted Kremenek7e7e6252008-08-08 02:46:37 +00001231 llvm::OwningPtr<ASTConsumer> Consumer;
Chris Lattnerbd247762007-07-22 06:05:44 +00001232 bool ClearSourceMgr = false;
Ted Kremenekd39bcd82007-09-26 18:39:29 +00001233
Reid Spencer5f016e22007-07-11 17:01:13 +00001234 switch (ProgAction) {
1235 default:
Ted Kremenek7e7e6252008-08-08 02:46:37 +00001236 Consumer.reset(CreateASTConsumer(InFile, PP.getDiagnostics(),
1237 PP.getFileManager(), PP.getLangOptions(),
1238 &PP, &PPF));
Ted Kremenekdb094a22007-12-05 18:27:04 +00001239
1240 if (!Consumer) {
1241 fprintf(stderr, "Unexpected program action!\n");
1242 return;
1243 }
Ted Kremenekfdfc1982007-12-19 22:24:34 +00001244
Ted Kremenekdb094a22007-12-05 18:27:04 +00001245 break;
1246
Reid Spencer5f016e22007-07-11 17:01:13 +00001247 case DumpTokens: { // Token dump mode.
Chris Lattnerd2177732007-07-20 16:59:19 +00001248 Token Tok;
Reid Spencer5f016e22007-07-11 17:01:13 +00001249 // Start parsing the specified input file.
Ted Kremenek95041a22007-12-19 22:51:13 +00001250 PP.EnterMainSourceFile();
Reid Spencer5f016e22007-07-11 17:01:13 +00001251 do {
1252 PP.Lex(Tok);
1253 PP.DumpToken(Tok, true);
1254 fprintf(stderr, "\n");
Chris Lattner057aaf62007-10-09 18:03:42 +00001255 } while (Tok.isNot(tok::eof));
Chris Lattnerbd247762007-07-22 06:05:44 +00001256 ClearSourceMgr = true;
Reid Spencer5f016e22007-07-11 17:01:13 +00001257 break;
1258 }
1259 case RunPreprocessorOnly: { // Just lex as fast as we can, no output.
Chris Lattnerd2177732007-07-20 16:59:19 +00001260 Token Tok;
Reid Spencer5f016e22007-07-11 17:01:13 +00001261 // Start parsing the specified input file.
Ted Kremenek95041a22007-12-19 22:51:13 +00001262 PP.EnterMainSourceFile();
Reid Spencer5f016e22007-07-11 17:01:13 +00001263 do {
1264 PP.Lex(Tok);
Chris Lattner057aaf62007-10-09 18:03:42 +00001265 } while (Tok.isNot(tok::eof));
Chris Lattnerbd247762007-07-22 06:05:44 +00001266 ClearSourceMgr = true;
Reid Spencer5f016e22007-07-11 17:01:13 +00001267 break;
1268 }
1269
1270 case PrintPreprocessedInput: // -E mode.
Chris Lattnere988bc22008-01-27 23:55:11 +00001271 DoPrintPreprocessedInput(PP, OutputFile);
Chris Lattnerbd247762007-07-22 06:05:44 +00001272 ClearSourceMgr = true;
Reid Spencer5f016e22007-07-11 17:01:13 +00001273 break;
Chris Lattnerb57e3d42008-05-08 06:52:13 +00001274
Reid Spencer5f016e22007-07-11 17:01:13 +00001275 case ParseNoop: // -parse-noop
Ted Kremenek95041a22007-12-19 22:51:13 +00001276 ParseFile(PP, new MinimalAction(PP.getIdentifierTable()));
Chris Lattnerbd247762007-07-22 06:05:44 +00001277 ClearSourceMgr = true;
Reid Spencer5f016e22007-07-11 17:01:13 +00001278 break;
1279
1280 case ParsePrintCallbacks:
Ted Kremenek95041a22007-12-19 22:51:13 +00001281 ParseFile(PP, CreatePrintParserActionsAction(PP.getIdentifierTable()));
Chris Lattnerbd247762007-07-22 06:05:44 +00001282 ClearSourceMgr = true;
Reid Spencer5f016e22007-07-11 17:01:13 +00001283 break;
Ted Kremenek44579782007-09-25 18:37:20 +00001284
Ted Kremenekd39bcd82007-09-26 18:39:29 +00001285 case ParseSyntaxOnly: // -fsyntax-only
Ted Kremenek7e7e6252008-08-08 02:46:37 +00001286 Consumer.reset(new ASTConsumer());
Ted Kremenek2bf55142007-09-17 20:49:30 +00001287 break;
Chris Lattnerb57e3d42008-05-08 06:52:13 +00001288
1289 case RewriteMacros:
Chris Lattner09510522008-05-09 22:43:24 +00001290 RewriteMacrosInInput(PP, InFile, OutputFile);
Chris Lattnerb57e3d42008-05-08 06:52:13 +00001291 ClearSourceMgr = true;
1292 break;
Chris Lattner580980b2007-09-16 19:46:59 +00001293 }
Ted Kremenekd39bcd82007-09-26 18:39:29 +00001294
1295 if (Consumer) {
Ted Kremenek9f3d9422007-09-26 20:14:22 +00001296 if (VerifyDiagnostics)
Ted Kremenek7e7e6252008-08-08 02:46:37 +00001297 exit(CheckASTConsumer(PP, Consumer.get()));
Chris Lattner31e6c7d2007-11-03 06:24:16 +00001298
Ted Kremenek7e7e6252008-08-08 02:46:37 +00001299 ParseAST(PP, Consumer.get(), Stats);
Reid Spencer5f016e22007-07-11 17:01:13 +00001300 }
Chris Lattnere66b65c2008-02-06 01:42:25 +00001301
Reid Spencer5f016e22007-07-11 17:01:13 +00001302 if (Stats) {
Ted Kremenekfdfc1982007-12-19 22:24:34 +00001303 fprintf(stderr, "\nSTATISTICS FOR '%s':\n", InFile.c_str());
Reid Spencer5f016e22007-07-11 17:01:13 +00001304 PP.PrintStats();
1305 PP.getIdentifierTable().PrintStats();
Chris Lattnerdee73592007-12-15 20:48:40 +00001306 PP.getHeaderSearchInfo().PrintStats();
Chris Lattnerbd247762007-07-22 06:05:44 +00001307 if (ClearSourceMgr)
Chris Lattnerdee73592007-12-15 20:48:40 +00001308 PP.getSourceManager().PrintStats();
Reid Spencer5f016e22007-07-11 17:01:13 +00001309 fprintf(stderr, "\n");
1310 }
Chris Lattnerbd247762007-07-22 06:05:44 +00001311
1312 // For a multi-file compilation, some things are ok with nuking the source
1313 // manager tables, other require stable fileid/macroid's across multiple
1314 // files.
Chris Lattnerdee73592007-12-15 20:48:40 +00001315 if (ClearSourceMgr)
1316 PP.getSourceManager().clearIDTables();
Reid Spencer5f016e22007-07-11 17:01:13 +00001317}
1318
Ted Kremenek20e97482007-12-12 23:41:08 +00001319static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
1320 FileManager& FileMgr) {
1321
1322 if (VerifyDiagnostics) {
1323 fprintf(stderr, "-verify does not yet work with serialized ASTs.\n");
1324 exit (1);
1325 }
1326
1327 llvm::sys::Path Filename(InFile);
1328
1329 if (!Filename.isValid()) {
1330 fprintf(stderr, "serialized file '%s' not available.\n",InFile.c_str());
1331 exit (1);
1332 }
1333
Ted Kremenekc1e9dea2008-04-23 16:25:39 +00001334 llvm::OwningPtr<TranslationUnit> TU(ReadASTBitcodeFile(Filename, FileMgr));
Ted Kremenekfe4e0152007-12-13 18:11:11 +00001335
1336 if (!TU) {
1337 fprintf(stderr, "error: file '%s' could not be deserialized\n",
1338 InFile.c_str());
1339 exit (1);
1340 }
1341
Ted Kremenek63ea8632007-12-19 19:27:38 +00001342 // Observe that we use the source file name stored in the deserialized
1343 // translation unit, rather than InFile.
Ted Kremenekee533642007-12-20 19:47:16 +00001344 llvm::OwningPtr<ASTConsumer>
Ted Kremeneke7d07d12008-06-04 15:55:15 +00001345 Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOptions(),
Ted Kremenek815c78f2008-08-05 18:50:11 +00001346 0, 0));
Ted Kremenek20e97482007-12-12 23:41:08 +00001347
1348 if (!Consumer) {
1349 fprintf(stderr, "Unsupported program action with serialized ASTs!\n");
1350 exit (1);
1351 }
1352
Ted Kremenekc1e9dea2008-04-23 16:25:39 +00001353 Consumer->Initialize(TU->getContext());
Ted Kremenek20e97482007-12-12 23:41:08 +00001354
Chris Lattnere66b65c2008-02-06 01:42:25 +00001355 // FIXME: We need to inform Consumer about completed TagDecls as well.
Ted Kremenek20e97482007-12-12 23:41:08 +00001356 for (TranslationUnit::iterator I=TU->begin(), E=TU->end(); I!=E; ++I)
1357 Consumer->HandleTopLevelDecl(*I);
Ted Kremenek20e97482007-12-12 23:41:08 +00001358}
1359
1360
Reid Spencer5f016e22007-07-11 17:01:13 +00001361static llvm::cl::list<std::string>
1362InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>"));
1363
Ted Kremenek20e97482007-12-12 23:41:08 +00001364static bool isSerializedFile(const std::string& InFile) {
1365 if (InFile.size() < 4)
1366 return false;
1367
1368 const char* s = InFile.c_str()+InFile.size()-4;
1369
1370 return s[0] == '.' &&
1371 s[1] == 'a' &&
1372 s[2] == 's' &&
1373 s[3] == 't';
1374}
1375
Reid Spencer5f016e22007-07-11 17:01:13 +00001376
1377int main(int argc, char **argv) {
Chris Lattnerdcaa0962008-03-03 03:16:03 +00001378 llvm::cl::ParseCommandLineOptions(argc, argv, " llvm clang cfe\n");
Reid Spencer5f016e22007-07-11 17:01:13 +00001379 llvm::sys::PrintStackTraceOnErrorSignal();
1380
1381 // If no input was specified, read from stdin.
1382 if (InputFilenames.empty())
1383 InputFilenames.push_back("-");
Ted Kremenek31e703b2007-12-11 23:28:38 +00001384
Reid Spencer5f016e22007-07-11 17:01:13 +00001385 // Create a file manager object to provide access to and cache the filesystem.
1386 FileManager FileMgr;
1387
Ted Kremenek31e703b2007-12-11 23:28:38 +00001388 // Create the diagnostic client for reporting errors or for
1389 // implementing -verify.
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001390 TextDiagnostics* TextDiagClient = 0;
Ted Kremenek88f5cde2008-03-27 06:17:42 +00001391
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001392 if (!VerifyDiagnostics) {
1393 // Print diagnostics to stderr by default.
1394 TextDiagClient = new TextDiagnosticPrinter(!NoShowColumn,
1395 !NoCaretDiagnostics);
1396 } else {
1397 // When checking diagnostics, just buffer them up.
1398 TextDiagClient = new TextDiagnosticBuffer();
1399
1400 if (InputFilenames.size() != 1) {
1401 fprintf(stderr,
1402 "-verify only works on single input files for now.\n");
1403 return 1;
Reid Spencer5f016e22007-07-11 17:01:13 +00001404 }
1405 }
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001406
Reid Spencer5f016e22007-07-11 17:01:13 +00001407 // Configure our handling of diagnostics.
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001408 llvm::OwningPtr<DiagnosticClient> DiagClient(TextDiagClient);
1409 Diagnostic Diags(DiagClient.get());
Ted Kremenek31e703b2007-12-11 23:28:38 +00001410 InitializeDiagnostics(Diags);
1411
Chris Lattner4f037832007-12-05 23:24:17 +00001412 // -I- is a deprecated GCC feature, scan for it and reject it.
1413 for (unsigned i = 0, e = I_dirs.size(); i != e; ++i) {
1414 if (I_dirs[i] == "-") {
Ted Kremenek2eefd862007-12-11 22:57:35 +00001415 Diags.Report(diag::err_pp_I_dash_not_supported);
Chris Lattner4f037832007-12-05 23:24:17 +00001416 I_dirs.erase(I_dirs.begin()+i);
1417 --i;
1418 }
1419 }
Chris Lattner11215192008-03-14 06:12:05 +00001420
1421 // Get information about the target being compiled for.
1422 std::string Triple = CreateTargetTriple();
Ted Kremenek7a08e282008-08-07 18:13:12 +00001423 llvm::OwningPtr<TargetInfo> Target(TargetInfo::CreateTargetInfo(Triple));
1424
Chris Lattner11215192008-03-14 06:12:05 +00001425 if (Target == 0) {
1426 fprintf(stderr, "Sorry, I don't know what target this is: %s\n",
1427 Triple.c_str());
1428 fprintf(stderr, "Please use -triple or -arch.\n");
1429 exit(1);
1430 }
Chris Lattner4f037832007-12-05 23:24:17 +00001431
Ted Kremenekf4381fd2008-07-02 00:03:09 +00001432 // Are we invoking one or more source analyses?
1433 if (!AnalysisList.empty() && ProgAction == ParseSyntaxOnly)
1434 ProgAction = RunAnalysis;
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001435
Ted Kremenekc0c03bc2008-06-06 22:42:39 +00001436 llvm::OwningPtr<SourceManager> SourceMgr;
1437
Reid Spencer5f016e22007-07-11 17:01:13 +00001438 for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
Ted Kremenek31e703b2007-12-11 23:28:38 +00001439 const std::string &InFile = InputFilenames[i];
Ted Kremenek31e703b2007-12-11 23:28:38 +00001440
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001441 if (isSerializedFile(InFile)) {
1442 Diags.setClient(TextDiagClient);
Ted Kremenek20e97482007-12-12 23:41:08 +00001443 ProcessSerializedFile(InFile,Diags,FileMgr);
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001444 }
Ted Kremenek20e97482007-12-12 23:41:08 +00001445 else {
1446 /// Create a SourceManager object. This tracks and owns all the file
1447 /// buffers allocated to a translation unit.
Ted Kremenekc0c03bc2008-06-06 22:42:39 +00001448 if (!SourceMgr)
1449 SourceMgr.reset(new SourceManager());
1450 else
1451 SourceMgr->clearIDTables();
Ted Kremenek31e703b2007-12-11 23:28:38 +00001452
Ted Kremenek20e97482007-12-12 23:41:08 +00001453 // Initialize language options, inferring file types from input filenames.
1454 LangOptions LangInfo;
1455 InitializeBaseLanguage();
1456 LangKind LK = GetLanguage(InFile);
1457 InitializeLangOptions(LangInfo, LK);
1458 InitializeLanguageStandard(LangInfo, LK);
Ted Kremenek01d9dbf2008-04-29 04:37:03 +00001459 InitializeGCMode(LangInfo);
Ted Kremenek20e97482007-12-12 23:41:08 +00001460
1461 // Process the -I options and set them in the HeaderInfo.
1462 HeaderSearch HeaderInfo(FileMgr);
Ted Kremenek88f5cde2008-03-27 06:17:42 +00001463 if (TextDiagClient) TextDiagClient->setHeaderSearch(HeaderInfo);
Ted Kremenekc68ecb52008-06-06 01:47:30 +00001464
1465 // FIXME: Sink IncludeGroup into this loop.
1466 IncludeGroup[0].clear();
1467 IncludeGroup[1].clear();
1468 IncludeGroup[2].clear();
1469 IncludeGroup[3].clear();
Chris Lattnerdcaa0962008-03-03 03:16:03 +00001470 InitializeIncludePaths(argv[0], HeaderInfo, FileMgr, LangInfo);
Ted Kremenek20e97482007-12-12 23:41:08 +00001471
Ted Kremenek20e97482007-12-12 23:41:08 +00001472 // Set up the preprocessor with these options.
Ted Kremenek339b9c22008-04-17 22:31:54 +00001473 DriverPreprocessorFactory PPFactory(InFile, Diags, LangInfo, *Target,
Ted Kremenekc0c03bc2008-06-06 22:42:39 +00001474 *SourceMgr.get(), HeaderInfo);
Ted Kremenek20e97482007-12-12 23:41:08 +00001475
Ted Kremeneka42cf2e2008-04-17 21:38:34 +00001476 llvm::OwningPtr<Preprocessor> PP(PPFactory.CreatePreprocessor());
1477
Ted Kremenek339b9c22008-04-17 22:31:54 +00001478 if (!PP)
Ted Kremenek76edd0e2007-12-19 22:29:55 +00001479 continue;
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001480
1481 // Create the HTMLDiagnosticsClient if we are using one. Otherwise,
1482 // always reset to using TextDiagClient.
1483 llvm::OwningPtr<DiagnosticClient> TmpClient;
Ted Kremenek76edd0e2007-12-19 22:29:55 +00001484
Ted Kremenekb4398aa2008-08-07 17:49:57 +00001485 if (!HTMLDiag.empty()) {
1486 TmpClient.reset(CreateHTMLDiagnosticClient(HTMLDiag, PP.get(),
1487 &PPFactory));
1488 Diags.setClient(TmpClient.get());
1489 }
1490 else
1491 Diags.setClient(TextDiagClient);
1492
1493 // Process the source file.
Ted Kremenek339b9c22008-04-17 22:31:54 +00001494 ProcessInputFile(*PP, PPFactory, InFile);
Ted Kremenekc0c03bc2008-06-06 22:42:39 +00001495 HeaderInfo.ClearFileInfo();
Ted Kremenek20e97482007-12-12 23:41:08 +00001496
1497 if (Stats)
Ted Kremenekc0c03bc2008-06-06 22:42:39 +00001498 SourceMgr->PrintStats();
Ted Kremenek20e97482007-12-12 23:41:08 +00001499 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001500 }
Chris Lattner11215192008-03-14 06:12:05 +00001501
Ted Kremenek7a08e282008-08-07 18:13:12 +00001502 if (unsigned NumDiagnostics = Diags.getNumDiagnostics())
Reid Spencer5f016e22007-07-11 17:01:13 +00001503 fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
1504 (NumDiagnostics == 1 ? "" : "s"));
1505
1506 if (Stats) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001507 FileMgr.PrintStats();
1508 fprintf(stderr, "\n");
1509 }
1510
Chris Lattner96f1a642007-07-21 05:40:53 +00001511 return Diags.getNumErrors() != 0;
Reid Spencer5f016e22007-07-11 17:01:13 +00001512}