summaryrefslogtreecommitdiff
path: root/tools/driver
diff options
context:
space:
mode:
Diffstat (limited to 'tools/driver')
-rw-r--r--tools/driver/CMakeLists.txt27
-rw-r--r--tools/driver/Info.plist.in2
-rw-r--r--tools/driver/cc1_main.cpp105
-rw-r--r--tools/driver/cc1as_main.cpp21
-rw-r--r--tools/driver/driver.cpp6
5 files changed, 145 insertions, 16 deletions
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index e03b3fa3951ef..49bde947f4c64 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -24,10 +24,17 @@ if(CLANG_PLUGIN_SUPPORT)
set(LLVM_NO_DEAD_STRIP 1)
endif()
+if(NOT CLANG_BUILT_STANDALONE)
+ set(tablegen_deps intrinsics_gen)
+endif()
+
add_clang_tool(clang
driver.cpp
cc1_main.cpp
cc1as_main.cpp
+
+ DEPENDS
+ ${tablegen_deps}
)
target_link_libraries(clang
@@ -52,7 +59,7 @@ endif()
add_dependencies(clang clang-headers)
if(NOT CLANG_LINKS_TO_CREATE)
- set(CLANG_LINKS_TO_CREATE clang++ clang-cl)
+ set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp)
if (WIN32)
list(APPEND CLANG_LINKS_TO_CREATE ../msbuild-bin/cl)
@@ -74,7 +81,7 @@ if (APPLE)
set(TOOL_INFO_UTI "${CLANG_VENDOR_UTI}")
set(TOOL_INFO_VERSION "${CLANG_VERSION}")
- set(TOOL_INFO_BUILD_VERSION "${LLVM_MAJOR_VERSION}.${LLVM_MINOR_VERSION}")
+ set(TOOL_INFO_BUILD_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}")
set(TOOL_INFO_PLIST_OUT "${CMAKE_CURRENT_BINARY_DIR}/${TOOL_INFO_PLIST}")
target_link_libraries(clang
@@ -101,8 +108,15 @@ if(LD64_EXECUTABLE AND CLANG_ORDER_FILE)
# This is a test to ensure the actual order file works with the linker.
check_linker_flag("-Wl,-order_file,${CLANG_ORDER_FILE}"
LINKER_ORDER_FILE_WORKS)
-
- if(LINKER_ORDER_FILE_WORKS)
+
+ # Passing an empty order file disables some linker layout optimizations.
+ # To work around this and enable workflows for re-linking when the order file
+ # changes we check during configuration if the file is empty, and make it a
+ # configuration dependency.
+ file(READ ${CLANG_ORDER_FILE} ORDER_FILE LIMIT 20)
+ if("${ORDER_FILE}" STREQUAL "\n")
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CLANG_ORDER_FILE})
+ elseif(LINKER_ORDER_FILE_WORKS)
target_link_libraries(clang "-Wl,-order_file,${CLANG_ORDER_FILE}")
set_target_properties(clang PROPERTIES LINK_DEPENDS ${CLANG_ORDER_FILE})
endif()
@@ -110,9 +124,4 @@ endif()
if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
target_link_libraries(clang Polly)
- if(POLLY_LINK_LIBS)
- foreach(lib ${POLLY_LINK_LIBS})
- target_link_libraries(clang ${lib})
- endforeach(lib)
- endif(POLLY_LINK_LIBS)
endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
diff --git a/tools/driver/Info.plist.in b/tools/driver/Info.plist.in
index c938fb053d927..c2b157021df4d 100644
--- a/tools/driver/Info.plist.in
+++ b/tools/driver/Info.plist.in
@@ -7,7 +7,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
- <string>@TOOL_INFO_NAME</string>
+ <string>@TOOL_INFO_NAME@</string>
<key>CFBundleShortVersionString</key>
<string>@TOOL_INFO_VERSION@</string>
<key>CFBundleVersion</key>
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index d78a31e67a2f9..1a16746d589d3 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -15,6 +15,7 @@
#include "llvm/Option/Arg.h"
#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
+#include "clang/Config/config.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
@@ -28,6 +29,7 @@
#include "llvm/LinkAllPasses.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Signals.h"
@@ -35,6 +37,11 @@
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
+
+#ifdef CLANG_HAVE_RLIMITS
+#include <sys/resource.h>
+#endif
+
using namespace clang;
using namespace llvm::opt;
@@ -64,7 +71,105 @@ void initializePollyPasses(llvm::PassRegistry &Registry);
}
#endif
+#ifdef CLANG_HAVE_RLIMITS
+// The amount of stack we think is "sufficient". If less than this much is
+// available, we may be unable to reach our template instantiation depth
+// limit and other similar limits.
+// FIXME: Unify this with the stack we request when spawning a thread to build
+// a module.
+static const int kSufficientStack = 8 << 20;
+
+#if defined(__linux__) && defined(__PIE__)
+static size_t getCurrentStackAllocation() {
+ // If we can't compute the current stack usage, allow for 512K of command
+ // line arguments and environment.
+ size_t Usage = 512 * 1024;
+ if (FILE *StatFile = fopen("/proc/self/stat", "r")) {
+ // We assume that the stack extends from its current address to the end of
+ // the environment space. In reality, there is another string literal (the
+ // program name) after the environment, but this is close enough (we only
+ // need to be within 100K or so).
+ unsigned long StackPtr, EnvEnd;
+ // Disable silly GCC -Wformat warning that complains about length
+ // modifiers on ignored format specifiers. We want to retain these
+ // for documentation purposes even though they have no effect.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#endif
+ if (fscanf(StatFile,
+ "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %*lu "
+ "%*lu %*ld %*ld %*ld %*ld %*ld %*ld %*llu %*lu %*ld %*lu %*lu "
+ "%*lu %*lu %lu %*lu %*lu %*lu %*lu %*lu %*llu %*lu %*lu %*d %*d "
+ "%*u %*u %*llu %*lu %*ld %*lu %*lu %*lu %*lu %*lu %*lu %lu %*d",
+ &StackPtr, &EnvEnd) == 2) {
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+ Usage = StackPtr < EnvEnd ? EnvEnd - StackPtr : StackPtr - EnvEnd;
+ }
+ fclose(StatFile);
+ }
+ return Usage;
+}
+
+#include <alloca.h>
+
+LLVM_ATTRIBUTE_NOINLINE
+static void ensureStackAddressSpace(int ExtraChunks = 0) {
+ // Linux kernels prior to 4.1 will sometimes locate the heap of a PIE binary
+ // relatively close to the stack (they are only guaranteed to be 128MiB
+ // apart). This results in crashes if we happen to heap-allocate more than
+ // 128MiB before we reach our stack high-water mark.
+ //
+ // To avoid these crashes, ensure that we have sufficient virtual memory
+ // pages allocated before we start running.
+ size_t Curr = getCurrentStackAllocation();
+ const int kTargetStack = kSufficientStack - 256 * 1024;
+ if (Curr < kTargetStack) {
+ volatile char *volatile Alloc =
+ static_cast<volatile char *>(alloca(kTargetStack - Curr));
+ Alloc[0] = 0;
+ Alloc[kTargetStack - Curr - 1] = 0;
+ }
+}
+#else
+static void ensureStackAddressSpace() {}
+#endif
+
+/// Attempt to ensure that we have at least 8MiB of usable stack space.
+static void ensureSufficientStack() {
+ struct rlimit rlim;
+ if (getrlimit(RLIMIT_STACK, &rlim) != 0)
+ return;
+
+ // Increase the soft stack limit to our desired level, if necessary and
+ // possible.
+ if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < kSufficientStack) {
+ // Try to allocate sufficient stack.
+ if (rlim.rlim_max == RLIM_INFINITY || rlim.rlim_max >= kSufficientStack)
+ rlim.rlim_cur = kSufficientStack;
+ else if (rlim.rlim_cur == rlim.rlim_max)
+ return;
+ else
+ rlim.rlim_cur = rlim.rlim_max;
+
+ if (setrlimit(RLIMIT_STACK, &rlim) != 0 ||
+ rlim.rlim_cur != kSufficientStack)
+ return;
+ }
+
+ // We should now have a stack of size at least kSufficientStack. Ensure
+ // that we can actually use that much, if necessary.
+ ensureStackAddressSpace();
+}
+#else
+static void ensureSufficientStack() {}
+#endif
+
int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
+ ensureSufficientStack();
+
std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 2d17be99e2d57..263751346b803 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -77,6 +77,9 @@ struct AssemblerInvocation {
/// be a list of strings starting with '+' or '-'.
std::vector<std::string> Features;
+ /// The list of symbol definitions.
+ std::vector<std::string> SymbolDefs;
+
/// @}
/// @name Language Options
/// @{
@@ -252,6 +255,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
Opts.IncrementalLinkerCompatible =
Args.hasArg(OPT_mincremental_linker_compatible);
+ Opts.SymbolDefs = Args.getAllArgValues(OPT_defsym);
return Success;
}
@@ -379,7 +383,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
MCAsmBackend *MAB = nullptr;
if (Opts.ShowEncoding) {
CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
- MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
+ MCTargetOptions Options;
+ MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU, Options);
}
auto FOut = llvm::make_unique<formatted_raw_ostream>(*Out);
Str.reset(TheTarget->createAsmStreamer(
@@ -396,8 +401,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
}
MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
+ MCTargetOptions Options;
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
- Opts.CPU);
+ Opts.CPU, Options);
Triple T(Opts.Triple);
Str.reset(TheTarget->createMCObjectStreamer(
T, Ctx, *MAB, *Out, CE, *STI, Opts.RelaxAll,
@@ -418,6 +424,17 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
if (!TAP)
Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
+ // Set values for symbols, if any.
+ for (auto &S : Opts.SymbolDefs) {
+ auto Pair = StringRef(S).split('=');
+ auto Sym = Pair.first;
+ auto Val = Pair.second;
+ int64_t Value;
+ // We have already error checked this in the driver.
+ Val.getAsInteger(0, Value);
+ Ctx.setSymbolValue(Parser->getStreamer(), Sym, Value);
+ }
+
if (!Failed) {
Parser->setTargetParser(*TAP.get());
Failed = Parser->Run(Opts.NoInitialTextSection);
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 4d69aaffba23e..61613028625b3 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -12,7 +12,6 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Basic/CharInfo.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
@@ -25,7 +24,6 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/llvm-config.h"
@@ -37,7 +35,6 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
@@ -49,6 +46,7 @@
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>
+#include <set>
#include <system_error>
using namespace clang;
using namespace clang::driver;
@@ -395,7 +393,7 @@ int main(int argc_, const char **argv_) {
// Handle CL and _CL_ which permits additional command line options to be
// prepended or appended.
- if (Tokenizer == &llvm::cl::TokenizeWindowsCommandLine) {
+ if (ClangCLMode) {
// Arguments in "CL" are prepended.
llvm::Optional<std::string> OptCL = llvm::sys::Process::GetEnv("CL");
if (OptCL.hasValue()) {