diff options
Diffstat (limited to 'tools/driver')
-rw-r--r-- | tools/driver/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tools/driver/Makefile | 29 | ||||
-rw-r--r-- | tools/driver/cc1_main.cpp | 20 | ||||
-rw-r--r-- | tools/driver/cc1as_main.cpp | 33 | ||||
-rw-r--r-- | tools/driver/driver.cpp | 119 |
5 files changed, 121 insertions, 82 deletions
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index 2545610..97ac7a4 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -3,6 +3,7 @@ set( LLVM_LINK_COMPONENTS asmparser bitreader bitwriter + irreader codegen instrumentation ipo @@ -39,6 +40,7 @@ target_link_libraries(clang ) set_target_properties(clang PROPERTIES VERSION ${CLANG_EXECUTABLE_VERSION}) +set_target_properties(clang PROPERTIES ENABLE_EXPORTS 1) add_dependencies(clang clang-headers) diff --git a/tools/driver/Makefile b/tools/driver/Makefile index f07b0f2..cdf3b52 100644 --- a/tools/driver/Makefile +++ b/tools/driver/Makefile @@ -30,14 +30,24 @@ TOOL_INFO_PLIST := Info.plist include $(CLANG_LEVEL)/../../Makefile.config LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \ - instrumentation ipo linker selectiondag + instrumentation ipo irreader linker selectiondag USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \ - clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \ - clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \ - clangStaticAnalyzerCore.a \ - clangAnalysis.a clangARCMigrate.a \ - clangRewriteFrontend.a clangRewriteCore.a \ - clangEdit.a clangAST.a clangLex.a clangBasic.a + clangSerialization.a clangCodeGen.a clangParse.a clangSema.a + +ifeq ($(ENABLE_CLANG_STATIC_ANALYZER),1) +USEDLIBS += clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \ + clangStaticAnalyzerCore.a +endif + +ifeq ($(ENABLE_CLANG_ARCMT),1) +USEDLIBS += clangARCMigrate.a +endif + +ifeq ($(ENABLE_CLANG_REWRITER),1) +USEDLIBS += clangRewriteFrontend.a clangRewriteCore.a +endif + +USEDLIBS += clangAnalysis.a clangEdit.a clangAST.a clangBasic.a clangLex.a include $(CLANG_LEVEL)/Makefile @@ -63,8 +73,3 @@ 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 -endif diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp index f196856..35cf5b8 100644 --- a/tools/driver/cc1_main.cpp +++ b/tools/driver/cc1_main.cpp @@ -15,9 +15,9 @@ #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" -#include "clang/Driver/Options.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/OptTable.h" +#include "clang/Driver/Options.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendDiagnostic.h" @@ -25,12 +25,13 @@ #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/FrontendTool/Utils.h" #include "llvm/ADT/Statistic.h" +#include "llvm/LinkAllPasses.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Signals.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/LinkAllPasses.h" #include <cstdio> using namespace clang; @@ -38,13 +39,20 @@ using namespace clang; // Main driver //===----------------------------------------------------------------------===// -static void LLVMErrorHandler(void *UserData, const std::string &Message) { +static void LLVMErrorHandler(void *UserData, const std::string &Message, + bool GenCrashDiag) { DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData); Diags.Report(diag::err_fe_error_backend) << Message; - // We cannot recover from llvm errors. - exit(1); + // Run the interrupt handlers to make sure any special cleanups get done, in + // particular that we remove files registered with RemoveFileOnSignal. + llvm::sys::RunInterruptHandlers(); + + // We cannot recover from llvm errors. When reporting a fatal error, exit + // with status 70 to generate crash diagnostics. For BSD systems this is + // defined as an internal software error. Otherwise, exit with status 1. + exit(GenCrashDiag ? 70 : 1); } int cc1_main(const char **ArgBegin, const char **ArgEnd, @@ -74,7 +82,7 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd, CompilerInvocation::GetResourcesPath(Argv0, MainAddr); // Create the actual diagnostics engine. - Clang->createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin)); + Clang->createDiagnostics(); if (!Clang->hasDiagnostics()) return 1; diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp index 5587e40..232ea2f 100644 --- a/tools/driver/cc1as_main.cpp +++ b/tools/driver/cc1as_main.cpp @@ -13,45 +13,45 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" -#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/CC1AsOptions.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/OptTable.h" #include "clang/Driver/Options.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Basic/DiagnosticOptions.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" -#include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/FormattedStream.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Host.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/Host.h" #include "llvm/Support/Path.h" +#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -#include "llvm/DataLayout.h" using namespace clang; using namespace clang::driver; using namespace llvm; @@ -83,6 +83,9 @@ struct AssemblerInvocation { unsigned SaveTemporaryLabels : 1; unsigned GenDwarfForAssembly : 1; std::string DwarfDebugFlags; + std::string DwarfDebugProducer; + std::string DebugCompilationDir; + std::string MainFileName; /// @} /// @name Frontend Options @@ -181,6 +184,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, Opts.SaveTemporaryLabels = Args->hasArg(OPT_L); Opts.GenDwarfForAssembly = Args->hasArg(OPT_g); Opts.DwarfDebugFlags = Args->getLastArgValue(OPT_dwarf_debug_flags); + Opts.DwarfDebugProducer = Args->getLastArgValue(OPT_dwarf_debug_producer); + Opts.DebugCompilationDir = Args->getLastArgValue(OPT_fdebug_compilation_dir); + Opts.MainFileName = Args->getLastArgValue(OPT_main_file_name); // Frontend Options if (Args->hasArg(OPT_INPUT)) { @@ -305,6 +311,12 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Ctx.setGenDwarfForAssembly(true); if (!Opts.DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags)); + if (!Opts.DwarfDebugProducer.empty()) + Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer)); + if (!Opts.DebugCompilationDir.empty()) + Ctx.setCompilationDir(Opts.DebugCompilationDir); + if (!Opts.MainFileName.empty()) + Ctx.setMainFileName(StringRef(Opts.MainFileName)); // Build up the feature string from the target feature list. std::string FS; @@ -372,7 +384,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, return Success; } -static void LLVMErrorHandler(void *UserData, const std::string &Message) { +static void LLVMErrorHandler(void *UserData, const std::string &Message, + bool GenCrashDiag) { DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData); Diags.Report(diag::err_fe_error_backend) << Message; diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index 81979ec..4c40da3 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -12,37 +12,37 @@ // //===----------------------------------------------------------------------===// +#include "clang/Basic/CharInfo.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Driver/ArgList.h" -#include "clang/Driver/Options.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" -#include "clang/Driver/Option.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/OptTable.h" +#include "clang/Driver/Option.h" +#include "clang/Driver/Options.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/Utils.h" - #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Host.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/Support/Host.h" #include "llvm/Support/Path.h" +#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Program.h" +#include "llvm/Support/Regex.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -#include <cctype> using namespace clang; using namespace clang::driver; @@ -202,7 +202,7 @@ static void ExpandArgsFromBuf(const char *Arg, std::string CurArg; for (const char *P = Buf; ; ++P) { - if (*P == '\0' || (isspace(*P) && InQuote == ' ')) { + if (*P == '\0' || (isWhitespace(*P) && InQuote == ' ')) { if (!CurArg.empty()) { if (CurArg[0] != '@') { @@ -219,7 +219,7 @@ static void ExpandArgsFromBuf(const char *Arg, continue; } - if (isspace(*P)) { + if (isWhitespace(*P)) { if (InQuote != ' ') CurArg.push_back(*P); continue; @@ -373,6 +373,32 @@ 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. + if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) { + // FIXME: Driver shouldn't take extra initial argument. + ApplyQAOverride(argv, OverrideStr, SavedStrings); + } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) { + // FIXME: Driver shouldn't take extra initial argument. + std::vector<const char*> ExtraArgs; + + for (;;) { + const char *Next = strchr(Cur, ','); + + if (Next) { + ExtraArgs.push_back(SaveStringInSet(SavedStrings, + std::string(Cur, Next))); + Cur = Next + 1; + } else { + if (*Cur != '\0') + ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur)); + break; + } + } + + argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end()); + } + llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes); IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions; @@ -391,19 +417,14 @@ int main(int argc_, const char **argv_) { // DiagnosticOptions instance. TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); - DiagClient->setPrefix(llvm::sys::path::stem(Path.str())); + DiagClient->setPrefix(llvm::sys::path::filename(Path.str())); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); - ProcessWarningOptions(Diags, *DiagOpts); + ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false); -#ifdef CLANG_IS_PRODUCTION - const bool IsProduction = true; -#else - const bool IsProduction = false; -#endif Driver TheDriver(Path.str(), llvm::sys::getDefaultTargetTriple(), - "a.out", IsProduction, Diags); + "a.out", 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 @@ -443,46 +464,34 @@ int main(int argc_, const char **argv_) { if (TheDriver.CCLogDiagnostics) TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE"); - // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a - // command line behind the scenes. - if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) { - // FIXME: Driver shouldn't take extra initial argument. - ApplyQAOverride(argv, OverrideStr, SavedStrings); - } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) { - // FIXME: Driver shouldn't take extra initial argument. - std::vector<const char*> ExtraArgs; - - for (;;) { - const char *Next = strchr(Cur, ','); - - if (Next) { - ExtraArgs.push_back(SaveStringInSet(SavedStrings, - std::string(Cur, Next))); - Cur = Next + 1; - } else { - if (*Cur != '\0') - ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur)); - break; - } - } - - argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end()); - } - OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv)); int Res = 0; - const Command *FailingCommand = 0; + SmallVector<std::pair<int, const Command *>, 4> FailingCommands; if (C.get()) - Res = TheDriver.ExecuteCompilation(*C, FailingCommand); + Res = TheDriver.ExecuteCompilation(*C, FailingCommands); // Force a crash to test the diagnostics. - if(::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) - Res = -1; + if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) { + Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH"; + const Command *FailingCommand = 0; + FailingCommands.push_back(std::make_pair(-1, FailingCommand)); + } - // If result status is < 0, then the driver command signalled an error. - // In this case, generate additional diagnostic information if possible. - if (Res < 0) - TheDriver.generateCompilationDiagnostics(*C, FailingCommand); + for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it = + FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) { + int CommandRes = it->first; + const Command *FailingCommand = it->second; + if (!Res) + Res = CommandRes; + + // If result status is < 0, then the driver command signalled an error. + // If result status is 70, then the driver command reported a fatal error. + // In these cases, generate additional diagnostic information if possible. + if (CommandRes < 0 || CommandRes == 70) { + TheDriver.generateCompilationDiagnostics(*C, FailingCommand); + break; + } + } // If any timers were active but haven't been destroyed yet, print their // results now. This happens in -disable-free mode. @@ -498,5 +507,7 @@ int main(int argc_, const char **argv_) { Res = 1; #endif + // If we have multiple failing commands, we return the result of the first + // failing command. return Res; } |