summaryrefslogtreecommitdiffstats
path: root/tools/driver
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2010-09-17 15:54:40 +0000
committerdim <dim@FreeBSD.org>2010-09-17 15:54:40 +0000
commit36c49e3f258dced101949edabd72e9bc3f1dedc4 (patch)
tree0bbe07708f7571f8b5291f6d7b96c102b7c99dee /tools/driver
parentfc84956ac8b7cd244ef30e7a4d4d38a58dec5904 (diff)
downloadFreeBSD-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.txt5
-rw-r--r--tools/driver/Info.plist.in18
-rw-r--r--tools/driver/Makefile33
-rw-r--r--tools/driver/cc1_main.cpp149
-rw-r--r--tools/driver/cc1as_main.cpp41
-rw-r--r--tools/driver/driver.cpp160
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.
OpenPOWER on IntegriCloud