summaryrefslogtreecommitdiff
path: root/tools/driver
diff options
context:
space:
mode:
Diffstat (limited to 'tools/driver')
-rw-r--r--tools/driver/CMakeLists.txt1
-rw-r--r--tools/driver/Makefile2
-rw-r--r--tools/driver/cc1_main.cpp2
-rw-r--r--tools/driver/cc1as_main.cpp9
-rw-r--r--tools/driver/driver.cpp105
5 files changed, 100 insertions, 19 deletions
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 552e7a5344279..0c41490175e90 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -23,6 +23,7 @@ set( LLVM_LINK_COMPONENTS
bitreader
bitwriter
codegen
+ instrumentation
ipo
selectiondag
)
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
index d96f9505ffe51..abe70983df42e 100644
--- a/tools/driver/Makefile
+++ b/tools/driver/Makefile
@@ -36,7 +36,7 @@ TOOL_INFO_PLIST := Info.plist
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
- ipo selectiondag
+ instrumentation ipo selectiondag
USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index 7fb394fa5b01a..535eaa9c96f82 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -168,7 +168,7 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd,
// When running with -disable-free, don't do any destruction or shutdown.
if (Clang->getFrontendOpts().DisableFree) {
- if (Clang->getFrontendOpts().ShowStats)
+ if (llvm::AreStatisticsEnabled() || Clang->getFrontendOpts().ShowStats)
llvm::PrintStatistics();
Clang.take();
return !Success;
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 1d544f3d3c9dd..ec6ce65a9b8b6 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -71,6 +71,7 @@ struct AssemblerInvocation {
std::vector<std::string> IncludePaths;
unsigned NoInitialTextSection : 1;
+ unsigned SaveTemporaryLabels : 1;
/// @}
/// @name Frontend Options
@@ -156,6 +157,7 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
// Language Options
Opts.IncludePaths = Args->getAllArgValues(OPT_I);
Opts.NoInitialTextSection = Args->hasArg(OPT_n);
+ Opts.SaveTemporaryLabels = Args->hasArg(OPT_L);
// Frontend Options
if (Args->hasArg(OPT_INPUT)) {
@@ -265,6 +267,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
const TargetAsmInfo *tai = new TargetAsmInfo(*TM);
MCContext Ctx(*MAI, tai);
+ if (Opts.SaveTemporaryLabels)
+ Ctx.setAllowTemporaryLabels(false);
OwningPtr<MCStreamer> Str;
@@ -275,7 +279,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
MCInstPrinter *IP =
- TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI);
+ TheTarget->createMCInstPrinter(*TM, Opts.OutputAsmVariant, *MAI);
MCCodeEmitter *CE = 0;
TargetAsmBackend *TAB = 0;
if (Opts.ShowEncoding) {
@@ -283,7 +287,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
TAB = TheTarget->createAsmBackend(Opts.Triple);
}
Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
- /*useLoc*/ true, IP, CE, TAB,
+ /*useLoc*/ true,
+ /*useCFI*/ true, IP, CE, TAB,
Opts.ShowInst));
} else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
Str.reset(createNullStreamer(Ctx));
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 0b5d2c97a4e7f..db72da42ea348 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -18,6 +18,7 @@
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/OwningPtr.h"
@@ -35,6 +36,8 @@
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetSelect.h"
#include <cctype>
using namespace clang;
using namespace clang::driver;
@@ -252,6 +255,85 @@ static void ExpandArgv(int argc, const char **argv,
}
}
+static void ParseProgName(llvm::SmallVectorImpl<const char *> &ArgVector,
+ std::set<std::string> &SavedStrings,
+ Driver &TheDriver)
+{
+ // Try to infer frontend type and default target from the program name.
+
+ // suffixes[] contains the list of known driver suffixes.
+ // Suffixes are compared against the program name in order.
+ // If there is a match, the frontend type is updated as necessary (CPP/C++).
+ // If there is no match, a second round is done after stripping the last
+ // hyphen and everything following it. This allows using something like
+ // "clang++-2.9".
+
+ // If there is a match in either the first or second round,
+ // 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.
+ static const struct {
+ const char *Suffix;
+ bool IsCXX;
+ bool IsCPP;
+ } suffixes [] = {
+ { "clang", false, false },
+ { "clang++", true, false },
+ { "clang-c++", true, false },
+ { "clang-cc", false, false },
+ { "clang-cpp", false, true },
+ { "clang-g++", true, false },
+ { "clang-gcc", false, false },
+ { "cc", false, false },
+ { "cpp", false, true },
+ { "++", true, false },
+ };
+ std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
+ llvm::StringRef ProgNameRef(ProgName);
+ llvm::StringRef Prefix;
+
+ for (int Components = 2; Components; --Components) {
+ bool FoundMatch = false;
+ size_t i;
+
+ for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
+ if (ProgNameRef.endswith(suffixes[i].Suffix)) {
+ FoundMatch = true;
+ if (suffixes[i].IsCXX)
+ TheDriver.CCCIsCXX = true;
+ if (suffixes[i].IsCPP)
+ TheDriver.CCCIsCPP = true;
+ break;
+ }
+ }
+
+ if (FoundMatch) {
+ llvm::StringRef::size_type LastComponent = ProgNameRef.rfind('-',
+ ProgNameRef.size() - strlen(suffixes[i].Suffix));
+ if (LastComponent != llvm::StringRef::npos)
+ Prefix = ProgNameRef.slice(0, LastComponent);
+ break;
+ }
+
+ llvm::StringRef::size_type LastComponent = ProgNameRef.rfind('-');
+ if (LastComponent == llvm::StringRef::npos)
+ break;
+ ProgNameRef = ProgNameRef.slice(0, LastComponent);
+ }
+
+ if (Prefix.empty())
+ return;
+
+ std::string IgnoredError;
+ if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
+ ArgVector.insert(&ArgVector[1],
+ SaveStringInSet(SavedStrings, Prefix));
+ ArgVector.insert(&ArgVector[1],
+ SaveStringInSet(SavedStrings, std::string("-ccc-host-triple")));
+ }
+}
+
int main(int argc_, const char **argv_) {
llvm::sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc_, argv_);
@@ -328,19 +410,8 @@ int main(int argc_, const char **argv_) {
TheDriver.setInstalledDir(InstalledPath);
}
- // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++
- // compiler. This matches things like "c++", "clang++", and "clang++-1.1".
- //
- // Note that we intentionally want to use argv[0] here, to support "clang++"
- // being a symlink.
- //
- // 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::stem(progname));
- if (llvm::StringRef(ProgName).endswith("++") ||
- llvm::StringRef(ProgName).rsplit('-').first.endswith("++")) {
- TheDriver.CCCIsCXX = true;
- }
+ llvm::InitializeAllTargets();
+ ParseProgName(argv, SavedStrings, TheDriver);
// Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
@@ -352,6 +423,11 @@ int main(int argc_, const char **argv_) {
if (TheDriver.CCPrintHeaders)
TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE");
+ // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE.
+ TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS");
+ 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")) {
@@ -378,8 +454,7 @@ int main(int argc_, const char **argv_) {
argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end());
}
- llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv.size(),
- &argv[0]));
+ llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 0;
if (C.get())
Res = TheDriver.ExecuteCompilation(*C);