diff options
Diffstat (limited to 'tools/driver')
-rw-r--r-- | tools/driver/CMakeLists.txt | 34 | ||||
-rw-r--r-- | tools/driver/Makefile | 14 | ||||
-rw-r--r-- | tools/driver/cc1_main.cpp | 10 | ||||
-rw-r--r-- | tools/driver/cc1as_main.cpp | 47 | ||||
-rw-r--r-- | tools/driver/clang_symlink.cmake | 20 | ||||
-rw-r--r-- | tools/driver/driver.cpp | 56 |
6 files changed, 123 insertions, 58 deletions
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index ec6e9c6e8026..6dc47d656cf9 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -1,20 +1,20 @@ -set(LLVM_NO_RTTI 1) - set( LLVM_USED_LIBS - clangFrontendTool - clangFrontend - clangDriver - clangSerialization - clangCodeGen - clangParse - clangSema - clangChecker + clangAST clangAnalysis + clangBasic + clangCodeGen + clangDriver + clangFrontend + clangFrontendTool clangIndex - clangRewrite - clangAST clangLex - clangBasic + clangParse + clangRewrite + clangSema + clangSerialization + clangStaticAnalyzerFrontend + clangStaticAnalyzerCheckers + clangStaticAnalyzerCore ) set( LLVM_LINK_COMPONENTS @@ -35,20 +35,22 @@ add_clang_executable(clang if(UNIX) set(CLANGXX_LINK_OR_COPY create_symlink) - set(CLANGXX_DESTDIR $ENV{DESTDIR}/) else() set(CLANGXX_LINK_OR_COPY copy) endif() # Create the clang++ symlink in the build directory. +set(clang_pp "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}") add_custom_target(clang++ ALL ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}" - "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}" + "${clang_pp}" DEPENDS clang) +set_property(DIRECTORY APPEND + PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${clang_pp}) install(TARGETS clang RUNTIME DESTINATION bin) # Create the clang++ symlink at installation time. -install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E ${CLANGXX_LINK_OR_COPY} \"${CMAKE_INSTALL_PREFIX}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}\" \"${CLANGXX_DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX}\")") +install(SCRIPT clang_symlink.cmake -DCMAKE_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\") diff --git a/tools/driver/Makefile b/tools/driver/Makefile index 447f0e4eb06b..d96f9505ffe5 100644 --- a/tools/driver/Makefile +++ b/tools/driver/Makefile @@ -17,6 +17,16 @@ else endif endif +# We don't currently expect production Clang builds to be interested in +# plugins. This is important for startup performance. +ifdef CLANG_IS_PRODUCTION +TOOL_NO_EXPORTS := 1 +endif + +ifdef CLANG_ORDER_FILE +TOOL_ORDER_FILE := $(CLANG_ORDER_FILE) +endif + # Include tool version information on OS X. TOOL_INFO_PLIST := Info.plist @@ -29,7 +39,9 @@ LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \ ipo selectiondag USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \ clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \ - clangChecker.a clangAnalysis.a clangIndex.a clangRewrite.a \ + clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \ + clangStaticAnalyzerCore.a \ + clangAnalysis.a clangIndex.a clangRewrite.a \ clangAST.a clangLex.a clangBasic.a include $(CLANG_LEVEL)/Makefile diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp index de5e8bf043bf..7fb394fa5b01 100644 --- a/tools/driver/cc1_main.cpp +++ b/tools/driver/cc1_main.cpp @@ -24,7 +24,6 @@ #include "clang/Frontend/TextDiagnosticBuffer.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/FrontendTool/Utils.h" -#include "llvm/LLVMContext.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" @@ -116,13 +115,12 @@ static int cc1_test(Diagnostic &Diags, int cc1_main(const char **ArgBegin, const char **ArgEnd, const char *Argv0, void *MainAddr) { llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); - - Clang->setLLVMContext(new llvm::LLVMContext()); + llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); // Run clang -cc1 test. if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") { - Diagnostic Diags(new TextDiagnosticPrinter(llvm::errs(), - DiagnosticOptions())); + Diagnostic Diags(DiagID, new TextDiagnosticPrinter(llvm::errs(), + DiagnosticOptions())); return cc1_test(Diags, ArgBegin + 1, ArgEnd); } @@ -134,7 +132,7 @@ 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 = new TextDiagnosticBuffer; - Diagnostic Diags(DiagsBuffer); + Diagnostic Diags(DiagID, DiagsBuffer); CompilerInvocation::CreateFromArgs(Clang->getInvocation(), ArgBegin, ArgEnd, Diags); diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp index 5bce70cb2a1b..1d544f3d3c9d 100644 --- a/tools/driver/cc1as_main.cpp +++ b/tools/driver/cc1as_main.cpp @@ -39,12 +39,16 @@ #include "llvm/Support/SourceMgr.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/Signals.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/system_error.h" #include "llvm/Target/TargetAsmBackend.h" +#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetAsmParser.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetSelect.h" @@ -97,6 +101,7 @@ struct AssemblerInvocation { /// @{ unsigned RelaxAll : 1; + unsigned NoExecStack : 1; /// @} @@ -111,6 +116,7 @@ public: ShowInst = 0; ShowEncoding = 0; RelaxAll = 0; + NoExecStack = 0; } static void CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin, @@ -189,6 +195,7 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, // Assemble Options Opts.RelaxAll = Args->hasArg(OPT_relax_all); + Opts.NoExecStack = Args->hasArg(OPT_no_exec_stack); } static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts, @@ -224,11 +231,13 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) { return false; } - MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, &Error); - if (Buffer == 0) { + OwningPtr<MemoryBuffer> BufferPtr; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) { + Error = ec.message(); Diags.Report(diag::err_fe_error_reading) << Opts.InputFile; return false; } + MemoryBuffer *Buffer = BufferPtr.take(); SourceMgr SrcMgr; @@ -242,7 +251,6 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) { OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(Opts.Triple)); assert(MAI && "Unable to create target asm info!"); - MCContext Ctx(*MAI); bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj; formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary); if (!Out) @@ -255,16 +263,28 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) { return false; } + const TargetAsmInfo *tai = new TargetAsmInfo(*TM); + MCContext Ctx(*MAI, tai); + OwningPtr<MCStreamer> Str; + const TargetLoweringObjectFile &TLOF = + TM->getTargetLowering()->getObjFileLowering(); + const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM); + + // FIXME: There is a bit of code duplication with addPassesToEmitFile. if (Opts.OutputType == AssemblerInvocation::FT_Asm) { MCInstPrinter *IP = TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI); MCCodeEmitter *CE = 0; - if (Opts.ShowEncoding) + TargetAsmBackend *TAB = 0; + if (Opts.ShowEncoding) { CE = TheTarget->createCodeEmitter(*TM, Ctx); - Str.reset(createAsmStreamer(Ctx, *Out,TM->getTargetData()->isLittleEndian(), - /*asmverbose*/true, IP, CE, Opts.ShowInst)); + TAB = TheTarget->createAsmBackend(Opts.Triple); + } + Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true, + /*useLoc*/ true, IP, CE, TAB, + Opts.ShowInst)); } else if (Opts.OutputType == AssemblerInvocation::FT_Null) { Str.reset(createNullStreamer(Ctx)); } else { @@ -273,7 +293,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) { MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx); TargetAsmBackend *TAB = TheTarget->createAsmBackend(Opts.Triple); Str.reset(TheTarget->createObjectStreamer(Opts.Triple, Ctx, *TAB, *Out, - CE, Opts.RelaxAll)); + CE, Opts.RelaxAll, + Opts.NoExecStack)); + Str.get()->InitSections(); } OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx, @@ -325,7 +347,8 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(errs(), DiagnosticOptions()); DiagClient->setPrefix("clang -cc1as"); - Diagnostic Diags(DiagClient); + llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + Diagnostic Diags(DiagID, DiagClient); // Set an error handler, so that any LLVM backend diagnostics go through our // error handler. @@ -366,7 +389,7 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, // Execute the invocation, unless there were parsing errors. bool Success = false; - if (!Diags.getNumErrors()) + if (!Diags.hasErrorOccurred()) Success = ExecuteAssembler(Asm, Diags); // If any timers were active but haven't been destroyed yet, print their diff --git a/tools/driver/clang_symlink.cmake b/tools/driver/clang_symlink.cmake new file mode 100644 index 000000000000..40a74824cf2b --- /dev/null +++ b/tools/driver/clang_symlink.cmake @@ -0,0 +1,20 @@ +# We need to execute this script at installation time because the +# DESTDIR environment variable may be unset at configuration time. +# See PR8397. + +if(UNIX) + set(CLANGXX_LINK_OR_COPY create_symlink) + set(CLANGXX_DESTDIR $ENV{DESTDIR}) +else() + set(CLANGXX_LINK_OR_COPY copy) +endif() + +set(bindir "${CLANGXX_DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/") +set(clang "clang${CMAKE_EXECUTABLE_SUFFIX}") +set(clangxx "clang++${CMAKE_EXECUTABLE_SUFFIX}") + +message("Creating clang++ executable based on ${clang}") + +execute_process( + COMMAND "${CMAKE_COMMAND}" -E ${CLANGXX_LINK_OR_COPY} "${clang}" "${clangxx}" + WORKING_DIRECTORY "${bindir}") diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index c058ece0dc9b..0b5d2c97a4e7 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -23,16 +23,19 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/Config/config.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.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" +#include "llvm/Support/Host.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/system_error.h" +#include <cctype> using namespace clang; using namespace clang::driver; @@ -181,8 +184,8 @@ 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) { + llvm::OwningPtr<llvm::MemoryBuffer> MemBuf; + if (llvm::MemoryBuffer::getFile(FName, MemBuf)) { ArgVector.push_back(SaveStringInSet(SavedStrings, Arg)); return; } @@ -233,7 +236,6 @@ static void ExpandArgsFromBuf(const char *Arg, } CurArg.push_back(*P); } - delete MemBuf; } static void ExpandArgv(int argc, const char **argv, @@ -287,8 +289,9 @@ int main(int argc_, const char **argv_) { TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions()); - DiagClient->setPrefix(Path.getBasename()); - Diagnostic Diags(DiagClient); + DiagClient->setPrefix(llvm::sys::path::stem(Path.str())); + llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + Diagnostic Diags(DiagID, DiagClient); #ifdef CLANG_IS_PRODUCTION const bool IsProduction = true; @@ -308,19 +311,22 @@ int main(int argc_, const char **argv_) { // 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; + { + llvm::SmallString<128> InstalledPath(argv[0]); + + // Do a PATH lookup, if there are no directory components. + if (llvm::sys::path::filename(InstalledPath) == InstalledPath) { + llvm::sys::Path Tmp = llvm::sys::Program::FindProgramByName( + llvm::sys::path::filename(InstalledPath.str())); + if (!Tmp.empty()) + InstalledPath = Tmp.str(); + } + llvm::sys::fs::make_absolute(InstalledPath); + InstalledPath = llvm::sys::path::parent_path(InstalledPath); + bool exists; + if (!llvm::sys::fs::exists(InstalledPath.str(), exists) && exists) + TheDriver.setInstalledDir(InstalledPath); } - 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". @@ -330,11 +336,10 @@ int main(int argc_, const char **argv_) { // // We use *argv instead of argv[0] to work around a bogus g++ warning. const char *progname = argv_[0]; - std::string ProgName(llvm::sys::Path(progname).getBasename()); + std::string ProgName(llvm::sys::path::stem(progname)); if (llvm::StringRef(ProgName).endswith("++") || llvm::StringRef(ProgName).rsplit('-').first.endswith("++")) { TheDriver.CCCIsCXX = true; - TheDriver.CCCGenericGCCName = "g++"; } // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE. @@ -342,6 +347,11 @@ int main(int argc_, const char **argv_) { if (TheDriver.CCPrintOptions) TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE"); + // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE. + TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS"); + if (TheDriver.CCPrintHeaders) + TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_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")) { |