mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-30 15:10:59 +03:00
parent
7657e5f7d8
commit
4b108025ef
3 changed files with 58 additions and 10 deletions
35
gen/uda.cpp
35
gen/uda.cpp
|
@ -1,6 +1,7 @@
|
|||
#include "gen/uda.h"
|
||||
|
||||
#include "gen/llvm.h"
|
||||
#include "gen/llvmhelpers.h"
|
||||
#include "aggregate.h"
|
||||
#include "attrib.h"
|
||||
#include "declaration.h"
|
||||
|
@ -13,6 +14,7 @@ namespace {
|
|||
|
||||
/// Names of the attribute structs we recognize.
|
||||
namespace attr {
|
||||
const std::string llvmAttr = "llvmAttr";
|
||||
const std::string section = "section";
|
||||
const std::string target = "target";
|
||||
const std::string weak = "_weak";
|
||||
|
@ -62,7 +64,7 @@ StructLiteralExp *getLdcAttributesStruct(Expression *attr) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void checkStructElems(StructLiteralExp *sle, llvm::ArrayRef<Type *> elemTypes) {
|
||||
void checkStructElems(StructLiteralExp *sle, ArrayParam<Type *> elemTypes) {
|
||||
if (sle->elements->dim != elemTypes.size()) {
|
||||
sle->error(
|
||||
"unexpected field count in 'ldc.attributes.%s'; does druntime not "
|
||||
|
@ -81,12 +83,33 @@ void checkStructElems(StructLiteralExp *sle, llvm::ArrayRef<Type *> elemTypes) {
|
|||
}
|
||||
}
|
||||
|
||||
const char *getFirstElemString(StructLiteralExp *sle) {
|
||||
auto arg = (*sle->elements)[0];
|
||||
assert(arg->op == TOKstring);
|
||||
const char *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();
|
||||
} else {
|
||||
// Default initialized element (arg->op == TOKnull)
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
const char *getFirstElemString(StructLiteralExp *sle) {
|
||||
return getStringElem(sle, 0);
|
||||
}
|
||||
|
||||
// @llvmAttr("key", "value")
|
||||
// @llvmAttr("key")
|
||||
void applyAttrLLVMAttr(StructLiteralExp *sle, llvm::Function *func) {
|
||||
checkStructElems(sle, {Type::tstring, Type::tstring});
|
||||
llvm::StringRef key = getStringElem(sle, 0);
|
||||
llvm::StringRef value = getStringElem(sle, 1);
|
||||
if (value.empty()) {
|
||||
func->addFnAttr(key);
|
||||
} else {
|
||||
func->addFnAttr(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void applyAttrSection(StructLiteralExp *sle, llvm::GlobalObject *globj) {
|
||||
|
@ -200,7 +223,9 @@ void applyFuncDeclUDAs(FuncDeclaration *decl, llvm::Function *func) {
|
|||
continue;
|
||||
|
||||
auto name = sle->sd->ident->string;
|
||||
if (name == attr::section) {
|
||||
if (name == attr::llvmAttr) {
|
||||
applyAttrLLVMAttr(sle, func);
|
||||
} else if (name == attr::section) {
|
||||
applyAttrSection(sle, func);
|
||||
} else if (name == attr::target) {
|
||||
applyAttrTarget(sle, func);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 68d026b0e0968134db632d0aa5975e3e6afbca4f
|
||||
Subproject commit a785ec2fdd2f597698980700fa3febbdba5f89b2
|
23
tests/codegen/attr_llvmattr.d
Normal file
23
tests/codegen/attr_llvmattr.d
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Tests @llvmAttr attribute
|
||||
|
||||
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
import ldc.attributes;
|
||||
|
||||
extern (C): // For easier name mangling
|
||||
|
||||
// CHECK: define{{.*}} @keyvalue{{.*}} #[[KEYVALUE:[0-9]+]]
|
||||
@(llvmAttr("key", "value"))
|
||||
void keyvalue()
|
||||
{
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} @keyonly{{.*}} #[[KEYONLY:[0-9]+]]
|
||||
@(llvmAttr("keyonly"))
|
||||
void keyonly()
|
||||
{
|
||||
}
|
||||
|
||||
// CHECK-DAG: attributes #[[KEYVALUE]] = {{.*}} "key"="value"
|
||||
// CHECK-NOT: attributes #[[KEYONLY]] = {{.*}} "keyonly"=
|
||||
// CHECK-DAG: attributes #[[KEYONLY]] = {{.*}} "keyonly"
|
Loading…
Add table
Add a link
Reference in a new issue