Revise recent adaptations to frontend refactorings

This commit is contained in:
Martin Kinkelin 2020-01-06 16:13:27 +01:00
parent a3efe6d89c
commit 1f5c442519
10 changed files with 76 additions and 93 deletions

View file

@ -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/} \

View file

@ -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)};

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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 &parameters) {
// 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

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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, "");

View file

@ -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;
}

View file

@ -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;