mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 16:11:08 +03:00
Merge branch 'master' into merge-2.075
Conflicts: runtime/druntime runtime/phobos
This commit is contained in:
commit
b085be1404
25 changed files with 543 additions and 262 deletions
|
@ -108,12 +108,6 @@ file(MAKE_DIRECTORY
|
|||
${PROJECT_BINARY_DIR}/${DDMDFE_PATH}
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
ENABLE_LANGUAGE(ASM)
|
||||
elseif(MSVC)
|
||||
ENABLE_LANGUAGE(ASM_MASM)
|
||||
endif()
|
||||
|
||||
# Setup D compiler flags (DMD syntax, which also works with LDMD).
|
||||
set(DDMD_DFLAGS "-wi")
|
||||
set(DDMD_LFLAGS "")
|
||||
|
@ -813,15 +807,24 @@ if(D_VERSION EQUAL 2)
|
|||
endif()
|
||||
add_subdirectory(tests)
|
||||
|
||||
# ldc-build-runtime tool
|
||||
set(LDC_BUILD_RUNTIME_EXE_FULL ${PROJECT_BINARY_DIR}/bin/ldc-build-runtime${CMAKE_EXECUTABLE_SUFFIX})
|
||||
build_d_executable(
|
||||
"${LDC_BUILD_RUNTIME_EXE_FULL}"
|
||||
"${PROJECT_BINARY_DIR}/ldc-build-runtime.d"
|
||||
""
|
||||
"${PROJECT_SOURCE_DIR}/runtime/ldc-build-runtime.d.in"
|
||||
""
|
||||
)
|
||||
add_custom_target(ldc-build-runtime ALL DEPENDS ${LDC_BUILD_RUNTIME_EXE_FULL})
|
||||
|
||||
#
|
||||
# Install target.
|
||||
#
|
||||
|
||||
install(PROGRAMS ${LDC_EXE_FULL} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(PROGRAMS ${LDMD_EXE_FULL} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
if(NOT CMAKE_INSTALL_PREFIX STREQUAL "/usr")
|
||||
install(PROGRAMS ${PROJECT_BINARY_DIR}/bin/build-ldc-runtime.sh DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
endif()
|
||||
install(PROGRAMS ${LDC_BUILD_RUNTIME_EXE_FULL} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
if(${BUILD_SHARED})
|
||||
# For now, only install libldc if explicitly building the shared library.
|
||||
# While it might theoretically be possible to use LDC as a static library
|
||||
|
|
16
appveyor.yml
16
appveyor.yml
|
@ -65,20 +65,19 @@ install:
|
|||
appveyor DownloadFile "http://downloads.dlang.org/releases/2.x/$dmdVersion/dmd.$dmdVersion.windows.7z" -FileName dmd2.7z
|
||||
7z x dmd2.7z > $null
|
||||
Set-Item -path env:DMD -value c:\projects\dmd2\windows\bin\dmd.exe
|
||||
c:\projects\dmd2\windows\bin\dmd.exe --version
|
||||
} Else {
|
||||
$ldcVersion = '1.3.0'
|
||||
If ($Env:APPVEYOR_JOB_ARCH -eq 'x64') {
|
||||
appveyor DownloadFile 'http://github.com/ldc-developers/ldc/releases/download/v1.0.0/ldc2-1.0.0-win64-msvc.zip' -FileName ldc2.zip
|
||||
appveyor DownloadFile "http://github.com/ldc-developers/ldc/releases/download/v$ldcVersion/ldc2-$ldcVersion-win64-msvc.zip" -FileName ldc2.zip
|
||||
7z x ldc2.zip > $null
|
||||
Set-Item -path env:DMD -value c:\projects\ldc2-1.0.0-win64-msvc\bin\ldmd2.exe
|
||||
c:\projects\ldc2-1.0.0-win64-msvc\bin\ldc2 --version
|
||||
Set-Item -path env:DMD -value c:\projects\ldc2-$ldcVersion-win64-msvc\bin\ldmd2.exe
|
||||
} Else {
|
||||
appveyor DownloadFile 'http://github.com/ldc-developers/ldc/releases/download/v1.0.0/ldc2-1.0.0-win32-msvc.zip' -FileName ldc2.zip
|
||||
appveyor DownloadFile "http://github.com/ldc-developers/ldc/releases/download/v$ldcVersion/ldc2-$ldcVersion-win32-msvc.zip" -FileName ldc2.zip
|
||||
7z x ldc2.zip > $null
|
||||
Set-Item -path env:DMD -value c:\projects\ldc2-1.0.0-win32-msvc\bin\ldmd2.exe
|
||||
c:\projects\ldc2-1.0.0-win32-msvc\bin\ldc2 --version
|
||||
Set-Item -path env:DMD -value c:\projects\ldc2-$ldcVersion-win32-msvc\bin\ldmd2.exe
|
||||
}
|
||||
}
|
||||
& $Env:DMD --version
|
||||
# Download & extract GNU make + utils (for dmd-testsuite)
|
||||
- bash --version
|
||||
- appveyor DownloadFile "https://dl.dropboxusercontent.com/s/4y36f5ydgrk4p5g/make-4.2.1.7z?dl=0" -FileName make.7z
|
||||
|
@ -100,7 +99,8 @@ install:
|
|||
- cd ..
|
||||
# Set environment variables
|
||||
- set PATH=%CD%\ninja;%CD%\make;%PATH%
|
||||
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -arch=%APPVEYOR_JOB_ARCH%
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2017" call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -arch=%APPVEYOR_JOB_ARCH%
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2015" call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %APPVEYOR_JOB_ARCH%
|
||||
# Print environment info
|
||||
- set
|
||||
- msbuild /version
|
||||
|
|
|
@ -8261,13 +8261,6 @@ extern (C++) final class TypeStruct : Type
|
|||
AliasThisRec att = RECfwdref;
|
||||
CPPMANGLE cppmangle = CPPMANGLE.def;
|
||||
|
||||
version(IN_LLVM)
|
||||
{
|
||||
// cache the hasUnalignedFields check
|
||||
// 0 = not checked, 1 = aligned, 2 = unaligned
|
||||
int unaligned;
|
||||
}
|
||||
|
||||
extern (D) this(StructDeclaration sym)
|
||||
{
|
||||
super(Tstruct);
|
||||
|
|
|
@ -758,12 +758,6 @@ public:
|
|||
AliasThisRec att;
|
||||
CPPMANGLE cppmangle;
|
||||
|
||||
#if IN_LLVM
|
||||
// cache the hasUnalignedFields check
|
||||
// 0 = not checked, 1 = aligned, 2 = unaligned
|
||||
int32_t unaligned;
|
||||
#endif
|
||||
|
||||
const char *kind();
|
||||
d_uns64 size(Loc loc);
|
||||
unsigned alignsize();
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
#include "driver/cl_options_sanitizers.h"
|
||||
|
||||
#include "ddmd/errors.h"
|
||||
#include "ddmd/dsymbol.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/SpecialCaseList.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -28,6 +30,13 @@ cl::list<std::string> fSanitize(
|
|||
"suspicious behavior."),
|
||||
cl::value_desc("checks"));
|
||||
|
||||
cl::list<std::string> fSanitizeBlacklist(
|
||||
"fsanitize-blacklist", cl::CommaSeparated,
|
||||
cl::desc("Add <file> to the blacklist files for the sanitizers."),
|
||||
cl::value_desc("file"));
|
||||
|
||||
std::unique_ptr<llvm::SpecialCaseList> sanitizerBlacklist;
|
||||
|
||||
#ifdef ENABLE_COVERAGE_SANITIZER
|
||||
cl::list<std::string> fSanitizeCoverage(
|
||||
"fsanitize-coverage", cl::CommaSeparated,
|
||||
|
@ -149,6 +158,14 @@ void initializeSanitizerOptionsFromCmdline()
|
|||
sancovOpts.CoverageType = llvm::SanitizerCoverageOptions::SCK_Edge;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isAnySanitizerEnabled() && !fSanitizeBlacklist.empty()) {
|
||||
std::string loadError;
|
||||
sanitizerBlacklist =
|
||||
llvm::SpecialCaseList::create(fSanitizeBlacklist, loadError);
|
||||
if (!sanitizerBlacklist)
|
||||
error(Loc(), "-fsanitize-blacklist error: %s", loadError.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COVERAGE_SANITIZER
|
||||
|
@ -180,4 +197,9 @@ void outputSanitizerSettings(llvm::raw_ostream &hash_os) {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool functionIsInSanitizerBlacklist(FuncDeclaration *funcDecl) {
|
||||
return sanitizerBlacklist &&
|
||||
sanitizerBlacklist->inSection("fun", mangleExact(funcDecl));
|
||||
}
|
||||
|
||||
} // namespace opts
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define ENABLE_COVERAGE_SANITIZER
|
||||
#endif
|
||||
|
||||
class FuncDeclaration;
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
}
|
||||
|
@ -54,6 +55,8 @@ llvm::SanitizerCoverageOptions getSanitizerCoverageOptions();
|
|||
|
||||
void outputSanitizerSettings(llvm::raw_ostream &hash_os);
|
||||
|
||||
bool functionIsInSanitizerBlacklist(FuncDeclaration *funcDecl);
|
||||
|
||||
} // namespace opts
|
||||
|
||||
#endif // LDC_DRIVER_CL_OPTIONS_SANITIZERS_H
|
||||
|
|
|
@ -54,7 +54,7 @@ private:
|
|||
|
||||
virtual void addUserSwitches();
|
||||
void addDefaultLibs();
|
||||
virtual void addArch();
|
||||
virtual void addTargetFlags();
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
void addLTOGoldPluginFlags();
|
||||
|
@ -404,7 +404,7 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
|
|||
|
||||
addDefaultLibs();
|
||||
|
||||
addArch();
|
||||
addTargetFlags();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -495,50 +495,8 @@ void ArgsBuilder::addDefaultLibs() {
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ArgsBuilder::addArch() {
|
||||
// Only specify -m32/-m64 for architectures where the two variants actually
|
||||
// exist (as e.g. the GCC ARM toolchain doesn't recognize the switches).
|
||||
// MIPS does not have -m32/-m64 but requires -mabi=.
|
||||
if (global.params.targetTriple->get64BitArchVariant().getArch() !=
|
||||
llvm::Triple::UnknownArch &&
|
||||
global.params.targetTriple->get32BitArchVariant().getArch() !=
|
||||
llvm::Triple::UnknownArch) {
|
||||
if (global.params.targetTriple->get64BitArchVariant().getArch() ==
|
||||
llvm::Triple::mips64 ||
|
||||
global.params.targetTriple->get64BitArchVariant().getArch() ==
|
||||
llvm::Triple::mips64el) {
|
||||
switch (getMipsABI()) {
|
||||
case MipsABI::EABI:
|
||||
args.push_back("-mabi=eabi");
|
||||
break;
|
||||
case MipsABI::O32:
|
||||
args.push_back("-mabi=32");
|
||||
break;
|
||||
case MipsABI::N32:
|
||||
args.push_back("-mabi=n32");
|
||||
break;
|
||||
case MipsABI::N64:
|
||||
args.push_back("-mabi=64");
|
||||
break;
|
||||
case MipsABI::Unknown:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (global.params.targetTriple->getArch()) {
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::armeb:
|
||||
case llvm::Triple::aarch64:
|
||||
case llvm::Triple::aarch64_be:
|
||||
break;
|
||||
default:
|
||||
if (global.params.is64bit) {
|
||||
args.push_back("-m64");
|
||||
} else {
|
||||
args.push_back("-m32");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void ArgsBuilder::addTargetFlags() {
|
||||
appendTargetArgsForGcc(args);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -556,7 +514,7 @@ class LdArgsBuilder : public ArgsBuilder {
|
|||
opts::linkerSwitches.end());
|
||||
}
|
||||
|
||||
void addArch() override {}
|
||||
void addTargetFlags() override {}
|
||||
|
||||
void addLdFlag(const llvm::Twine &flag) override {
|
||||
args.push_back(flag.str());
|
||||
|
|
|
@ -102,45 +102,7 @@ static void assemble(const std::string &asmpath, const std::string &objpath) {
|
|||
args.push_back("-o");
|
||||
args.push_back(objpath);
|
||||
|
||||
// Only specify -m32/-m64 for architectures where the two variants actually
|
||||
// exist (as e.g. the GCC ARM toolchain doesn't recognize the switches).
|
||||
// MIPS does not have -m32/-m64 but requires -mabi=.
|
||||
if (global.params.targetTriple->get64BitArchVariant().getArch() !=
|
||||
llvm::Triple::UnknownArch &&
|
||||
global.params.targetTriple->get32BitArchVariant().getArch() !=
|
||||
llvm::Triple::UnknownArch) {
|
||||
if (global.params.targetTriple->get64BitArchVariant().getArch() ==
|
||||
llvm::Triple::mips64 ||
|
||||
global.params.targetTriple->get64BitArchVariant().getArch() ==
|
||||
llvm::Triple::mips64el) {
|
||||
switch (getMipsABI()) {
|
||||
case MipsABI::EABI:
|
||||
args.push_back("-mabi=eabi");
|
||||
args.push_back("-march=mips32r2");
|
||||
break;
|
||||
case MipsABI::O32:
|
||||
args.push_back("-mabi=32");
|
||||
args.push_back("-march=mips32r2");
|
||||
break;
|
||||
case MipsABI::N32:
|
||||
args.push_back("-mabi=n32");
|
||||
args.push_back("-march=mips64r2");
|
||||
break;
|
||||
case MipsABI::N64:
|
||||
args.push_back("-mabi=64");
|
||||
args.push_back("-march=mips64r2");
|
||||
break;
|
||||
case MipsABI::Unknown:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (global.params.is64bit) {
|
||||
args.push_back("-m64");
|
||||
} else {
|
||||
args.push_back("-m32");
|
||||
}
|
||||
}
|
||||
}
|
||||
appendTargetArgsForGcc(args);
|
||||
|
||||
// Run the compiler to assembly the program.
|
||||
int R = executeToolAndWait(getGcc(), args, global.params.verbose);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "driver/tool.h"
|
||||
#include "mars.h"
|
||||
#include "driver/exe_path.h"
|
||||
#include "driver/targetmachine.h"
|
||||
#include "llvm/Support/ConvertUTF.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
@ -70,6 +71,51 @@ std::string getGcc() {
|
|||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void appendTargetArgsForGcc(std::vector<std::string> &args) {
|
||||
using llvm::Triple;
|
||||
|
||||
const auto &triple = *global.params.targetTriple;
|
||||
const auto arch64 = triple.get64BitArchVariant().getArch();
|
||||
const auto arch32 = triple.get32BitArchVariant().getArch();
|
||||
|
||||
// Only specify -m32/-m64 for architectures where the two variants actually
|
||||
// exist (as e.g. the GCC ARM toolchain doesn't recognize the switches).
|
||||
if (arch64 == Triple::UnknownArch || arch32 == Triple::UnknownArch ||
|
||||
arch64 == Triple::aarch64 || arch64 == Triple::aarch64_be) {
|
||||
return;
|
||||
}
|
||||
|
||||
// MIPS does not have -m32/-m64 but requires -mabi=.
|
||||
if (arch64 == Triple::mips64 || arch64 == Triple::mips64el) {
|
||||
switch (getMipsABI()) {
|
||||
case MipsABI::EABI:
|
||||
args.push_back("-mabi=eabi");
|
||||
args.push_back("-march=mips32r2");
|
||||
break;
|
||||
case MipsABI::O32:
|
||||
args.push_back("-mabi=32");
|
||||
args.push_back("-march=mips32r2");
|
||||
break;
|
||||
case MipsABI::N32:
|
||||
args.push_back("-mabi=n32");
|
||||
args.push_back("-march=mips64r2");
|
||||
break;
|
||||
case MipsABI::N64:
|
||||
args.push_back("-mabi=64");
|
||||
args.push_back("-march=mips64r2");
|
||||
break;
|
||||
case MipsABI::Unknown:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
args.push_back(triple.isArch64Bit() ? "-m64" : "-m32");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void createDirectoryForFileOrFail(llvm::StringRef fileName) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
std::string getGcc();
|
||||
void appendTargetArgsForGcc(std::vector<std::string> &args);
|
||||
|
||||
std::string getProgram(const char *name,
|
||||
const llvm::cl::opt<std::string> *opt = nullptr,
|
||||
|
|
|
@ -954,7 +954,8 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
if (gABI->needsUnwindTables()) {
|
||||
func->addFnAttr(LLAttribute::UWTable);
|
||||
}
|
||||
if (opts::isAnySanitizerEnabled()) {
|
||||
if (opts::isAnySanitizerEnabled() &&
|
||||
!opts::functionIsInSanitizerBlacklist(fd)) {
|
||||
// Set the required sanitizer attribute.
|
||||
if (opts::isSanitizerEnabled(opts::AddressSanitizer)) {
|
||||
func->addFnAttr(LLAttribute::SanitizeAddress);
|
||||
|
@ -997,14 +998,21 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
|
||||
emitInstrumentationFnEnter(fd);
|
||||
|
||||
// this hack makes sure the frame pointer elimination optimization is
|
||||
// disabled.
|
||||
// this this eliminates a bunch of inline asm related issues.
|
||||
// disable frame-pointer-elimination for functions with inline asm
|
||||
if (fd->hasReturnExp & 8) // has inline asm
|
||||
{
|
||||
// emit a call to llvm_eh_unwind_init
|
||||
#if LDC_LLVM_VER >= 309
|
||||
func->addAttribute(
|
||||
LLAttributeSet::FunctionIndex,
|
||||
llvm::Attribute::get(gIR->context(), "no-frame-pointer-elim", "true"));
|
||||
func->addAttribute(
|
||||
LLAttributeSet::FunctionIndex,
|
||||
llvm::Attribute::get(gIR->context(), "no-frame-pointer-elim-non-leaf"));
|
||||
#else
|
||||
// hack: emit a call to llvm_eh_unwind_init
|
||||
LLFunction *hack = GET_INTRINSIC_DECL(eh_unwind_init);
|
||||
gIR->ir->CreateCall(hack, {});
|
||||
#endif
|
||||
}
|
||||
|
||||
// give the 'this' parameter (an lvalue) storage and debug info
|
||||
|
|
|
@ -1302,42 +1302,6 @@ void DtoSetFuncDeclIntrinsicName(TemplateInstance *ti, TemplateDeclaration *td,
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool hasUnalignedFields(Type *t) {
|
||||
t = t->toBasetype();
|
||||
if (t->ty == Tsarray) {
|
||||
assert(t->nextOf()->size() % t->nextOf()->alignsize() == 0);
|
||||
return hasUnalignedFields(t->nextOf());
|
||||
}
|
||||
if (t->ty != Tstruct) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeStruct *ts = static_cast<TypeStruct *>(t);
|
||||
if (ts->unaligned) {
|
||||
return (ts->unaligned == 2);
|
||||
}
|
||||
|
||||
StructDeclaration *sym = ts->sym;
|
||||
|
||||
// go through all the fields and try to find something unaligned
|
||||
ts->unaligned = 2;
|
||||
for (unsigned i = 0; i < sym->fields.dim; i++) {
|
||||
VarDeclaration *f = static_cast<VarDeclaration *>(sym->fields.data[i]);
|
||||
unsigned a = f->type->alignsize() - 1;
|
||||
if (((f->offset + a) & ~a) != f->offset) {
|
||||
return true;
|
||||
}
|
||||
if (f->type->toBasetype()->ty == Tstruct && hasUnalignedFields(f->type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ts->unaligned = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t getMemberSize(Type *type) {
|
||||
const dinteger_t dSize = type->size();
|
||||
llvm::Type *const llType = DtoType(type);
|
||||
|
|
|
@ -127,9 +127,6 @@ LLConstant *DtoTypeInfoOf(Type *ty, bool base = true);
|
|||
// target stuff
|
||||
void findDefaultTarget();
|
||||
|
||||
/// Returns true if there is any unaligned type inside the aggregate.
|
||||
bool hasUnalignedFields(Type *t);
|
||||
|
||||
/// Returns a pointer to the given member field of an aggregate.
|
||||
///
|
||||
/// 'src' is a pointer to the start of the memory of an 'ad' instance.
|
||||
|
|
|
@ -203,16 +203,24 @@ IrTypeAggr::IrTypeAggr(AggregateDeclaration *ad)
|
|||
aggr(ad) {}
|
||||
|
||||
bool IrTypeAggr::isPacked(AggregateDeclaration *ad) {
|
||||
if (ad->isUnionDeclaration()) {
|
||||
return true;
|
||||
}
|
||||
for (unsigned i = 0; i < ad->fields.dim; i++) {
|
||||
VarDeclaration *vd = static_cast<VarDeclaration *>(ad->fields.data[i]);
|
||||
unsigned a = vd->type->alignsize() - 1;
|
||||
if (((vd->offset + a) & ~a) != vd->offset) {
|
||||
const auto aggregateSize = (ad->sizeok == SIZEOKdone ? ad->structsize : ~0u);
|
||||
|
||||
// For unions, only a subset of the fields are actually used for the IR type -
|
||||
// don't care.
|
||||
for (const auto field : ad->fields) {
|
||||
// The aggregate's size and the field offset need to be multiples of the
|
||||
// field's natural alignment, otherwise the aggregate type is unnaturally
|
||||
// aligned, and LLVM would insert padding.
|
||||
const auto naturalFieldAlignment = field->type->alignsize();
|
||||
const auto mask = naturalFieldAlignment - 1;
|
||||
|
||||
// If the aggregate's size is unknown, any field with natural alignment > 1
|
||||
// will make it packed.
|
||||
if ((aggregateSize & mask) != 0 || (field->offset & mask) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,12 +45,7 @@ IrTypeStruct *IrTypeStruct::get(StructDeclaration *sd) {
|
|||
return t;
|
||||
}
|
||||
|
||||
t->packed = sd->alignment == 1;
|
||||
if (!t->packed) {
|
||||
// Unfortunately, the previous check is not enough in case the struct
|
||||
// contains an align declaration. See issue 726.
|
||||
t->packed = isPacked(sd);
|
||||
}
|
||||
|
||||
// For ldc.dcomptetypes.Pointer!(uint n,T),
|
||||
// emit { T addrspace(gIR->dcomputetarget->mapping[n])* }
|
||||
|
|
|
@ -10,6 +10,17 @@ if(NOT LDC_EXE)
|
|||
if(NOT DEFINED D_VERSION OR NOT DEFINED DMDFE_MINOR_VERSION OR NOT DEFINED DMDFE_PATCH_VERSION)
|
||||
message(FATAL_ERROR "Please define the CMake variables D_VERSION, DMDFE_MINOR_VERSION and DMDFE_PATCH_VERSION.")
|
||||
endif()
|
||||
|
||||
# Helper function
|
||||
function(append value)
|
||||
foreach(variable ${ARGN})
|
||||
if(${variable} STREQUAL "")
|
||||
set(${variable} "${value}" PARENT_SCOPE)
|
||||
else()
|
||||
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach(variable)
|
||||
endfunction()
|
||||
endif()
|
||||
|
||||
#
|
||||
|
@ -22,11 +33,13 @@ set(MULTILIB OFF CACHE BOOL "Buil
|
|||
set(BUILD_BC_LIBS OFF CACHE BOOL "Build the runtime as LLVM bitcode libraries")
|
||||
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/d CACHE PATH "Path to install D modules to")
|
||||
set(BUILD_SHARED_LIBS AUTO CACHE STRING "Whether to build the runtime as a shared library (ON|OFF|BOTH)")
|
||||
set(D_FLAGS -w CACHE STRING "Runtime build flags, separated by ;")
|
||||
set(D_FLAGS_DEBUG -g;-link-debuglib CACHE STRING "Runtime build flags (debug libraries), separated by ;")
|
||||
set(D_FLAGS_RELEASE -O3;-release CACHE STRING "Runtime build flags (release libraries), separated by ;")
|
||||
set(D_FLAGS -w CACHE STRING "Runtime D compiler flags, separated by ';'")
|
||||
set(D_FLAGS_DEBUG -g;-link-debuglib CACHE STRING "Runtime D compiler flags (debug libraries), separated by ';'")
|
||||
set(D_FLAGS_RELEASE -O3;-release CACHE STRING "Runtime D compiler flags (release libraries), separated by ';'")
|
||||
set(COMPILE_ALL_D_FILES_AT_ONCE ON CACHE BOOL "Compile all D files for a lib in a single command line instead of separately")
|
||||
set(C_SYSTEM_LIBS AUTO CACHE STRING "C system libraries for linking shared libraries and test runners, separated by ;")
|
||||
set(RT_CFLAGS "" CACHE STRING "Runtime extra C compiler flags, separated by ' '")
|
||||
set(LD_FLAGS "" CACHE STRING "Runtime extra C linker flags, separated by ' '")
|
||||
set(C_SYSTEM_LIBS AUTO CACHE STRING "C system libraries for linking shared libraries and test runners, separated by ';'")
|
||||
set(TARGET_SYSTEM AUTO CACHE STRING "Targeted platform for cross-compilation (e.g., 'Linux;UNIX', 'Darwin;APPLE;UNIX', 'Windows;MSVC')")
|
||||
|
||||
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
|
||||
|
@ -46,6 +59,12 @@ if("${TARGET_SYSTEM}" STREQUAL "AUTO")
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if("${TARGET_SYSTEM}" MATCHES "UNIX")
|
||||
ENABLE_LANGUAGE(ASM)
|
||||
elseif("${TARGET_SYSTEM}" MATCHES "MSVC")
|
||||
ENABLE_LANGUAGE(ASM_MASM)
|
||||
endif()
|
||||
|
||||
include(CheckTypeSize)
|
||||
check_type_size(void* ptr_size)
|
||||
if(${ptr_size} MATCHES "^8$") ## if it's 64-bit OS
|
||||
|
@ -241,7 +260,7 @@ if(LDC_EXE)
|
|||
endif()
|
||||
configure_file(${PROJECT_PARENT_DIR}/${CONFIG_NAME}.conf.in ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}.conf @ONLY)
|
||||
configure_file(${PROJECT_PARENT_DIR}/${LDC_EXE}_install.conf.in ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}_install.conf @ONLY)
|
||||
configure_file(${PROJECT_SOURCE_DIR}/build-ldc-runtime.sh.in ${PROJECT_BINARY_DIR}/../bin/build-ldc-runtime.sh @ONLY)
|
||||
configure_file(${PROJECT_SOURCE_DIR}/ldc-build-runtime.d.in ${PROJECT_BINARY_DIR}/../ldc-build-runtime.d @ONLY)
|
||||
endif()
|
||||
|
||||
#
|
||||
|
@ -585,8 +604,6 @@ include(profile-rt/DefineBuildProfileRT.cmake)
|
|||
# Set up build and install targets
|
||||
#
|
||||
|
||||
set(RT_CFLAGS "")
|
||||
|
||||
if(MULTILIB AND "${TARGET_SYSTEM}" MATCHES "APPLE")
|
||||
# On OS X, build "fat" libraries containing code for both architectures.
|
||||
|
||||
|
@ -675,13 +692,13 @@ install(FILES ${GCCBUILTINS} DESTINATION ${INCLUDE_INSTALL_DIR}/ldc)
|
|||
# link the test runners against those. Some linker command-line magic is
|
||||
# required to make sure all objects are pulled in.
|
||||
|
||||
macro(append_testrunner_linkflags lib name_suffix path_suffix target_suffix is_shared output_flags)
|
||||
macro(append_testrunner_linkflags libname path_suffix is_shared output_flags)
|
||||
# (Re)set variable 'tested_lib_path', initialize to directory containing the tested lib.
|
||||
# It'll contain the full path to the linked-in library when 'returning' to calling build_test_runners().
|
||||
set(tested_lib_path "${CMAKE_BINARY_DIR}/lib${path_suffix}")
|
||||
|
||||
if("${TARGET_SYSTEM}" MATCHES "MSVC")
|
||||
set(tested_lib_path "${tested_lib_path}/${lib}${name_suffix}.lib")
|
||||
set(tested_lib_path "${tested_lib_path}/${libname}.lib")
|
||||
if("${is_shared}" STREQUAL "ON")
|
||||
append("${tested_lib_path}" ${output_flags})
|
||||
append("msvcrt.lib vcruntime.lib" ${output_flags})
|
||||
|
@ -694,14 +711,14 @@ macro(append_testrunner_linkflags lib name_suffix path_suffix target_suffix is_s
|
|||
if("${is_shared}" STREQUAL "ON")
|
||||
append("-Wl,-rpath,${tested_lib_path}" ${output_flags})
|
||||
if("${TARGET_SYSTEM}" MATCHES "APPLE")
|
||||
set(tested_lib_path "${tested_lib_path}/lib${lib}${name_suffix}.dylib")
|
||||
set(tested_lib_path "${tested_lib_path}/lib${libname}.dylib")
|
||||
append("${tested_lib_path}" ${output_flags})
|
||||
else()
|
||||
set(tested_lib_path "${tested_lib_path}/lib${lib}${name_suffix}.so")
|
||||
set(tested_lib_path "${tested_lib_path}/lib${libname}.so")
|
||||
append("-Wl,--no-as-needed,${tested_lib_path},--as-needed" ${output_flags})
|
||||
endif()
|
||||
else()
|
||||
set(tested_lib_path "${tested_lib_path}/lib${lib}${name_suffix}.a")
|
||||
set(tested_lib_path "${tested_lib_path}/lib${libname}.a")
|
||||
if("${TARGET_SYSTEM}" MATCHES "APPLE")
|
||||
append("-Wl,-force_load,${tested_lib_path}" ${output_flags})
|
||||
else()
|
||||
|
@ -714,11 +731,12 @@ macro(append_testrunner_linkflags lib name_suffix path_suffix target_suffix is_s
|
|||
endif()
|
||||
endmacro()
|
||||
|
||||
set(_GLOBAL_TESTRUNNERS "" CACHE INTERNAL "List all test runner build targets")
|
||||
set(_GLOBAL_TESTRUNNERS "" CACHE INTERNAL "List of all test runner build targets")
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/dummy.c "")
|
||||
|
||||
# Generates targets for a pair of druntime/Phobos test runners.
|
||||
# The build targets are also appended to the _GLOBAL_TESTRUNNERS list.
|
||||
function(build_test_runners name_suffix path_suffix d_flags linkflags is_shared)
|
||||
function(build_test_runners name_suffix path_suffix d_flags c_flags linkflags is_shared)
|
||||
set(target_suffix)
|
||||
get_target_suffix("${name_suffix}" "${path_suffix}" target_suffix)
|
||||
|
||||
|
@ -732,31 +750,32 @@ function(build_test_runners name_suffix path_suffix d_flags linkflags is_shared)
|
|||
test_runner_o
|
||||
test_runner_bc
|
||||
)
|
||||
add_custom_target(test_runner${target_suffix} DEPENDS ${test_runner_o})
|
||||
|
||||
set(druntime_name druntime-test-runner${target_suffix})
|
||||
add_executable(${druntime_name} EXCLUDE_FROM_ALL ${test_runner_o})
|
||||
set(full_linkflags ${linkflags})
|
||||
append_testrunner_linkflags("druntime-ldc-unittest" "${name_suffix}" "${path_suffix}" "${target_suffix}" "${is_shared}" full_linkflags)
|
||||
add_dependencies(${druntime_name} druntime-ldc-unittest${target_suffix})
|
||||
add_executable(${druntime_name} EXCLUDE_FROM_ALL ${PROJECT_BINARY_DIR}/dummy.c)
|
||||
set(full_linkflags "${test_runner_o} ${linkflags}")
|
||||
append_testrunner_linkflags("druntime-ldc-unittest${name_suffix}" "${path_suffix}" "${is_shared}" full_linkflags)
|
||||
add_dependencies(${druntime_name} test_runner${target_suffix} druntime-ldc-unittest${target_suffix})
|
||||
set_target_properties(${druntime_name} PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${c_flags}
|
||||
LINK_FLAGS ${full_linkflags}
|
||||
LINK_DEPENDS ${tested_lib_path}
|
||||
LINK_DEPENDS "${test_runner_o};${tested_lib_path}"
|
||||
)
|
||||
add_test(build-${druntime_name} "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${druntime_name})
|
||||
set(_GLOBAL_TESTRUNNERS "${_GLOBAL_TESTRUNNERS};${druntime_name}" CACHE INTERNAL "")
|
||||
|
||||
if(PHOBOS2_DIR)
|
||||
set(phobos_name phobos2-test-runner${target_suffix})
|
||||
add_executable(${phobos_name} EXCLUDE_FROM_ALL ${test_runner_o})
|
||||
add_executable(${phobos_name} EXCLUDE_FROM_ALL ${PROJECT_BINARY_DIR}/dummy.c)
|
||||
target_link_libraries(${phobos_name} druntime-ldc-unittest${target_suffix})
|
||||
set(full_linkflags ${linkflags})
|
||||
append_testrunner_linkflags("phobos2-ldc-unittest" "${name_suffix}" "${path_suffix}" "${target_suffix}" "${is_shared}" full_linkflags)
|
||||
add_dependencies(${phobos_name} phobos2-ldc-unittest${target_suffix})
|
||||
set(full_linkflags "${test_runner_o} ${linkflags}")
|
||||
append_testrunner_linkflags("phobos2-ldc-unittest${name_suffix}" "${path_suffix}" "${is_shared}" full_linkflags)
|
||||
add_dependencies(${phobos_name} test_runner${target_suffix} phobos2-ldc-unittest${target_suffix})
|
||||
set_target_properties(${phobos_name} PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${c_flags}
|
||||
LINK_FLAGS ${full_linkflags}
|
||||
LINK_DEPENDS ${tested_lib_path}
|
||||
LINK_DEPENDS "${test_runner_o};${tested_lib_path}"
|
||||
)
|
||||
add_test(build-${phobos_name} "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${phobos_name})
|
||||
set(_GLOBAL_TESTRUNNERS "${_GLOBAL_TESTRUNNERS};${phobos_name}" CACHE INTERNAL "")
|
||||
|
@ -766,6 +785,7 @@ endfunction()
|
|||
# Generates targets for static and/or shared pairs of druntime/Phobos test runners.
|
||||
function(build_test_runner_variant name_suffix path_suffix d_flags c_flags)
|
||||
set(full_d_flags ${D_FLAGS} ${d_flags} -unittest)
|
||||
set(full_c_flags "${RT_CFLAGS} ${c_flags}")
|
||||
set(linkflags "${LD_FLAGS} ${c_flags}")
|
||||
if("${TARGET_SYSTEM}" MATCHES "MSVC")
|
||||
# enforce identical COMDAT folding, apparently needed for std.variant
|
||||
|
@ -776,7 +796,7 @@ function(build_test_runner_variant name_suffix path_suffix d_flags c_flags)
|
|||
set(unittest_libs "")
|
||||
build_runtime_variant(
|
||||
"${full_d_flags}"
|
||||
"${RT_CFLAGS} ${c_flags}"
|
||||
"${full_c_flags}"
|
||||
"${linkflags}"
|
||||
"-unittest${name_suffix}"
|
||||
"${path_suffix}"
|
||||
|
@ -789,11 +809,11 @@ function(build_test_runner_variant name_suffix path_suffix d_flags c_flags)
|
|||
|
||||
# static druntime/Phobos test runners
|
||||
if(NOT ${BUILD_SHARED_LIBS} STREQUAL "ON")
|
||||
build_test_runners("${name_suffix}" "${path_suffix}" "${full_d_flags}" "${linkflags}" "OFF")
|
||||
build_test_runners("${name_suffix}" "${path_suffix}" "${full_d_flags}" "${full_c_flags}" "${linkflags}" "OFF")
|
||||
endif()
|
||||
# shared druntime/Phobos test runners
|
||||
if(NOT ${BUILD_SHARED_LIBS} STREQUAL "OFF")
|
||||
build_test_runners("${name_suffix}${SHARED_LIB_SUFFIX}" "${path_suffix}" "${full_d_flags}" "${linkflags}" "ON")
|
||||
build_test_runners("${name_suffix}${SHARED_LIB_SUFFIX}" "${path_suffix}" "${full_d_flags}" "${full_c_flags}" "${linkflags}" "ON")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
# Use LDC executable in the same directory as this script.
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
LDC_EXE="$DIR/ldc2"
|
||||
if [ ! -e "$LDC_EXE" ]; then
|
||||
echo "Aborting: LDC executable '$LDC_EXE' not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use environment variable LDC_SRC_DIR to use an existing LDC source tree.
|
||||
if [ ! -z "$LDC_SRC_DIR" ]; then
|
||||
if [ ! -d "$LDC_SRC_DIR" ]; then
|
||||
echo "Aborting: LDC source directory '$LDC_SRC_DIR' not found."
|
||||
exit 1
|
||||
fi
|
||||
LDC_SRC_DIR="$( cd "$LDC_SRC_DIR" && pwd )"
|
||||
fi
|
||||
|
||||
# Set up build directory, using environment variable BUILD_DIR if set.
|
||||
if [ -z "$BUILD_DIR" ]; then
|
||||
BUILD_DIR="build-ldc-runtime.tmp"
|
||||
fi
|
||||
if [ -d "$BUILD_DIR" ]; then
|
||||
echo "WARNING: build directory '$BUILD_DIR' already exists."
|
||||
else
|
||||
mkdir "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
set -x
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
if [ -z "$LDC_SRC_DIR" ]; then
|
||||
LDC_SRC_DIR=ldc-src
|
||||
# Download & extract LDC source archive if the directory doesn't exist yet.
|
||||
if [ ! -d "$LDC_SRC_DIR" ]; then
|
||||
wget -O ldc-src.tar.gz https://github.com/ldc-developers/ldc/releases/download/v@LDC_VERSION@/ldc-@LDC_VERSION@-src.tar.gz
|
||||
mkdir "$LDC_SRC_DIR"
|
||||
tar -xzf ldc-src.tar.gz --strip 1 -C "$LDC_SRC_DIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Forward all script args to the CMake command line.
|
||||
cmake "-DLDC_EXE_FULL=$LDC_EXE" -DD_VERSION=@D_VERSION@ \
|
||||
-DDMDFE_MINOR_VERSION=@DMDFE_MINOR_VERSION@ \
|
||||
-DDMDFE_PATCH_VERSION=@DMDFE_PATCH_VERSION@ "$@" "$LDC_SRC_DIR/runtime"
|
||||
|
||||
# Build.
|
||||
if [ -z "$MAKE_ARGS" ]; then
|
||||
MAKE_ARGS=-j4
|
||||
echo "Environment variable MAKE_ARGS not set, defaulting to '$MAKE_ARGS'."
|
||||
fi
|
||||
make $MAKE_ARGS
|
||||
|
||||
echo "Runtime libraries built successfully into '$BUILD_DIR'."
|
|
@ -1 +1 @@
|
|||
Subproject commit 6f48308009cd52fe1956d5c89cc6f15c0baa0dee
|
||||
Subproject commit d6ad1b9dd51ceac6299c0e0c828b392c74a24d8e
|
247
runtime/ldc-build-runtime.d.in
Normal file
247
runtime/ldc-build-runtime.d.in
Normal file
|
@ -0,0 +1,247 @@
|
|||
module ldcBuildRuntime;
|
||||
|
||||
import core.stdc.stdlib : exit;
|
||||
import std.file;
|
||||
import std.path;
|
||||
import std.stdio;
|
||||
|
||||
struct Config {
|
||||
string ldcExecutable;
|
||||
string buildDir;
|
||||
bool resetBuildDir;
|
||||
string ldcSourceDir;
|
||||
bool ninja;
|
||||
bool buildTestrunners;
|
||||
string[] dFlags;
|
||||
string[] cFlags;
|
||||
string[] linkerFlags;
|
||||
uint numBuildJobs;
|
||||
string[string] cmakeVars;
|
||||
}
|
||||
|
||||
string defaultLdcExecutable;
|
||||
Config config;
|
||||
|
||||
int main(string[] args) {
|
||||
version(Windows)
|
||||
enum exeName = "ldc2.exe";
|
||||
else
|
||||
enum exeName = "ldc2";
|
||||
defaultLdcExecutable = buildPath(thisExePath.dirName, exeName);
|
||||
|
||||
parseCommandLine(args);
|
||||
|
||||
findLdcExecutable();
|
||||
prepareBuildDir();
|
||||
prepareLdcSource();
|
||||
runCMake();
|
||||
build();
|
||||
|
||||
writefln("Runtime libraries built successfully into: %s", config.buildDir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void findLdcExecutable() {
|
||||
if (config.ldcExecutable !is null) {
|
||||
if (!config.ldcExecutable.exists) {
|
||||
writefln("Error: LDC executable not found: %s", config.ldcExecutable);
|
||||
exit(1);
|
||||
}
|
||||
config.ldcExecutable = config.ldcExecutable.absolutePath;
|
||||
return;
|
||||
}
|
||||
|
||||
if (defaultLdcExecutable.exists) {
|
||||
config.ldcExecutable = defaultLdcExecutable;
|
||||
return;
|
||||
}
|
||||
|
||||
writeln("Please specify LDC executable via '--ldc=<path/to/ldc2[.exe]>'. Aborting.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void prepareBuildDir() {
|
||||
if (config.buildDir is null)
|
||||
config.buildDir = "ldc-build-runtime.tmp";
|
||||
|
||||
if (config.buildDir.exists) {
|
||||
if (!config.resetBuildDir) {
|
||||
writefln("Warning: build directory already exists: %s", config.buildDir);
|
||||
} else {
|
||||
writefln("Resetting build directory: %s", config.buildDir);
|
||||
import std.array : array;
|
||||
auto items = dirEntries(config.buildDir, SpanMode.shallow, false).array;
|
||||
const ldcSrc = buildPath(config.buildDir, "ldc-src");
|
||||
foreach (i; items) {
|
||||
if (i.isFile) {
|
||||
remove(i.name);
|
||||
} else if (i.isDir && i.name != ldcSrc) {
|
||||
rmdirRecurse(i.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writefln("Creating build directory: %s", config.buildDir);
|
||||
mkdirRecurse(config.buildDir);
|
||||
}
|
||||
|
||||
config.buildDir = config.buildDir.absolutePath;
|
||||
}
|
||||
|
||||
void prepareLdcSource() {
|
||||
if (config.ldcSourceDir !is null) {
|
||||
if (!config.ldcSourceDir.exists) {
|
||||
writefln("Error: LDC source directory not found: %s", config.ldcSourceDir);
|
||||
exit(1);
|
||||
}
|
||||
config.ldcSourceDir = config.ldcSourceDir.absolutePath;
|
||||
return;
|
||||
}
|
||||
|
||||
const ldcSrc = "ldc-src";
|
||||
config.ldcSourceDir = buildPath(config.buildDir, ldcSrc);
|
||||
if (buildPath(config.ldcSourceDir, "runtime").exists)
|
||||
return;
|
||||
|
||||
// Download & extract LDC source archive if <buildDir>/ldc-src/runtime doesn't exist yet.
|
||||
|
||||
const wd = WorkingDirScope(config.buildDir);
|
||||
|
||||
auto ldcVersion = "@LDC_VERSION@";
|
||||
void removeVersionSuffix(string beginning) {
|
||||
import std.string : indexOf;
|
||||
const suffixIndex = ldcVersion.indexOf(beginning);
|
||||
if (suffixIndex > 0)
|
||||
ldcVersion = ldcVersion[0 .. suffixIndex];
|
||||
}
|
||||
removeVersionSuffix("git-");
|
||||
removeVersionSuffix("-dirty");
|
||||
|
||||
const localArchiveFile = "ldc-src.tar.gz";
|
||||
if (!localArchiveFile.exists) {
|
||||
import std.format : format;
|
||||
const url = "https://github.com/ldc-developers/ldc/releases/download/v%1$s/ldc-%1$s-src.tar.gz".format(ldcVersion);
|
||||
writefln("Downloading LDC source archive: %s", url);
|
||||
import std.net.curl : download;
|
||||
download(url, localArchiveFile);
|
||||
if (getSize(localArchiveFile) < 1_048_576) {
|
||||
writefln("Error: downloaded file is corrupt; has LDC v%s been released?", ldcVersion);
|
||||
writefln("You can work around this by manually downloading a src package and moving it to: %s",
|
||||
buildPath(config.buildDir, localArchiveFile));
|
||||
localArchiveFile.remove;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ldcSrc.exists)
|
||||
mkdir(ldcSrc);
|
||||
|
||||
import std.array : split;
|
||||
exec("tar -xzf ldc-src.tar.gz --strip 1 -C ldc-src".split);
|
||||
}
|
||||
|
||||
void runCMake() {
|
||||
import std.array : byPair, join;
|
||||
|
||||
const wd = WorkingDirScope(config.buildDir);
|
||||
|
||||
string[] args = [
|
||||
"cmake",
|
||||
"-DLDC_EXE_FULL=" ~ config.ldcExecutable,
|
||||
"-DD_VERSION=@D_VERSION@",
|
||||
"-DDMDFE_MINOR_VERSION=@DMDFE_MINOR_VERSION@",
|
||||
"-DDMDFE_PATCH_VERSION=@DMDFE_PATCH_VERSION@",
|
||||
"-DD_FLAGS=" ~ config.dFlags.join(";"),
|
||||
"-DRT_CFLAGS=" ~ config.cFlags.join(" "),
|
||||
"-DLD_FLAGS=" ~ config.linkerFlags.join(" "),
|
||||
];
|
||||
foreach (pair; config.cmakeVars.byPair)
|
||||
args ~= "-D" ~ pair[0] ~ '=' ~ pair[1];
|
||||
if (config.ninja)
|
||||
args ~= [ "-G", "Ninja" ];
|
||||
args ~= buildPath(config.ldcSourceDir, "runtime");
|
||||
|
||||
exec(args);
|
||||
}
|
||||
|
||||
void build() {
|
||||
const wd = WorkingDirScope(config.buildDir);
|
||||
|
||||
string[] args = [ config.ninja ? "ninja" : "make" ];
|
||||
if (config.numBuildJobs != 0) {
|
||||
import std.conv : to;
|
||||
args ~= "-j" ~ config.numBuildJobs.to!string;
|
||||
}
|
||||
args ~= "all";
|
||||
if (config.buildTestrunners)
|
||||
args ~= "all-test-runners";
|
||||
|
||||
exec(args);
|
||||
}
|
||||
|
||||
/*** helpers ***/
|
||||
|
||||
struct WorkingDirScope {
|
||||
string originalPath;
|
||||
this(string path) { originalPath = getcwd(); chdir(path); }
|
||||
~this() { chdir(originalPath); }
|
||||
}
|
||||
|
||||
void exec(string[] command ...) {
|
||||
writeln("Invoking: ", command);
|
||||
|
||||
import std.process;
|
||||
auto pid = spawnProcess(command);
|
||||
const exitStatus = wait(pid);
|
||||
|
||||
if (exitStatus != 0) {
|
||||
writeln("Error: command failed with status ", exitStatus);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void parseCommandLine(string[] args) {
|
||||
import std.getopt : arraySep, getopt, defaultGetoptPrinter;
|
||||
|
||||
arraySep = ";";
|
||||
auto helpInformation = getopt(
|
||||
args,
|
||||
"ldc", "Path to LDC executable (default: '" ~ defaultLdcExecutable ~ "')", &config.ldcExecutable,
|
||||
"buildDir", "Path to build directory (default: './ldc-build-runtime.tmp')", &config.buildDir,
|
||||
"reset", "If build directory exists, start with removing everything but the ldc-src subdirectory", &config.resetBuildDir,
|
||||
"ldcSrcDir", "Path to LDC source directory (if not specified: downloads & extracts source archive into '<buildDir>/ldc-src')", &config.ldcSourceDir,
|
||||
"ninja", "Use Ninja as CMake build system", &config.ninja,
|
||||
"testrunners", "Build the testrunner executables too", &config.buildTestrunners,
|
||||
"dFlags", "LDC flags for the D modules (separated by ';')", &config.dFlags,
|
||||
"cFlags", "C/ASM compiler flags for the handful of C/ASM files (separated by ';')", &config.cFlags,
|
||||
"linkerFlags", "C linker flags for shared libraries and testrunner executables (separated by ';')", &config.linkerFlags,
|
||||
"j", "Number of parallel build jobs", &config.numBuildJobs
|
||||
);
|
||||
|
||||
// getopt() removed all consumed args from `args`
|
||||
import std.range : drop;
|
||||
foreach (arg; args.drop(1)) {
|
||||
import std.algorithm.searching : findSplit;
|
||||
const r = arg.findSplit("=");
|
||||
if (r[1].length == 0) {
|
||||
helpInformation.helpWanted = true;
|
||||
break;
|
||||
}
|
||||
config.cmakeVars[r[0]] = r[2];
|
||||
}
|
||||
|
||||
if (helpInformation.helpWanted) {
|
||||
defaultGetoptPrinter(
|
||||
"Builds the LDC runtime libraries.\n" ~
|
||||
"Programs required to be found in your PATH:\n" ~
|
||||
" * CMake\n" ~
|
||||
" * either Make or Ninja (recommended, enable with '--ninja')\n" ~
|
||||
" * C toolchain (compiler and linker)\n" ~
|
||||
" * tar (can be worked around via '--ldcSrcDir=path/to/src')\n" ~
|
||||
"All arguments are optional.\n" ~
|
||||
"CMake variables (see runtime/CMakeLists.txt in LDC source) can be specified via arguments like 'VAR=value'.\n",
|
||||
helpInformation.options
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit 14b5d6ef08ffa6fba50c70518cc895dc7e690e30
|
||||
Subproject commit ab2907630688e8eb12d8ad305871f63a280e4969
|
29
tests/codegen/gh2235.d
Normal file
29
tests/codegen/gh2235.d
Normal file
|
@ -0,0 +1,29 @@
|
|||
// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
// RUN: %ldc -run %s
|
||||
|
||||
// CHECK: %gh2235.Foo = type <{
|
||||
align(2) struct Foo {
|
||||
long y;
|
||||
byte z;
|
||||
}
|
||||
|
||||
// CHECK: %gh2235.Bar = type <{
|
||||
class Bar {
|
||||
union {
|
||||
bool b;
|
||||
Foo foo;
|
||||
}
|
||||
byte x;
|
||||
|
||||
void set(Foo f) {
|
||||
x = 99;
|
||||
foo = f;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
Bar bar = new Bar();
|
||||
Foo f;
|
||||
bar.set(f);
|
||||
assert(bar.x == 99);
|
||||
}
|
12
tests/compilable/no-integrated-as.d
Normal file
12
tests/compilable/no-integrated-as.d
Normal file
|
@ -0,0 +1,12 @@
|
|||
// RUN: %ldc -no-integrated-as %s
|
||||
|
||||
// We currently rely on gcc/clang; no MSVC toolchain support yet.
|
||||
// UNSUPPORTED: Windows
|
||||
|
||||
module noIntegratedAs;
|
||||
|
||||
void main()
|
||||
{
|
||||
import std.stdio;
|
||||
writeln("This object is assembled externally and linked to an executable.");
|
||||
}
|
63
tests/sanitizers/fsanitize_blacklist.d
Normal file
63
tests/sanitizers/fsanitize_blacklist.d
Normal file
|
@ -0,0 +1,63 @@
|
|||
// Test sanitizer blacklist functionality
|
||||
|
||||
// RUN: %ldc -c -output-ll -fsanitize=address \
|
||||
// RUN: -fsanitize-blacklist=%S/inputs/fsanitize_blacklist.txt \
|
||||
// RUN: -fsanitize-blacklist=%S/inputs/fsanitize_blacklist2.txt \
|
||||
// RUN: -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
// Don't attempt to load the blacklist when no sanitizer is active
|
||||
// RUN: %ldc -o- -fsanitize-blacklist=%S/thisfilecertainlydoesnotexist %s
|
||||
|
||||
// CHECK-LABEL: define {{.*}}9foofoofoo
|
||||
// CHECK-SAME: #[[ATTR_WITHASAN:[0-9]+]]
|
||||
void foofoofoo(int* i)
|
||||
{
|
||||
// CHECK: call {{.*}}_asan
|
||||
*i = 1;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{.*}}blacklisted
|
||||
// CHECK-SAME: #[[ATTR_NOASAN:[0-9]+]]
|
||||
extern (C) void blacklisted(int* i)
|
||||
{
|
||||
// CHECK-NOT: call {{.*}}_asan
|
||||
*i = 1;
|
||||
}
|
||||
|
||||
// Test blacklisted wildcard
|
||||
// CHECK-LABEL: define {{.*}}10black_set1
|
||||
// CHECK-SAME: #[[ATTR_NOASAN:[0-9]+]]
|
||||
void black_set1(int* i)
|
||||
{
|
||||
// CHECK-NOT: call {{.*}}_asan
|
||||
*i = 1;
|
||||
}
|
||||
// CHECK-LABEL: define {{.*}}10black_set2
|
||||
// CHECK-SAME: #[[ATTR_NOASAN:[0-9]+]]
|
||||
void black_set2(int* i)
|
||||
{
|
||||
// CHECK-NOT: call {{.*}}_asan
|
||||
*i = 1;
|
||||
}
|
||||
|
||||
// Test blacklisting of template class methods
|
||||
class ABCDEF(T)
|
||||
{
|
||||
void method(int* i)
|
||||
{
|
||||
*i = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{.*}}TiZ6ABCDEF6method
|
||||
// CHECK-SAME: #[[ATTR_NOASAN:[0-9]+]]
|
||||
ABCDEF!int ofBlacklistedType;
|
||||
|
||||
// CHECK-LABEL: define {{.*}}TAyaZ6ABCDEF6method
|
||||
// CHECK-SAME: #[[ATTR_WITHASAN:[0-9]+]]
|
||||
ABCDEF!string ofInstrumentedType;
|
||||
|
||||
//CHECK: attributes #[[ATTR_WITHASAN]] ={{.*}}sanitize_address
|
||||
//CHECK: attributes #[[ATTR_NOASAN]]
|
||||
//CHECK-NOT: sanitize_address
|
||||
//CHECK-SAME: }
|
13
tests/sanitizers/inputs/fsanitize_blacklist.txt
Normal file
13
tests/sanitizers/inputs/fsanitize_blacklist.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Blacklist for the sanitizers. Turns off instrumentation of particular
|
||||
# functions or sources. Use with care. You may set location of blacklist
|
||||
# at compile-time using -fsanitize-blacklist=<path> flag.
|
||||
|
||||
# Example usage:
|
||||
# fun:*bad_function_name*
|
||||
# src:file_with_tricky_code.cc
|
||||
# global:*global_with_bad_access_or_initialization*
|
||||
# global:*global_with_initialization_issues*=init
|
||||
# type:*Namespace::ClassName*=init
|
||||
|
||||
fun:blacklisted
|
||||
fun:*black_set*
|
1
tests/sanitizers/inputs/fsanitize_blacklist2.txt
Normal file
1
tests/sanitizers/inputs/fsanitize_blacklist2.txt
Normal file
|
@ -0,0 +1 @@
|
|||
fun:_D*TiZ6ABCDEF6method*
|
Loading…
Add table
Add a link
Reference in a new issue