mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 08:01:11 +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
|
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/} \
|
||||||
|
|
|
@ -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;
|
||||||
|
|
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
|
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 ¶meters) {
|
||||||
// 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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, "");
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
gen/uda.cpp
26
gen/uda.cpp
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue