mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-29 22:50:53 +03:00
Revise recent adaptations to frontend refactorings
This commit is contained in:
parent
a3efe6d89c
commit
1f5c442519
10 changed files with 76 additions and 93 deletions
|
@ -231,7 +231,7 @@ steps:
|
|||
if [ "$arch" = "x86" ]; then arch="i686"; fi
|
||||
bootstrap-ldc/bin/ldc-build-runtime --ninja -j $PARALLEL_JOBS \
|
||||
--buildDir=build-libs-$arch \
|
||||
--dFlags="-mtriple=$arch-linux-android" \
|
||||
--dFlags="-w;-de;-dip1000;-mtriple=$arch-linux-android" \
|
||||
--targetSystem='Android;Linux;UNIX' \
|
||||
--ldcSrcDir=$BUILD_SOURCESDIRECTORY \
|
||||
${EXTRA_CMAKE_FLAGS//-D/} \
|
||||
|
|
|
@ -385,14 +385,7 @@ public:
|
|||
void accept(Visitor *v) { v->visit(this); }
|
||||
#if IN_LLVM
|
||||
// The D version returns a slice.
|
||||
const char *toStringz() const
|
||||
{
|
||||
auto nbytes = len * sz;
|
||||
char *s = (char *)mem.xmalloc(nbytes + sz);
|
||||
writeTo(s, true);
|
||||
return s;
|
||||
}
|
||||
DString toUTF8String() const
|
||||
DString peekString() const
|
||||
{
|
||||
assert(sz == 1);
|
||||
return {len, static_cast<const char *>(string)};
|
||||
|
|
33
gen/abi.cpp
33
gen/abi.cpp
|
@ -107,11 +107,11 @@ bool isNestedHFA(const TypeStruct *t, d_uns64 &floatSize, int &num,
|
|||
// For unions, need to find field with most floats
|
||||
int maxn = num;
|
||||
|
||||
for (size_t i = 0; i < fields.length; ++i) {
|
||||
Type *field = fields[i]->type;
|
||||
for (VarDeclaration *field : fields) {
|
||||
Type *tf = field->type;
|
||||
|
||||
// reset to initial num floats (all union fields are at offset 0)
|
||||
if (fields[i]->offset == 0)
|
||||
if (field->offset == 0)
|
||||
n = num;
|
||||
|
||||
// reset dim to dimension of sarray we are in (will be 1 if not)
|
||||
|
@ -120,22 +120,21 @@ bool isNestedHFA(const TypeStruct *t, d_uns64 &floatSize, int &num,
|
|||
// Field is an array. Process the arrayof type and multiply dim by
|
||||
// array dim. Note that empty arrays immediately exclude this struct
|
||||
// from HFA status.
|
||||
if (field->ty == Tsarray) {
|
||||
TypeSArray *array = (TypeSArray *)field;
|
||||
if (array->dim->toUInteger() == 0)
|
||||
if (auto tarray = tf->isTypeSArray()) {
|
||||
if (tarray->dim->toUInteger() == 0)
|
||||
return false;
|
||||
field = array->nextOf();
|
||||
dim *= array->dim->toUInteger();
|
||||
tf = tarray->nextOf();
|
||||
dim *= tarray->dim->toUInteger();
|
||||
}
|
||||
|
||||
if (field->ty == Tstruct) {
|
||||
if (!isNestedHFA((TypeStruct *)field, floatSize, n, dim))
|
||||
if (auto tstruct = tf->isTypeStruct()) {
|
||||
if (!isNestedHFA(tstruct, floatSize, n, dim))
|
||||
return false;
|
||||
} else if (field->isfloating()) {
|
||||
d_uns64 sz = field->size();
|
||||
} else if (tf->isfloating()) {
|
||||
d_uns64 sz = tf->size();
|
||||
n += dim;
|
||||
|
||||
if (field->iscomplex()) {
|
||||
if (tf->iscomplex()) {
|
||||
sz /= 2; // complex is 2 floats, adjust sz
|
||||
n += dim;
|
||||
}
|
||||
|
@ -203,10 +202,10 @@ namespace {
|
|||
bool hasCtor(StructDeclaration *s) {
|
||||
if (s->ctor)
|
||||
return true;
|
||||
for (size_t i = 0; i < s->fields.length; i++) {
|
||||
Type *tf = s->fields[i]->type->baseElemOf();
|
||||
if (tf->ty == Tstruct) {
|
||||
if (hasCtor(static_cast<TypeStruct *>(tf)->sym))
|
||||
for (VarDeclaration *field : s->fields) {
|
||||
Type *tf = field->type->baseElemOf();
|
||||
if (auto tstruct = tf->isTypeStruct()) {
|
||||
if (hasCtor(tstruct->sym))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -433,30 +433,29 @@ public:
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static std::string getPragmaStringArg(PragmaDeclaration *decl) {
|
||||
static llvm::StringRef getPragmaStringArg(PragmaDeclaration *decl) {
|
||||
assert(decl->args && decl->args->length == 1);
|
||||
Expression *e = static_cast<Expression *>((*decl->args)[0]);
|
||||
Expression *e = (*decl->args)[0];
|
||||
assert(e->op == TOKstring);
|
||||
StringExp *se = static_cast<StringExp *>(e);
|
||||
DString str = se->toUTF8String();
|
||||
DString str = se->peekString();
|
||||
return {str.ptr, str.length};
|
||||
}
|
||||
|
||||
void visit(PragmaDeclaration *decl) override {
|
||||
if (decl->ident == Id::lib) {
|
||||
assert(!irs->dcomputetarget);
|
||||
const std::string name = getPragmaStringArg(decl);
|
||||
auto nameLen = name.size();
|
||||
llvm::StringRef name = getPragmaStringArg(decl);
|
||||
|
||||
if (global.params.targetTriple->isWindowsGNUEnvironment()) {
|
||||
if (nameLen > 4 && !memcmp(&name[nameLen - 4], ".lib", 4)) {
|
||||
// On MinGW, strip the .lib suffix, if any, to improve
|
||||
// compatibility with code written for DMD (we pass the name to GCC
|
||||
// via -l, just as on Posix).
|
||||
nameLen -= 4;
|
||||
if (name.endswith(".lib")) {
|
||||
// On MinGW, strip the .lib suffix, if any, to improve compatibility
|
||||
// with code written for DMD (we pass the name to GCC via -l, just as
|
||||
// on Posix).
|
||||
name = name.drop_back(4);
|
||||
}
|
||||
|
||||
if (nameLen >= 7 && !memcmp(name.data(), "shell32", 7)) {
|
||||
if (name.startswith("shell32")) {
|
||||
// Another DMD compatibility kludge: Ignore
|
||||
// pragma(lib, "shell32.lib"), it is implicitly provided by
|
||||
// MinGW.
|
||||
|
@ -467,37 +466,33 @@ public:
|
|||
// With LLVM 3.3 or later we can place the library name in the object
|
||||
// file. This seems to be supported only on Windows.
|
||||
if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
|
||||
llvm::SmallString<24> LibName(name);
|
||||
|
||||
// Win32: /DEFAULTLIB:"curl"
|
||||
if (LibName.endswith(".a")) {
|
||||
LibName = LibName.substr(0, LibName.size() - 2);
|
||||
if (name.endswith(".a")) {
|
||||
name = name.drop_back(2);
|
||||
}
|
||||
if (LibName.endswith(".lib")) {
|
||||
LibName = LibName.substr(0, LibName.size() - 4);
|
||||
if (name.endswith(".lib")) {
|
||||
name = name.drop_back(4);
|
||||
}
|
||||
llvm::SmallString<24> tmp("/DEFAULTLIB:\"");
|
||||
tmp.append(LibName);
|
||||
tmp.append("\"");
|
||||
LibName = tmp;
|
||||
|
||||
std::string arg = ("/DEFAULTLIB:\"" + name + "\"").str();
|
||||
|
||||
// Embed library name as linker option in object file
|
||||
auto Value = llvm::MDString::get(gIR->context(), LibName);
|
||||
auto Value = llvm::MDString::get(gIR->context(), arg);
|
||||
gIR->LinkerMetadataArgs.push_back(
|
||||
llvm::MDNode::get(gIR->context(), Value));
|
||||
} else {
|
||||
size_t const n = nameLen + 3;
|
||||
size_t const n = name.size() + 3;
|
||||
char *arg = static_cast<char *>(mem.xmalloc(n));
|
||||
arg[0] = '-';
|
||||
arg[1] = 'l';
|
||||
memcpy(arg + 2, name.data(), nameLen);
|
||||
memcpy(arg + 2, name.data(), name.size());
|
||||
arg[n - 1] = 0;
|
||||
global.params.linkswitches.push(arg);
|
||||
}
|
||||
} else if (decl->ident == Id::linkerDirective) {
|
||||
if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
|
||||
// Embed directly as linker option in object file
|
||||
const std::string directive = getPragmaStringArg(decl);
|
||||
llvm::StringRef directive = getPragmaStringArg(decl);
|
||||
auto Value = llvm::MDString::get(gIR->context(), directive);
|
||||
gIR->LinkerMetadataArgs.push_back(
|
||||
llvm::MDNode::get(gIR->context(), Value));
|
||||
|
@ -523,9 +518,7 @@ public:
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Declaration_codegen(Dsymbol *decl) {
|
||||
Declaration_codegen(decl, gIR);
|
||||
}
|
||||
void Declaration_codegen(Dsymbol *decl) { Declaration_codegen(decl, gIR); }
|
||||
|
||||
void Declaration_codegen(Dsymbol *decl, IRState *irs) {
|
||||
CodegenVisitor v(irs);
|
||||
|
|
|
@ -762,9 +762,7 @@ static LinkageWithCOMDAT lowerFuncLinkage(FuncDeclaration *fdecl) {
|
|||
// LDC has the same problem with destructors of struct arguments in closures
|
||||
// as DMD, so we copy the failure detection
|
||||
void verifyScopedDestructionInClosure(FuncDeclaration *fd) {
|
||||
for (size_t i = 0; i < fd->closureVars.length; i++) {
|
||||
VarDeclaration *v = fd->closureVars[i];
|
||||
|
||||
for (VarDeclaration *v : fd->closureVars) {
|
||||
// Hack for the case fail_compilation/fail10666.d, until
|
||||
// proper issue https://issues.dlang.org/show_bug.cgi?id=5730 fix will come.
|
||||
bool isScopeDtorParam = v->edtor && (v->storage_class & STCparameter);
|
||||
|
@ -791,8 +789,7 @@ void defineParameters(IrFuncTy &irFty, VarDeclarations ¶meters) {
|
|||
// index in the IrFuncTy args array separately.
|
||||
size_t llArgIdx = 0;
|
||||
|
||||
for (size_t i = 0; i < parameters.length; ++i) {
|
||||
auto *const vd = parameters[i];
|
||||
for (VarDeclaration *vd : parameters) {
|
||||
IrParameter *irparam = getIrParameter(vd);
|
||||
|
||||
// vd->type (parameter) and irparam->arg->type (argument) don't always
|
||||
|
|
|
@ -41,9 +41,9 @@ void copyFnAttributes(llvm::Function *wannabe, llvm::Function *idol) {
|
|||
wannabe->addAttributes(LLAttributeSet::FunctionIndex, fnAttrSet);
|
||||
}
|
||||
|
||||
std::string exprToString(StringExp *strexp) {
|
||||
assert(strexp != nullptr);
|
||||
auto str = strexp->toUTF8String();
|
||||
llvm::StringRef exprToString(StringExp *strexp) {
|
||||
assert(strexp);
|
||||
auto str = strexp->peekString();
|
||||
return {str.ptr, str.length};
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
@ -127,9 +127,7 @@ DValue *DtoInlineIRExpr(Loc &loc, FuncDeclaration *fdecl,
|
|||
assert(objs.length == 3 || objs.length == 5);
|
||||
const bool isExtended = (objs.length == 5);
|
||||
|
||||
std::string prefix;
|
||||
std::string code;
|
||||
std::string suffix;
|
||||
llvm::StringRef prefix, code, suffix;
|
||||
if (isExtended) {
|
||||
Expression *a0 = isExpression(objs[0]);
|
||||
assert(a0);
|
||||
|
@ -184,11 +182,11 @@ DValue *DtoInlineIRExpr(Loc &loc, FuncDeclaration *fdecl,
|
|||
stream << ", ";
|
||||
}
|
||||
|
||||
stream << ")\n{\n" << code;
|
||||
if (ret->ty == Tvoid) {
|
||||
code.append("\nret void");
|
||||
stream << "\nret void";
|
||||
}
|
||||
|
||||
stream << ")\n{\n" << code << "\n}";
|
||||
stream << "\n}";
|
||||
if (!suffix.empty()) {
|
||||
stream << "\n" << suffix;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,8 @@ Expression semanticTraitsLDC(TraitsExp e, Scope* sc)
|
|||
return new ErrorExp();
|
||||
}
|
||||
|
||||
auto str = se.toUTF8(sc).peekString();
|
||||
se = se.toUTF8(sc);
|
||||
auto str = se.peekString();
|
||||
auto featureFound = traitsTargetHasFeature(Dstring(str.length, str.ptr));
|
||||
return new IntegerExp(e.loc, featureFound ? 1 : 0, Type.tbool);
|
||||
}
|
||||
|
|
|
@ -420,7 +420,8 @@ DValue *DtoInlineAsmExpr(Loc &loc, FuncDeclaration *fd, Expressions *arguments,
|
|||
e->error("`__asm` code argument is not a `char[]` string literal");
|
||||
fatal();
|
||||
}
|
||||
const auto code = se->toUTF8String();
|
||||
const DString codeStr = se->peekString();
|
||||
const llvm::StringRef code = {codeStr.ptr, codeStr.length};
|
||||
|
||||
// get constraints param
|
||||
e = (*arguments)[1];
|
||||
|
@ -430,7 +431,9 @@ DValue *DtoInlineAsmExpr(Loc &loc, FuncDeclaration *fd, Expressions *arguments,
|
|||
e->error("`__asm` constraints argument is not a `char[]` string literal");
|
||||
fatal();
|
||||
}
|
||||
const auto constraints = se->toUTF8String();
|
||||
const DString constraintsStr = se->peekString();
|
||||
const llvm::StringRef constraints = {constraintsStr.ptr,
|
||||
constraintsStr.length};
|
||||
|
||||
// build runtime arguments
|
||||
size_t n = arguments->length;
|
||||
|
@ -451,16 +454,14 @@ DValue *DtoInlineAsmExpr(Loc &loc, FuncDeclaration *fd, Expressions *arguments,
|
|||
llvm::FunctionType *FT = llvm::FunctionType::get(ret_type, argtypes, false);
|
||||
|
||||
// make sure the constraints are valid
|
||||
if (!llvm::InlineAsm::Verify(FT, {constraints.ptr, constraints.length})) {
|
||||
if (!llvm::InlineAsm::Verify(FT, constraints)) {
|
||||
e->error("`__asm` constraint argument is invalid");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// build asm call
|
||||
bool sideeffect = true;
|
||||
llvm::InlineAsm *ia =
|
||||
llvm::InlineAsm::get(FT, {code.ptr, code.length},
|
||||
{constraints.ptr, constraints.length}, sideeffect);
|
||||
llvm::InlineAsm *ia = llvm::InlineAsm::get(FT, code, constraints, sideeffect);
|
||||
|
||||
llvm::Value *rv = gIR->ir->CreateCall(ia, args, "");
|
||||
|
||||
|
|
|
@ -28,8 +28,11 @@ bool parseStringExp(Expression *e, const char *&res) {
|
|||
if (e->op != TOKstring) {
|
||||
return false;
|
||||
}
|
||||
auto s = static_cast<StringExp *>(e);
|
||||
res = s->toStringz();
|
||||
auto se = static_cast<StringExp *>(e);
|
||||
auto size = (se->len + 1) * se->sz;
|
||||
auto s = static_cast<char *>(mem.xmalloc(size));
|
||||
se->writeTo(s, true);
|
||||
res = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
26
gen/uda.cpp
26
gen/uda.cpp
|
@ -126,20 +126,18 @@ sinteger_t getIntElem(StructLiteralExp *sle, size_t idx) {
|
|||
return arg->toInteger();
|
||||
}
|
||||
|
||||
/// Returns a null-terminated string
|
||||
const char *getStringElem(StructLiteralExp *sle, size_t idx) {
|
||||
llvm::StringRef getStringElem(StructLiteralExp *sle, size_t idx) {
|
||||
auto arg = (*sle->elements)[idx];
|
||||
if (arg && arg->op == TOKstring) {
|
||||
auto strexp = static_cast<StringExp *>(arg);
|
||||
assert(strexp->sz == 1);
|
||||
return strexp->toStringz();
|
||||
DString str = strexp->peekString();
|
||||
return {str.ptr, str.length};
|
||||
}
|
||||
// Default initialized element (arg->op == TOKnull)
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
|
||||
/// Returns a null-terminated string
|
||||
const char *getFirstElemString(StructLiteralExp *sle) {
|
||||
llvm::StringRef getFirstElemString(StructLiteralExp *sle) {
|
||||
return getStringElem(sle, 0);
|
||||
}
|
||||
|
||||
|
@ -255,11 +253,10 @@ void applyAttrLLVMFastMathFlag(StructLiteralExp *sle, IrFunction *irFunc) {
|
|||
} else if (value == "arcp") {
|
||||
irFunc->FMF.setAllowReciprocal();
|
||||
} else {
|
||||
// `value` is a null-terminated returned from getStringElem so can be passed
|
||||
// to warning("... %s ...").
|
||||
sle->warning(
|
||||
"ignoring unrecognized flag parameter `%s` for `@ldc.attributes.%s`",
|
||||
value.data(), sle->sd->ident->toChars());
|
||||
"ignoring unrecognized flag parameter `%.*s` for `@ldc.attributes.%s`",
|
||||
static_cast<int>(value.size()), value.data(),
|
||||
sle->sd->ident->toChars());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,8 +280,9 @@ void applyAttrOptStrategy(StructLiteralExp *sle, IrFunction *irFunc) {
|
|||
func->addFnAttr(llvm::Attribute::MinSize);
|
||||
} else {
|
||||
sle->warning(
|
||||
"ignoring unrecognized parameter `%s` for `@ldc.attributes.%s`",
|
||||
value.data(), sle->sd->ident->toChars());
|
||||
"ignoring unrecognized parameter `%.*s` for `@ldc.attributes.%s`",
|
||||
static_cast<int>(value.size()), value.data(),
|
||||
sle->sd->ident->toChars());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,7 +300,7 @@ void applyAttrTarget(StructLiteralExp *sle, llvm::Function *func,
|
|||
// string and simply passes all to llvm.
|
||||
|
||||
checkStructElems(sle, {Type::tstring});
|
||||
std::string targetspec = getFirstElemString(sle);
|
||||
llvm::StringRef targetspec = getFirstElemString(sle);
|
||||
|
||||
if (targetspec.empty() || targetspec == "default")
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue