-
-
Notifications
You must be signed in to change notification settings - Fork 606
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix bugzilla 23812 - ImportC: allow adding function attributes to imp…
…orted C functions This adds a new pragma for ImportC, which allows to set default storage classes. Only `nothrow`, `@nogc` and `pure` are supported for now. They can be disabled later using `#pragma D pop`. Unknown storage classes are ignored. The pragma starts with identifier `D` to avoid conflicts.
- Loading branch information
Showing
4 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
A pragma for ImportC allows to set `nothrow`, `@nogc` or `pure` | ||
|
||
The following new pragma for ImportC allows to set default storage | ||
classes for function declarations: | ||
``` | ||
#pragma D push([storage classes...]) | ||
``` | ||
The storage classes `nothrow`, `nogc` and `pure` are supported. | ||
Enabling a default storage class affects all function declarations | ||
after the pragma until it is disabled with another pragma. | ||
Declarations in includes are also affected. The following example | ||
enables `@nogc` and `nothrow` for a library: | ||
|
||
``` | ||
#pragma D push(nogc, nothrow) | ||
#include <somelibrary.h> | ||
``` | ||
|
||
The changed storage classes are pushed on a stack. The last change can | ||
be undone with the following pragma: | ||
``` | ||
#pragma D pop | ||
``` | ||
This can also disable multiple default storage classes at the same time, | ||
if they were enabled with a single `#pragma D push` directive. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
void funcDefault(void); | ||
|
||
#pragma D push(nothrow) | ||
void funcNothrow(void); | ||
#pragma D pop | ||
|
||
#pragma D push(nogc) | ||
void funcNogc(void); | ||
#pragma D pop | ||
|
||
#pragma D push(pure) | ||
void funcPure(void); | ||
#pragma D pop | ||
|
||
#pragma D push(nothrow, nogc) | ||
void funcNothrowNogc(void); | ||
#pragma D pop | ||
|
||
void funcDefault2(void); | ||
|
||
#pragma D push(nothrow) | ||
#pragma D push(nogc) | ||
void funcNothrowNogc2(void); | ||
#pragma D pop | ||
void funcNothrow2(void); | ||
#pragma D pop | ||
|
||
#pragma D push(nothrow) | ||
void funcWithCallback(void (*f)(void)); | ||
struct Callbacks | ||
{ | ||
void (*f)(void); | ||
}; | ||
#pragma D pop |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// EXTRA_FILES: imports/imp23812.c | ||
|
||
import imports.imp23812; | ||
|
||
void callDefault() | ||
{ | ||
funcDefault(); | ||
funcDefault2(); | ||
} | ||
|
||
static assert(!__traits(compiles, () nothrow { funcDefault(); } )); | ||
static assert(!__traits(compiles, () @nogc { funcDefault(); } )); | ||
static assert(!__traits(compiles, () pure { funcDefault(); } )); | ||
|
||
static assert(!__traits(compiles, () nothrow { funcDefault2(); } )); | ||
static assert(!__traits(compiles, () @nogc { funcDefault2(); } )); | ||
static assert(!__traits(compiles, () pure { funcDefault2(); } )); | ||
|
||
void callNothrow() nothrow | ||
{ | ||
funcNothrow(); | ||
funcNothrow2(); | ||
} | ||
|
||
static assert(!__traits(compiles, () @nogc { funcNothrow(); } )); | ||
static assert(!__traits(compiles, () pure { funcNothrow(); } )); | ||
|
||
static assert(!__traits(compiles, () @nogc { funcNothrow2(); } )); | ||
static assert(!__traits(compiles, () pure { funcNothrow2(); } )); | ||
|
||
void callNogc() @nogc | ||
{ | ||
funcNogc(); | ||
} | ||
|
||
static assert(!__traits(compiles, () nothrow { funcNogc(); } )); | ||
static assert(!__traits(compiles, () pure { funcNogc(); } )); | ||
|
||
void callPure() pure | ||
{ | ||
funcPure(); | ||
} | ||
|
||
static assert(!__traits(compiles, () nothrow { funcPure(); } )); | ||
static assert(!__traits(compiles, () @nogc { funcPure(); } )); | ||
|
||
void callNothrowNogc() nothrow @nogc | ||
{ | ||
funcNothrowNogc(); | ||
funcNothrowNogc2(); | ||
} | ||
|
||
static assert(!__traits(compiles, () pure { funcNothrowNogc(); } )); | ||
|
||
static assert(!__traits(compiles, () pure { funcNothrowNogc2(); } )); | ||
|
||
extern(C) void callbackDefault() | ||
{ | ||
} | ||
|
||
extern(C) void callbackNothrow() nothrow | ||
{ | ||
} | ||
|
||
void callFuncWithCallback() nothrow | ||
{ | ||
funcWithCallback(&callbackNothrow); | ||
|
||
Callbacks callbacks; | ||
callbacks.f = &callbackNothrow; | ||
} | ||
|
||
static assert(!__traits(compiles, () { funcWithCallback(&callbackDefault); } )); | ||
|
||
static assert(!__traits(compiles, () { Callbacks callbacks; callbacks.f = &callbackDefault; } )); |