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 if [ "$arch" = "x86" ]; then arch="i686"; fi
bootstrap-ldc/bin/ldc-build-runtime --ninja -j $PARALLEL_JOBS \ bootstrap-ldc/bin/ldc-build-runtime --ninja -j $PARALLEL_JOBS \
--buildDir=build-libs-$arch \ --buildDir=build-libs-$arch \
--dFlags="-mtriple=$arch-linux-android" \ --dFlags="-w;-de;-dip1000;-mtriple=$arch-linux-android" \
--targetSystem='Android;Linux;UNIX' \ --targetSystem='Android;Linux;UNIX' \
--ldcSrcDir=$BUILD_SOURCESDIRECTORY \ --ldcSrcDir=$BUILD_SOURCESDIRECTORY \
${EXTRA_CMAKE_FLAGS//-D/} \ ${EXTRA_CMAKE_FLAGS//-D/} \

View file

@ -385,17 +385,10 @@ public:
void accept(Visitor *v) { v->visit(this); } void accept(Visitor *v) { v->visit(this); }
#if IN_LLVM #if IN_LLVM
// The D version returns a slice. // The D version returns a slice.
const char *toStringz() const DString peekString() const
{ {
auto nbytes = len * sz; assert(sz == 1);
char *s = (char *)mem.xmalloc(nbytes + sz); return {len, static_cast<const char *>(string)};
writeTo(s, true);
return s;
}
DString toUTF8String() const
{
assert(sz == 1);
return {len, static_cast<const char *>(string)};
} }
#endif #endif
size_t numberOfCodeUnits(int tynto = 0) const; size_t numberOfCodeUnits(int tynto = 0) const;

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 // For unions, need to find field with most floats
int maxn = num; int maxn = num;
for (size_t i = 0; i < fields.length; ++i) { for (VarDeclaration *field : fields) {
Type *field = fields[i]->type; Type *tf = field->type;
// reset to initial num floats (all union fields are at offset 0) // reset to initial num floats (all union fields are at offset 0)
if (fields[i]->offset == 0) if (field->offset == 0)
n = num; n = num;
// reset dim to dimension of sarray we are in (will be 1 if not) // 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 // Field is an array. Process the arrayof type and multiply dim by
// array dim. Note that empty arrays immediately exclude this struct // array dim. Note that empty arrays immediately exclude this struct
// from HFA status. // from HFA status.
if (field->ty == Tsarray) { if (auto tarray = tf->isTypeSArray()) {
TypeSArray *array = (TypeSArray *)field; if (tarray->dim->toUInteger() == 0)
if (array->dim->toUInteger() == 0)
return false; return false;
field = array->nextOf(); tf = tarray->nextOf();
dim *= array->dim->toUInteger(); dim *= tarray->dim->toUInteger();
} }
if (field->ty == Tstruct) { if (auto tstruct = tf->isTypeStruct()) {
if (!isNestedHFA((TypeStruct *)field, floatSize, n, dim)) if (!isNestedHFA(tstruct, floatSize, n, dim))
return false; return false;
} else if (field->isfloating()) { } else if (tf->isfloating()) {
d_uns64 sz = field->size(); d_uns64 sz = tf->size();
n += dim; n += dim;
if (field->iscomplex()) { if (tf->iscomplex()) {
sz /= 2; // complex is 2 floats, adjust sz sz /= 2; // complex is 2 floats, adjust sz
n += dim; n += dim;
} }
@ -203,10 +202,10 @@ namespace {
bool hasCtor(StructDeclaration *s) { bool hasCtor(StructDeclaration *s) {
if (s->ctor) if (s->ctor)
return true; return true;
for (size_t i = 0; i < s->fields.length; i++) { for (VarDeclaration *field : s->fields) {
Type *tf = s->fields[i]->type->baseElemOf(); Type *tf = field->type->baseElemOf();
if (tf->ty == Tstruct) { if (auto tstruct = tf->isTypeStruct()) {
if (hasCtor(static_cast<TypeStruct *>(tf)->sym)) if (hasCtor(tstruct->sym))
return true; 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); assert(decl->args && decl->args->length == 1);
Expression *e = static_cast<Expression *>((*decl->args)[0]); Expression *e = (*decl->args)[0];
assert(e->op == TOKstring); assert(e->op == TOKstring);
StringExp *se = static_cast<StringExp *>(e); StringExp *se = static_cast<StringExp *>(e);
DString str = se->toUTF8String(); DString str = se->peekString();
return {str.ptr, str.length}; return {str.ptr, str.length};
} }
void visit(PragmaDeclaration *decl) override { void visit(PragmaDeclaration *decl) override {
if (decl->ident == Id::lib) { if (decl->ident == Id::lib) {
assert(!irs->dcomputetarget); assert(!irs->dcomputetarget);
const std::string name = getPragmaStringArg(decl); llvm::StringRef name = getPragmaStringArg(decl);
auto nameLen = name.size();
if (global.params.targetTriple->isWindowsGNUEnvironment()) { if (global.params.targetTriple->isWindowsGNUEnvironment()) {
if (nameLen > 4 && !memcmp(&name[nameLen - 4], ".lib", 4)) { if (name.endswith(".lib")) {
// On MinGW, strip the .lib suffix, if any, to improve // On MinGW, strip the .lib suffix, if any, to improve compatibility
// compatibility with code written for DMD (we pass the name to GCC // with code written for DMD (we pass the name to GCC via -l, just as
// via -l, just as on Posix). // on Posix).
nameLen -= 4; name = name.drop_back(4);
} }
if (nameLen >= 7 && !memcmp(name.data(), "shell32", 7)) { if (name.startswith("shell32")) {
// Another DMD compatibility kludge: Ignore // Another DMD compatibility kludge: Ignore
// pragma(lib, "shell32.lib"), it is implicitly provided by // pragma(lib, "shell32.lib"), it is implicitly provided by
// MinGW. // MinGW.
@ -467,37 +466,33 @@ public:
// With LLVM 3.3 or later we can place the library name in the object // With LLVM 3.3 or later we can place the library name in the object
// file. This seems to be supported only on Windows. // file. This seems to be supported only on Windows.
if (global.params.targetTriple->isWindowsMSVCEnvironment()) { if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
llvm::SmallString<24> LibName(name);
// Win32: /DEFAULTLIB:"curl" // Win32: /DEFAULTLIB:"curl"
if (LibName.endswith(".a")) { if (name.endswith(".a")) {
LibName = LibName.substr(0, LibName.size() - 2); name = name.drop_back(2);
} }
if (LibName.endswith(".lib")) { if (name.endswith(".lib")) {
LibName = LibName.substr(0, LibName.size() - 4); name = name.drop_back(4);
} }
llvm::SmallString<24> tmp("/DEFAULTLIB:\"");
tmp.append(LibName); std::string arg = ("/DEFAULTLIB:\"" + name + "\"").str();
tmp.append("\"");
LibName = tmp;
// Embed library name as linker option in object file // 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( gIR->LinkerMetadataArgs.push_back(
llvm::MDNode::get(gIR->context(), Value)); llvm::MDNode::get(gIR->context(), Value));
} else { } else {
size_t const n = nameLen + 3; size_t const n = name.size() + 3;
char *arg = static_cast<char *>(mem.xmalloc(n)); char *arg = static_cast<char *>(mem.xmalloc(n));
arg[0] = '-'; arg[0] = '-';
arg[1] = 'l'; arg[1] = 'l';
memcpy(arg + 2, name.data(), nameLen); memcpy(arg + 2, name.data(), name.size());
arg[n - 1] = 0; arg[n - 1] = 0;
global.params.linkswitches.push(arg); global.params.linkswitches.push(arg);
} }
} else if (decl->ident == Id::linkerDirective) { } else if (decl->ident == Id::linkerDirective) {
if (global.params.targetTriple->isWindowsMSVCEnvironment()) { if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
// Embed directly as linker option in object file // 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); auto Value = llvm::MDString::get(gIR->context(), directive);
gIR->LinkerMetadataArgs.push_back( gIR->LinkerMetadataArgs.push_back(
llvm::MDNode::get(gIR->context(), Value)); llvm::MDNode::get(gIR->context(), Value));
@ -523,9 +518,7 @@ public:
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
void Declaration_codegen(Dsymbol *decl) { void Declaration_codegen(Dsymbol *decl) { Declaration_codegen(decl, gIR); }
Declaration_codegen(decl, gIR);
}
void Declaration_codegen(Dsymbol *decl, IRState *irs) { void Declaration_codegen(Dsymbol *decl, IRState *irs) {
CodegenVisitor v(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 // LDC has the same problem with destructors of struct arguments in closures
// as DMD, so we copy the failure detection // as DMD, so we copy the failure detection
void verifyScopedDestructionInClosure(FuncDeclaration *fd) { void verifyScopedDestructionInClosure(FuncDeclaration *fd) {
for (size_t i = 0; i < fd->closureVars.length; i++) { for (VarDeclaration *v : fd->closureVars) {
VarDeclaration *v = fd->closureVars[i];
// Hack for the case fail_compilation/fail10666.d, until // Hack for the case fail_compilation/fail10666.d, until
// proper issue https://issues.dlang.org/show_bug.cgi?id=5730 fix will come. // proper issue https://issues.dlang.org/show_bug.cgi?id=5730 fix will come.
bool isScopeDtorParam = v->edtor && (v->storage_class & STCparameter); 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. // index in the IrFuncTy args array separately.
size_t llArgIdx = 0; size_t llArgIdx = 0;
for (size_t i = 0; i < parameters.length; ++i) { for (VarDeclaration *vd : parameters) {
auto *const vd = parameters[i];
IrParameter *irparam = getIrParameter(vd); IrParameter *irparam = getIrParameter(vd);
// vd->type (parameter) and irparam->arg->type (argument) don't always // 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); wannabe->addAttributes(LLAttributeSet::FunctionIndex, fnAttrSet);
} }
std::string exprToString(StringExp *strexp) { llvm::StringRef exprToString(StringExp *strexp) {
assert(strexp != nullptr); assert(strexp);
auto str = strexp->toUTF8String(); auto str = strexp->peekString();
return {str.ptr, str.length}; return {str.ptr, str.length};
} }
} // anonymous namespace } // anonymous namespace
@ -127,9 +127,7 @@ DValue *DtoInlineIRExpr(Loc &loc, FuncDeclaration *fdecl,
assert(objs.length == 3 || objs.length == 5); assert(objs.length == 3 || objs.length == 5);
const bool isExtended = (objs.length == 5); const bool isExtended = (objs.length == 5);
std::string prefix; llvm::StringRef prefix, code, suffix;
std::string code;
std::string suffix;
if (isExtended) { if (isExtended) {
Expression *a0 = isExpression(objs[0]); Expression *a0 = isExpression(objs[0]);
assert(a0); assert(a0);
@ -184,11 +182,11 @@ DValue *DtoInlineIRExpr(Loc &loc, FuncDeclaration *fdecl,
stream << ", "; stream << ", ";
} }
stream << ")\n{\n" << code;
if (ret->ty == Tvoid) { if (ret->ty == Tvoid) {
code.append("\nret void"); stream << "\nret void";
} }
stream << "\n}";
stream << ")\n{\n" << code << "\n}";
if (!suffix.empty()) { if (!suffix.empty()) {
stream << "\n" << suffix; stream << "\n" << suffix;
} }

View file

@ -65,7 +65,8 @@ Expression semanticTraitsLDC(TraitsExp e, Scope* sc)
return new ErrorExp(); 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)); auto featureFound = traitsTargetHasFeature(Dstring(str.length, str.ptr));
return new IntegerExp(e.loc, featureFound ? 1 : 0, Type.tbool); 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"); e->error("`__asm` code argument is not a `char[]` string literal");
fatal(); fatal();
} }
const auto code = se->toUTF8String(); const DString codeStr = se->peekString();
const llvm::StringRef code = {codeStr.ptr, codeStr.length};
// get constraints param // get constraints param
e = (*arguments)[1]; 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"); e->error("`__asm` constraints argument is not a `char[]` string literal");
fatal(); fatal();
} }
const auto constraints = se->toUTF8String(); const DString constraintsStr = se->peekString();
const llvm::StringRef constraints = {constraintsStr.ptr,
constraintsStr.length};
// build runtime arguments // build runtime arguments
size_t n = arguments->length; 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); llvm::FunctionType *FT = llvm::FunctionType::get(ret_type, argtypes, false);
// make sure the constraints are valid // 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"); e->error("`__asm` constraint argument is invalid");
fatal(); fatal();
} }
// build asm call // build asm call
bool sideeffect = true; bool sideeffect = true;
llvm::InlineAsm *ia = llvm::InlineAsm *ia = llvm::InlineAsm::get(FT, code, constraints, sideeffect);
llvm::InlineAsm::get(FT, {code.ptr, code.length},
{constraints.ptr, constraints.length}, sideeffect);
llvm::Value *rv = gIR->ir->CreateCall(ia, args, ""); 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) { if (e->op != TOKstring) {
return false; return false;
} }
auto s = static_cast<StringExp *>(e); auto se = static_cast<StringExp *>(e);
res = s->toStringz(); auto size = (se->len + 1) * se->sz;
auto s = static_cast<char *>(mem.xmalloc(size));
se->writeTo(s, true);
res = s;
return true; return true;
} }

View file

@ -126,20 +126,18 @@ sinteger_t getIntElem(StructLiteralExp *sle, size_t idx) {
return arg->toInteger(); return arg->toInteger();
} }
/// Returns a null-terminated string llvm::StringRef getStringElem(StructLiteralExp *sle, size_t idx) {
const char *getStringElem(StructLiteralExp *sle, size_t idx) {
auto arg = (*sle->elements)[idx]; auto arg = (*sle->elements)[idx];
if (arg && arg->op == TOKstring) { if (arg && arg->op == TOKstring) {
auto strexp = static_cast<StringExp *>(arg); auto strexp = static_cast<StringExp *>(arg);
assert(strexp->sz == 1); DString str = strexp->peekString();
return strexp->toStringz(); return {str.ptr, str.length};
} }
// Default initialized element (arg->op == TOKnull) // Default initialized element (arg->op == TOKnull)
return ""; return {};
} }
/// Returns a null-terminated string llvm::StringRef getFirstElemString(StructLiteralExp *sle) {
const char *getFirstElemString(StructLiteralExp *sle) {
return getStringElem(sle, 0); return getStringElem(sle, 0);
} }
@ -255,11 +253,10 @@ void applyAttrLLVMFastMathFlag(StructLiteralExp *sle, IrFunction *irFunc) {
} else if (value == "arcp") { } else if (value == "arcp") {
irFunc->FMF.setAllowReciprocal(); irFunc->FMF.setAllowReciprocal();
} else { } else {
// `value` is a null-terminated returned from getStringElem so can be passed
// to warning("... %s ...").
sle->warning( sle->warning(
"ignoring unrecognized flag parameter `%s` for `@ldc.attributes.%s`", "ignoring unrecognized flag parameter `%.*s` for `@ldc.attributes.%s`",
value.data(), sle->sd->ident->toChars()); 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); func->addFnAttr(llvm::Attribute::MinSize);
} else { } else {
sle->warning( sle->warning(
"ignoring unrecognized parameter `%s` for `@ldc.attributes.%s`", "ignoring unrecognized parameter `%.*s` for `@ldc.attributes.%s`",
value.data(), sle->sd->ident->toChars()); 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. // string and simply passes all to llvm.
checkStructElems(sle, {Type::tstring}); checkStructElems(sle, {Type::tstring});
std::string targetspec = getFirstElemString(sle); llvm::StringRef targetspec = getFirstElemString(sle);
if (targetspec.empty() || targetspec == "default") if (targetspec.empty() || targetspec == "default")
return; return;