diff options
author | dim <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
commit | 50b73317314e889cf39c7b1d6cbf419fa7502f22 (patch) | |
tree | be1815eb79b42ff482a8562b13c2dcbf0c5dcbee /tools/driver | |
parent | dc04cb328508e61aad809d9b53b12f9799a00e7d (diff) | |
download | FreeBSD-src-50b73317314e889cf39c7b1d6cbf419fa7502f22.zip FreeBSD-src-50b73317314e889cf39c7b1d6cbf419fa7502f22.tar.gz |
Vendor import of clang trunk r154661:
http://llvm.org/svn/llvm-project/cfe/trunk@r154661
Diffstat (limited to 'tools/driver')
-rw-r--r-- | tools/driver/CMakeLists.txt | 16 | ||||
-rw-r--r-- | tools/driver/Makefile | 4 | ||||
-rw-r--r-- | tools/driver/cc1_main.cpp | 22 | ||||
-rw-r--r-- | tools/driver/cc1as_main.cpp | 80 | ||||
-rw-r--r-- | tools/driver/driver.cpp | 38 |
5 files changed, 116 insertions, 44 deletions
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index e6d0f1a..c4c864b 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -1,14 +1,16 @@ set( LLVM_USED_LIBS + clangFrontendTool clangAST clangAnalysis clangBasic clangCodeGen clangDriver + clangEdit clangFrontend - clangFrontendTool clangIndex clangLex clangParse + clangEdit clangARCMigrate clangRewrite clangSema @@ -26,6 +28,7 @@ set( LLVM_LINK_COMPONENTS codegen instrumentation ipo + linker selectiondag ) @@ -39,18 +42,17 @@ set_target_properties(clang PROPERTIES VERSION ${CLANG_EXECUTABLE_VERSION}) if(UNIX) set(CLANGXX_LINK_OR_COPY create_symlink) +# Create a relative symlink + set(clang_binary "clang${CMAKE_EXECUTABLE_SUFFIX}") else() set(CLANGXX_LINK_OR_COPY copy) + set(clang_binary "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}") 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}" - "${clang_pp}" - DEPENDS clang) -set_target_properties(clang++ PROPERTIES FOLDER "Clang executables") +add_custom_command(TARGET clang POST_BUILD + COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_pp}") set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${clang_pp}) diff --git a/tools/driver/Makefile b/tools/driver/Makefile index 6b34a99..d828f67 100644 --- a/tools/driver/Makefile +++ b/tools/driver/Makefile @@ -30,13 +30,13 @@ TOOL_INFO_PLIST := Info.plist include $(CLANG_LEVEL)/../../Makefile.config LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \ - instrumentation ipo selectiondag + instrumentation ipo 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 clangIndex.a clangARCMigrate.a clangRewrite.a \ - clangAST.a clangLex.a clangBasic.a + clangEdit.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 27f79b7..a211090 100644 --- a/tools/driver/cc1_main.cpp +++ b/tools/driver/cc1_main.cpp @@ -30,6 +30,7 @@ #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; @@ -76,7 +77,8 @@ static int cc1_test(DiagnosticsEngine &Diags, // Create a compiler invocation. llvm::errs() << "cc1 creating invocation.\n"; CompilerInvocation Invocation; - CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags); + if (!CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags)) + return 1; // Convert the invocation back to argument strings. std::vector<std::string> InvocationArgs; @@ -94,8 +96,9 @@ static int cc1_test(DiagnosticsEngine &Diags, // Convert those arguments to another invocation, and check that we got the // same thing. CompilerInvocation Invocation2; - CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(), - Invocation2Args.end(), Diags); + if (!CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(), + Invocation2Args.end(), Diags)) + return 1; // FIXME: Implement CompilerInvocation comparison. if (true) { @@ -114,8 +117,8 @@ static int cc1_test(DiagnosticsEngine &Diags, int cc1_main(const char **ArgBegin, const char **ArgEnd, const char *Argv0, void *MainAddr) { - llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + OwningPtr<CompilerInstance> Clang(new CompilerInstance()); + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); // Run clang -cc1 test. if (ArgBegin != ArgEnd && StringRef(ArgBegin[0]) == "-cc1test") { @@ -134,8 +137,9 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd, // well formed diagnostic object. TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; DiagnosticsEngine Diags(DiagID, DiagsBuffer); - CompilerInvocation::CreateFromArgs(Clang->getInvocation(), ArgBegin, ArgEnd, - Diags); + bool Success; + Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(), + ArgBegin, ArgEnd, Diags); // Infer the builtin include path if unspecified. if (Clang->getHeaderSearchOpts().UseBuiltinIncludes && @@ -154,9 +158,11 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd, static_cast<void*>(&Clang->getDiagnostics())); DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics()); + if (!Success) + return 1; // Execute the frontend actions. - bool Success = ExecuteCompilerInvocation(Clang.get()); + 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. diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp index 7cc42aa..508d6da 100644 --- a/tools/driver/cc1as_main.cpp +++ b/tools/driver/cc1as_main.cpp @@ -63,8 +63,17 @@ struct AssemblerInvocation { /// @name Target Options /// @{ + /// The name of the target triple to assemble for. std::string Triple; + /// If given, the name of the target CPU to determine which instructions + /// are legal. + std::string CPU; + + /// The list of target specific features to enable or disable -- this should + /// be a list of strings starting with '+' or '-'. + std::vector<std::string> Features; + /// @} /// @name Language Options /// @{ @@ -72,6 +81,8 @@ struct AssemblerInvocation { std::vector<std::string> IncludePaths; unsigned NoInitialTextSection : 1; unsigned SaveTemporaryLabels : 1; + unsigned GenDwarfForAssembly : 1; + std::string DwarfDebugFlags; /// @} /// @name Frontend Options @@ -120,17 +131,19 @@ public: NoExecStack = 0; } - static void CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin, + static bool CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin, const char **ArgEnd, DiagnosticsEngine &Diags); }; } -void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, +bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, const char **ArgBegin, const char **ArgEnd, DiagnosticsEngine &Diags) { using namespace clang::driver::cc1asoptions; + bool Success = true; + // Parse the arguments. OwningPtr<OptTable> OptTbl(createCC1AsOptTable()); unsigned MissingArgIndex, MissingArgCount; @@ -138,26 +151,36 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, OptTbl->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount)); // Check for missing argument error. - if (MissingArgCount) + if (MissingArgCount) { Diags.Report(diag::err_drv_missing_argument) << Args->getArgString(MissingArgIndex) << MissingArgCount; + Success = false; + } // Issue errors on unknown arguments. for (arg_iterator it = Args->filtered_begin(cc1asoptions::OPT_UNKNOWN), - ie = Args->filtered_end(); it != ie; ++it) + ie = Args->filtered_end(); it != ie; ++it) { Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args); + Success = false; + } // Construct the invocation. // Target Options - Opts.Triple = Triple::normalize(Args->getLastArgValue(OPT_triple)); - if (Opts.Triple.empty()) // Use the host triple if unspecified. - Opts.Triple = sys::getHostTriple(); + Opts.Triple = llvm::Triple::normalize(Args->getLastArgValue(OPT_triple)); + Opts.CPU = Args->getLastArgValue(OPT_target_cpu); + Opts.Features = Args->getAllArgValues(OPT_target_feature); + + // Use the default target triple if unspecified. + if (Opts.Triple.empty()) + Opts.Triple = llvm::sys::getDefaultTargetTriple(); // Language Options Opts.IncludePaths = Args->getAllArgValues(OPT_I); Opts.NoInitialTextSection = Args->hasArg(OPT_n); Opts.SaveTemporaryLabels = Args->hasArg(OPT_L); + Opts.GenDwarfForAssembly = Args->hasArg(OPT_g); + Opts.DwarfDebugFlags = Args->getLastArgValue(OPT_dwarf_debug_flags); // Frontend Options if (Args->hasArg(OPT_INPUT)) { @@ -167,8 +190,10 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, const Arg *A = it; if (First) Opts.InputFile = A->getValue(*Args); - else + else { Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args); + Success = false; + } } } Opts.LLVMArgs = Args->getAllArgValues(OPT_mllvm); @@ -182,10 +207,11 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, .Case("null", FT_Null) .Case("obj", FT_Obj) .Default(~0U); - if (OutputType == ~0U) + if (OutputType == ~0U) { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(*Args) << Name; - else + Success = false; + } else Opts.OutputType = FileType(OutputType); } Opts.ShowHelp = Args->hasArg(OPT_help); @@ -200,6 +226,8 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, // Assemble Options Opts.RelaxAll = Args->hasArg(OPT_relax_all); Opts.NoExecStack = Args->hasArg(OPT_no_exec_stack); + + return Success; } static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts, @@ -267,23 +295,36 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); - MCContext Ctx(*MAI, *MRI, MOFI.get()); + MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr); // FIXME: Assembler behavior can change with -static. MOFI->InitMCObjectFileInfo(Opts.Triple, Reloc::Default, CodeModel::Default, Ctx); if (Opts.SaveTemporaryLabels) Ctx.setAllowTemporaryLabels(false); + if (Opts.GenDwarfForAssembly) + Ctx.setGenDwarfForAssembly(true); + if (!Opts.DwarfDebugFlags.empty()) + Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags)); + + // Build up the feature string from the target feature list. + std::string FS; + if (!Opts.Features.empty()) { + FS = Opts.Features[0]; + for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i) + FS += "," + Opts.Features[i]; + } OwningPtr<MCStreamer> Str; OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); OwningPtr<MCSubtargetInfo> - STI(TheTarget->createMCSubtargetInfo(Opts.Triple, "", "")); + STI(TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS)); // FIXME: There is a bit of code duplication with addPassesToEmitFile. if (Opts.OutputType == AssemblerInvocation::FT_Asm) { MCInstPrinter *IP = - TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *STI); + TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI, + *STI); MCCodeEmitter *CE = 0; MCAsmBackend *MAB = 0; if (Opts.ShowEncoding) { @@ -292,7 +333,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, } Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true, /*useLoc*/ true, - /*useCFI*/ true, IP, CE, MAB, + /*useCFI*/ true, + /*useDwarfDirectory*/ true, + IP, CE, MAB, Opts.ShowInst)); } else if (Opts.OutputType == AssemblerInvocation::FT_Null) { Str.reset(createNullStreamer(Ctx)); @@ -354,7 +397,7 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(errs(), DiagnosticOptions()); DiagClient->setPrefix("clang -cc1as"); - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, DiagClient); // Set an error handler, so that any LLVM backend diagnostics go through our @@ -364,11 +407,12 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, // Parse the arguments. AssemblerInvocation Asm; - AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags); + if (!AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags)) + return 1; // Honor -help. if (Asm.ShowHelp) { - llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1AsOptTable()); + OwningPtr<driver::OptTable> Opts(driver::createCC1AsOptTable()); Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler"); return 0; } @@ -391,7 +435,7 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, for (unsigned i = 0; i != NumArgs; ++i) Args[i + 1] = Asm.LLVMArgs[i].c_str(); Args[NumArgs + 1] = 0; - llvm::cl::ParseCommandLineOptions(NumArgs + 1, const_cast<char **>(Args)); + llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args); } // Execute the invocation, unless there were parsing errors. diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index bd1d2a2..8c05fff 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -12,17 +12,21 @@ // //===----------------------------------------------------------------------===// +#include "clang/Driver/ArgList.h" +#include "clang/Driver/CC1Options.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Option.h" +#include "clang/Driver/OptTable.h" +#include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/DiagnosticOptions.h" #include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Frontend/Utils.h" #include "llvm/ADT/ArrayRef.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/FileSystem.h" #include "llvm/Support/ManagedStatic.h" @@ -187,7 +191,7 @@ static void ExpandArgsFromBuf(const char *Arg, SmallVectorImpl<const char*> &ArgVector, std::set<std::string> &SavedStrings) { const char *FName = Arg + 1; - llvm::OwningPtr<llvm::MemoryBuffer> MemBuf; + OwningPtr<llvm::MemoryBuffer> MemBuf; if (llvm::MemoryBuffer::getFile(FName, MemBuf)) { ArgVector.push_back(SaveStringInSet(SavedStrings, Arg)); return; @@ -272,7 +276,7 @@ static void ParseProgName(SmallVectorImpl<const char *> &ArgVector, // the function tries to identify a target as prefix. E.g. // "x86_64-linux-clang" as interpreted as suffix "clang" with // target prefix "x86_64-linux". If such a target prefix is found, - // is gets added via -ccc-host-triple as implicit first argument. + // is gets added via -target as implicit first argument. static const struct { const char *Suffix; bool IsCXX; @@ -332,7 +336,7 @@ static void ParseProgName(SmallVectorImpl<const char *> &ArgVector, ++it; ArgVector.insert(it, SaveStringInSet(SavedStrings, Prefix)); ArgVector.insert(it, - SaveStringInSet(SavedStrings, std::string("-ccc-host-triple"))); + SaveStringInSet(SavedStrings, std::string("-target"))); } } @@ -371,25 +375,41 @@ int main(int argc_, const char **argv_) { llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes); + DiagnosticOptions DiagOpts; + { + // Note that ParseDiagnosticArgs() uses the cc1 option table. + OwningPtr<OptTable> CC1Opts(createCC1OptTable()); + unsigned MissingArgIndex, MissingArgCount; + OwningPtr<InputArgList> Args(CC1Opts->ParseArgs(argv.begin()+1, argv.end(), + MissingArgIndex, MissingArgCount)); + // We ignore MissingArgCount and the return value of ParseDiagnosticArgs. + // Any errors that would be diagnosed here will also be diagnosed later, + // when the DiagnosticsEngine actually exists. + (void) ParseDiagnosticArgs(DiagOpts, *Args); + } + // Now we can create the DiagnosticsEngine with a properly-filled-out + // DiagnosticOptions instance. TextDiagnosticPrinter *DiagClient - = new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions()); + = new TextDiagnosticPrinter(llvm::errs(), DiagOpts); DiagClient->setPrefix(llvm::sys::path::stem(Path.str())); - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + DiagnosticsEngine Diags(DiagID, DiagClient); + ProcessWarningOptions(Diags, DiagOpts); #ifdef CLANG_IS_PRODUCTION const bool IsProduction = true; #else const bool IsProduction = false; #endif - Driver TheDriver(Path.str(), llvm::sys::getHostTriple(), + Driver TheDriver(Path.str(), llvm::sys::getDefaultTargetTriple(), "a.out", IsProduction, 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::SmallString<128> InstalledPath(argv[0]); + SmallString<128> InstalledPath(argv[0]); // Do a PATH lookup, if there are no directory components. if (llvm::sys::path::filename(InstalledPath) == InstalledPath) { @@ -449,7 +469,7 @@ int main(int argc_, const char **argv_) { argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end()); } - llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv)); + OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv)); int Res = 0; const Command *FailingCommand = 0; if (C.get()) |