diff options
author | dim <dim@FreeBSD.org> | 2010-09-17 15:54:40 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-09-17 15:54:40 +0000 |
commit | 36c49e3f258dced101949edabd72e9bc3f1dedc4 (patch) | |
tree | 0bbe07708f7571f8b5291f6d7b96c102b7c99dee /tools/driver | |
parent | fc84956ac8b7cd244ef30e7a4d4d38a58dec5904 (diff) | |
download | FreeBSD-src-36c49e3f258dced101949edabd72e9bc3f1dedc4.zip FreeBSD-src-36c49e3f258dced101949edabd72e9bc3f1dedc4.tar.gz |
Vendor import of clang r114020 (from the release_28 branch):
http://llvm.org/svn/llvm-project/cfe/branches/release_28@114020
Approved by: rpaulo (mentor)
Diffstat (limited to 'tools/driver')
-rw-r--r-- | tools/driver/CMakeLists.txt | 5 | ||||
-rw-r--r-- | tools/driver/Info.plist.in | 18 | ||||
-rw-r--r-- | tools/driver/Makefile | 33 | ||||
-rw-r--r-- | tools/driver/cc1_main.cpp | 149 | ||||
-rw-r--r-- | tools/driver/cc1as_main.cpp | 41 | ||||
-rw-r--r-- | tools/driver/driver.cpp | 160 |
6 files changed, 211 insertions, 195 deletions
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index 0eaddba..ec6e9c6 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -1,15 +1,18 @@ set(LLVM_NO_RTTI 1) set( LLVM_USED_LIBS + clangFrontendTool clangFrontend clangDriver + clangSerialization clangCodeGen + clangParse clangSema clangChecker clangAnalysis + clangIndex clangRewrite clangAST - clangParse clangLex clangBasic ) diff --git a/tools/driver/Info.plist.in b/tools/driver/Info.plist.in new file mode 100644 index 0000000..c938fb0 --- /dev/null +++ b/tools/driver/Info.plist.in @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleIdentifier</key> + <string>@TOOL_INFO_UTI@</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>@TOOL_INFO_NAME</string> + <key>CFBundleShortVersionString</key> + <string>@TOOL_INFO_VERSION@</string> + <key>CFBundleVersion</key> + <string>@TOOL_INFO_BUILD_VERSION@</string> + <key>CFBundleSignature</key> + <string>????</string> +</dict> +</plist> diff --git a/tools/driver/Makefile b/tools/driver/Makefile index b049af6..447f0e4 100644 --- a/tools/driver/Makefile +++ b/tools/driver/Makefile @@ -17,6 +17,9 @@ else endif endif +# Include tool version information on OS X. +TOOL_INFO_PLIST := Info.plist + # Include this here so we can get the configuration of the targets that have # been configured for construction. We have to do this early so we can set up # LINK_COMPONENTS before including Makefile.rules @@ -24,12 +27,36 @@ include $(CLANG_LEVEL)/../../Makefile.config LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \ ipo selectiondag -USEDLIBS = clangFrontend.a clangDriver.a clangCodeGen.a clangSema.a \ - clangChecker.a clangAnalysis.a clangRewrite.a clangAST.a \ - clangParse.a clangLex.a clangBasic.a +USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \ + clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \ + clangChecker.a clangAnalysis.a clangIndex.a clangRewrite.a \ + clangAST.a clangLex.a clangBasic.a include $(CLANG_LEVEL)/Makefile +# Set the tool version information values. +ifeq ($(HOST_OS),Darwin) +ifdef CLANG_VENDOR +TOOL_INFO_NAME := $(CLANG_VENDOR) clang +else +TOOL_INFO_NAME := clang +endif + +ifdef CLANG_VENDOR_UTI +TOOL_INFO_UTI := $(CLANG_VENDOR_UTI) +else +TOOL_INFO_UTI := org.llvm.clang +endif + +TOOL_INFO_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \ + $(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc)) +ifdef LLVM_SUBMIT_VERSION +TOOL_INFO_BUILD_VERSION := $(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION) +else +TOOL_INFO_BUILD_VERSION := +endif +endif + # Translate make variable to define when building a "production" clang. ifdef CLANG_IS_PRODUCTION CPP.Defines += -DCLANG_IS_PRODUCTION diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp index 841e40a..de5e8bf 100644 --- a/tools/driver/cc1_main.cpp +++ b/tools/driver/cc1_main.cpp @@ -13,9 +13,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/Diagnostic.h" -#include "clang/Checker/FrontendActions.h" -#include "clang/CodeGen/CodeGenAction.h" #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/CC1Options.h" @@ -23,20 +20,16 @@ #include "clang/Driver/OptTable.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" -#include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Frontend/FrontendPluginRegistry.h" #include "clang/Frontend/TextDiagnosticBuffer.h" #include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Rewrite/FrontendActions.h" +#include "clang/FrontendTool/Utils.h" #include "llvm/LLVMContext.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/System/DynamicLibrary.h" #include "llvm/Target/TargetSelect.h" #include <cstdio> using namespace clang; @@ -54,78 +47,6 @@ static void LLVMErrorHandler(void *UserData, const std::string &Message) { exit(1); } -static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { - using namespace clang::frontend; - - switch (CI.getFrontendOpts().ProgramAction) { - default: - llvm_unreachable("Invalid program action!"); - - case ASTDump: return new ASTDumpAction(); - case ASTPrint: return new ASTPrintAction(); - case ASTPrintXML: return new ASTPrintXMLAction(); - case ASTView: return new ASTViewAction(); - case BoostCon: return new BoostConAction(); - case DumpRawTokens: return new DumpRawTokensAction(); - case DumpTokens: return new DumpTokensAction(); - case EmitAssembly: return new EmitAssemblyAction(); - case EmitBC: return new EmitBCAction(); - case EmitHTML: return new HTMLPrintAction(); - case EmitLLVM: return new EmitLLVMAction(); - case EmitLLVMOnly: return new EmitLLVMOnlyAction(); - case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); - case EmitObj: return new EmitObjAction(); - case FixIt: return new FixItAction(); - case GeneratePCH: return new GeneratePCHAction(); - case GeneratePTH: return new GeneratePTHAction(); - case InheritanceView: return new InheritanceViewAction(); - case InitOnly: return new InitOnlyAction(); - case ParseNoop: return new ParseOnlyAction(); - case ParsePrintCallbacks: return new PrintParseAction(); - case ParseSyntaxOnly: return new SyntaxOnlyAction(); - - case PluginAction: { - - for (FrontendPluginRegistry::iterator it = - FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); - it != ie; ++it) { - if (it->getName() == CI.getFrontendOpts().ActionName) { - PluginASTAction* plugin = it->instantiate(); - plugin->ParseArgs(CI.getFrontendOpts().PluginArgs); - return plugin; - } - } - - CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) - << CI.getFrontendOpts().ActionName; - return 0; - } - - case PrintDeclContext: return new DeclContextPrintAction(); - case PrintPreprocessedInput: return new PrintPreprocessedAction(); - case RewriteMacros: return new RewriteMacrosAction(); - case RewriteObjC: return new RewriteObjCAction(); - case RewriteTest: return new RewriteTestAction(); - case RunAnalysis: return new AnalysisAction(); - case RunPreprocessorOnly: return new PreprocessOnlyAction(); - } -} - -static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { - // Create the underlying action. - FrontendAction *Act = CreateFrontendBaseAction(CI); - if (!Act) - return 0; - - // If there are any AST files to merge, create a frontend action - // adaptor to perform the merge. - if (!CI.getFrontendOpts().ASTMergeFiles.empty()) - Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0], - CI.getFrontendOpts().ASTMergeFiles.size()); - - return Act; -} - // FIXME: Define the need for this testing away. static int cc1_test(Diagnostic &Diags, const char **ArgBegin, const char **ArgEnd) { @@ -200,8 +121,8 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd, // Run clang -cc1 test. if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") { - TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions()); - Diagnostic Diags(&DiagClient); + Diagnostic Diags(new TextDiagnosticPrinter(llvm::errs(), + DiagnosticOptions())); return cc1_test(Diags, ArgBegin + 1, ArgEnd); } @@ -212,8 +133,8 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd, // Buffer diagnostics from argument parsing so that we can output them using a // well formed diagnostic object. - TextDiagnosticBuffer DiagsBuffer; - Diagnostic Diags(&DiagsBuffer); + TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; + Diagnostic Diags(DiagsBuffer); CompilerInvocation::CreateFromArgs(Clang->getInvocation(), ArgBegin, ArgEnd, Diags); @@ -223,35 +144,6 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd, Clang->getHeaderSearchOpts().ResourceDir = CompilerInvocation::GetResourcesPath(Argv0, MainAddr); - // Honor -help. - if (Clang->getFrontendOpts().ShowHelp) { - llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable()); - Opts->PrintHelp(llvm::outs(), "clang -cc1", - "LLVM 'Clang' Compiler: http://clang.llvm.org"); - return 0; - } - - // Honor -version. - // - // FIXME: Use a better -version message? - if (Clang->getFrontendOpts().ShowVersion) { - llvm::cl::PrintVersionMessage(); - return 0; - } - - // Honor -mllvm. - // - // FIXME: Remove this, one day. - if (!Clang->getFrontendOpts().LLVMArgs.empty()) { - unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size(); - const char **Args = new const char*[NumArgs + 2]; - Args[0] = "clang (LLVM option parsing)"; - for (unsigned i = 0; i != NumArgs; ++i) - Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str(); - Args[NumArgs + 1] = 0; - llvm::cl::ParseCommandLineOptions(NumArgs + 1, const_cast<char **>(Args)); - } - // Create the actual diagnostics engine. Clang->createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin)); if (!Clang->hasDiagnostics()) @@ -262,33 +154,20 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd, llvm::install_fatal_error_handler(LLVMErrorHandler, static_cast<void*>(&Clang->getDiagnostics())); - DiagsBuffer.FlushDiagnostics(Clang->getDiagnostics()); + DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics()); - // Load any requested plugins. - for (unsigned i = 0, - e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { - const std::string &Path = Clang->getFrontendOpts().Plugins[i]; - std::string Error; - if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) - Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error; - } - - // If there were errors in processing arguments, don't do anything else. - bool Success = false; - if (!Clang->getDiagnostics().getNumErrors()) { - // Create and execute the frontend action. - llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(*Clang)); - if (Act) { - Success = Clang->ExecuteAction(*Act); - if (Clang->getFrontendOpts().DisableFree) - Act.take(); - } - } + // Execute the frontend actions. + bool Success = ExecuteCompilerInvocation(Clang.get()); // If any timers were active but haven't been destroyed yet, print their // results now. This happens in -disable-free mode. llvm::TimerGroup::printAll(llvm::errs()); - + + // Our error handler depends on the Diagnostics object, which we're + // potentially about to delete. Uninstall the handler now so that any + // later errors use the default handling behavior instead. + llvm::remove_fatal_error_handler(); + // When running with -disable-free, don't do any destruction or shutdown. if (Clang->getFrontendOpts().DisableFree) { if (Clang->getFrontendOpts().ShowStats) diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp index 3c5ca92..5bce70c 100644 --- a/tools/driver/cc1as_main.cpp +++ b/tools/driver/cc1as_main.cpp @@ -24,7 +24,9 @@ #include "clang/Frontend/TextDiagnosticPrinter.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/MC/MCParser/AsmParser.h" +#include "llvm/ADT/Triple.h" +#include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" @@ -141,7 +143,7 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, // Construct the invocation. // Target Options - Opts.Triple = Args->getLastArgValue(OPT_triple); + Opts.Triple = Triple::normalize(Args->getLastArgValue(OPT_triple)); if (Opts.Triple.empty()) // Use the host triple if unspecified. Opts.Triple = sys::getHostTriple(); @@ -253,38 +255,38 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) { return false; } - OwningPtr<MCCodeEmitter> CE; OwningPtr<MCStreamer> Str; - OwningPtr<TargetAsmBackend> TAB; if (Opts.OutputType == AssemblerInvocation::FT_Asm) { MCInstPrinter *IP = TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI); + MCCodeEmitter *CE = 0; if (Opts.ShowEncoding) - CE.reset(TheTarget->createCodeEmitter(*TM, Ctx)); + CE = TheTarget->createCodeEmitter(*TM, Ctx); Str.reset(createAsmStreamer(Ctx, *Out,TM->getTargetData()->isLittleEndian(), - /*asmverbose*/true, IP, CE.get(), - Opts.ShowInst)); + /*asmverbose*/true, IP, CE, Opts.ShowInst)); } else if (Opts.OutputType == AssemblerInvocation::FT_Null) { Str.reset(createNullStreamer(Ctx)); } else { assert(Opts.OutputType == AssemblerInvocation::FT_Obj && "Invalid file type!"); - CE.reset(TheTarget->createCodeEmitter(*TM, Ctx)); - TAB.reset(TheTarget->createAsmBackend(Opts.Triple)); - Str.reset(createMachOStreamer(Ctx, *TAB, *Out, CE.get(), Opts.RelaxAll)); + MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx); + TargetAsmBackend *TAB = TheTarget->createAsmBackend(Opts.Triple); + Str.reset(TheTarget->createObjectStreamer(Opts.Triple, Ctx, *TAB, *Out, + CE, Opts.RelaxAll)); } - AsmParser Parser(*TheTarget, SrcMgr, Ctx, *Str.get(), *MAI); - OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(Parser)); + OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx, + *Str.get(), *MAI)); + OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*Parser, *TM)); if (!TAP) { Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; return false; } - Parser.setTargetParser(*TAP.get()); + Parser->setTargetParser(*TAP.get()); - bool Success = !Parser.Run(Opts.NoInitialTextSection); + bool Success = !Parser->Run(Opts.NoInitialTextSection); // Close the output. delete Out; @@ -320,14 +322,15 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, InitializeAllAsmParsers(); // Construct our diagnostic client. - TextDiagnosticPrinter DiagClient(errs(), DiagnosticOptions()); - DiagClient.setPrefix("clang -cc1as"); - Diagnostic Diags(&DiagClient); + TextDiagnosticPrinter *DiagClient + = new TextDiagnosticPrinter(errs(), DiagnosticOptions()); + DiagClient->setPrefix("clang -cc1as"); + Diagnostic Diags(DiagClient); // Set an error handler, so that any LLVM backend diagnostics go through our // error handler. - install_fatal_error_handler(LLVMErrorHandler, - static_cast<void*>(&Diags)); + ScopedFatalErrorHandler FatalErrorHandler + (LLVMErrorHandler, static_cast<void*>(&Diags)); // Parse the arguments. AssemblerInvocation Asm; diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index c4b12cb..c058ece 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -19,15 +19,19 @@ #include "clang/Frontend/TextDiagnosticPrinter.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Config/config.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Regex.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Host.h" #include "llvm/System/Path.h" +#include "llvm/System/Program.h" #include "llvm/System/Signals.h" using namespace clang; using namespace clang::driver; @@ -75,7 +79,7 @@ static const char *SaveStringInSet(std::set<std::string> &SavedStrings, /// \param Edit - The override command to perform. /// \param SavedStrings - Set to use for storing string representations. static void ApplyOneQAOverride(llvm::raw_ostream &OS, - std::vector<const char*> &Args, + llvm::SmallVectorImpl<const char*> &Args, llvm::StringRef Edit, std::set<std::string> &SavedStrings) { // This does not need to be efficient. @@ -141,7 +145,7 @@ static void ApplyOneQAOverride(llvm::raw_ostream &OS, /// ApplyQAOverride - Apply a comma separate list of edits to the /// input argument lists. See ApplyOneQAOverride. -static void ApplyQAOverride(std::vector<const char*> &Args, +static void ApplyQAOverride(llvm::SmallVectorImpl<const char*> &Args, const char *OverrideStr, std::set<std::string> &SavedStrings) { llvm::raw_ostream *OS = &llvm::errs(); @@ -173,19 +177,97 @@ extern int cc1_main(const char **ArgBegin, const char **ArgEnd, extern int cc1as_main(const char **ArgBegin, const char **ArgEnd, const char *Argv0, void *MainAddr); -int main(int argc, const char **argv) { +static void ExpandArgsFromBuf(const char *Arg, + llvm::SmallVectorImpl<const char*> &ArgVector, + std::set<std::string> &SavedStrings) { + const char *FName = Arg + 1; + llvm::MemoryBuffer *MemBuf = llvm::MemoryBuffer::getFile(FName); + if (!MemBuf) { + ArgVector.push_back(SaveStringInSet(SavedStrings, Arg)); + return; + } + + const char *Buf = MemBuf->getBufferStart(); + char InQuote = ' '; + std::string CurArg; + + for (const char *P = Buf; ; ++P) { + if (*P == '\0' || (isspace(*P) && InQuote == ' ')) { + if (!CurArg.empty()) { + + if (CurArg[0] != '@') { + ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg)); + } else { + ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings); + } + + CurArg = ""; + } + if (*P == '\0') + break; + else + continue; + } + + if (isspace(*P)) { + if (InQuote != ' ') + CurArg.push_back(*P); + continue; + } + + if (*P == '"' || *P == '\'') { + if (InQuote == *P) + InQuote = ' '; + else if (InQuote == ' ') + InQuote = *P; + else + CurArg.push_back(*P); + continue; + } + + if (*P == '\\') { + ++P; + if (*P != '\0') + CurArg.push_back(*P); + continue; + } + CurArg.push_back(*P); + } + delete MemBuf; +} + +static void ExpandArgv(int argc, const char **argv, + llvm::SmallVectorImpl<const char*> &ArgVector, + std::set<std::string> &SavedStrings) { + for (int i = 0; i < argc; ++i) { + const char *Arg = argv[i]; + if (Arg[0] != '@') { + ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg))); + continue; + } + + ExpandArgsFromBuf(Arg, ArgVector, SavedStrings); + } +} + +int main(int argc_, const char **argv_) { llvm::sys::PrintStackTraceOnErrorSignal(); - llvm::PrettyStackTraceProgram X(argc, argv); + llvm::PrettyStackTraceProgram X(argc_, argv_); + + std::set<std::string> SavedStrings; + llvm::SmallVector<const char*, 256> argv; + + ExpandArgv(argc_, argv_, argv, SavedStrings); // Handle -cc1 integrated tools. - if (argc > 1 && llvm::StringRef(argv[1]).startswith("-cc1")) { + if (argv.size() > 1 && llvm::StringRef(argv[1]).startswith("-cc1")) { llvm::StringRef Tool = argv[1] + 4; if (Tool == "") - return cc1_main(argv+2, argv+argc, argv[0], + return cc1_main(argv.data()+2, argv.data()+argv.size(), argv[0], (void*) (intptr_t) GetExecutablePath); if (Tool == "as") - return cc1as_main(argv+2, argv+argc, argv[0], + return cc1as_main(argv.data()+2, argv.data()+argv.size(), argv[0], (void*) (intptr_t) GetExecutablePath); // Reject unknown tools. @@ -194,7 +276,7 @@ int main(int argc, const char **argv) { } bool CanonicalPrefixes = true; - for (int i = 1; i < argc; ++i) { + for (int i = 1, size = argv.size(); i < size; ++i) { if (llvm::StringRef(argv[i]) == "-no-canonical-prefixes") { CanonicalPrefixes = false; break; @@ -203,10 +285,10 @@ int main(int argc, const char **argv) { llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes); - TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions()); - DiagClient.setPrefix(Path.getBasename()); - - Diagnostic Diags(&DiagClient); + TextDiagnosticPrinter *DiagClient + = new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions()); + DiagClient->setPrefix(Path.getBasename()); + Diagnostic Diags(DiagClient); #ifdef CLANG_IS_PRODUCTION const bool IsProduction = true; @@ -219,11 +301,27 @@ int main(int argc, const char **argv) { const bool IsProduction = false; const bool CXXIsProduction = false; #endif - Driver TheDriver(Path.getBasename(), Path.getDirname(), - llvm::sys::getHostTriple(), + Driver TheDriver(Path.str(), llvm::sys::getHostTriple(), "a.out", IsProduction, CXXIsProduction, Diags); + // Attempt to find the original path used to invoke the driver, to determine + // the installed path. We do this manually, because we want to support that + // path being a symlink. + llvm::sys::Path InstalledPath(argv[0]); + + // Do a PATH lookup, if there are no directory components. + if (InstalledPath.getLast() == InstalledPath.str()) { + llvm::sys::Path Tmp = + llvm::sys::Program::FindProgramByName(InstalledPath.getLast()); + if (!Tmp.empty()) + InstalledPath = Tmp; + } + InstalledPath.makeAbsolute(); + InstalledPath.eraseComponent(); + if (InstalledPath.exists()) + TheDriver.setInstalledDir(InstalledPath.str()); + // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++ // compiler. This matches things like "c++", "clang++", and "clang++-1.1". // @@ -231,15 +329,14 @@ int main(int argc, const char **argv) { // being a symlink. // // We use *argv instead of argv[0] to work around a bogus g++ warning. - std::string ProgName(llvm::sys::Path(*argv).getBasename()); + const char *progname = argv_[0]; + std::string ProgName(llvm::sys::Path(progname).getBasename()); if (llvm::StringRef(ProgName).endswith("++") || llvm::StringRef(ProgName).rsplit('-').first.endswith("++")) { TheDriver.CCCIsCXX = true; TheDriver.CCCGenericGCCName = "g++"; } - llvm::OwningPtr<Compilation> C; - // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE. TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS"); if (TheDriver.CCPrintOptions) @@ -247,46 +344,35 @@ int main(int argc, const char **argv) { // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a // command line behind the scenes. - std::set<std::string> SavedStrings; if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) { // FIXME: Driver shouldn't take extra initial argument. - std::vector<const char*> StringPointers(argv, argv + argc); - - ApplyQAOverride(StringPointers, OverrideStr, SavedStrings); - - C.reset(TheDriver.BuildCompilation(StringPointers.size(), - &StringPointers[0])); + ApplyQAOverride(argv, OverrideStr, SavedStrings); } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) { - std::vector<const char*> StringPointers; - // FIXME: Driver shouldn't take extra initial argument. - StringPointers.push_back(argv[0]); + std::vector<const char*> ExtraArgs; for (;;) { const char *Next = strchr(Cur, ','); if (Next) { - StringPointers.push_back(SaveStringInSet(SavedStrings, - std::string(Cur, Next))); + ExtraArgs.push_back(SaveStringInSet(SavedStrings, + std::string(Cur, Next))); Cur = Next + 1; } else { if (*Cur != '\0') - StringPointers.push_back(SaveStringInSet(SavedStrings, Cur)); + ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur)); break; } } - StringPointers.insert(StringPointers.end(), argv + 1, argv + argc); - - C.reset(TheDriver.BuildCompilation(StringPointers.size(), - &StringPointers[0])); - } else - C.reset(TheDriver.BuildCompilation(argc, argv)); + argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end()); + } + llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv.size(), + &argv[0])); int Res = 0; if (C.get()) Res = TheDriver.ExecuteCompilation(*C); - // If any timers were active but haven't been destroyed yet, print their // results now. This happens in -disable-free mode. |