HTMLRewrite.cpp revision 0bc735ffcfb223c0186419547abaa5c84482663e
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- clang.cpp - C-Language Front-end ---------------------------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This utility may be invoked in the following manner:
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   clang --help                - Output help info.
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   clang [options]             - Read from stdin.
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   clang [options] file        - Read from "file".
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   clang [options] file1 file2 - Read these files.
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// TODO: Options to support:
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   -ffatal-errors
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   -ftabstop=width
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang.h"
2697e8b6f3c5c578f35c3f392cc7cfdec88cef74f2Chris Lattner#include "ASTConsumers.h"
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "TextDiagnosticBuffer.h"
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "TextDiagnosticPrinter.h"
2977cda500803f6dc8f4bec1bc30acc991349770a2Ted Kremenek#include "clang/AST/TranslationUnit.h"
30556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner#include "clang/Sema/ASTStreamer.h"
31556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner#include "clang/AST/ASTConsumer.h"
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/Parser.h"
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/HeaderSearch.h"
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/FileManager.h"
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/SourceManager.h"
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TargetInfo.h"
378f3dab88f7725c97103a8c91dd2605009d9c755eChris Lattner#include "llvm/ADT/SmallPtrSet.h"
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/CommandLine.h"
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/MemoryBuffer.h"
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/System/Signals.h"
41ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek#include "llvm/Config/config.h"
42ee533641635fc3e10dd14072972b378be110b21dTed Kremenek#include "llvm/ADT/OwningPtr.h"
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <memory>
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Global options.
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerVerbose("v", llvm::cl::desc("Enable verbose output"));
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerStats("stats", llvm::cl::desc("Print performance metrics and statistics"));
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerenum ProgActions {
5677cd2a0b6eea81cc393b4c9e2941ec31fa09fdbeChris Lattner  RewriteTest,                  // Rewriter testing stuff.
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  EmitLLVM,                     // Emit a .ll file.
58fe947ad3624ad45bc5ef9fd36a3f9ff00efdb1fdSeo Sanghyeon  EmitBC,                       // Emit a .bc file.
59a1fa3a19bf2c4553aa7e7f27ff2a1b3b2e2db62cTed Kremenek  SerializeAST,                 // Emit a .ast file.
603b427b3ba518f7a7293458c2d3d92eebd8458d87Chris Lattner  ASTPrint,                     // Parse ASTs and print them.
613b427b3ba518f7a7293458c2d3d92eebd8458d87Chris Lattner  ASTDump,                      // Parse ASTs and dump them.
623b427b3ba518f7a7293458c2d3d92eebd8458d87Chris Lattner  ASTView,                      // Parse ASTs and view them in Graphviz.
63fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ParseCFGDump,                 // Parse ASTS. Build CFGs. Print CFGs.
64055c275fabcbe1ef246942c8b5f7d49b3a173500Ted Kremenek  ParseCFGView,                 // Parse ASTS. Build CFGs. View CFGs.
65e4e633400b1993c1174b47b774fa015220fa695cTed Kremenek  AnalysisLiveVariables,        // Print results of live-variable analysis.
66055c275fabcbe1ef246942c8b5f7d49b3a173500Ted Kremenek  WarnDeadStores,               // Run DeadStores checker on parsed ASTs.
67445797873fcd5810e48e4c8937c33959a647bbf7Ted Kremenek  WarnDeadStoresCheck,          // Check diagnostics for "DeadStores".
682bf55140b893c874ef16929bfe953f7cc7823425Ted Kremenek  WarnUninitVals,               // Run UnitializedVariables checker.
69bfa82c4c23ce96fdcf357a8f7ef70a9b71b69144Ted Kremenek  TestSerialization,            // Run experimental serialization code.
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ParsePrintCallbacks,          // Parse and print each callback.
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ParseSyntaxOnly,              // Parse and perform semantic analysis.
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ParseNoop,                    // Parse with noop callbacks.
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  RunPreprocessorOnly,          // Just lex, no output.
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PrintPreprocessedInput,       // -E mode.
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DumpTokens                    // Token dump mode.
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<ProgActions>
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           llvm::cl::init(ParseSyntaxOnly),
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           llvm::cl::values(
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             clEnumValN(RunPreprocessorOnly, "Eonly",
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        "Just run preprocessor, no output (for timings)"),
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             clEnumValN(PrintPreprocessedInput, "E",
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        "Run preprocessor, emit preprocessed file"),
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             clEnumValN(DumpTokens, "dumptokens",
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        "Run preprocessor, dump internal rep of tokens"),
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             clEnumValN(ParseNoop, "parse-noop",
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        "Run parser with noop callbacks (for timings)"),
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             clEnumValN(ParseSyntaxOnly, "fsyntax-only",
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        "Run parser and perform semantic analysis"),
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             clEnumValN(ParsePrintCallbacks, "parse-print-callbacks",
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        "Run parser and print each callback invoked"),
943b427b3ba518f7a7293458c2d3d92eebd8458d87Chris Lattner             clEnumValN(ASTPrint, "ast-print",
953b427b3ba518f7a7293458c2d3d92eebd8458d87Chris Lattner                        "Build ASTs and then pretty-print them"),
963b427b3ba518f7a7293458c2d3d92eebd8458d87Chris Lattner             clEnumValN(ASTDump, "ast-dump",
973b427b3ba518f7a7293458c2d3d92eebd8458d87Chris Lattner                        "Build ASTs and then debug dump them"),
98ea254dbbc0d46e9947b146dfe624bd70089b3f5aChris Lattner             clEnumValN(ASTView, "ast-view",
993b427b3ba518f7a7293458c2d3d92eebd8458d87Chris Lattner                        "Build ASTs and view them with GraphViz."),
100fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek             clEnumValN(ParseCFGDump, "dump-cfg",
1017dba8607e59096014b7139ff20ef00870041d518Ted Kremenek                        "Run parser, then build and print CFGs."),
1027dba8607e59096014b7139ff20ef00870041d518Ted Kremenek             clEnumValN(ParseCFGView, "view-cfg",
103e4e633400b1993c1174b47b774fa015220fa695cTed Kremenek                        "Run parser, then build and view CFGs with Graphviz."),
104e4e633400b1993c1174b47b774fa015220fa695cTed Kremenek             clEnumValN(AnalysisLiveVariables, "dump-live-variables",
10527b07c5fb9926c9d69fa1d8239e96ad0b7a178f7Ted Kremenek                        "Print results of live variable analysis."),
106786d337d4d9d01169cd970948949f549a5095782Ted Kremenek             clEnumValN(WarnDeadStores, "warn-dead-stores",
107055c275fabcbe1ef246942c8b5f7d49b3a173500Ted Kremenek                        "Flag warnings of stores to dead variables."),
108786d337d4d9d01169cd970948949f549a5095782Ted Kremenek             clEnumValN(WarnUninitVals, "warn-uninit-values",
1092bf55140b893c874ef16929bfe953f7cc7823425Ted Kremenek                        "Flag warnings of uses of unitialized variables."),
110bfa82c4c23ce96fdcf357a8f7ef70a9b71b69144Ted Kremenek             clEnumValN(TestSerialization, "test-pickling",
111bfa82c4c23ce96fdcf357a8f7ef70a9b71b69144Ted Kremenek                        "Run prototype serializtion code."),
1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             clEnumValN(EmitLLVM, "emit-llvm",
11327b07c5fb9926c9d69fa1d8239e96ad0b7a178f7Ted Kremenek                        "Build ASTs then convert to LLVM, emit .ll file"),
114fe947ad3624ad45bc5ef9fd36a3f9ff00efdb1fdSeo Sanghyeon             clEnumValN(EmitBC, "emit-llvm-bc",
115fe947ad3624ad45bc5ef9fd36a3f9ff00efdb1fdSeo Sanghyeon                        "Build ASTs then convert to LLVM, emit .bc file"),
116ccc7647b129f284e0344876eaee7c8ce27e96024Ted Kremenek             clEnumValN(SerializeAST, "serialize",
117a1fa3a19bf2c4553aa7e7f27ff2a1b3b2e2db62cTed Kremenek                        "Build ASTs and emit .ast file"),
11877cd2a0b6eea81cc393b4c9e2941ec31fa09fdbeChris Lattner             clEnumValN(RewriteTest, "rewrite-test",
11977cd2a0b6eea81cc393b4c9e2941ec31fa09fdbeChris Lattner                        "Playground for the code rewriter"),
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             clEnumValEnd));
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
122ccc7647b129f284e0344876eaee7c8ce27e96024Ted Kremenek
123ccc7647b129f284e0344876eaee7c8ce27e96024Ted Kremenekstatic llvm::cl::opt<std::string>
124ccc7647b129f284e0344876eaee7c8ce27e96024Ted KremenekOutputFile("o",
12550b5641e1ba42ae6b542b3044b6bb268e793602cTed Kremenek llvm::cl::value_desc("path"),
126ccc7647b129f284e0344876eaee7c8ce27e96024Ted Kremenek llvm::cl::desc("Specify output file (for --serialize, this is a directory)"));
127ccc7647b129f284e0344876eaee7c8ce27e96024Ted Kremenek
12841193e4464818d5c4809a8a4140bb0bf26d7733fTed Kremenekstatic llvm::cl::opt<bool>
12941193e4464818d5c4809a8a4140bb0bf26d7733fTed KremenekVerifyDiagnostics("verify",
13041193e4464818d5c4809a8a4140bb0bf26d7733fTed Kremenek                  llvm::cl::desc("Verify emitted diagnostics and warnings."));
13141193e4464818d5c4809a8a4140bb0bf26d7733fTed Kremenek
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Language Options
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerenum LangKind {
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_unspecified,
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_c,
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_c_cpp,
1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_cxx,
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_cxx_cpp,
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_objc,
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_objc_cpp,
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_objcxx,
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  langkind_objcxx_cpp
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/* TODO: GCC also accepts:
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   c-header c++-header objective-c-header objective-c++-header
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   assembler  assembler-with-cpp
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   ada, f77*, ratfor (!), f95, java, treelang
1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer */
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<LangKind>
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerBaseLang("x", llvm::cl::desc("Base language to compile"),
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         llvm::cl::init(langkind_unspecified),
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   llvm::cl::values(clEnumValN(langkind_c,     "c",            "C"),
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    clEnumValN(langkind_cxx,   "c++",          "C++"),
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    clEnumValN(langkind_objc,  "objective-c",  "Objective C"),
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    clEnumValN(langkind_objcxx,"objective-c++","Objective C++"),
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    clEnumValN(langkind_c_cpp,     "c-cpp-output",
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               "Preprocessed C"),
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    clEnumValN(langkind_cxx_cpp,   "c++-cpp-output",
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               "Preprocessed C++"),
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    clEnumValN(langkind_objc_cpp,  "objective-c-cpp-output",
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               "Preprocessed Objective C"),
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    clEnumValN(langkind_objcxx_cpp,"objective-c++-cpp-output",
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               "Preprocessed Objective C++"),
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    clEnumValEnd));
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerLangObjC("ObjC", llvm::cl::desc("Set base language to Objective-C"),
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         llvm::cl::Hidden);
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerLangObjCXX("ObjC++", llvm::cl::desc("Set base language to Objective-C++"),
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           llvm::cl::Hidden);
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1778904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek/// InitializeBaseLanguage - Handle the -x foo options.
1788904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenekstatic void InitializeBaseLanguage() {
1798904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  if (LangObjC)
1808904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    BaseLang = langkind_objc;
1818904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else if (LangObjCXX)
1828904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    BaseLang = langkind_objcxx;
1838904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek}
1848904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek
1858904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenekstatic LangKind GetLanguage(const std::string &Filename) {
1868904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  if (BaseLang != langkind_unspecified)
1878904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return BaseLang;
1888904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek
1898904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  std::string::size_type DotPos = Filename.rfind('.');
1908904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek
1918904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  if (DotPos == std::string::npos) {
1928904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    BaseLang = langkind_c;  // Default to C if no extension.
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1958904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
1968904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  // C header: .h
1978904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  // C++ header: .hh or .H;
1988904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  // assembler no preprocessing: .s
1998904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  // assembler: .S
2008904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  if (Ext == "c")
2018904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_c;
2028904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else if (Ext == "i")
2038904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_c_cpp;
2048904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else if (Ext == "ii")
2058904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_cxx_cpp;
2068904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else if (Ext == "m")
2078904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_objc;
2088904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else if (Ext == "mi")
2098904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_objc_cpp;
2108904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else if (Ext == "mm" || Ext == "M")
2118904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_objcxx;
2128904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else if (Ext == "mii")
2138904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_objcxx_cpp;
2148904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else if (Ext == "C" || Ext == "cc" || Ext == "cpp" || Ext == "CPP" ||
2158904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek           Ext == "c++" || Ext == "cp" || Ext == "cxx")
2168904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_cxx;
2178904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  else
2188904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    return langkind_c;
2198904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek}
2208904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek
2218904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek
2228904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenekstatic void InitializeLangOptions(LangOptions &Options, LangKind LK) {
2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: implement -fpreprocessed mode.
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool NoPreprocess = false;
2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2268904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek  switch (LK) {
2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default: assert(0 && "Unknown language kind!");
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case langkind_c_cpp:
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoPreprocess = true;
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FALLTHROUGH
2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case langkind_c:
2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case langkind_cxx_cpp:
2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoPreprocess = true;
2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FALLTHROUGH
2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case langkind_cxx:
2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.CPlusPlus = 1;
2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case langkind_objc_cpp:
2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoPreprocess = true;
2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FALLTHROUGH
2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case langkind_objc:
2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.ObjC1 = Options.ObjC2 = 1;
2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case langkind_objcxx_cpp:
2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoPreprocess = true;
2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FALLTHROUGH
2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case langkind_objcxx:
2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.ObjC1 = Options.ObjC2 = 1;
2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.CPlusPlus = 1;
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// LangStds - Language standards we support.
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerenum LangStds {
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  lang_unspecified,
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  lang_c89, lang_c94, lang_c99,
2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  lang_gnu89, lang_gnu99,
260d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner  lang_cxx98, lang_gnucxx98,
261d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner  lang_cxx0x, lang_gnucxx0x
2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<LangStds>
2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerLangStd("std", llvm::cl::desc("Language standard to compile for"),
2665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        llvm::cl::init(lang_unspecified),
2675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::cl::values(clEnumValN(lang_c89,      "c89",            "ISO C 1990"),
2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_c89,      "c90",            "ISO C 1990"),
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_c89,      "iso9899:1990",   "ISO C 1990"),
2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_c94,      "iso9899:199409",
2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              "ISO C 1990 with amendment 1"),
2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_c99,      "c99",            "ISO C 1999"),
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                 clEnumValN(lang_c99,      "c9x",            "ISO C 1999"),
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_c99,      "iso9899:1999",   "ISO C 1999"),
2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                 clEnumValN(lang_c99,      "iso9899:199x",   "ISO C 1999"),
2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_gnu89,    "gnu89",
2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              "ISO C 1990 with GNU extensions (default for C)"),
2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_gnu99,    "gnu99",
2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              "ISO C 1999 with GNU extensions"),
2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_gnu99,    "gnu9x",
2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              "ISO C 1999 with GNU extensions"),
2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_cxx98,    "c++98",
2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              "ISO C++ 1998 with amendments"),
2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValN(lang_gnucxx98, "gnu++98",
2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              "ISO C++ 1998 with amendments and GNU "
2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              "extensions (default for C++)"),
287d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner                   clEnumValN(lang_cxx0x,    "c++0x",
288d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner                              "Upcoming ISO C++ 200x with amendments"),
289d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner                   clEnumValN(lang_gnucxx0x, "gnu++0x",
290d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner                              "Upcoming ISO C++ 200x with amendments and GNU "
291d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner                              "extensions (default for C++)"),
2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   clEnumValEnd));
2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerNoOperatorNames("fno-operator-names",
2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                llvm::cl::desc("Do not treat C++ operator name keywords as "
2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               "synonyms for operators"));
2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
299ee98ac5a1330db432b188dd2d38b6631aac47bf1Anders Carlssonstatic llvm::cl::opt<bool>
300ee98ac5a1330db432b188dd2d38b6631aac47bf1Anders CarlssonPascalStrings("fpascal-strings",
301ee98ac5a1330db432b188dd2d38b6631aac47bf1Anders Carlsson              llvm::cl::desc("Recognize and construct Pascal-style "
302ee98ac5a1330db432b188dd2d38b6631aac47bf1Anders Carlsson                             "string literals"));
30345e8cbdce25c2e16c7aac2036a591f6190097ae6Chris Lattner
30445e8cbdce25c2e16c7aac2036a591f6190097ae6Chris Lattnerstatic llvm::cl::opt<bool>
30545e8cbdce25c2e16c7aac2036a591f6190097ae6Chris LattnerWritableStrings("fwritable-strings",
30645e8cbdce25c2e16c7aac2036a591f6190097ae6Chris Lattner              llvm::cl::desc("Store string literals as writable data."));
307695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson
308695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlssonstatic llvm::cl::opt<bool>
309695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders CarlssonLaxVectorConversions("flax-vector-conversions",
310695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson                     llvm::cl::desc("Allow implicit conversions between vectors"
311695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson                                    " with a different number of elements or "
312695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson                                    "different element types."));
3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// FIXME: add:
3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   -ansi
3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   -trigraphs
3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   -fdollars-in-identifiers
317ee98ac5a1330db432b188dd2d38b6631aac47bf1Anders Carlsson//   -fpascal-strings
3188904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenekstatic void InitializeLanguageStandard(LangOptions &Options, LangKind LK) {
3195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (LangStd == lang_unspecified) {
3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Based on the base language, pick one.
3218904f15ed9c49392232de80d55af3e4ceb88f854Ted Kremenek    switch (LK) {
3225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    default: assert(0 && "Unknown base language");
3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case langkind_c:
3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case langkind_c_cpp:
3255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case langkind_objc:
3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case langkind_objc_cpp:
3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      LangStd = lang_gnu99;
3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      break;
3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case langkind_cxx:
3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case langkind_cxx_cpp:
3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case langkind_objcxx:
3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case langkind_objcxx_cpp:
3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      LangStd = lang_gnucxx98;
3345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      break;
3355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
3365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (LangStd) {
3395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default: assert(0 && "Unknown language standard!");
3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Fall through from newer standards to older ones.  This isn't really right.
3425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: Enable specifically the right features based on the language stds.
343d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner  case lang_gnucxx0x:
344d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner  case lang_cxx0x:
345d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner    Options.CPlusPlus0x = 1;
346d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116Chris Lattner    // FALL THROUGH
3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case lang_gnucxx98:
3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case lang_cxx98:
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.CPlusPlus = 1;
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.CXXOperatorNames = !NoOperatorNames;
3518aebcb739a4aff5ccf007fd740aa9105071feff4Nate Begeman    Options.Boolean = 1;
3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FALL THROUGH.
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case lang_gnu99:
3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case lang_c99:
3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.Digraphs = 1;
3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.C99 = 1;
3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.HexFloats = 1;
3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FALL THROUGH.
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case lang_gnu89:
3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Options.BCPLComment = 1;  // Only for C99/C++.
3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FALL THROUGH.
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case lang_c94:
3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case lang_c89:
3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Options.Trigraphs = 1; // -trigraphs or -ansi
3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Options.DollarIdents = 1;  // FIXME: Really a target property.
369ee98ac5a1330db432b188dd2d38b6631aac47bf1Anders Carlsson  Options.PascalStrings = PascalStrings;
37045e8cbdce25c2e16c7aac2036a591f6190097ae6Chris Lattner  Options.WritableStrings = WritableStrings;
371695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson  Options.LaxVectorConversions = LaxVectorConversions;
3725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Our DiagnosticClient implementation
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// FIXME: Werror should take a list of things, -Werror=foo,bar
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerWarningsAsErrors("Werror", llvm::cl::desc("Treat all warnings as errors"));
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerWarnOnExtensions("pedantic", llvm::cl::init(false),
3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                 llvm::cl::desc("Issue a warning on uses of GCC extensions"));
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerErrorOnExtensions("pedantic-errors",
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                  llvm::cl::desc("Issue an error on uses of GCC extensions"));
3895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerWarnUnusedMacros("Wunused_macros",
3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         llvm::cl::desc("Warn for unused macros in the main translation unit"));
3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
394db87bca211deed14f8d5bb9ef25b8e9ee5c8e139Ted Kremenekstatic llvm::cl::opt<bool>
395db87bca211deed14f8d5bb9ef25b8e9ee5c8e139Ted KremenekWarnFloatEqual("Wfloat-equal",
396db87bca211deed14f8d5bb9ef25b8e9ee5c8e139Ted Kremenek   llvm::cl::desc("Warn about equality comparisons of floating point values."));
397db87bca211deed14f8d5bb9ef25b8e9ee5c8e139Ted Kremenek
39873da590134d55cf3d0d5df25d332286c1d420dabTed Kremenekstatic llvm::cl::opt<bool>
39973da590134d55cf3d0d5df25d332286c1d420dabTed KremenekWarnNoFormatNonLiteral("Wno-format-nonliteral",
40073da590134d55cf3d0d5df25d332286c1d420dabTed Kremenek   llvm::cl::desc("Do not warn about non-literal format strings."));
40173da590134d55cf3d0d5df25d332286c1d420dabTed Kremenek
4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// InitializeDiagnostics - Initialize the diagnostic object, based on the
4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// current command line option settings.
4045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void InitializeDiagnostics(Diagnostic &Diags) {
4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Diags.setWarningsAsErrors(WarningsAsErrors);
4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Diags.setWarnOnExtensions(WarnOnExtensions);
4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Diags.setErrorOnExtensions(ErrorOnExtensions);
4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Silence the "macro is not used" warning unless requested.
4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!WarnUnusedMacros)
4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diags.setDiagnosticMapping(diag::pp_macro_not_used, diag::MAP_IGNORE);
412db87bca211deed14f8d5bb9ef25b8e9ee5c8e139Ted Kremenek
413db87bca211deed14f8d5bb9ef25b8e9ee5c8e139Ted Kremenek  // Silence "floating point comparison" warnings unless requested.
414db87bca211deed14f8d5bb9ef25b8e9ee5c8e139Ted Kremenek  if (!WarnFloatEqual)
415db87bca211deed14f8d5bb9ef25b8e9ee5c8e139Ted Kremenek    Diags.setDiagnosticMapping(diag::warn_floatingpoint_eq, diag::MAP_IGNORE);
41673da590134d55cf3d0d5df25d332286c1d420dabTed Kremenek
41773da590134d55cf3d0d5df25d332286c1d420dabTed Kremenek  // Silence "format string is not a string literal" warnings if requested
41873da590134d55cf3d0d5df25d332286c1d420dabTed Kremenek  if (WarnNoFormatNonLiteral)
4197c1d3df338b28a968df8f73f2b56b718514385fdTed Kremenek    Diags.setDiagnosticMapping(diag::warn_printf_not_string_constant,
4207c1d3df338b28a968df8f73f2b56b718514385fdTed Kremenek                               diag::MAP_IGNORE);
42173da590134d55cf3d0d5df25d332286c1d420dabTed Kremenek
4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
425ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek// Target Triple Processing.
426ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek//===----------------------------------------------------------------------===//
427ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
428ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenekstatic llvm::cl::opt<std::string>
429ae3607684c5978dc2d877141015056c9d24f17eaTed KremenekTargetTriple("triple",
430ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)."));
431ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
432ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenekstatic llvm::cl::list<std::string>
433ae3607684c5978dc2d877141015056c9d24f17eaTed KremenekArchs("arch",
434ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  llvm::cl::desc("Specify target architecture (e.g. i686)."));
435ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
436ae3607684c5978dc2d877141015056c9d24f17eaTed Kremeneknamespace {
437ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  class TripleProcessor {
438ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek    llvm::StringMap<char> TriplesProcessed;
439ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek    std::vector<std::string>& triples;
440ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  public:
441ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek    TripleProcessor(std::vector<std::string>& t) :  triples(t) {}
442ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
443ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek    void addTriple(const std::string& t) {
444ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek      if (TriplesProcessed.find(t.c_str(),t.c_str()+t.size()) ==
445ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek          TriplesProcessed.end()) {
446ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek        triples.push_back(t);
447ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek        TriplesProcessed.GetOrCreateValue(t.c_str(),t.c_str()+t.size());
448ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek      }
449ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek    }
450ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  };
451ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek}
452ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
453ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenekstatic void CreateTargetTriples(std::vector<std::string>& triples) {
454ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  // Initialize base triple.  If a -triple option has been specified, use
455ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  // that triple.  Otherwise, default to the host triple.
4566590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner  std::string Triple = TargetTriple;
4576590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner  if (Triple.empty()) Triple = LLVM_HOSTTRIPLE;
458ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
459ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  // Decompose the base triple into "arch" and suffix.
4606590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner  std::string::size_type firstDash = Triple.find("-");
461ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
4629b4ebc21d2b2d1514d30ff34f558dd956297be91Ted Kremenek  if (firstDash == std::string::npos) {
4639b4ebc21d2b2d1514d30ff34f558dd956297be91Ted Kremenek    fprintf(stderr,
4649b4ebc21d2b2d1514d30ff34f558dd956297be91Ted Kremenek            "Malformed target triple: \"%s\" ('-' could not be found).\n",
4656590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner            Triple.c_str());
4666590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner    exit(1);
4679b4ebc21d2b2d1514d30ff34f558dd956297be91Ted Kremenek  }
468ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
4696590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner  std::string suffix(Triple, firstDash+1);
4709b4ebc21d2b2d1514d30ff34f558dd956297be91Ted Kremenek
4719b4ebc21d2b2d1514d30ff34f558dd956297be91Ted Kremenek  if (suffix.empty()) {
4726590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner    fprintf(stderr, "Malformed target triple: \"%s\" (no vendor or OS).\n",
4736590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner            Triple.c_str());
4746590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner    exit(1);
4759b4ebc21d2b2d1514d30ff34f558dd956297be91Ted Kremenek  }
476ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
477ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  // Create triple cacher.
478ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  TripleProcessor tp(triples);
479ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
480ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  // Add the primary triple to our set of triples if we are using the
481ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  // host-triple with no archs or using a specified target triple.
482ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  if (!TargetTriple.getValue().empty() || Archs.empty())
4836590d21767ebc65e22f4dfcf291bf30ca214eb56Chris Lattner    tp.addTriple(Triple);
484ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
485ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek  for (unsigned i = 0, e = Archs.size(); i !=e; ++i)
486ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek    tp.addTriple(Archs[i] + "-" + suffix);
487ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek}
488ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek
489ae3607684c5978dc2d877141015056c9d24f17eaTed Kremenek//===----------------------------------------------------------------------===//
4905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Preprocessor Initialization
4915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
4925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// FIXME: Preprocessor builtins to support.
4945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   -A...    - Play with #assertions
4955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//   -undef   - Undefine all predefined macros
4965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
4985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerD_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix,
4995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer       llvm::cl::desc("Predefine the specified macro"));
5005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
5015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerU_macros("U", llvm::cl::value_desc("macro"), llvm::cl::Prefix,
5025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         llvm::cl::desc("Undefine the specified macro"));
5035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Append a #define line to Buf for Macro.  Macro should be of the form XXX,
5055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
5065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// "#define XXX Y z W".  To get a #define with no value, use "XXX=".
5075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void DefineBuiltinMacro(std::vector<char> &Buf, const char *Macro,
5085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               const char *Command = "#define ") {
5095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Buf.insert(Buf.end(), Command, Command+strlen(Command));
5105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const char *Equal = strchr(Macro, '=')) {
5115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Turn the = into ' '.
5125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Buf.insert(Buf.end(), Macro, Equal);
5135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Buf.push_back(' ');
5145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Buf.insert(Buf.end(), Equal+1, Equal+strlen(Equal));
5155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
5165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Push "macroname 1".
5175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
5185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Buf.push_back(' ');
5195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Buf.push_back('1');
5205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Buf.push_back('\n');
5225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
52453b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner
52553b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner/// InitializePreprocessor - Initialize the preprocessor getting it and the
52653b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner/// environment ready to process a single file. This returns the file ID for the
52753b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner/// input file. If a failure happens, it returns 0.
52853b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner///
52953b0dabbe52219a8057659b90539837394ef0fa1Chris Lattnerstatic unsigned InitializePreprocessor(Preprocessor &PP,
53053b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner                                       const std::string &InFile,
53153b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner                                       std::vector<char> &PredefineBuffer) {
53253b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner
533dee7359a59e6327206ba710cf22f3851e2a0fc48Chris Lattner  FileManager &FileMgr = PP.getFileManager();
53453b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner
53553b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  // Figure out where to get and map in the main file.
536dee7359a59e6327206ba710cf22f3851e2a0fc48Chris Lattner  SourceManager &SourceMgr = PP.getSourceManager();
53753b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  if (InFile != "-") {
53853b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner    const FileEntry *File = FileMgr.getFile(InFile);
5391036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek    if (File) SourceMgr.createMainFileID(File, SourceLocation());
5401036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek    if (SourceMgr.getMainFileID() == 0) {
54153b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner      fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
54253b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner      return 0;
54353b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner    }
54453b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  } else {
54553b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner    llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
5461036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek    if (SB) SourceMgr.createMainFileIDForMemBuffer(SB);
5471036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek    if (SourceMgr.getMainFileID() == 0) {
54853b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner      fprintf(stderr, "Error reading standard input!  Empty?\n");
54953b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner      return 0;
55053b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner    }
5515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Add macros from the command line.
5545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: Should traverse the #define/#undef lists in parallel.
5555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = D_macros.size(); i != e; ++i)
55653b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner    DefineBuiltinMacro(PredefineBuffer, D_macros[i].c_str());
5575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = U_macros.size(); i != e; ++i)
55853b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner    DefineBuiltinMacro(PredefineBuffer, U_macros[i].c_str(), "#undef ");
55953b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner
56053b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  // FIXME: Read any files specified by -imacros or -include.
56153b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner
56253b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  // Null terminate PredefinedBuffer and add it.
56353b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  PredefineBuffer.push_back(0);
56453b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  PP.setPredefines(&PredefineBuffer[0]);
56553b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner
56653b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  // Once we've read this, we're done.
5671036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek  return SourceMgr.getMainFileID();
5685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
5715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Preprocessor include path information.
5725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This tool exports a large number of command line options to control how the
5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// preprocessor searches for header files.  At root, however, the Preprocessor
5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// object takes a very simple interface: a list of directories to search for
5775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
5785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// FIXME: -nostdinc,-nostdinc++
5790c946411566527d625c3ed68769f062ed1cb9931Chris Lattner// FIXME: -imultilib
5805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
5815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// FIXME: -include,-imacros
5825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::opt<bool>
5845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories"));
5855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Various command line options.  These four add directories to each chain.
5875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerF_dirs("F", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
5895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer       llvm::cl::desc("Add directory to framework include search path"));
5905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
5915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerI_dirs("I", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer       llvm::cl::desc("Add directory to include search path"));
5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spenceridirafter_dirs("idirafter", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer               llvm::cl::desc("Add directory to AFTER include search path"));
5965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
5975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spenceriquote_dirs("iquote", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer               llvm::cl::desc("Add directory to QUOTE include search path"));
5995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
6005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerisystem_dirs("isystem", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
6015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            llvm::cl::desc("Add directory to SYSTEM include search path"));
6025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// These handle -iprefix/-iwithprefix/-iwithprefixbefore.
6045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
6055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spenceriprefix_vals("iprefix", llvm::cl::value_desc("prefix"), llvm::cl::Prefix,
6065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             llvm::cl::desc("Set the -iwithprefix/-iwithprefixbefore prefix"));
6075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
6085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spenceriwithprefix_vals("iwithprefix", llvm::cl::value_desc("dir"), llvm::cl::Prefix,
6095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer     llvm::cl::desc("Set directory to SYSTEM include search path with prefix"));
6105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
6115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spenceriwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"),
6125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                       llvm::cl::Prefix,
6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            llvm::cl::desc("Set directory to include search path with prefix"));
6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6150c946411566527d625c3ed68769f062ed1cb9931Chris Lattnerstatic llvm::cl::opt<std::string>
6160c946411566527d625c3ed68769f062ed1cb9931Chris Lattnerisysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::init("/"),
6170c946411566527d625c3ed68769f062ed1cb9931Chris Lattner         llvm::cl::desc("Set the system root directory (usually /)"));
6180c946411566527d625c3ed68769f062ed1cb9931Chris Lattner
6195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Finally, implement the code that groks the options above.
6205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerenum IncludeDirGroup {
6215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Quoted = 0,
6225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Angled,
6235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  System,
6245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  After
6255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic std::vector<DirectoryLookup> IncludeGroup[4];
6285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddPath - Add the specified path to the specified group list.
6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void AddPath(const std::string &Path, IncludeDirGroup Group,
6325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    bool isCXXAware, bool isUserSupplied,
633822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner                    bool isFramework, HeaderSearch &HS) {
634b3de9e798c0227200f1197f8f573b9e1838a42c8Chris Lattner  assert(!Path.empty() && "can't handle empty path here");
635822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  FileManager &FM = HS.getFileMgr();
636b3de9e798c0227200f1197f8f573b9e1838a42c8Chris Lattner
637d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  // Compute the actual path, taking into consideration -isysroot.
638d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  llvm::SmallString<256> MappedPath;
6390c946411566527d625c3ed68769f062ed1cb9931Chris Lattner
640d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  // Handle isysroot.
641d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  if (Group == System) {
64260e4e2b7d125b735bd1f8b5b065dde5663641c43Chris Lattner    // FIXME: Portability.  This should be a sys::Path interface, this doesn't
64360e4e2b7d125b735bd1f8b5b065dde5663641c43Chris Lattner    // handle things like C:\ right, nor win32 \\network\device\blah.
644d66552797f9a34f5b966adbe45234111752678a0Chris Lattner    if (isysroot.size() != 1 || isysroot[0] != '/') // Add isysroot if present.
645d66552797f9a34f5b966adbe45234111752678a0Chris Lattner      MappedPath.append(isysroot.begin(), isysroot.end());
646d66552797f9a34f5b966adbe45234111752678a0Chris Lattner    if (Path[0] != '/')  // If in the system group, add a /.
647d66552797f9a34f5b966adbe45234111752678a0Chris Lattner      MappedPath.push_back('/');
6485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
650d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  MappedPath.append(Path.begin(), Path.end());
651d66552797f9a34f5b966adbe45234111752678a0Chris Lattner
652d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  // Compute the DirectoryLookup type.
6535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DirectoryLookup::DirType Type;
6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (Group == Quoted || Group == Angled)
6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Type = DirectoryLookup::NormalHeaderDir;
6565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  else if (isCXXAware)
6575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Type = DirectoryLookup::SystemHeaderDir;
6585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  else
6595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Type = DirectoryLookup::ExternCSystemHeaderDir;
6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
661d66552797f9a34f5b966adbe45234111752678a0Chris Lattner
662d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  // If the directory exists, add it.
663d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  if (const DirectoryEntry *DE = FM.getDirectory(&MappedPath[0],
664d66552797f9a34f5b966adbe45234111752678a0Chris Lattner                                                 &MappedPath[0]+
665d66552797f9a34f5b966adbe45234111752678a0Chris Lattner                                                 MappedPath.size())) {
666d66552797f9a34f5b966adbe45234111752678a0Chris Lattner    IncludeGroup[Group].push_back(DirectoryLookup(DE, Type, isUserSupplied,
667d66552797f9a34f5b966adbe45234111752678a0Chris Lattner                                                  isFramework));
668d66552797f9a34f5b966adbe45234111752678a0Chris Lattner    return;
669d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  }
670d66552797f9a34f5b966adbe45234111752678a0Chris Lattner
671df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  // Check to see if this is an apple-style headermap (which are not allowed to
672df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  // be frameworks).
673df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  if (!isFramework) {
674df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    if (const FileEntry *FE = FM.getFile(&MappedPath[0],
675df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner                                         &MappedPath[0]+MappedPath.size())) {
6761bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner      if (const HeaderMap *HM = HS.CreateHeaderMap(FE)) {
6771bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner        // It is a headermap, add it to the search path.
678df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner        IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied));
679df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner        return;
680df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner      }
681822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    }
682822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  }
683822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner
684d66552797f9a34f5b966adbe45234111752678a0Chris Lattner  if (Verbose)
685d66552797f9a34f5b966adbe45234111752678a0Chris Lattner    fprintf(stderr, "ignoring nonexistent directory \"%s\"\n", Path.c_str());
6865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// RemoveDuplicates - If there are duplicate directory entries in the specified
6895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// search list, remove the later (dead) ones.
6905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList) {
6918f3dab88f7725c97103a8c91dd2605009d9c755eChris Lattner  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
692df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
693b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner  llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
6945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0; i != SearchList.size(); ++i) {
695b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner    if (SearchList[i].isNormalDir()) {
696b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner      // If this isn't the first time we've seen this dir, remove it.
697b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner      if (SeenDirs.insert(SearchList[i].getDir()))
698b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner        continue;
699b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner
700b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner      if (Verbose)
701b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner        fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
702b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner                SearchList[i].getDir()->getName());
703df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    } else if (SearchList[i].isFramework()) {
704df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner      // If this isn't the first time we've seen this framework dir, remove it.
705df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner      if (SeenFrameworkDirs.insert(SearchList[i].getFrameworkDir()))
706df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner        continue;
707df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner
708df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner      if (Verbose)
709df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner        fprintf(stderr, "ignoring duplicate framework \"%s\"\n",
710df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner                SearchList[i].getFrameworkDir()->getName());
711df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner
712b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner    } else {
713b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner      assert(SearchList[i].isHeaderMap() && "Not a headermap or normal dir?");
714b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner      // If this isn't the first time we've seen this headermap, remove it.
715b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner      if (SeenHeaderMaps.insert(SearchList[i].getHeaderMap()))
716b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner        continue;
717b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner
7185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      if (Verbose)
7195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
7205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                SearchList[i].getDir()->getName());
7215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
722b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner
723b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner    // This is reached if the current entry is a duplicate.
724b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner    SearchList.erase(SearchList.begin()+i);
725b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner    --i;
7265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// InitializeIncludePaths - Process the -I options and set them in the
7305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// HeaderSearch object.
7315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void InitializeIncludePaths(HeaderSearch &Headers, FileManager &FM,
7324f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner                                   const LangOptions &Lang) {
7335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle -F... options.
7345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = F_dirs.size(); i != e; ++i)
735822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath(F_dirs[i], Angled, false, true, true, Headers);
7365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle -I... options.
7384f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner  for (unsigned i = 0, e = I_dirs.size(); i != e; ++i)
739822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath(I_dirs[i], Angled, false, true, false, Headers);
7405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle -idirafter... options.
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i)
743822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath(idirafter_dirs[i], After, false, true, false, Headers);
7445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle -iquote... options.
7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i)
747822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath(iquote_dirs[i], Quoted, false, true, false, Headers);
7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle -isystem... options.
7505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i)
751822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath(isystem_dirs[i], System, false, true, false, Headers);
7525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in
7545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // parallel, processing the values in order of occurance to get the right
7555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // prefixes.
7565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  {
7575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string Prefix = "";  // FIXME: this isn't the correct default prefix.
7585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    unsigned iprefix_idx = 0;
7595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    unsigned iwithprefix_idx = 0;
7605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    unsigned iwithprefixbefore_idx = 0;
7615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool iprefix_done           = iprefix_vals.empty();
7625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool iwithprefix_done       = iwithprefix_vals.empty();
7635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool iwithprefixbefore_done = iwithprefixbefore_vals.empty();
7645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    while (!iprefix_done || !iwithprefix_done || !iwithprefixbefore_done) {
7655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      if (!iprefix_done &&
7665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          (iwithprefix_done ||
7675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           iprefix_vals.getPosition(iprefix_idx) <
7685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           iwithprefix_vals.getPosition(iwithprefix_idx)) &&
7695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          (iwithprefixbefore_done ||
7705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           iprefix_vals.getPosition(iprefix_idx) <
7715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
7725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        Prefix = iprefix_vals[iprefix_idx];
7735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        ++iprefix_idx;
7745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        iprefix_done = iprefix_idx == iprefix_vals.size();
7755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      } else if (!iwithprefix_done &&
7765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                 (iwithprefixbefore_done ||
7775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                  iwithprefix_vals.getPosition(iwithprefix_idx) <
7785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                  iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
7795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        AddPath(Prefix+iwithprefix_vals[iwithprefix_idx],
780822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner                System, false, false, false, Headers);
7815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        ++iwithprefix_idx;
7825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size();
7835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      } else {
7845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx],
785822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner                Angled, false, false, false, Headers);
7865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        ++iwithprefixbefore_idx;
7875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        iwithprefixbefore_done =
7885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          iwithprefixbefore_idx == iwithprefixbefore_vals.size();
7895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      }
7905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
7915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: Add contents of the CPATH, C_INCLUDE_PATH, CPLUS_INCLUDE_PATH,
7945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // OBJC_INCLUDE_PATH, OBJCPLUS_INCLUDE_PATH environment variables.
7955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: temporary hack: hard-coded paths.
7975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: get these from the target?
7985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!nostdinc) {
7995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (Lang.CPlusPlus) {
800822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner      AddPath("/usr/include/c++/4.0.0", System, true, false, false, Headers);
8015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      AddPath("/usr/include/c++/4.0.0/i686-apple-darwin8", System, true, false,
802822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner              false, Headers);
803822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner      AddPath("/usr/include/c++/4.0.0/backward", System, true, false, false,
804822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner              Headers);
8055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
8065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
807822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath("/usr/local/include", System, false, false, false, Headers);
8085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // leopard
8095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    AddPath("/usr/lib/gcc/i686-apple-darwin9/4.0.1/include", System,
810822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner            false, false, false, Headers);
8115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    AddPath("/usr/lib/gcc/powerpc-apple-darwin9/4.0.1/include",
812822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner            System, false, false, false, Headers);
8135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    AddPath("/usr/lib/gcc/powerpc-apple-darwin9/"
8145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            "4.0.1/../../../../powerpc-apple-darwin0/include",
815822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner            System, false, false, false, Headers);
8165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // tiger
8185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    AddPath("/usr/lib/gcc/i686-apple-darwin8/4.0.1/include", System,
819822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner            false, false, false, Headers);
8205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    AddPath("/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/include",
821822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner            System, false, false, false, Headers);
8225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    AddPath("/usr/lib/gcc/powerpc-apple-darwin8/"
8235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            "4.0.1/../../../../powerpc-apple-darwin8/include",
824822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner            System, false, false, false, Headers);
8255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
826822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath("/usr/include", System, false, false, false, Headers);
827822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath("/System/Library/Frameworks", System, true, false, true, Headers);
828822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    AddPath("/Library/Frameworks", System, true, false, true, Headers);
8295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Now that we have collected all of the include paths, merge them all
8325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // together and tell the preprocessor about them.
8335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
8355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::vector<DirectoryLookup> SearchList;
8365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SearchList = IncludeGroup[Angled];
8375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SearchList.insert(SearchList.end(), IncludeGroup[System].begin(),
8385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    IncludeGroup[System].end());
8395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SearchList.insert(SearchList.end(), IncludeGroup[After].begin(),
8405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    IncludeGroup[After].end());
8415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  RemoveDuplicates(SearchList);
8425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  RemoveDuplicates(IncludeGroup[Quoted]);
8435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Prepend QUOTED list on the search list.
8455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SearchList.insert(SearchList.begin(), IncludeGroup[Quoted].begin(),
8465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    IncludeGroup[Quoted].end());
8475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool DontSearchCurDir = false;  // TODO: set to true if -I- is set?
8505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Headers.SetSearchPaths(SearchList, IncludeGroup[Quoted].size(),
8515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                         DontSearchCurDir);
8525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If verbose, print the list of directories that will be searched.
8545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (Verbose) {
8555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    fprintf(stderr, "#include \"...\" search starts here:\n");
8565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    unsigned QuotedIdx = IncludeGroup[Quoted].size();
8575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
8585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      if (i == QuotedIdx)
8595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        fprintf(stderr, "#include <...> search starts here:\n");
8603af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner      const char *Name = SearchList[i].getName();
8613af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner      const char *Suffix;
8620048b5180124b681bfbd36b40d2f48d19018c688Chris Lattner      if (SearchList[i].isNormalDir())
8633af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner        Suffix = "";
8640048b5180124b681bfbd36b40d2f48d19018c688Chris Lattner      else if (SearchList[i].isFramework())
8653af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner        Suffix = " (framework directory)";
8660048b5180124b681bfbd36b40d2f48d19018c688Chris Lattner      else {
8670048b5180124b681bfbd36b40d2f48d19018c688Chris Lattner        assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
8683af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner        Suffix = " (headermap)";
8690048b5180124b681bfbd36b40d2f48d19018c688Chris Lattner      }
8703af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner      fprintf(stderr, " %s%s\n", Name, Suffix);
8715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
87280e1715ddccff4b64cb47b1f26615cc0986f0c2fChris Lattner    fprintf(stderr, "End of search list.\n");
8735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
8785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Basic Parser driver
8795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
8805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
88195041a2029a069386ee67439f6d0fb524a9d184fTed Kremenekstatic void ParseFile(Preprocessor &PP, MinimalAction *PA){
8825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Parser P(PP, *PA);
88395041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek  PP.EnterMainSourceFile();
8845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parsing the specified input file.
8865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  P.ParseTranslationUnit();
8875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  delete PA;
8885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
8915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Main driver
8925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
8935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
894db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek/// CreateASTConsumer - Create the ASTConsumer for the corresponding program
895db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek///  action.  These consumers can operate on both ASTs that are freshly
896db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek///  parsed from source files as well as those deserialized from Bitcode.
897fdfc198013c372c41669957639eac56d27fd57f4Ted Kremenekstatic ASTConsumer* CreateASTConsumer(const std::string& InFile,
898a1fa3a19bf2c4553aa7e7f27ff2a1b3b2e2db62cTed Kremenek                                      Diagnostic& Diag, FileManager& FileMgr,
899db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek                                      const LangOptions& LangOpts) {
900db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek  switch (ProgAction) {
901db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    default:
902db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return NULL;
903db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
904db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case ASTPrint:
905db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateASTPrinter();
906db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
907db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case ASTDump:
908db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateASTDumper();
909db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
910db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case ASTView:
911db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateASTViewer();
912db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
913db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case ParseCFGDump:
914db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case ParseCFGView:
915db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateCFGDumper(ProgAction == ParseCFGView);
916db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
917db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case AnalysisLiveVariables:
918db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateLiveVarAnalyzer();
919db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
920db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case WarnDeadStores:
921db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateDeadStoreChecker(Diag);
922db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
923db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case WarnUninitVals:
924db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateUnitValsChecker(Diag);
925db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
926db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case TestSerialization:
927fdfc198013c372c41669957639eac56d27fd57f4Ted Kremenek      return CreateSerializationTest(Diag, FileMgr, LangOpts);
928db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
929db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case EmitLLVM:
930db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateLLVMEmitter(Diag, LangOpts);
931fe947ad3624ad45bc5ef9fd36a3f9ff00efdb1fdSeo Sanghyeon
932fe947ad3624ad45bc5ef9fd36a3f9ff00efdb1fdSeo Sanghyeon    case EmitBC:
933fe947ad3624ad45bc5ef9fd36a3f9ff00efdb1fdSeo Sanghyeon      return CreateBCWriter(InFile, OutputFile, Diag, LangOpts);
934fe947ad3624ad45bc5ef9fd36a3f9ff00efdb1fdSeo Sanghyeon
9353910c7ceb905a03aeffcb0aa1dc5308d0fc64f4cTed Kremenek    case SerializeAST:
936a1fa3a19bf2c4553aa7e7f27ff2a1b3b2e2db62cTed Kremenek      // FIXME: Allow user to tailor where the file is written.
9371036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek      return CreateASTSerializer(InFile, OutputFile, Diag, LangOpts);
938a1fa3a19bf2c4553aa7e7f27ff2a1b3b2e2db62cTed Kremenek
939db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    case RewriteTest:
940db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return CreateCodeRewriterTest(Diag);
941db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek  }
942db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek}
943db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
9445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ProcessInputFile - Process a single input file with the specified state.
9455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
9467dcc968f17a6ff9088c9651dddccc8d4025a1271Ted Kremenekstatic void ProcessInputFile(Preprocessor &PP, const std::string &InFile,
947dee7359a59e6327206ba710cf22f3851e2a0fc48Chris Lattner                             TextDiagnostics &OurDiagnosticClient) {
948d39bcd838f1980a9f5e3df23cf91c0c435f4b974Ted Kremenek
949d39bcd838f1980a9f5e3df23cf91c0c435f4b974Ted Kremenek  ASTConsumer* Consumer = NULL;
950bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner  bool ClearSourceMgr = false;
951d39bcd838f1980a9f5e3df23cf91c0c435f4b974Ted Kremenek
9525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (ProgAction) {
9535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default:
954fdfc198013c372c41669957639eac56d27fd57f4Ted Kremenek    Consumer = CreateASTConsumer(InFile,
955fdfc198013c372c41669957639eac56d27fd57f4Ted Kremenek                                 PP.getDiagnostics(),
956dee7359a59e6327206ba710cf22f3851e2a0fc48Chris Lattner                                 PP.getFileManager(),
957db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek                                 PP.getLangOptions());
958db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
959db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    if (!Consumer) {
960db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      fprintf(stderr, "Unexpected program action!\n");
961db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek      return;
962db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    }
963fdfc198013c372c41669957639eac56d27fd57f4Ted Kremenek
964db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek    break;
965db094a24e9a1efcd224d69ba34c5f396293605bcTed Kremenek
9665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case DumpTokens: {                 // Token dump mode.
967d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner    Token Tok;
9685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Start parsing the specified input file.
96995041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek    PP.EnterMainSourceFile();
9705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    do {
9715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PP.Lex(Tok);
9725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PP.DumpToken(Tok, true);
9735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      fprintf(stderr, "\n");
974057aaf6304a5f59bcafa7b46c19625bb779af1d1Chris Lattner    } while (Tok.isNot(tok::eof));
975bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner    ClearSourceMgr = true;
9765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
9775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
9785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case RunPreprocessorOnly: {        // Just lex as fast as we can, no output.
979d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner    Token Tok;
9805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Start parsing the specified input file.
98195041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek    PP.EnterMainSourceFile();
9825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    do {
9835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PP.Lex(Tok);
984057aaf6304a5f59bcafa7b46c19625bb779af1d1Chris Lattner    } while (Tok.isNot(tok::eof));
985bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner    ClearSourceMgr = true;
9865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
9875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
9885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
9895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case PrintPreprocessedInput:       // -E mode.
99095041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek    DoPrintPreprocessedInput(PP);
991bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner    ClearSourceMgr = true;
9925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
9935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
9945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ParseNoop:                    // -parse-noop
99595041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek    ParseFile(PP, new MinimalAction(PP.getIdentifierTable()));
996bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner    ClearSourceMgr = true;
9975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
9985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
9995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ParsePrintCallbacks:
100095041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek    ParseFile(PP, CreatePrintParserActionsAction(PP.getIdentifierTable()));
1001bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner    ClearSourceMgr = true;
10025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
1003d39bcd838f1980a9f5e3df23cf91c0c435f4b974Ted Kremenek
10045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ParseSyntaxOnly:              // -fsyntax-only
1005d39bcd838f1980a9f5e3df23cf91c0c435f4b974Ted Kremenek    Consumer = new ASTConsumer();
10065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
1007580980b3d4334016cf60d22bd19cdaad5a4e1256Chris Lattner  }
1008d39bcd838f1980a9f5e3df23cf91c0c435f4b974Ted Kremenek
1009d39bcd838f1980a9f5e3df23cf91c0c435f4b974Ted Kremenek  if (Consumer) {
10109f3d942e9970bc8f51add390b2a2c46b5a2ab747Ted Kremenek    if (VerifyDiagnostics)
101195041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek      exit(CheckASTConsumer(PP, Consumer));
101231e6c7ddfeeefe05b67220bc87fa23d4338d1056Chris Lattner
101331e6c7ddfeeefe05b67220bc87fa23d4338d1056Chris Lattner    // This deletes Consumer.
101495041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek    ParseAST(PP, Consumer, Stats);
10155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (Stats) {
1018fdfc198013c372c41669957639eac56d27fd57f4Ted Kremenek    fprintf(stderr, "\nSTATISTICS FOR '%s':\n", InFile.c_str());
10195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.PrintStats();
10205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.getIdentifierTable().PrintStats();
1021dee7359a59e6327206ba710cf22f3851e2a0fc48Chris Lattner    PP.getHeaderSearchInfo().PrintStats();
1022bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner    if (ClearSourceMgr)
1023dee7359a59e6327206ba710cf22f3851e2a0fc48Chris Lattner      PP.getSourceManager().PrintStats();
10245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    fprintf(stderr, "\n");
10255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1026bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner
1027bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner  // For a multi-file compilation, some things are ok with nuking the source
1028bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner  // manager tables, other require stable fileid/macroid's across multiple
1029bd24776a825a18a59067c68a9d32f2d22e4cbf79Chris Lattner  // files.
1030dee7359a59e6327206ba710cf22f3851e2a0fc48Chris Lattner  if (ClearSourceMgr)
1031dee7359a59e6327206ba710cf22f3851e2a0fc48Chris Lattner    PP.getSourceManager().clearIDTables();
10325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
103420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenekstatic void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
103520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek                                  FileManager& FileMgr) {
103620e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
103720e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  if (VerifyDiagnostics) {
103820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    fprintf(stderr, "-verify does not yet work with serialized ASTs.\n");
103920e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    exit (1);
104020e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  }
104120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
104220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  llvm::sys::Path Filename(InFile);
104320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
104420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  if (!Filename.isValid()) {
104520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    fprintf(stderr, "serialized file '%s' not available.\n",InFile.c_str());
104620e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    exit (1);
104720e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  }
104820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
1049ee533641635fc3e10dd14072972b378be110b21dTed Kremenek  llvm::OwningPtr<TranslationUnit> TU(ReadASTBitcodeFile(Filename,FileMgr));
1050fe4e0156c91ffbf582a7133357af74bed2304acbTed Kremenek
1051fe4e0156c91ffbf582a7133357af74bed2304acbTed Kremenek  if (!TU) {
1052fe4e0156c91ffbf582a7133357af74bed2304acbTed Kremenek    fprintf(stderr, "error: file '%s' could not be deserialized\n",
1053fe4e0156c91ffbf582a7133357af74bed2304acbTed Kremenek            InFile.c_str());
1054fe4e0156c91ffbf582a7133357af74bed2304acbTed Kremenek    exit (1);
1055fe4e0156c91ffbf582a7133357af74bed2304acbTed Kremenek  }
1056fe4e0156c91ffbf582a7133357af74bed2304acbTed Kremenek
105763ea863d4715249551ab10ae207386ddc383419eTed Kremenek  // Observe that we use the source file name stored in the deserialized
105863ea863d4715249551ab10ae207386ddc383419eTed Kremenek  // translation unit, rather than InFile.
1059ee533641635fc3e10dd14072972b378be110b21dTed Kremenek  llvm::OwningPtr<ASTConsumer>
1060fdfc198013c372c41669957639eac56d27fd57f4Ted Kremenek    Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOpts()));
106120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
106220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  if (!Consumer) {
106320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    fprintf(stderr, "Unsupported program action with serialized ASTs!\n");
106420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    exit (1);
106520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  }
106620e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
106795041a2029a069386ee67439f6d0fb524a9d184fTed Kremenek  Consumer->Initialize(*TU->getContext());
106820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
106920e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  for (TranslationUnit::iterator I=TU->begin(), E=TU->end(); I!=E; ++I)
107020e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    Consumer->HandleTopLevelDecl(*I);
107120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek}
107220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
107320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
10745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic llvm::cl::list<std::string>
10755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerInputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>"));
10765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
107720e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenekstatic bool isSerializedFile(const std::string& InFile) {
107820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  if (InFile.size() < 4)
107920e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    return false;
108020e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
108120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  const char* s = InFile.c_str()+InFile.size()-4;
108220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
108320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek  return s[0] == '.' &&
108420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek         s[1] == 'a' &&
108520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek         s[2] == 's' &&
108620e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek         s[3] == 't';
108720e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek}
108820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
10895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerint main(int argc, char **argv) {
10915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::cl::ParseCommandLineOptions(argc, argv, " llvm cfe\n");
10925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::sys::PrintStackTraceOnErrorSignal();
10935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If no input was specified, read from stdin.
10955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (InputFilenames.empty())
10965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    InputFilenames.push_back("-");
109731e703b5883c9fb2bcf0df5370b50c509d49216aTed Kremenek
10985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Create a file manager object to provide access to and cache the filesystem.
10995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager FileMgr;
11005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
110131e703b5883c9fb2bcf0df5370b50c509d49216aTed Kremenek  // Create the diagnostic client for reporting errors or for
110231e703b5883c9fb2bcf0df5370b50c509d49216aTed Kremenek  // implementing -verify.
11035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::auto_ptr<TextDiagnostics> DiagClient;
11049f3d942e9970bc8f51add390b2a2c46b5a2ab747Ted Kremenek  if (!VerifyDiagnostics) {
11055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Print diagnostics to stderr by default.
11067a9d49fd2bfac00e905b361ba76d26ab5b6c3b09Ted Kremenek    DiagClient.reset(new TextDiagnosticPrinter());
11075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
11085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // When checking diagnostics, just buffer them up.
11097a9d49fd2bfac00e905b361ba76d26ab5b6c3b09Ted Kremenek    DiagClient.reset(new TextDiagnosticBuffer());
11105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (InputFilenames.size() != 1) {
11125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      fprintf(stderr,
11139f3d942e9970bc8f51add390b2a2c46b5a2ab747Ted Kremenek              "-verify only works on single input files for now.\n");
11145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return 1;
11155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
11165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Configure our handling of diagnostics.
11195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Diagnostic Diags(*DiagClient);
112031e703b5883c9fb2bcf0df5370b50c509d49216aTed Kremenek  InitializeDiagnostics(Diags);
112131e703b5883c9fb2bcf0df5370b50c509d49216aTed Kremenek
11224f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner  // -I- is a deprecated GCC feature, scan for it and reject it.
11234f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner  for (unsigned i = 0, e = I_dirs.size(); i != e; ++i) {
11244f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner    if (I_dirs[i] == "-") {
11252eefd8657c233bc7c9330acfe475fc270bbe7cabTed Kremenek      Diags.Report(diag::err_pp_I_dash_not_supported);
11264f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner      I_dirs.erase(I_dirs.begin()+i);
11274f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner      --i;
11284f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner    }
11294f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner  }
11304f03783e04baea18f0372cfc626d0ece87b88fa7Chris Lattner
11315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
113231e703b5883c9fb2bcf0df5370b50c509d49216aTed Kremenek    const std::string &InFile = InputFilenames[i];
113331e703b5883c9fb2bcf0df5370b50c509d49216aTed Kremenek
113420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    if (isSerializedFile(InFile))
113520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      ProcessSerializedFile(InFile,Diags,FileMgr);
113620e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    else {
113720e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      /// Create a SourceManager object.  This tracks and owns all the file
113820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      /// buffers allocated to a translation unit.
113920e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      SourceManager SourceMgr;
114031e703b5883c9fb2bcf0df5370b50c509d49216aTed Kremenek
114120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      // Initialize language options, inferring file types from input filenames.
114220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      LangOptions LangInfo;
114320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      InitializeBaseLanguage();
114420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      LangKind LK = GetLanguage(InFile);
114520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      InitializeLangOptions(LangInfo, LK);
114620e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      InitializeLanguageStandard(LangInfo, LK);
114720e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
114820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      // Process the -I options and set them in the HeaderInfo.
114920e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      HeaderSearch HeaderInfo(FileMgr);
115020e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      DiagClient->setHeaderSearch(HeaderInfo);
115120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      InitializeIncludePaths(HeaderInfo, FileMgr, LangInfo);
115220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
115320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      // Get information about the targets being compiled for.  Note that this
115420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      // pointer and the TargetInfoImpl objects are never deleted by this toy
115520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      // driver.
115620e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      TargetInfo *Target;
115720e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
115820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      // Create triples, and create the TargetInfo.
115920e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      std::vector<std::string> triples;
116020e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      CreateTargetTriples(triples);
116120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      Target = TargetInfo::CreateTargetInfo(&triples[0],
116220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek                                            &triples[0]+triples.size(),
116320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek                                            &Diags);
116420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
116520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      if (Target == 0) {
116620e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek        fprintf(stderr, "Sorry, I don't know what target this is: %s\n",
116720e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek                triples[0].c_str());
116820e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek        fprintf(stderr, "Please use -triple or -arch.\n");
116920e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek        exit(1);
117020e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      }
117120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
117220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      // Set up the preprocessor with these options.
117320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      Preprocessor PP(Diags, LangInfo, *Target, SourceMgr, HeaderInfo);
117420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
117520e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      std::vector<char> PredefineBuffer;
11761036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek      if (!InitializePreprocessor(PP, InFile, PredefineBuffer))
117776edd0e4ae0592a7225d50d0bad6732ac64dca2aTed Kremenek        continue;
117876edd0e4ae0592a7225d50d0bad6732ac64dca2aTed Kremenek
11791036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek      ProcessInputFile(PP, InFile, *DiagClient);
118020e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      HeaderInfo.ClearFileInfo();
118120e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek
118220e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek      if (Stats)
118320e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek        SourceMgr.PrintStats();
118420e974886dafeefb1f5a33b57eeaf004e4253da4Ted Kremenek    }
11855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumDiagnostics = Diags.getNumDiagnostics();
11885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (NumDiagnostics)
11905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
11915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            (NumDiagnostics == 1 ? "" : "s"));
11925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (Stats) {
11945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FileMgr.PrintStats();
11955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    fprintf(stderr, "\n");
11965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
119896f1a6403d5011c44ba75e6d70d0779da2413cadChris Lattner  return Diags.getNumErrors() != 0;
11995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1200