Merge branch 'master' into merge-2.068

This commit is contained in:
Martin 2015-10-02 15:38:02 +02:00
commit 8ee0e250c7
23 changed files with 246 additions and 172 deletions

View file

@ -36,11 +36,12 @@ addons:
- llvm-3.7-dev - llvm-3.7-dev
install: install:
- if [[ "${LLVM_CONFIG}" == *3\.[567]* ]]; then export CC="gcc-4.9"; export CXX="g++-4.9"; fi - if [[ "${LLVM_CONFIG}" == *3\.[567]* ]]; then export CC="gcc-4.9"; export CXX="g++-4.9"; fi
- if [[ "${OPTS}" == *TEST_COVERAGE*ON* ]]; then pip install --user coveralls; fi
env: env:
- LLVM_CONFIG="llvm-config-3.7" - LLVM_CONFIG="llvm-config-3.7" OPTS="-DMULTILIB=ON"
- LLVM_CONFIG="llvm-config-3.6" OPTS="-DMULTILIB=ON" - LLVM_CONFIG="llvm-config-3.6" OPTS="-DBUILD_SHARED_LIBS=ON"
- LLVM_CONFIG="llvm-config-3.5" OPTS="-DBUILD_SHARED_LIBS=ON" - LLVM_CONFIG="llvm-config-3.5" OPTS="-DTEST_COVERAGE=ON"
- LLVM_CONFIG="llvm-config-3.4" OPTS="-DTEST_COVERAGE=ON" - LLVM_CONFIG="llvm-config-3.4"
- LLVM_CONFIG="llvm-config-3.3" - LLVM_CONFIG="llvm-config-3.3"
- LLVM_CONFIG="llvm-config-3.2" - LLVM_CONFIG="llvm-config-3.2"
- LLVM_CONFIG="llvm-config-3.1" - LLVM_CONFIG="llvm-config-3.1"

View file

