Skip to content

Commit

Permalink
[PS4] Support dllimport/export attributes
Browse files Browse the repository at this point in the history
For PS4 development we support dllimport/export annotations in
source code. This patch enables the dllimport/export attributes
on PS4 by adding a new function to query the triple for whether
dllimport/export are used and using that function to decide
whether these attributes are supported. This replaces the current
method of checking if the target is Windows.

This means we can drop the use of "TargetArch" in the .td file
(which is an improvement as dllimport/export support isn't really
a function of the architecture).

I have included a simple codgen test to show that the attributes
are accepted and have an effect on codegen for PS4. I have also
enabled the DLLExportStaticLocal and DLLImportStaticLocal
attributes, which we support downstream. However, I am unable to
write a test for these attributes until other patches for PS4
dllimport/export handling land upstream. Whilst writing this
patch I noticed that, as these attributes are internal, they do
not need to be target specific (when these attributes are added
internally in Clang the target specific checks have already been
run); however, I think leaving them target specific is fine
because it isn't harmful and they "really are" target specific
even if that has no functional impact.

Differential Revision: https://reviews.llvm.org/D90442
  • Loading branch information
bd1976bris committed Nov 2, 2020
1 parent a5b899b commit ff2e24a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
26 changes: 13 additions & 13 deletions clang/include/clang/Basic/Attr.td
Expand Up @@ -368,8 +368,8 @@ def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>;
def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> {
let OSes = ["Win32"];
def TargetHasDLLImportExport : TargetSpec {
let CustomCode = [{ Target.getTriple().hasDLLImportExport() }];
}
def TargetItaniumCXXABI : TargetSpec {
let CustomCode = [{ Target.getCXXABI().isItaniumFamily() }];
Expand Down Expand Up @@ -3144,24 +3144,24 @@ def MSStruct : InheritableAttr {
let SimpleHandler = 1;
}

def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def DLLExport : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
let Documentation = [DLLExportDocs];
}

def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
// This attribute is used internally only when -fno-dllexport-inlines is
// passed. This attribute is added to inline function of class having
// dllexport attribute. And if the function has static local variables, this
// attribute is used to whether the variables are exported or not. Also if
// function has local static variables, the function is dllexported too.
// passed. This attribute is added to inline functions of a class having the
// dllexport attribute. If the function has static local variables, this
// attribute is used to determine whether the variables are exported or not. If
// the function has local static variables, the function is dllexported too.
let Spellings = [];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}

def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def DLLImport : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
let Documentation = [DLLImportDocs];
Expand All @@ -3177,11 +3177,11 @@ public:
}];
}

def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
// This attribute is used internally only when -fno-dllexport-inlines is
// passed. This attribute is added to inline function of class having
// dllimport attribute. And if the function has static local variables, this
// attribute is used to whether the variables are imported or not.
// passed. This attribute is added to inline functions of a class having the
// dllimport attribute. If the function has static local variables, this
// attribute is used to determine whether the variables are imported or not.
let Spellings = [];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
Expand Down
27 changes: 27 additions & 0 deletions clang/test/CodeGen/ps4-dllimport-dllexport.c
@@ -0,0 +1,27 @@
// RUN: %clang_cc1 \
// RUN: -triple x86_64-scei-ps4 \
// RUN: -fdeclspec \
// RUN: -Werror \
// RUN: -emit-llvm %s -o - | \
// RUN: FileCheck %s

__declspec(dllexport) int export_int;

__declspec(dllimport) int import_int;

__declspec(dllexport) void export_declared_function();

__declspec(dllexport) void export_implemented_function() {
}

__declspec(dllimport) void import_function(int);

void call_imported_function() {
export_declared_function();
return import_function(import_int);
}

// CHECK-DAG: @import_int = external dllimport
// CHECK-DAG: @export_int = dllexport global i32 0
// CHECK-DAG: define dllexport void @export_implemented_function()
// CHECK-DAG: declare dllimport void @import_function(i32)
3 changes: 3 additions & 0 deletions llvm/include/llvm/ADT/Triple.h
Expand Up @@ -782,6 +782,9 @@ class Triple {
return isOSBinFormatXCOFF() || isWasm();
}

/// Tests if the environment supports dllimport/export annotations.
bool hasDLLImportExport() const { return isOSWindows() || isPS4CPU(); }

/// @}
/// @name Mutators
/// @{
Expand Down

0 comments on commit ff2e24a

Please sign in to comment.