@ -248,6 +248,7 @@ set(DRV_SRC
driver/cl_options.cpp driver/cl_options.cpp
driver/codegenerator.cpp driver/codegenerator.cpp
driver/configfile.cpp driver/configfile.cpp
driver/exe_path.cpp
driver/targetmachine.cpp driver/targetmachine.cpp
driver/toobj.cpp driver/toobj.cpp
driver/tool.cpp driver/tool.cpp
@ -260,6 +261,7 @@ set(DRV_HDR
driver/cl_options.h driver/cl_options.h
driver/codegenerator.h driver/codegenerator.h
driver/configfile.h driver/configfile.h
driver/exe_path.h
driver/ldc-version.h driver/ldc-version.h
driver/targetmachine.h driver/targetmachine.h
driver/toobj.h driver/toobj.h
@ -498,7 +500,7 @@ endif()
set_source_files_properties(driver/ldmd.cpp driver/response.cpp PROPERTIES set_source_files_properties(driver/ldmd.cpp driver/response.cpp PROPERTIES
COMPILE_FLAGS "${LDC_CXXFLAGS}" COMPILE_FLAGS "${LDC_CXXFLAGS}"
) )
add_executable(${LDMD_EXE} dmd2/root/man.c driver/ldmd.cpp driver/response.cpp) add_executable(${LDMD_EXE} dmd2/root/man.c driver/exe_path.cpp driver/ldmd.cpp driver/response.cpp driver/exe_path.h)
set_target_properties(${LDMD_EXE} PROPERTIES set_target_properties(${LDMD_EXE} PROPERTIES
COMPILE_DEFINITIONS LDC_EXE_NAME="${LDC_EXE_NAME}" COMPILE_DEFINITIONS LDC_EXE_NAME="${LDC_EXE_NAME}"
COMPILE_FLAGS "${LLVM_CXXFLAGS}" COMPILE_FLAGS "${LLVM_CXXFLAGS}"
@ -534,6 +536,10 @@ if(${BUILD_SHARED})
endif() endif()
install(FILES ${PROJECT_BINARY_DIR}/bin/${LDC_EXE}_install.conf DESTINATION ${CONF_INST_DIR} RENAME ${LDC_EXE}.conf) install(FILES ${PROJECT_BINARY_DIR}/bin/${LDC_EXE}_install.conf DESTINATION ${CONF_INST_DIR} RENAME ${LDC_EXE}.conf)
if(MSVC)
install(DIRECTORY vcbuild/ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin FILES_MATCHING PATTERN "*.bat")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
find_package(bash-completion QUIET) find_package(bash-completion QUIET)
if(NOT BASH_COMPLETION_FOUND) if(NOT BASH_COMPLETION_FOUND)

View file

@ -90,10 +90,6 @@ before_build:
build_script: build_script:
- cd c:\projects - cd c:\projects
# Config file templates: add a lib required in combination with VS 2015
- ps: (gc ldc\ldc2.conf.in).replace('@ADDITIONAL_DEFAULT_LDC_SWITCHES@', ', "-Llegacy_stdio_definitions.lib"@ADDITIONAL_DEFAULT_LDC_SWITCHES@') | sc ldc\ldc2.conf.in
- ps: (gc ldc\ldc2_install.conf.in).replace('@ADDITIONAL_DEFAULT_LDC_SWITCHES@', ', "-Llegacy_stdio_definitions.lib"@ADDITIONAL_DEFAULT_LDC_SWITCHES@') | sc ldc\ldc2_install.conf.in
- ps: (gc ldc\ldc2_phobos.conf.in).replace('@ADDITIONAL_DEFAULT_LDC_SWITCHES@', ', "-Llegacy_stdio_definitions.lib"@ADDITIONAL_DEFAULT_LDC_SWITCHES@') | sc ldc\ldc2_phobos.conf.in
# Generate build files for LDC # Generate build files for LDC
- md ninja-ldc - md ninja-ldc
- cd ninja-ldc - cd ninja-ldc

View file

@ -83,6 +83,10 @@ if ((WIN32 AND NOT(MINGW OR CYGWIN)) OR NOT LLVM_CONFIG)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfodwarf" index) list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfodwarf" index)
list(APPEND LLVM_FIND_COMPONENTS "debuginfo") list(APPEND LLVM_FIND_COMPONENTS "debuginfo")
endif() endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[8-9][\\.0-9A-Za-z]*")
# Versions beginning with 3.8 do not support component ipa
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "ipa" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*") if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
llvm_map_components_to_libraries(tmplibs ${LLVM_FIND_COMPONENTS}) llvm_map_components_to_libraries(tmplibs ${LLVM_FIND_COMPONENTS})
@ -163,6 +167,10 @@ else()
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfodwarf" index) list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfodwarf" index)
list(APPEND LLVM_FIND_COMPONENTS "debuginfo") list(APPEND LLVM_FIND_COMPONENTS "debuginfo")
endif() endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[8-9][\\.0-9A-Za-z]*")
# Versions beginning with 3.8 do not support component ipa
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "ipa" index)
endif()
llvm_set(LDFLAGS ldflags) llvm_set(LDFLAGS ldflags)
if(NOT ${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*") if(NOT ${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")

View file

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "driver/configfile.h" #include "driver/configfile.h"
#include "driver/exe_path.h"
#include "mars.h" #include "mars.h"
#include "libconfig.h" #include "libconfig.h"
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
@ -51,16 +52,6 @@ std::string getUserHomeDirectory() {
} }
#endif #endif
#if LDC_LLVM_VER >= 304
static std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
return sys::fs::getMainExecutable(argv0, MainExecAddr);
}
#else
static std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
return llvm::sys::Path::GetMainExecutable(argv0, MainExecAddr).str();
}
#endif
#if _WIN32 #if _WIN32
static bool ReadPathFromRegistry(llvm::SmallString<128> &p) static bool ReadPathFromRegistry(llvm::SmallString<128> &p)
{ {
@ -98,7 +89,7 @@ ConfigFile::~ConfigFile()
} }
bool ConfigFile::locate(llvm::SmallString<128> &p, const char* argv0, void* mainAddr, const char* filename) bool ConfigFile::locate(llvm::SmallString<128>& p, const char* filename)
{ {
// temporary configuration // temporary configuration
@ -111,9 +102,7 @@ bool ConfigFile::locate(llvm::SmallString<128> &p, const char* argv0, void* main
} }
// try next to the executable // try next to the executable
p = getMainExecutable(argv0, mainAddr); p = exe_path::prependBinDir(filename);
sys::path::remove_filename(p);
sys::path::append(p, filename);
if (sys::fs::exists(p.str())) if (sys::fs::exists(p.str()))
return true; return true;
@ -138,9 +127,7 @@ bool ConfigFile::locate(llvm::SmallString<128> &p, const char* argv0, void* main
// try in etc relative to the executable: exe\..\etc // try in etc relative to the executable: exe\..\etc
// do not use .. in path because of security risks // do not use .. in path because of security risks
p = getMainExecutable(argv0, mainAddr); p = exe_path::getBaseDir();
sys::path::remove_filename(p);
sys::path::remove_filename(p);
if (!p.empty()) if (!p.empty())
{ {
sys::path::append(p, "etc"); sys::path::append(p, "etc");
@ -190,10 +177,10 @@ bool ConfigFile::locate(llvm::SmallString<128> &p, const char* argv0, void* main
return false; return false;
} }
bool ConfigFile::read(const char* argv0, void* mainAddr, const char* filename) bool ConfigFile::read(const char* filename)
{ {
llvm::SmallString<128> p; llvm::SmallString<128> p;
if (!locate(p, argv0, mainAddr, filename)) if (!locate(p, filename))
{ {
// failed to find cfg, users still have the DFLAGS environment var // failed to find cfg, users still have the DFLAGS environment var
std::cerr << "Error failed to locate the configuration file: " << filename << std::endl; std::cerr << "Error failed to locate the configuration file: " << filename << std::endl;
@ -228,7 +215,7 @@ bool ConfigFile::read(const char* argv0, void* mainAddr, const char* filename)
{ {
std::string binpathkey = "%%ldcbinarypath%%"; std::string binpathkey = "%%ldcbinarypath%%";
std::string binpath = sys::path::parent_path(getMainExecutable(argv0, mainAddr)); std::string binpath = exe_path::getBinDir();
int len = config_setting_length(sw); int len = config_setting_length(sw);
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)

View file

@ -29,7 +29,7 @@ public:
ConfigFile(); ConfigFile();
~ConfigFile(); ~ConfigFile();
bool read(const char* argv0, void* mainAddr, const char* filename); bool read(const char* filename);
s_iterator switches_begin() { return switches.begin(); } s_iterator switches_begin() { return switches.begin(); }
s_iterator switches_end() { return switches.end(); } s_iterator switches_end() { return switches.end(); }
@ -37,7 +37,7 @@ public:
const std::string& path() { return pathstr; } const std::string& path() { return pathstr; }
private: private:
bool locate(llvm::SmallString<128> &path, const char* argv0, void* mainAddr, const char* filename); bool locate(llvm::SmallString<128> &path, const char* filename);
config_t* cfg; config_t* cfg;
std::string pathstr; std::string pathstr;

56
driver/exe_path.cpp Normal file
View file

@ -0,0 +1,56 @@
//===-- exe_path.cpp ------------------------------------------------------===//
//
// LDC the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
#include "exe_path.h"
#include <llvm/Support/Path.h>
#if LDC_LLVM_VER >= 304
#include <llvm/Support/FileSystem.h>
#endif
using std::string;
namespace path = llvm::sys::path;
namespace { string exePath; }
void exe_path::initialize(const char* arg0, void* mainAddress)
{
assert(exePath.empty());
#if LDC_LLVM_VER >= 304
exePath = llvm::sys::fs::getMainExecutable(arg0, mainAddress);
#else
exePath = llvm::sys::Path::GetMainExecutable(arg0, mainAddress).str();
#endif
}
const string& exe_path::getExePath()
{
assert(!exePath.empty());
return exePath;
}
string exe_path::getBinDir()
{
assert(!exePath.empty());
return path::parent_path(exePath);
}
string exe_path::getBaseDir()
{
string binDir = getBinDir();
assert(!binDir.empty());
return path::parent_path(binDir);
}
string exe_path::prependBinDir(const char* suffix)
{
llvm::SmallString<128> r(getBinDir());
path::append(r, suffix);
return r.str();
}

30
driver/exe_path.h Normal file
View file

@ -0,0 +1,30 @@
//===-- driver/exe_path.h - Executable path management ----------*- C++ -*-===//
//
// LDC the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
//
// Stores the program's executable path and provides some helpers to generate
// derived paths.
//
//===----------------------------------------------------------------------===//
#ifndef LDC_DRIVER_EXE_PATH_H
#define LDC_DRIVER_EXE_PATH_H
#include <string>
namespace exe_path
{
void initialize(const char* arg0, void* mainAddress);
const std::string& getExePath(); // <baseDir>/bin/ldc2
std::string getBinDir(); // <baseDir>/bin
std::string getBaseDir(); // <baseDir>
std::string prependBinDir(const char* suffix); // <baseDir>/bin/<suffix>
}
#endif // LDC_DRIVER_EXE_PATH_H

View file

@ -48,6 +48,7 @@
# error "Please define LDC_EXE_NAME to the name of the LDC executable to use." # error "Please define LDC_EXE_NAME to the name of the LDC executable to use."
#endif #endif
#include "driver/exe_path.h"
#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h" #include "llvm/Support/Path.h"
@ -94,58 +95,8 @@ error_code createUniqueFile(const Twine &Model, int &ResultFD,
} }
#endif #endif
#if LDC_LLVM_VER >= 304
std::string getEXESuffix() {
#if _WIN32
return "exe";
#else
return llvm::StringRef();
#endif
}
#else
std::string getEXESuffix() {
return ls::Path::GetEXESuffix().str();
}
#endif
#if LDC_LLVM_VER >= 304
namespace llvm {
/// Prepend the path to the program being executed
/// to \p ExeName, given the value of argv[0] and the address of main()
/// itself. This allows us to find another LLVM tool if it is built in the same
/// directory. An empty string is returned on error; note that this function
/// just mainpulates the path and doesn't check for executability.
/// @brief Find a named executable.
static std::string prependMainExecutablePath(const std::string &ExeName,
const char *Argv0, void *MainAddr) {
// Check the directory that the calling program is in. We can do
// this if ProgramPath contains at least one / character, indicating that it
// is a relative path to the executable itself.
llvm::SmallString<128> Result(ls::fs::getMainExecutable(Argv0, MainAddr));
sys::path::remove_filename(Result);
if (!Result.empty()) {
sys::path::append(Result, ExeName);
// Do not use path::append here, this is not a path component before which
// to insert the path seperator.
Result.append(getEXESuffix());
}
return Result.str();
}
}
#else
namespace llvm {
static std::string prependMainExecutablePath(const std::string &ExeName,
const char *Argv0, void *MainAddr) {
return llvm::PrependMainExecutablePath(ExeName, Argv0, MainAddr).str();
}
}
#endif
// We reuse DMD's response file parsing routine for maximum compatibilty - it // We reuse DMD's response file parsing routine for maximum compatibilty - it
// handles quotes in a very peciuliar way. // handles quotes in a very peculiar way.
int response_expand(size_t *pargc, char ***pargv); int response_expand(size_t *pargc, char ***pargv);
void browse(const char *url); void browse(const char *url);
@ -1090,10 +1041,9 @@ size_t maxCommandLineLen()
* nothing was found. Search paths: 1. Directory where this binary resides. * nothing was found. Search paths: 1. Directory where this binary resides.
* 2. System PATH. * 2. System PATH.
*/ */
std::string locateBinary(std::string exeName, const char* argv0) std::string locateBinary(std::string exeName)
{ {
std::string path = llvm::prependMainExecutablePath(exeName, std::string path = exe_path::prependBinDir(exeName.c_str());
argv0, (void*)&locateBinary);
if (ls::fs::can_execute(path)) return path; if (ls::fs::can_execute(path)) return path;
#if LDC_LLVM_VER >= 306 #if LDC_LLVM_VER >= 306
@ -1130,7 +1080,13 @@ static size_t addStrlen(size_t acc, const char* str)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
std::string ldcPath = locateBinary(LDC_EXE_NAME, argv[0]); exe_path::initialize(argv[0], reinterpret_cast<void*>(main));
std::string ldcExeName = LDC_EXE_NAME;
#ifdef _WIN32
ldcExeName += ".exe";
#endif
std::string ldcPath = locateBinary(ldcExeName);
if (ldcPath.empty()) if (ldcPath.empty())
{ {
error("Could not locate " LDC_EXE_NAME " executable."); error("Could not locate " LDC_EXE_NAME " executable.");

View file

@ -12,6 +12,7 @@
#include "module.h" #include "module.h"
#include "root.h" #include "root.h"
#include "driver/cl_options.h" #include "driver/cl_options.h"
#include "driver/exe_path.h"
#include "driver/tool.h" #include "driver/tool.h"
#include "gen/llvm.h" #include "gen/llvm.h"
#include "gen/logger.h" #include "gen/logger.h"
@ -277,42 +278,58 @@ static int linkObjToBinaryGcc(bool sharedLib)
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
static bool setupMSVCEnvironment(std::string& tool, std::vector<std::string>& args)
{
// if the VSINSTALLDIR environment variable is NOT set,
// the environment is most likely not set up properly
bool setup = !getenv("VSINSTALLDIR");
if (setup)
{
// use a helper batch file to let MSVC set up the environment and
// then invoke the tool
args.push_back(tool); // tool is first arg for batch file
tool = exe_path::prependBinDir(
global.params.targetTriple.isArch64Bit() ? "amd64.bat" : "x86.bat");
}
else
tool = getProgram(tool.c_str());
return setup;
}
//////////////////////////////////////////////////////////////////////////////
static int linkObjToBinaryWin(bool sharedLib) static int linkObjToBinaryWin(bool sharedLib)
{ {
Logger::println("*** Linking executable ***"); Logger::println("*** Linking executable ***");
// find link.exe for linking std::string tool = "link.exe";
std::string tool(getLink());
// build arguments // build arguments
std::vector<std::string> args; std::vector<std::string> args;
const bool setupMSVC = setupMSVCEnvironment(tool, args);
args.push_back("/NOLOGO"); args.push_back("/NOLOGO");
// specify that the image will contain a table of safe exception handlers (32bit only) // specify that the image will contain a table of safe exception handlers (32bit only)
if (!global.params.is64bit) if (!global.params.is64bit)
args.push_back("/SAFESEH"); args.push_back("/SAFESEH");
// mark executable to be compatible with Windows Data Execution Prevention feature // because of a LLVM bug, see LDC issue 442
args.push_back("/NXCOMPAT");
// use address space layout randomization (ASLR) feature
args.push_back("/DYNAMICBASE");
// because of a LLVM bug
// most of the bug is fixed in LLVM 3.4
#if LDC_LLVM_VER < 304
if (global.params.symdebug) if (global.params.symdebug)
args.push_back("/LARGEADDRESSAWARE:NO"); args.push_back("/LARGEADDRESSAWARE:NO");
else else
#endif args.push_back("/LARGEADDRESSAWARE");
args.push_back("/LARGEADDRESSAWARE");
// output debug information // output debug information
if (global.params.symdebug) if (global.params.symdebug)
{
args.push_back("/DEBUG"); args.push_back("/DEBUG");
}
// enable Link-time Code Generation (aka. whole program optimization)
if (global.params.optimize)
args.push_back("/LTCG");
// remove dead code and fold identical COMDATs // remove dead code and fold identical COMDATs
if (opts::disableLinkerStripDead) if (opts::disableLinkerStripDead)
@ -356,7 +373,7 @@ static int linkObjToBinaryWin(bool sharedLib)
// additional linker switches // additional linker switches
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) for (unsigned i = 0; i < global.params.linkswitches->dim; i++)
{ {
std::string str(static_cast<const char *>(global.params.linkswitches->data[i])); std::string str = global.params.linkswitches->data[i];
if (str.length() > 2) if (str.length() > 2)
{ {
// rewrite common -L and -l switches // rewrite common -L and -l switches
@ -385,6 +402,7 @@ static int linkObjToBinaryWin(bool sharedLib)
Logger::println("Linking with: "); Logger::println("Linking with: ");
std::vector<std::string>::const_iterator I = args.begin(), E = args.end(); std::vector<std::string>::const_iterator I = args.begin(), E = args.end();
if (setupMSVC) ++I; // skip link.exe, the first arg for the batch file
Stream logstr = Logger::cout(); Stream logstr = Logger::cout();
for (; I != E; ++I) for (; I != E; ++I)
if (!(*I).empty()) if (!(*I).empty())
@ -424,11 +442,14 @@ void createStaticLibrary()
#endif #endif
// find archiver // find archiver
std::string tool(isTargetWindows ? getLib() : getArchiver()); std::string tool(isTargetWindows ? "lib.exe" : getArchiver());
// build arguments // build arguments
std::vector<std::string> args; std::vector<std::string> args;
if (isTargetWindows)
setupMSVCEnvironment(tool, args);
// ask ar to create a new library // ask ar to create a new library
if (!isTargetWindows) if (!isTargetWindows)
args.push_back("rcs"); args.push_back("rcs");
@ -437,6 +458,10 @@ void createStaticLibrary()
if (isTargetWindows) if (isTargetWindows)
args.push_back("/NOLOGO"); args.push_back("/NOLOGO");
// enable Link-time Code Generation (aka. whole program optimization)
if (isTargetWindows && global.params.optimize)
args.push_back("/LTCG");
// output filename // output filename
std::string libName; std::string libName;
if (global.params.objname) if (global.params.objname)

View file

@ -17,7 +17,6 @@
/** /**
* Link an executable only from object files. * Link an executable only from object files.
* @param argv0 the argv[0] value as passed to main
* @return 0 on success. * @return 0 on success.
*/ */
int linkObjToBinary(bool sharedLib); int linkObjToBinary(bool sharedLib);

View file

@ -23,6 +23,7 @@
#include "driver/cl_options.h" #include "driver/cl_options.h"
#include "driver/codegenerator.h" #include "driver/codegenerator.h"
#include "driver/configfile.h" #include "driver/configfile.h"
#include "driver/exe_path.h"
#include "driver/ldc-version.h" #include "driver/ldc-version.h"
#include "driver/linker.h" #include "driver/linker.h"
#include "driver/targetmachine.h" #include "driver/targetmachine.h"
@ -103,18 +104,6 @@ static cl::opt<bool> linkDebugLib("link-debuglib",
cl::desc("Link with libraries specified in -debuglib, not -defaultlib"), cl::desc("Link with libraries specified in -debuglib, not -defaultlib"),
cl::ZeroOrMore); cl::ZeroOrMore);
#if LDC_LLVM_VER < 304
namespace llvm {
namespace sys {
namespace fs {
static std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
return llvm::sys::Path::GetMainExecutable(argv0, MainExecAddr).str();
}
}
}
}
#endif
void printVersion() { void printVersion() {
printf("LDC - the LLVM D compiler (%s):\n", global.ldc_version); printf("LDC - the LLVM D compiler (%s):\n", global.ldc_version);
printf(" based on DMD %s and LLVM %s\n", global.version, global.llvm_version); printf(" based on DMD %s and LLVM %s\n", global.version, global.llvm_version);
@ -263,16 +252,7 @@ int main(int argc, char **argv);
/// ///
/// Returns a list of source file names. /// Returns a list of source file names.
static void parseCommandLine(int argc, char **argv, Strings &sourceFiles, bool &helpOnly) { static void parseCommandLine(int argc, char **argv, Strings &sourceFiles, bool &helpOnly) {
#if _WIN32 global.params.argv0 = exe_path::getExePath().data();
char buf[MAX_PATH];
GetModuleFileName(NULL, buf, MAX_PATH);
const char* argv0 = &buf[0];
// FIXME: We cannot set params.argv0 here, as we would escape a stack
// reference, but it is unused anyway.
global.params.argv0 = NULL;
#else
const char* argv0 = global.params.argv0 = argv[0];
#endif
// Set some default values. // Set some default values.
global.params.useSwitchError = 1; global.params.useSwitchError = 1;
@ -292,7 +272,7 @@ static void parseCommandLine(int argc, char **argv, Strings &sourceFiles, bool &
ConfigFile cfg_file; ConfigFile cfg_file;
// just ignore errors for now, they are still printed // just ignore errors for now, they are still printed
cfg_file.read(argv0, (void*)main, "ldc2.conf"); cfg_file.read("ldc2.conf");
final_args.insert(final_args.end(), cfg_file.switches_begin(), cfg_file.switches_end()); final_args.insert(final_args.end(), cfg_file.switches_begin(), cfg_file.switches_end());
final_args.insert(final_args.end(), &argv[1], &argv[argc]); final_args.insert(final_args.end(), &argv[1], &argv[argc]);
@ -316,7 +296,7 @@ static void parseCommandLine(int argc, char **argv, Strings &sourceFiles, bool &
// - version number // - version number
// - used config file // - used config file
if (global.params.verbose) { if (global.params.verbose) {
fprintf(global.stdmsg, "binary %s\n", llvm::sys::fs::getMainExecutable(argv0, (void*)main).c_str()); fprintf(global.stdmsg, "binary %s\n", exe_path::getExePath().c_str());
fprintf(global.stdmsg, "version %s (DMD %s, LLVM %s)\n", global.ldc_version, global.version, global.llvm_version); fprintf(global.stdmsg, "version %s (DMD %s, LLVM %s)\n", global.ldc_version, global.version, global.llvm_version);
const std::string& path = cfg_file.path(); const std::string& path = cfg_file.path();
if (!path.empty()) if (!path.empty())
@ -940,6 +920,8 @@ int main(int argc, char **argv)
// stack trace on signals // stack trace on signals
llvm::sys::PrintStackTraceOnErrorSignal(); llvm::sys::PrintStackTraceOnErrorSignal();
exe_path::initialize(argv[0], reinterpret_cast<void*>(main));
global.init(); global.init();
global.version = ldc::dmd_version; global.version = ldc::dmd_version;
global.ldc_version = ldc::ldc_version; global.ldc_version = ldc::ldc_version;

View file

@ -363,15 +363,15 @@ static void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr)
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit, Type* targetType)
{ {
IF_LOG Logger::println("DtoConstArrayInitializer: %s | %s", arrinit->toChars(), arrinit->type->toChars()); IF_LOG Logger::println("DtoConstArrayInitializer: %s | %s", arrinit->toChars(), targetType->toChars());
LOG_SCOPE; LOG_SCOPE;
assert(arrinit->value.dim == arrinit->index.dim); assert(arrinit->value.dim == arrinit->index.dim);
// get base array type // get base array type
Type* arrty = arrinit->type->toBasetype(); Type* arrty = targetType->toBasetype();
size_t arrlen = arrinit->dim; size_t arrlen = arrinit->dim;
// for statis arrays, dmd does not include any trailing default // for statis arrays, dmd does not include any trailing default

View file

@ -30,8 +30,11 @@ llvm::StructType* DtoArrayType(Type* arrayTy);
llvm::StructType* DtoArrayType(LLType* elemTy); llvm::StructType* DtoArrayType(LLType* elemTy);
llvm::ArrayType* DtoStaticArrayType(Type* sarrayTy); llvm::ArrayType* DtoStaticArrayType(Type* sarrayTy);
LLType* DtoConstArrayInitializerType(ArrayInitializer* arrinit); /// Creates a (global) constant with the element data for the given arary
LLConstant* DtoConstArrayInitializer(ArrayInitializer* si); /// initializer. targetType is explicit because the frontend sometimes emits
/// ArrayInitializers for vectors typed as static arrays.
LLConstant* DtoConstArrayInitializer(ArrayInitializer* si, Type* targetType);
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr, Type *type = 0); LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr, Type *type = 0);
/// Returns whether the array literal can be evaluated to a (LLVM) constant. /// Returns whether the array literal can be evaluated to a (LLVM) constant.

View file

@ -81,16 +81,17 @@ void ldc::DIBuilder::Declare(const Loc &loc, llvm::Value *var, ldc::DILocalVaria
#endif #endif
) )
{ {
unsigned charnum = (loc.linnum ? loc.charnum : 0);
llvm::Instruction *instr = DBuilder.insertDeclare(var, divar, llvm::Instruction *instr = DBuilder.insertDeclare(var, divar,
#if LDC_LLVM_VER >= 306 #if LDC_LLVM_VER >= 306
diexpr, diexpr,
#endif #endif
#if LDC_LLVM_VER >= 307 #if LDC_LLVM_VER >= 307
llvm::DebugLoc::get(loc.linnum, loc.charnum, GetCurrentScope()), llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope()),
#endif #endif
IR->scopebb()); IR->scopebb());
#if LDC_LLVM_VER < 307 #if LDC_LLVM_VER < 307
instr->setDebugLoc(llvm::DebugLoc::get(loc.linnum, loc.charnum, GetCurrentScope())); instr->setDebugLoc(llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope()));
#endif #endif
} }
@ -810,7 +811,7 @@ void ldc::DIBuilder::EmitBlockStart(Loc& loc)
GetCurrentScope(), // scope GetCurrentScope(), // scope
CreateFile(loc), // file CreateFile(loc), // file
loc.linnum, // line loc.linnum, // line
loc.charnum // column loc.linnum ? loc.charnum : 0 // column
#if LDC_LLVM_VER == 305 #if LDC_LLVM_VER == 305
, 0 // DWARF path discriminator value , 0 // DWARF path discriminator value
#endif #endif
@ -849,9 +850,10 @@ void ldc::DIBuilder::EmitStopPoint(Loc& loc)
) )
return; return;
Logger::println("D to dwarf stoppoint at line %u, column %u", loc.linnum, loc.charnum); unsigned charnum = (loc.linnum ? loc.charnum : 0);
Logger::println("D to dwarf stoppoint at line %u, column %u", loc.linnum, charnum);
LOG_SCOPE; LOG_SCOPE;
IR->ir->SetCurrentDebugLocation(llvm::DebugLoc::get(loc.linnum, loc.charnum, GetCurrentScope())); IR->ir->SetCurrentDebugLocation(llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope()));
} }
void ldc::DIBuilder::EmitValue(llvm::Value *val, VarDeclaration *vd) void ldc::DIBuilder::EmitValue(llvm::Value *val, VarDeclaration *vd)

View file

@ -1178,7 +1178,7 @@ LLConstant* DtoConstInitializer(Loc& loc, Type* type, Initializer* init)
else if (ArrayInitializer* ai = init->isArrayInitializer()) else if (ArrayInitializer* ai = init->isArrayInitializer())
{ {
Logger::println("const array initializer"); Logger::println("const array initializer");
_init = DtoConstArrayInitializer(ai); _init = DtoConstArrayInitializer(ai, type);
} }
else if (init->isVoidInitializer()) else if (init->isVoidInitializer())
{ {

View file

@ -535,7 +535,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
LLSmallVector<LLValue*, 2> addr; LLSmallVector<LLValue*, 2> addr;
#endif #endif
gIR->DBuilder.OpOffset(addr, frameType, irLocal->nestedIndex); gIR->DBuilder.OpOffset(addr, frameType, irLocal->nestedIndex);
gIR->DBuilder.EmitLocalVariable(frame, vd, 0, false, addr); gIR->DBuilder.EmitLocalVariable(gep, vd, 0, false, addr);
} }
} }
} }

View file

@ -24,17 +24,7 @@ static cl::opt<std::string> ar("ar",
cl::Hidden, cl::Hidden,
cl::ZeroOrMore); cl::ZeroOrMore);
static cl::opt<std::string> mslink("ms-link", static std::string findProgramByName(const std::string& name)
cl::desc("LINK to use for linking on Windows"),
cl::Hidden,
cl::ZeroOrMore);
static cl::opt<std::string> mslib("ms-lib",
cl::desc("Library Manager to use on Windows"),
cl::Hidden,
cl::ZeroOrMore);
inline static std::string findProgramByName(const std::string& name)
{ {
#if LDC_LLVM_VER >= 306 #if LDC_LLVM_VER >= 306
llvm::ErrorOr<std::string> res = llvm::sys::findProgramByName(name); llvm::ErrorOr<std::string> res = llvm::sys::findProgramByName(name);
@ -46,12 +36,12 @@ inline static std::string findProgramByName(const std::string& name)
#endif #endif
} }
static std::string getProgram(const char *name, const cl::opt<std::string> &opt, const char *envVar = 0) static std::string getProgram(const char* name, const cl::opt<std::string>* opt, const char* envVar = NULL)
{ {
std::string path; std::string path;
const char *prog = NULL; const char *prog = NULL;
if (opt.getNumOccurrences() > 0 && opt.length() > 0 && (prog = opt.c_str())) if (opt && opt->getNumOccurrences() > 0 && opt->length() > 0 && (prog = opt->c_str()))
path = findProgramByName(prog); path = findProgramByName(prog);
if (path.empty() && envVar && (prog = getenv(envVar))) if (path.empty() && envVar && (prog = getenv(envVar)))
@ -68,27 +58,22 @@ static std::string getProgram(const char *name, const cl::opt<std::string> &opt,
return path; return path;
} }
std::string getProgram(const char* name, const char* envVar)
{
return getProgram(name, NULL, envVar);
}
std::string getGcc() std::string getGcc()
{ {
#if defined(__FreeBSD__) && __FreeBSD__ >= 10 #if defined(__FreeBSD__) && __FreeBSD__ >= 10
// Default compiler on FreeBSD 10 is clang // Default compiler on FreeBSD 10 is clang
return getProgram("clang", gcc, "CC"); return getProgram("clang", gcc, "CC");
#else #else
return getProgram("gcc", gcc, "CC"); return getProgram("gcc", &gcc, "CC");
#endif #endif
} }
std::string getArchiver() std::string getArchiver()
{ {
return getProgram("ar", ar); return getProgram("ar", &ar);
}
std::string getLink()
{
return getProgram("link.exe", mslink);
}
std::string getLib()
{
return getProgram("lib.exe", mslib);
} }

View file

@ -16,11 +16,9 @@
#include <string> #include <string>
std::string getProgram(const char* name, const char* envVar = 0);
std::string getGcc(); std::string getGcc();
std::string getArchiver(); std::string getArchiver();
// For Windows with MS tool chain
std::string getLink();
std::string getLib();
#endif #endif

View file

@ -191,8 +191,10 @@ endif()
# #
# Create configuration files. # Create configuration files.
# #
if(MSVC)
set(ADDITIONAL_DEFAULT_LDC_SWITCHES ",\n \"-L/LARGEADDRESSAWARE:NO\"") # Add a lib required by VS 2015+ when building LDC with VS 2015+.
if(MSVC AND (MSVC_VERSION GREATER 1800))
set(ADDITIONAL_DEFAULT_LDC_SWITCHES ",\n \"-Llegacy_stdio_definitions.lib\"")
endif() endif()
# Add extra paths on Linux and disable linker arch mismatch warnings (like # Add extra paths on Linux and disable linker arch mismatch warnings (like
@ -245,7 +247,7 @@ foreach(variable ${variables})
endforeach() endforeach()
# Compiles the given D module into an object file, and if enabled, a bitcode # Compiles the given D module into an object file, and if enabled, a bitcode
# file. The ouput is written to a path based on output_dir. The paths of the # file. The output is written to a path based on output_dir. The paths of the
# output files are appended to outlist_o and outlist_bc, respectively. # output files are appended to outlist_o and outlist_bc, respectively.
macro(dc input_d d_flags output_dir output_suffix outlist_o outlist_bc) macro(dc input_d d_flags output_dir output_suffix outlist_o outlist_bc)
file(RELATIVE_PATH output ${output_dir} ${input_d}) file(RELATIVE_PATH output ${output_dir} ${input_d})

6
vcbuild/amd64.bat Normal file
View file

@ -0,0 +1,6 @@
@echo off
setlocal EnableDelayedExpansion
call "%~dp0msvcEnv.bat" amd64
:: Invoke the actual command, represented by all args
%*
endlocal

26
vcbuild/msvcEnv.bat Normal file
View file

@ -0,0 +1,26 @@
@echo off
:: Environment already set up?
if not "%VSINSTALLDIR%"=="" goto :eof
:: Clear an existing LDC_VSDIR environment variable if the directory doesn't exist
if not "%LDC_VSDIR%"=="" if not exist "%LDC_VSDIR%" set LDC_VSDIR=
:: Try to detect the latest VS installation directory if LDC_VSDIR is not set
if not "%LDC_VSDIR%"=="" goto setup
for /F "tokens=1,2*" %%i in ('reg query HKCU\Software\Microsoft\VisualStudio\12.0_Config /v ShellFolder 2^> nul') do set LDC_VSDIR=%%k
for /F "tokens=1,2*" %%i in ('reg query HKCU\Software\Microsoft\VisualStudio\14.0_Config /v ShellFolder 2^> nul') do set LDC_VSDIR=%%k
if "%LDC_VSDIR%"=="" (
echo WARNING: no Visual Studio installation detected
goto :eof
)
:: Let MSVC set up environment variables
:setup
echo Using Visual Studio: %LDC_VSDIR%
if not exist "%LDC_VSDIR%VC\vcvarsall.bat" (
echo WARNING: could not find VC\vcvarsall.bat
goto :eof
)
:: Forward the first arg to the MS batch file
call "%LDC_VSDIR%VC\vcvarsall.bat" %1

6
vcbuild/x86.bat Normal file
View file

@ -0,0 +1,6 @@
@echo off
setlocal EnableDelayedExpansion
call "%~dp0msvcEnv.bat" x86
:: Invoke the actual command, represented by all args
%*
endlocal