auto-update ddoc-based constants

This commit is contained in:
WebFreak001 2023-04-27 00:45:17 +02:00 committed by Jan Jurzitza
parent 218d047760
commit 64e318e707
4 changed files with 1730 additions and 621 deletions

View File

@ -21,10 +21,12 @@ immutable ConstantCompletion[] pragmas = [
immutable ConstantCompletion[] traits = [ immutable ConstantCompletion[] traits = [
// generated from traits.dd // generated from traits.dd
ConstantCompletion("allMembers", `$(P Takes a single argument, which must evaluate to either ConstantCompletion("allMembers", `$(P Takes a single argument, which must evaluate to either
a type or an expression of type. a module, a struct, a union, a class, an interface, an enum, or a
A tuple of string literals is returned, each of which template instantiation.
is the name of a member of that type combined with all
of the members of the base classes (if the type is a class). A sequence of string literals is returned, each of which
is the name of a member of that argument combined with all
of the members of its base classes (if the argument is a class).
No name is repeated. No name is repeated.
Builtin properties are not included. Builtin properties are not included.
) )
@ -53,6 +55,59 @@ void main()
$(P The order in which the strings appear in the result $(P The order in which the strings appear in the result
is not defined.)`), is not defined.)`),
ConstantCompletion("child", `$(P Takes two arguments.
The first must be a symbol or expression.
The second is a symbol, such as an alias to a member of the first
argument.
The result is the second argument interpreted with its $(D this)
context set to the value of the first argument.
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
import std.stdio;
struct A
{
int i;
int foo(int j) {
return i * j;
}
T bar(T)(T t) {
return i + t;
}
}
alias Ai = A.i;
alias Abar = A.bar!int;
void main()
{
A a;
__traits(child, a, Ai) = 3;
writeln(a.i);
writeln(__traits(child, a, A.foo)(2));
writeln(__traits(child, a, Abar)(5));
}
---
)
Prints:
$(CONSOLE
3
6
8
)`),
ConstantCompletion("classInstanceAlignment", `$(P Takes a single argument, which must evaluate to either
a class type or an expression of class type.
The result
is of type $(CODE size_t), and the value is the alignment
of a runtime instance of the class type.
It is based on the static type of a class, not the
polymorphic type.
)`),
ConstantCompletion("classInstanceSize", `$(P Takes a single argument, which must evaluate to either ConstantCompletion("classInstanceSize", `$(P Takes a single argument, which must evaluate to either
a class type or an expression of class type. a class type or an expression of class type.
The result The result
@ -109,7 +164,7 @@ partial specialization allows for.)
)`), )`),
ConstantCompletion("derivedMembers", `$(P Takes a single argument, which must evaluate to either ConstantCompletion("derivedMembers", `$(P Takes a single argument, which must evaluate to either
a type or an expression of type. a type or an expression of type.
A tuple of string literals is returned, each of which A sequence of string literals is returned, each of which
is the name of a member of that type. is the name of a member of that type.
No name is repeated. No name is repeated.
Base class member names are not included. Base class member names are not included.
@ -139,7 +194,7 @@ void main()
$(P The order in which the strings appear in the result $(P The order in which the strings appear in the result
is not defined.)`), is not defined.)`),
ConstantCompletion("getAliasThis", `$(P Takes one argument, a type. If the type has ` ~ "`" ~ `alias this` ~ "`" ~ ` declarations, ConstantCompletion("getAliasThis", `$(P Takes one argument, a type. If the type has ` ~ "`" ~ `alias this` ~ "`" ~ ` declarations,
returns a sequence of the names (as ` ~ "`" ~ `string` ~ "`" ~ `s) of the members used in returns a *ValueSeq* of the names (as ` ~ "`" ~ `string` ~ "`" ~ `s) of the members used in
those declarations. Otherwise returns an empty sequence. those declarations. Otherwise returns an empty sequence.
) )
@ -167,8 +222,8 @@ tuple("var")
tuple() tuple()
)`), )`),
ConstantCompletion("getAttributes", `$(P ConstantCompletion("getAttributes", `$(P
Takes one argument, a symbol. Returns a tuple of all attached user-defined attributes. Takes one argument, a symbol. Returns a sequence of all attached user-defined attributes.
If no UDAs exist it will return an empty tuple. If no UDAs exist it will return an empty sequence
) )
$(P $(P
@ -196,22 +251,40 @@ tuple(3)
tuple("string", 7) tuple("string", 7)
tuple((Foo)) tuple((Foo))
) )
)`),
ConstantCompletion("getCppNamespaces", `$(P The argument is a symbol.
The result is a *ValueSeq* of strings, possibly empty, that correspond to the namespaces the symbol resides in.
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
extern(C++, "ns")
struct Foo {}
struct Bar {}
extern(C++, __traits(getCppNamespaces, Foo)) struct Baz {}
static assert(__traits(getCppNamespaces, Foo) == __traits(getCppNamespaces, Baz));
void main()
{
static assert(__traits(getCppNamespaces, Foo)[0] == "ns");
static assert(!__traits(getCppNamespaces, Bar).length);
static assert(__traits(getCppNamespaces, Foo) == __traits(getCppNamespaces, Baz));
}
---
)`), )`),
ConstantCompletion("getFunctionAttributes", `$(P ConstantCompletion("getFunctionAttributes", `$(P
Takes one argument which must either be a function symbol, function literal, Takes one argument which must either be a function symbol, function literal,
or a function pointer. It returns a string tuple of all the attributes of or a function pointer. It returns a string *ValueSeq* of all the attributes of
that function $(B excluding) any user-defined attributes (UDAs can be that function $(B excluding) any user-defined attributes (UDAs can be
retrieved with the $(RELATIVE_LINK2 get-attributes, getAttributes) trait). retrieved with the $(GLINK getAttributes) trait).
If no attributes exist it will return an empty tuple. If no attributes exist it will return an empty sequence.
) )
$(B Note:) The order of the attributes in the returned tuple is $(B Note:) The order of the attributes in the returned sequence is
implementation-defined and should not be relied upon. implementation-defined and should not be relied upon.
$(P $(P
A list of currently supported attributes are:) A list of currently supported attributes are:)
$(UL $(LI $(D pure), $(D nothrow), $(D @nogc), $(D @property), $(D @system), $(D @trusted), $(D @safe), and $(D ref))) $(UL $(LI $(D pure), $(D nothrow), $(D @nogc), $(D @property), $(D @system), $(D @trusted), $(D @safe), $(D ref) and $(D @live)))
$(B Note:) $(D ref) is a function attribute even though it applies to the return type. $(B Note:) $(D ref) is a function attribute even though it applies to the return type.
$(P $(P
@ -232,8 +305,6 @@ struct S
} }
pragma(msg, __traits(getFunctionAttributes, S.test)); pragma(msg, __traits(getFunctionAttributes, S.test));
void main(){}
--- ---
) )
@ -249,8 +320,6 @@ $(P Note that some attributes can be inferred. For example:)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
--- ---
pragma(msg, __traits(getFunctionAttributes, (int x) @trusted { return x * 2; })); pragma(msg, __traits(getFunctionAttributes, (int x) @trusted { return x * 2; }));
void main(){}
--- ---
) )
@ -260,7 +329,10 @@ $(CONSOLE
tuple("pure", "nothrow", "@nogc", "@trusted") tuple("pure", "nothrow", "@nogc", "@trusted")
) )
) )
)`), )
$(H2 $(LNAME2 function-parameters, Function Parameter Traits))`),
ConstantCompletion("getFunctionVariadicStyle", `$(P ConstantCompletion("getFunctionVariadicStyle", `$(P
Takes one argument which must either be a function symbol, or a type Takes one argument which must either be a function symbol, or a type
that is a function, delegate or a function pointer. that is a function, delegate or a function pointer.
@ -329,6 +401,11 @@ static assert(__traits(getLinkage, FooCPPStruct) == "C++");
static assert(__traits(getLinkage, FooCPPClass) == "C++"); static assert(__traits(getLinkage, FooCPPClass) == "C++");
static assert(__traits(getLinkage, FooCPPInterface) == "C++"); static assert(__traits(getLinkage, FooCPPInterface) == "C++");
--- ---
)`),
ConstantCompletion("getLocation", `$(P Takes one argument which is a symbol.
To disambiguate between overloads, pass the result of $(GLINK getOverloads) with the desired index, to ` ~ "`" ~ `getLocation` ~ "`" ~ `.
Returns a *ValueSeq* of a string and two ` ~ "`" ~ `int` ~ "`" ~ `s which correspond to the filename, line number and column number where the argument
was declared.
)`), )`),
ConstantCompletion("getMember", `$(P Takes two arguments, the second must be a string. ConstantCompletion("getMember", `$(P Takes two arguments, the second must be a string.
The result is an expression formed from the first The result is an expression formed from the first
@ -363,7 +440,7 @@ The second argument is a ` ~ "`" ~ `string` ~ "`" ~ ` that matches the name of
the member(s) to return. the member(s) to return.
The third argument is a ` ~ "`" ~ `bool` ~ "`" ~ `, and is optional. If ` ~ "`" ~ `true` ~ "`" ~ `, the The third argument is a ` ~ "`" ~ `bool` ~ "`" ~ `, and is optional. If ` ~ "`" ~ `true` ~ "`" ~ `, the
result will also include template overloads. result will also include template overloads.
The result is a tuple of all the overloads of the supplied name. The result is a symbol sequence of all the overloads of the supplied name.
) )
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
@ -413,11 +490,11 @@ bar(int n)
)`), )`),
ConstantCompletion("getParameterStorageClasses", `$(P ConstantCompletion("getParameterStorageClasses", `$(P
Takes two arguments. Takes two arguments.
The first must either be a function symbol, or a type The first must either be a function symbol, a function call, or a type
that is a function, delegate or a function pointer. that is a function, delegate or a function pointer.
The second is an integer identifying which parameter, where the first parameter is The second is an integer identifying which parameter, where the first parameter is
0. 0.
It returns a tuple of strings representing the storage classes of that parameter. It returns a *ValueSeq* of strings representing the storage classes of that parameter.
) )
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
@ -430,6 +507,13 @@ static assert(__traits(getParameterStorageClasses, foo, 0)[1] == "ref");
static assert(__traits(getParameterStorageClasses, foo, 1)[0] == "scope"); static assert(__traits(getParameterStorageClasses, foo, 1)[0] == "scope");
static assert(__traits(getParameterStorageClasses, foo, 2)[0] == "out"); static assert(__traits(getParameterStorageClasses, foo, 2)[0] == "out");
static assert(__traits(getParameterStorageClasses, typeof(&foo), 3)[0] == "lazy"); static assert(__traits(getParameterStorageClasses, typeof(&foo), 3)[0] == "lazy");
int* p, a;
int b, c;
static assert(__traits(getParameterStorageClasses, foo(p, a, b, c), 1)[0] == "scope");
static assert(__traits(getParameterStorageClasses, foo(p, a, b, c), 2)[0] == "out");
static assert(__traits(getParameterStorageClasses, foo(p, a, b, c), 3)[0] == "lazy");
--- ---
)`), )`),
ConstantCompletion("getPointerBitmap", `$(P The argument is a type. ConstantCompletion("getPointerBitmap", `$(P The argument is a type.
@ -470,39 +554,7 @@ void main()
} }
--- ---
)`), )`),
ConstantCompletion("getProtection", `$(P The argument is a symbol. ConstantCompletion("getProtection", `$(P A backward-compatible alias for $(GLINK getVisibility).)`),
The result is a string giving its protection level: "public", "private", "protected", "export", or "package".
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
import std.stdio;
class D
{
export void foo() { }
public int bar;
}
void main()
{
D d = new D();
auto i = __traits(getProtection, d.foo);
writeln(i);
auto j = __traits(getProtection, d.bar);
writeln(j);
}
---
)
Prints:
$(CONSOLE
export
public
)`),
ConstantCompletion("getTargetInfo", `$(P Receives a string key as argument. ConstantCompletion("getTargetInfo", `$(P Receives a string key as argument.
The result is an expression describing the requested target information. The result is an expression describing the requested target information.
) )
@ -520,23 +572,24 @@ A reliable subset exists which are always available:
$(UL $(UL
$(LI $(D "cppRuntimeLibrary") - The C++ runtime library affinity for this toolchain) $(LI $(D "cppRuntimeLibrary") - The C++ runtime library affinity for this toolchain)
$(LI $(D "cppStd") - The version of the C++ standard supported by $(D extern$(LPAREN)C++$(RPAREN)) code, equivalent to the ` ~ "`" ~ `__cplusplus` ~ "`" ~ ` macro in a C++ compiler)
$(LI $(D "floatAbi") - Floating point ABI; may be $(D "hard"), $(D "soft"), or $(D "softfp")) $(LI $(D "floatAbi") - Floating point ABI; may be $(D "hard"), $(D "soft"), or $(D "softfp"))
$(LI $(D "objectFormat") - Target object format) $(LI $(D "objectFormat") - Target object format)
)`), )`),
ConstantCompletion("getUnitTests", `$(P ConstantCompletion("getUnitTests", `$(P
Takes one argument, a symbol of an aggregate (e.g. struct/class/module). Takes one argument, a symbol of an aggregate (e.g. struct/class/module).
The result is a tuple of all the unit test functions of that aggregate. The result is a symbol sequence of all the unit test functions of that aggregate.
The functions returned are like normal nested static functions, The functions returned are like normal nested static functions,
$(DDSUBLINK glossary, ctfe, CTFE) will work and $(DDSUBLINK glossary, ctfe, CTFE) will work and
$(DDSUBLINK spec/attribute, uda, UDAs) will be accessible. $(DDSUBLINK spec/attribute, uda, UDAs) will be accessible.
) )
$(H3 Note:) $(H4 Note:)
$(P $(P
The -unittest flag needs to be passed to the compiler. If the flag The -unittest flag needs to be passed to the compiler. If the flag
is not passed $(CODE __traits(getUnitTests)) will always return an is not passed $(CODE __traits(getUnitTests)) will always return an
empty tuple. empty sequence.
) )
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
@ -612,7 +665,7 @@ a virtual function, $(D -1) is returned instead.
class type. class type.
The second argument is a string that matches the name of The second argument is a string that matches the name of
one of the functions of that class. one of the functions of that class.
The result is a tuple of the virtual overloads of that function. The result is a symbol sequence of the virtual overloads of that function.
It does not include final functions that do not override anything. It does not include final functions that do not override anything.
) )
@ -653,6 +706,74 @@ int()
void() void()
int() int()
2 2
)`),
ConstantCompletion("getVisibility", `$(P The argument is a symbol.
The result is a string giving its visibility level: "public", "private", "protected", "export", or "package".
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
import std.stdio;
class D
{
export void foo() { }
public int bar;
}
void main()
{
D d = new D();
auto i = __traits(getVisibility, d.foo);
writeln(i);
auto j = __traits(getVisibility, d.bar);
writeln(j);
}
---
)
Prints:
$(CONSOLE
export
public
)`),
ConstantCompletion("hasCopyConstructor", `$(P The argument is a type. If it is a struct with a copy constructor, returns $(D true). Otherwise, return $(D false). Note that a copy constructor is distinct from a postblit.
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
import std.stdio;
struct S
{
}
class C
{
}
struct P
{
this(ref P rhs) {}
}
struct B
{
this(this) {}
}
void main()
{
writeln(__traits(hasCopyConstructor, S)); // false
writeln(__traits(hasCopyConstructor, C)); // false
writeln(__traits(hasCopyConstructor, P)); // true
writeln(__traits(hasCopyConstructor, B)); // false, this is a postblit
}
---
)`), )`),
ConstantCompletion("hasMember", `$(P The first argument is a type that has members, or ConstantCompletion("hasMember", `$(P The first argument is a type that has members, or
is an expression of a type that has members. is an expression of a type that has members.
@ -668,8 +789,6 @@ import std.stdio;
struct S struct S
{ {
int m; int m;
import std.stdio; // imports write
} }
void main() void main()
@ -679,18 +798,52 @@ void main()
writeln(__traits(hasMember, S, "m")); // true writeln(__traits(hasMember, S, "m")); // true
writeln(__traits(hasMember, s, "m")); // true writeln(__traits(hasMember, s, "m")); // true
writeln(__traits(hasMember, S, "y")); // false writeln(__traits(hasMember, S, "y")); // false
writeln(__traits(hasMember, S, "write")); // true writeln(__traits(hasMember, S, "write")); // false, but callable like a member via UFCS
writeln(__traits(hasMember, int, "sizeof")); // true writeln(__traits(hasMember, int, "sizeof")); // true
} }
--- ---
)`),
ConstantCompletion("hasPostblit", `$(P The argument is a type. If it is a struct with a postblit, returns $(D true). Otherwise, return $(D false). Note a postblit is distinct from a copy constructor.
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
import std.stdio;
struct S
{
}
class C
{
}
struct P
{
this(ref P rhs) {}
}
struct B
{
this(this) {}
}
void main()
{
writeln(__traits(hasPostblit, S)); // false
writeln(__traits(hasPostblit, C)); // false
writeln(__traits(hasPostblit, P)); // false, this is a copy ctor
writeln(__traits(hasPostblit, B)); // true
}
---
)`), )`),
ConstantCompletion("identifier", `$(P Takes one argument, a symbol. Returns the identifier ConstantCompletion("identifier", `$(P Takes one argument, a symbol. Returns the identifier
for that symbol as a string literal. for that symbol as a string literal.
) )
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_RUN
--- ---
import std.stdio;
int var = 123; int var = 123;
pragma(msg, typeof(var)); // int pragma(msg, typeof(var)); // int
pragma(msg, typeof(__traits(identifier, var))); // string pragma(msg, typeof(__traits(identifier, var))); // string
@ -698,6 +851,50 @@ writeln(var); // 123
writeln(__traits(identifier, var)); // "var" writeln(__traits(identifier, var)); // "var"
--- ---
)`), )`),
ConstantCompletion("initSymbol", `$(P Takes a single argument, which must evaluate to a ` ~ "`" ~ `class` ~ "`" ~ `, ` ~ "`" ~ `struct` ~ "`" ~ ` or ` ~ "`" ~ `union` ~ "`" ~ ` type.
Returns a ` ~ "`" ~ `const(void)[]` ~ "`" ~ ` that holds the initial state of any instance of the supplied type.
The slice is constructed for any type ` ~ "`" ~ `T` ~ "`" ~ ` as follows:
- ` ~ "`" ~ `ptr` ~ "`" ~ ` points to either the initializer symbol of ` ~ "`" ~ `T` ~ "`" ~ `
or ` ~ "`" ~ `null` ~ "`" ~ ` if ` ~ "`" ~ `T` ~ "`" ~ ` is a zero-initialized struct / unions.
- ` ~ "`" ~ `length` ~ "`" ~ ` is equal to the size of an instance, i.e. ` ~ "`" ~ `T.sizeof` ~ "`" ~ ` for structs / unions and
$(RELATIVE_LINK2 classInstanceSize, $(D __traits(classInstanceSize, T)` ~ "`" ~ `)) for classes.
)
$(P
This trait matches the behaviour of ` ~ "`" ~ `TypeInfo.initializer()` ~ "`" ~ ` but can also be used when
` ~ "`" ~ `TypeInfo` ~ "`" ~ ` is not available.
)
$(P
This traits is not available during $(DDSUBLINK glossary, ctfe, CTFE) because the actual address
of the initializer symbol will be set by the linker and hence is not available at compile time.
)
---
class C
{
int i = 4;
}
/// Initializes a malloc'ed instance of ` ~ "`" ~ `C` ~ "`" ~ `
void main()
{
const void[] initSym = __traits(initSymbol, C);
void* ptr = malloc(initSym.length);
scope (exit) free(ptr);
ptr[0..initSym.length] = initSym[];
C c = cast(C) ptr;
assert(c.i == 4);
}
---
$(H2 $(LNAME2 functions, Function Traits))`),
ConstantCompletion("isAbstractClass", `$(P If the arguments are all either types that are abstract classes, ConstantCompletion("isAbstractClass", `$(P If the arguments are all either types that are abstract classes,
or expressions that are typed as abstract classes, then $(D true) or expressions that are typed as abstract classes, then $(D true)
is returned. is returned.
@ -766,6 +963,8 @@ is returned.
Otherwise, $(D false) is returned. Otherwise, $(D false) is returned.
If there are no arguments, $(D false) is returned.) If there are no arguments, $(D false) is returned.)
$(P Arithmetic types are integral types and floating point types.)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
--- ---
import std.stdio; import std.stdio;
@ -791,6 +990,24 @@ false
)`), )`),
ConstantCompletion("isAssociativeArray", `$(P Works like $(D isArithmetic), except it's for associative array ConstantCompletion("isAssociativeArray", `$(P Works like $(D isArithmetic), except it's for associative array
types.)`), types.)`),
ConstantCompletion("isCopyable", `$(P Takes one argument. If that argument is a copyable type then $(D true) is returned,
otherwise $(D false).
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
struct S
{
}
static assert( __traits(isCopyable, S));
struct T
{
@disable this(this); // disable copy construction
}
static assert(!__traits(isCopyable, T));
---
)`),
ConstantCompletion("isDeprecated", `$(P Takes one argument. It returns ` ~ "`" ~ `true` ~ "`" ~ ` if the argument is a symbol ConstantCompletion("isDeprecated", `$(P Takes one argument. It returns ` ~ "`" ~ `true` ~ "`" ~ ` if the argument is a symbol
marked with the ` ~ "`" ~ `deprecated` ~ "`" ~ ` keyword, otherwise ` ~ "`" ~ `false` ~ "`" ~ `.)`), marked with the ` ~ "`" ~ `deprecated` ~ "`" ~ ` keyword, otherwise ` ~ "`" ~ `false` ~ "`" ~ `.)`),
ConstantCompletion("isDisabled", `$(P Takes one argument and returns ` ~ "`" ~ `true` ~ "`" ~ ` if it's a function declaration ConstantCompletion("isDisabled", `$(P Takes one argument and returns ` ~ "`" ~ `true` ~ "`" ~ ` if it's a function declaration
@ -854,8 +1071,17 @@ void main()
} }
--- ---
)`), )`),
ConstantCompletion("isFloating", `$(P Works like $(D isArithmetic), except it's for floating ConstantCompletion("isFloating", `$(P If the arguments are all either types that are floating point types,
point types (including imaginary and complex types).) or expressions that are typed as floating point types, then $(D true)
is returned.
Otherwise, $(D false) is returned.
If there are no arguments, $(D false) is returned.)
$(P The floating point types are:
` ~ "`" ~ `float` ~ "`" ~ `, ` ~ "`" ~ `double` ~ "`" ~ `, ` ~ "`" ~ `real` ~ "`" ~ `,
` ~ "`" ~ `ifloat` ~ "`" ~ `, ` ~ "`" ~ `idouble` ~ "`" ~ `, ` ~ "`" ~ `ireal` ~ "`" ~ `,
` ~ "`" ~ `cfloat` ~ "`" ~ `, ` ~ "`" ~ `cdouble` ~ "`" ~ `, ` ~ "`" ~ `creal` ~ "`" ~ `,
vectors of floating point types, and enums with a floating point base type.)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
--- ---
@ -864,8 +1090,6 @@ import core.simd : float4;
enum E : float { a, b } enum E : float { a, b }
static assert(__traits(isFloating, float)); static assert(__traits(isFloating, float));
static assert(__traits(isFloating, idouble));
static assert(__traits(isFloating, creal));
static assert(__traits(isFloating, E)); static assert(__traits(isFloating, E));
static assert(__traits(isFloating, float4)); static assert(__traits(isFloating, float4));
@ -875,8 +1099,16 @@ static assert(!__traits(isFloating, float[4]));
ConstantCompletion("isFuture", `$(P Takes one argument. It returns ` ~ "`" ~ `true` ~ "`" ~ ` if the argument is a symbol ConstantCompletion("isFuture", `$(P Takes one argument. It returns ` ~ "`" ~ `true` ~ "`" ~ ` if the argument is a symbol
marked with the ` ~ "`" ~ `@future` ~ "`" ~ ` keyword, otherwise ` ~ "`" ~ `false` ~ "`" ~ `. Currently, only marked with the ` ~ "`" ~ `@future` ~ "`" ~ ` keyword, otherwise ` ~ "`" ~ `false` ~ "`" ~ `. Currently, only
functions and variable declarations have support for the ` ~ "`" ~ `@future` ~ "`" ~ ` keyword.)`), functions and variable declarations have support for the ` ~ "`" ~ `@future` ~ "`" ~ ` keyword.)`),
ConstantCompletion("isIntegral", `$(P Works like $(D isArithmetic), except it's for integral ConstantCompletion("isIntegral", `$(P If the arguments are all either types that are integral types,
types (including character types).) or expressions that are typed as integral types, then $(D true)
is returned.
Otherwise, $(D false) is returned.
If there are no arguments, $(D false) is returned.)
$(P The integral types are:
` ~ "`" ~ `byte` ~ "`" ~ `, ` ~ "`" ~ `ubyte` ~ "`" ~ `, ` ~ "`" ~ `short` ~ "`" ~ `, ` ~ "`" ~ `ushort` ~ "`" ~ `, ` ~ "`" ~ `int` ~ "`" ~ `, ` ~ "`" ~ `uint` ~ "`" ~ `, ` ~ "`" ~ `long` ~ "`" ~ `, ` ~ "`" ~ `ulong` ~ "`" ~ `, ` ~ "`" ~ `cent` ~ "`" ~ `, ` ~ "`" ~ `ucent` ~ "`" ~ `,
` ~ "`" ~ `bool` ~ "`" ~ `, ` ~ "`" ~ `char` ~ "`" ~ `, ` ~ "`" ~ `wchar` ~ "`" ~ `, ` ~ "`" ~ `dchar` ~ "`" ~ `,
vectors of integral types, and enums with an integral base type.)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
--- ---
@ -923,6 +1155,27 @@ void foolazy(lazy int x)
static assert(__traits(isLazy, x)); static assert(__traits(isLazy, x));
} }
--- ---
)`),
ConstantCompletion("isModule", `$(P Takes one argument. If that argument is a symbol that refers to a
$(DDLINK spec/module, Modules, module) then $(D true) is returned, otherwise $(D false).
$(DDSUBLINK spec/module, package-module, Package modules) are considered to be
modules even if they have not been directly imported as modules.
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
import core.thread;
import std.algorithm.sorting;
// A regular package (no package.d)
static assert(!__traits(isModule, core));
// A package module (has a package.d file)
// Note that we haven't imported std.algorithm directly.
// (In other words, we don't have an "import std.algorithm;" directive.)
static assert(__traits(isModule, std.algorithm));
// A regular module
static assert(__traits(isModule, std.algorithm.sorting));
---
)`), )`),
ConstantCompletion("isNested", `$(P Takes one argument. ConstantCompletion("isNested", `$(P Takes one argument.
It returns $(D true) if the argument is a nested type which internally It returns $(D true) if the argument is a nested type which internally
@ -988,6 +1241,17 @@ void main()
)`), )`),
ConstantCompletion("isPOD", `$(P Takes one argument, which must be a type. It returns ConstantCompletion("isPOD", `$(P Takes one argument, which must be a type. It returns
$(D true) if the type is a $(DDSUBLINK glossary, pod, POD) type, otherwise $(D false).)`), $(D true) if the type is a $(DDSUBLINK glossary, pod, POD) type, otherwise $(D false).)`),
ConstantCompletion("isPackage", `$(P Takes one argument. If that argument is a symbol that refers to a
$(DDSUBLINK spec/module, PackageName, package) then $(D true) is returned,
otherwise $(D false).
)
---
import std.algorithm.sorting;
static assert(__traits(isPackage, std));
static assert(__traits(isPackage, std.algorithm));
static assert(!__traits(isPackage, std.algorithm.sorting));
---`),
ConstantCompletion("isRef", `$(P Takes one argument. If that argument is a declaration, ConstantCompletion("isRef", `$(P Takes one argument. If that argument is a declaration,
$(D true) is returned if it is $(D_KEYWORD ref), $(D_KEYWORD out), $(D true) is returned if it is $(D_KEYWORD ref), $(D_KEYWORD out),
or $(D_KEYWORD lazy), otherwise $(D false). or $(D_KEYWORD lazy), otherwise $(D false).
@ -1049,34 +1313,42 @@ $(LI When using inline assembly to correctly call a function.)
$(LI Testing that the compiler does this correctly is normally hackish and awkward, $(LI Testing that the compiler does this correctly is normally hackish and awkward,
this enables efficient, direct, and simple testing.) this enables efficient, direct, and simple testing.)
))`), ))`),
ConstantCompletion("isSame", `$(P Takes two arguments and returns bool $(D true) if they ConstantCompletion("isSame", `$(P Compares two arguments and evaluates to ` ~ "`" ~ `bool` ~ "`" ~ `.)
are the same symbol, $(D false) if not.)
$(P The result is ` ~ "`" ~ `true` ~ "`" ~ ` if the two arguments are the same symbol
(once aliases are resolved).)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
--- ---
import std.stdio;
struct S { } struct S { }
int foo(); int foo();
int bar(); int bar();
void main() static assert(__traits(isSame, foo, foo));
{ static assert(!__traits(isSame, foo, bar));
writeln(__traits(isSame, foo, foo)); // true static assert(!__traits(isSame, foo, S));
writeln(__traits(isSame, foo, bar)); // false static assert(__traits(isSame, S, S));
writeln(__traits(isSame, foo, S)); // false static assert(!__traits(isSame, object, S));
writeln(__traits(isSame, S, S)); // true static assert(__traits(isSame, object, object));
writeln(__traits(isSame, std, S)); // false
writeln(__traits(isSame, std, std)); // true alias daz = foo;
} static assert(__traits(isSame, foo, daz));
--- ---
) )
$(P If the two arguments are expressions made up of literals $(P The result is ` ~ "`" ~ `true` ~ "`" ~ ` if the two arguments are expressions
or enums that evaluate to the same value, true is returned.) made up of literals or enums that evaluate to the same value.)
$(P If the two arguments are both lambda functions (or aliases $(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
enum e = 3;
static assert(__traits(isSame, (e), 3));
static assert(__traits(isSame, 5, 2 + e));
---
)
$(P If the two arguments are both
$(DDSUBLINK spec/expression, function_literals, lambda functions) (or aliases
to lambda functions), then they are compared for equality. For to lambda functions), then they are compared for equality. For
the comparison to be computed correctly, the following conditions the comparison to be computed correctly, the following conditions
must be met for both lambda functions:) must be met for both lambda functions:)
@ -1093,11 +1365,20 @@ statements, the function is considered incomparable.)
) )
$(P If these constraints aren't fulfilled, the function is considered $(P If these constraints aren't fulfilled, the function is considered
incomparable and ` ~ "`" ~ `isSame` ~ "`" ~ ` returns $(D false).) incomparable and the result is $(D false).)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
--- ---
static assert(__traits(isSame, (a, b) => a + b, (c, d) => c + d));
static assert(__traits(isSame, a => ++a, b => ++b));
static assert(!__traits(isSame, (int a, int b) => a + b, (a, b) => a + b));
static assert(__traits(isSame, (a, b) => a + b + 10, (c, d) => c + d + 10));
---
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
int f() { return 2; } int f() { return 2; }
void test(alias pred)() void test(alias pred)()
{ {
// f() from main is a different function from top-level f() // f() from main is a different function from top-level f()
@ -1106,11 +1387,6 @@ void test(alias pred)()
void main() void main()
{ {
static assert(__traits(isSame, (a, b) => a + b, (c, d) => c + d));
static assert(__traits(isSame, a => ++a, b => ++b));
static assert(!__traits(isSame, (int a, int b) => a + b, (a, b) => a + b));
static assert(__traits(isSame, (a, b) => a + b + 10, (c, d) => c + d + 10));
// lambdas accessing local variables are considered incomparable // lambdas accessing local variables are considered incomparable
int b; int b;
static assert(!__traits(isSame, a => a + b, a => a + b)); static assert(!__traits(isSame, a => a + b, a => a + b));
@ -1119,7 +1395,11 @@ void main()
int f() { return 3;} int f() { return 3;}
static assert(__traits(isSame, a => a + f(), a => a + f())); static assert(__traits(isSame, a => a + f(), a => a + f()));
test!((int a) => a + f())(); test!((int a) => a + f())();
}
---
)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
class A class A
{ {
int a; int a;
@ -1142,11 +1422,38 @@ void main()
// lambdas with different data types are considered incomparable, // lambdas with different data types are considered incomparable,
// even if the memory layout is the same // even if the memory layout is the same
static assert(!__traits(isSame, (A a) => ++a.a, (B a) => ++a.a)); static assert(!__traits(isSame, (A a) => ++a.a, (B a) => ++a.a));
} ---
)
$(P If the two arguments are tuples then the result is ` ~ "`" ~ `true` ~ "`" ~ ` if the
two tuples, after expansion, have the same length and if each pair
of nth argument respects the constraints previously specified.)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
---
import std.meta;
struct S { }
// like __traits(isSame,0,0) && __traits(isSame,1,1)
static assert(__traits(isSame, AliasSeq!(0,1), AliasSeq!(0,1)));
// like __traits(isSame,S,std.meta) && __traits(isSame,1,1)
static assert(!__traits(isSame, AliasSeq!(S,1), AliasSeq!(std.meta,1)));
// the length of the sequences is different
static assert(!__traits(isSame, AliasSeq!(1), AliasSeq!(1,2)));
--- ---
)`), )`),
ConstantCompletion("isScalar", `$(P Works like $(D isArithmetic), except it's for scalar ConstantCompletion("isScalar", `$(P If the arguments are all either types that are scalar types,
types.) or expressions that are typed as scalar types, then $(D true)
is returned.
Otherwise, $(D false) is returned.
If there are no arguments, $(D false) is returned.)
$(P Scalar types are integral types,
floating point types,
pointer types,
vectors of scalar types,
and enums with a scalar base type.)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
--- ---
@ -1207,8 +1514,8 @@ void main()
} }
--- ---
)`), )`),
ConstantCompletion("isTemplate", `$(P Takes one argument. If that argument is a template then $(D true) is returned, ConstantCompletion("isTemplate", `$(P Takes one argument. If that argument or any of its overloads is a template
otherwise $(D false). then $(D true) is returned, otherwise $(D false).
) )
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
@ -1219,8 +1526,16 @@ static assert(!__traits(isTemplate,foo!int()));
static assert(!__traits(isTemplate,"string")); static assert(!__traits(isTemplate,"string"));
--- ---
)`), )`),
ConstantCompletion("isUnsigned", `$(P Works like $(D isArithmetic), except it's for unsigned ConstantCompletion("isUnsigned", `$(P If the arguments are all either types that are unsigned types,
types.) or expressions that are typed as unsigned types, then $(D true)
is returned.
Otherwise, $(D false) is returned.
If there are no arguments, $(D false) is returned.)
$(P The unsigned types are:
` ~ "`" ~ `ubyte` ~ "`" ~ `, ` ~ "`" ~ `ushort` ~ "`" ~ `, ` ~ "`" ~ `uint` ~ "`" ~ `, ` ~ "`" ~ `ulong` ~ "`" ~ `, ` ~ "`" ~ `ucent` ~ "`" ~ `,
` ~ "`" ~ `bool` ~ "`" ~ `, ` ~ "`" ~ `char` ~ "`" ~ `, ` ~ "`" ~ `wchar` ~ "`" ~ `, ` ~ "`" ~ `dchar` ~ "`" ~ `,
vectors of unsigned types, and enums with an unsigned base type.)
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(SPEC_RUNNABLE_EXAMPLE_COMPILE
--- ---
@ -1295,9 +1610,90 @@ void test()
class C { int x = -1; } class C { int x = -1; }
static assert(__traits(isZeroInit, C)); static assert(__traits(isZeroInit, C));
// For initializing arrays of element type ` ~ "`" ~ `void` ~ "`" ~ `.
static assert(__traits(isZeroInit, void));
--- ---
)`), )`),
ConstantCompletion("parameters", `$(P May only be used inside a function. Takes no arguments, and returns
a sequence of the enclosing function's parameters.)
$(P If the function is nested, the parameters returned are those of the
inner function, not the outer one.)
---
int add(int x, int y)
{
return x + y;
}
int forwardToAdd(int x, int y)
{
return add(__traits(parameters));
// equivalent to;
//return add(x, y);
}
int nestedExample(int x)
{
// outer function's parameters
static assert(typeof(__traits(parameters)).length == 1);
int add(int x, int y)
{
// inner function's parameters
static assert(typeof(__traits(parameters)).length == 2);
return x + y;
}
return add(x, x);
}
class C
{
int opApply(int delegate(size_t, C) dg)
{
if (dg(0, this)) return 1;
return 0;
}
}
void foreachExample(C c, int x)
{
foreach(idx; 0..5)
{
static assert(is(typeof(__traits(parameters)) == AliasSeq!(C, int)));
}
foreach(idx, elem; c)
{
// __traits(parameters) sees past the delegate passed to opApply
static assert(is(typeof(__traits(parameters)) == AliasSeq!(C, int)));
}
}
---
$(H2 $(LNAME2 symbols, Symbol Traits))`),
ConstantCompletion("parent", `$(P Takes a single argument which must evaluate to a symbol. ConstantCompletion("parent", `$(P Takes a single argument which must evaluate to a symbol.
The result is the symbol that is the parent of it. The result is the symbol that is the parent of it.
)`), )`),
ConstantCompletion("toType", `$(P Takes a single argument, which must evaluate to an expression of type ` ~ "`" ~ `string` ~ "`" ~ `.
The contents of the string must correspond to the $(DDSUBLINK spec/abi, name_mangling, mangled contents of a type)
that has been seen by the implementation.)
$(P Only D mangling is supported. Other manglings, such as C++ mangling, are not.)
$(P The value returned is a type.)
---
template Type(T) { alias Type = T; }
Type!(__traits(toType, "i")) j = 3; // j is declared as type ` ~ "`" ~ `int` ~ "`" ~ `
static assert(is(Type!(__traits(toType, (int*).mangleof)) == int*));
__traits(toType, "i") x = 4; // x is also declared as type ` ~ "`" ~ `int` ~ "`" ~ `
---
$(RATIONALE Provides the inverse operation of the $(DDSUBLINK spec/property, mangleof, ` ~ "`" ~ `.mangleof` ~ "`" ~ `) property.)`),
]; ];

View File

@ -5,23 +5,29 @@ $(SPEC_S Pragmas,
$(HEADERNAV_TOC) $(HEADERNAV_TOC)
$(GRAMMAR $(GRAMMAR
$(GNAME PragmaDeclaration):
$(GLINK Pragma) $(D ;)
$(GLINK Pragma) $(GLINK2 attribute, DeclarationBlock)
$(GNAME PragmaStatement):
$(GLINK Pragma) $(D ;)
$(GLINK Pragma) $(GLINK2 statement, NoScopeStatement)
$(GNAME Pragma): $(GNAME Pragma):
$(D pragma) $(D $(LPAREN)) $(GLINK_LEX Identifier) $(D $(RPAREN)) $(D pragma) $(D $(LPAREN)) $(GLINK_LEX Identifier) $(D $(RPAREN))
$(D pragma) $(D $(LPAREN)) $(GLINK_LEX Identifier) $(D ,) $(GLINK2 expression, ArgumentList) $(D $(RPAREN)) $(D pragma) $(D $(LPAREN)) $(GLINK_LEX Identifier) $(D ,) $(GLINK2 expression, ArgumentList) $(D $(RPAREN))
) )
$(P Pragmas are a way to pass special information to the compiler $(P Pragmas pass special information to the implementation
and to add vendor specific extensions to D. and can add vendor specific extensions.
Pragmas can be used by themselves terminated with a $(SINGLEQUOTE ;), Pragmas can be used by themselves terminated with a $(TT ;),
they can influence a statement, a block of statements, a declaration, or and can apply to a statement, a block of statements, a declaration, or
a block of declarations. a block of declarations.
) )
$(P Pragmas can appear as either declarations, $(P Pragmas can be either a $(GLINK PragmaDeclaration)
$(I Pragma) $(GLINK2 attribute, DeclarationBlock), or a $(GLINK PragmaStatement).
or as statements,
$(GLINK2 statement, PragmaStatement).
) )
----------------- -----------------
@ -60,23 +66,143 @@ $(H2 $(LEGACY_LNAME2 Predefined-Pragmas, predefined-pragmas, Predefined Pragmas)
$(P All implementations must support these, even if by just ignoring them:) $(P All implementations must support these, even if by just ignoring them:)
$(UL $(UL
$(LI $(LINK2 #crtctor, pragma crt$(UNDERSCORE)constructor))
$(LI $(LINK2 #crtdtor, pragma crt$(UNDERSCORE)destructor))
$(LI $(LINK2 #inline, pragma inline)) $(LI $(LINK2 #inline, pragma inline))
$(LI $(LINK2 #lib, pragma lib)) $(LI $(LINK2 #lib, pragma lib))
$(LI $(LINK2 #linkerDirective, pragma linkerDirective)) $(LI $(LINK2 #linkerDirective, pragma linkerDirective))
$(LI $(LINK2 #mangle, pragma mangle)) $(LI $(LINK2 #mangle, pragma mangle))
$(LI $(LINK2 #msg, pragma msg)) $(LI $(LINK2 #msg, pragma msg))
$(LI $(LINK2 #printf, pragma printf))
$(LI $(LINK2 #scanf, pragma scanf))
$(LI $(LINK2 #startaddress, pragma startaddress)) $(LI $(LINK2 #startaddress, pragma startaddress))
) )
$(IMPLEMENTATION_DEFINED An implementation may ignore these pragmas.) $(IMPLEMENTATION_DEFINED An implementation may ignore these pragmas.)
$(H3 $(LNAME2 crtctor, $(D pragma crt_constructor)))
$(P Annotates a function so it is run after the C runtime library is initialized
and before the D runtime library is initialized.
)
$(P The function must:)
$(OL
$(LI be `extern (C)`)
$(LI not have any parameters)
$(LI not be a non-static member function)
$(LI be a function definition, not a declaration (i.e. it must have a function body))
$(LI not return a type that has a destructor)
$(LI not be a nested function)
)
---
__gshared int initCount;
pragma(crt_constructor)
extern(C) void initializer() { initCount += 1; }
---
$(P No arguments to the pragma are allowed.)
$(P A function may be annotated with both `pragma(crt_constructor)`
and `pragma(crt_destructor)`.
)
$(P Annotating declarations other than function definitions has no effect.)
$(P Annotating a struct or class definition does not affect the members of
the aggregate.)
$(P A function that is annotated with `pragma(crt_constructor)` may initialize
`const` or `immutable` variables.)
$(BEST_PRACTICE Use for system programming and interfacing with C/C++,
for example to allow for initialization of the runtime when loading a DSO,
or as a simple replacement for `shared static this` in
$(DDLINK spec/betterc, betterC mode, betterC mode).
)
$(IMPLEMENTATION_DEFINED The order in which functions annotated with `pragma(crt_constructor)`
are run is implementation defined.
)
$(BEST_PRACTICE to control the order in which the functions are called within one module, write
a single function that calls them in the desired order, and only annotate that function.
)
$(IMPLEMENTATION_DEFINED This uses the mechanism C compilers use to run
code before `main()` is called. C++ compilers use it to run static
constructors and destructors.
For example, GCC's $(LINK2 https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html, `__attribute__((constructor))`)
is equivalent.
Digital Mars C uses $(TT _STI) and $(TT _STD) identifier prefixes to mark crt_constructor and crt_destructor functions.
)
$(IMPLEMENTATION_DEFINED
A reference to the annotated function will be inserted in
the $(TT .init_array) section for Elf systems,
the $(TT XI) section for Win32 OMF systems,
the $(TT .CRT$XCU) section for Windows MSCOFF systems,
and the $(TT __mod_init_func) section for OSX systems.
)
$(NOTE `crt_constructor` and `crt_destructor` were implemented in
$(LINK2 $(ROOT_DIR)changelog/2.078.0.html, v2.078.0 (2018-01-01)).
Some compilers exposed non-standard, compiler-specific mechanism before.
)
$(H3 $(LNAME2 crtdtor, $(D pragma crt_destructor)))
$(P `pragma(crt_destructor)` works the same as `pragma(crt_constructor)` except:)
$(OL
$(LI Annotates a function so it is run after the D runtime library is terminated
and before the C runtime library is terminated.
Calling C's `exit()` function also causes the annotated functions to run.)
$(LI The order in which the annotated functions are run is the reverse of those functions
annotated with `pragma(crt_constructor)`.)
)
$(IMPLEMENTATION_DEFINED This uses the mechanism C compilers use to run
code after `main()` returns or `exit()` is called. C++ compilers use it to run static
destructors.
For example, GCC's $(LINK2 https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html, `__attribute__((destructor))`)
is equivalent.
Digital Mars C uses $(TT _STI) and $(TT _STD) identifier prefixes to mark crt_constructor and crt_destructor functions.
)
$(IMPLEMENTATION_DEFINED
A reference to the annotated function will be inserted in
the $(TT .fini_array) section for Elf systems,
the $(TT XC) section for Win32 OMF systems,
the $(TT .CRT$XPU) section for Windows MSCOFF systems,
and the $(TT __mod_term_func) section for OSX systems.
)
---
__gshared int initCount;
pragma(crt_constructor)
extern(C) void initialize() { initCount += 1; }
pragma(crt_destructor)
extern(C) void deinitialize() { initCount -= 1; }
pragma(crt_constructor)
pragma(crt_destructor)
extern(C) void innuendo() { printf("Inside a constructor... Or destructor?\n"); }
---
$(H3 $(LNAME2 inline, $(D pragma inline))) $(H3 $(LNAME2 inline, $(D pragma inline)))
$(P Affects whether functions are inlined or not. If at the declaration level, it $(P Affects whether functions are inlined or not. If at the declaration level, it
affects the functions declared in the block it controls. If inside a function, it affects the functions declared in the block it controls. If inside a function, it
affects the function it is enclosed by.) affects the function it is enclosed by.)
$(P It takes three forms:) $(P It takes two forms:)
$(OL $(OL
$(LI $(LI
--- ---
@ -86,21 +212,15 @@ pragma(inline)
) )
$(LI $(LI
--- ---
pragma(inline, false) pragma(inline, AssignExpression)
--- ---
Functions are never inlined. The $(GLINK2 expression, AssignExpression) is evaluated and must have a type that can be converted
) to a boolean.
$(LI If the result is false the functions are never inlined, otherwise they are always inlined.
---
pragma(inline, true)
---
Always inline the functions.
) )
) )
$(P There can be only zero or one $(I AssignExpression)s. If one is there, it must $(P More than one $(I AssignExpression) is not allowed.)
be `true`, `false`, or an integer value. An integer value is implicitly converted
to a bool.)
$(P If there are multiple pragma inlines in a function, $(P If there are multiple pragma inlines in a function,
the lexically last one takes effect.) the lexically last one takes effect.)
@ -133,8 +253,8 @@ pragma(lib, "foo.lib");
----------------- -----------------
$(IMPLEMENTATION_DEFINED $(IMPLEMENTATION_DEFINED
Typically, the string literal specifies the file name of a library file. This name The string literal specifies the file name of a library file. This name
is inserted into the generated object file, or otherwise is passed to the linker, is inserted into the generated object file, or otherwise passed to the linker,
so the linker automatically links in that library. so the linker automatically links in that library.
) )
@ -147,44 +267,177 @@ pragma(linkerDirective, "/FAILIFMISMATCH:_ITERATOR_DEBUG_LEVEL=2");
----------------- -----------------
$(IMPLEMENTATION_DEFINED $(IMPLEMENTATION_DEFINED
$(P The string literal specifies a linker directive to be embedded in the generated object file.) The string literal specifies a linker directive to be embedded in the generated object file.
Linker directives are only supported for MS-COFF output.
$(P Linker directives are only supported for MS-COFF output.)
) )
$(H3 $(LNAME2 mangle, $(D pragma mangle))) $(H3 $(LNAME2 mangle, $(D pragma mangle)))
$(P Overrides the default mangling for a symbol.) $(P Overrides the default mangling for a symbol.)
$(P There must be one $(ASSIGNEXPRESSION) and it must evaluate at compile time to a string literal. $(P For variables and functions there must be one $(ASSIGNEXPRESSION) and it must evaluate at compile time to a string literal.
For aggregates there may be one or two $(ASSIGNEXPRESSION)s, one of which must evaluate at compile time to a string literal and
one which must evaluate to a symbol. If that symbol is a $(I TemplateInstance), the aggregate is treated as a template
that has the signature and arguments of the $(I TemplateInstance). The identifier of the symbol is used when no string is supplied.
Both arguments may be used used when an aggregate's name is a D keyword.
) )
$(P It only applies to function and variable symbols. Other symbols are ignored.)
$(IMPLEMENTATION_DEFINED On macOS and Win32, an extra underscore (`_`) is prepended to the string $(IMPLEMENTATION_DEFINED On macOS and Win32, an extra underscore (`_`) is prepended to the string
since 2.079, as is done by the C/C++ toolchain. This allows using the same `pragma(mangle)` since 2.079, as is done by the C/C++ toolchain. This allows using the same `pragma(mangle)`
for all compatible (POSIX in one case, win64 in another) platforms instead of having to special-case. for all compatible (POSIX in one case, win64 in another) platforms instead of having to special-case.
) )
$(IMPLEMENTATION_DEFINED It's only effective $(RATIONALE
when the symbol is a function declaration or a variable declaration. $(UL
For example this allows linking to a symbol which is a D keyword, which would normally $(LI Enables linking to symbol names that D cannot represent.)
be disallowed as a symbol name: $(LI Enables linking to a symbol which is a D keyword, since an $(GLINK_LEX Identifier)
cannot be a keyword.)
) )
----------------- ---
pragma(mangle, "body") pragma(mangle, "body")
extern(C) void body_func(); extern(C) void body_func();
----------------- pragma(mangle, "function")
extern(C++) struct _function {}
template ScopeClass(C)
{
pragma(mangle, C.stringof, C)
struct ScopeClass { align(__traits(classInstanceAlignment, C)) void[__traits(classInstanceSize, C)] buffer; }
}
extern(C++)
{
class MyClassA(T) {}
void func(ref ScopeClass!(MyClassA!int)); // mangles as MyClass<int>&
}
---
)
$(H3 $(LNAME2 msg, $(D pragma msg))) $(H3 $(LNAME2 msg, $(D pragma msg)))
$(P Constructs a message from the $(I ArgumentList).) $(P Each $(ASSIGNEXPRESSION) is evaluated at compile time and then all are combined into a message.)
---
pragma(msg, "compiling...", 6, 1.0); // prints "compiling...61.0" at compile time
---
$(IMPLEMENTATION_DEFINED The form the message takes and how it is presented to the user.
One way is by printing them to the standard error stream.)
$(RATIONALE Analogously to how `writeln()` performs a role of writing informational messages during runtime,
`pragma(msg)` performs the equivalent role at compile time.
For example,
---
static if (kilroy)
pragma(msg, "Kilroy was here");
else
pragma(msg, "Kilroy got lost");
---
)
$(H3 $(LNAME2 printf, $(D pragma printf)))
$(P `pragma(printf)` specifies that a function declaration is a printf-like function, meaning
it is an `extern (C)` or `extern (C++)` function with a `format` parameter accepting a
pointer to a 0-terminated `char` string conforming to the C99 Standard 7.19.6.1, immediately followed
by either a `...` variadic argument list or a parameter of type `va_list` as the last parameter.
)
$(P If the `format` argument is a string literal, it is verified to be a valid format string
per the C99 Standard. If the `format` parameter is followed by `...`, the number and types
of the variadic arguments are checked against the format string.)
$(P Diagnosed incompatibilities are:)
$(UL
$(LI incompatible sizes which may cause argument misalignment)
$(LI deferencing arguments that are not pointers)
$(LI insufficient number of arguments)
$(LI struct arguments)
$(LI array and slice arguments)
$(LI non-pointer arguments to `s` specifier)
$(LI non-standard formats)
$(LI undefined behavior per C99)
)
$(P Per the C99 Standard, extra arguments are ignored.)
$(P Ignored mismatches are:)
$(UL
$(LI sign mismatches, such as printing an `int` with a `%u` format)
$(LI integral promotion mismatches, where the format specifies a smaller integral
type than `int` or `uint`, such as printing a `short` with the `%d` format rather than `%hd`)
)
---
printf("%k\n", value); // error: non-Standard format k
printf("%d\n"); // error: not enough arguments
printf("%d\n", 1, 2); // ok, extra arguments ignored
---
$(BEST_PRACTICE
In order to use non-Standard printf/scanf formats, an easy workaround is:
---
const format = "%k\n";
printf(format.ptr, value); // no error
---
)
$(BEST_PRACTICE
Most of the errors detected are portability issues. For instance,
---
string s;
printf("%.*s\n", s.length, s.ptr);
printf("%d\n", s.sizeof);
ulong u;
scanf("%lld%*c\n", &u);
---
should be replaced with:
---
string s;
printf("%.*s\n", cast(int) s.length, s.ptr);
printf("%zd\n", s.sizeof);
ulong u;
scanf("%llu%*c\n", &u);
---
)
$(P `pragma(printf)` applied to declarations that are not functions are ignored.
In particular, it has no effect on the declaration of a pointer to function type.
)
$(H3 $(LNAME2 scanf, $(D pragma scanf)))
$(P `pragma(scanf)` specifies that a function declaration is a scanf-like function, meaning
it is an `extern (C)` or `extern (C++)` function with a `format` parameter accepting a
pointer to a 0-terminated `char` string conforming to the C99 Standard 7.19.6.2, immediately followed
by either a `...` variadic argument list or a parameter of type `va_list` as the last parameter.
)
$(P If the `format` argument is a string literal, it is verified to be a valid format string
per the C99 Standard. If the `format` parameter is followed by `...`, the number and types
of the variadic arguments are checked against the format string.)
$(P Diagnosed incompatibilities are:)
$(UL
$(LI argument is not a pointer to the format specified type)
$(LI insufficient number of arguments)
$(LI non-standard formats)
$(LI undefined behavior per C99)
)
$(P Per the C99 Standard, extra arguments are ignored.)
$(P `pragma(scanf)` applied to declarations that are not functions are ignored.
In particular, it has no effect on the declaration of a pointer to function type.
)
-----------------
pragma(msg, "compiling...", 1, 1.0);
-----------------
$(IMPLEMENTATION_DEFINED The arguments are typically presented to the user during compilation,
such as by printing them to the standard error stream.)
$(H3 $(LNAME2 startaddress, $(D pragma startaddress))) $(H3 $(LNAME2 startaddress, $(D pragma startaddress)))

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,17 @@
identifiers identifiers
allMembers k allMembers k
child k
classInstanceAlignment k
classInstanceSize k classInstanceSize k
compiles k compiles k
derivedMembers k derivedMembers k
getAliasThis k getAliasThis k
getAttributes k getAttributes k
getCppNamespaces k
getFunctionAttributes k getFunctionAttributes k
getFunctionVariadicStyle k getFunctionVariadicStyle k
getLinkage k getLinkage k
getLocation k
getMember k getMember k
getOverloads k getOverloads k
getParameterStorageClasses k getParameterStorageClasses k
@ -18,12 +22,17 @@ getUnitTests k
getVirtualFunctions k getVirtualFunctions k
getVirtualIndex k getVirtualIndex k
getVirtualMethods k getVirtualMethods k
getVisibility k
hasCopyConstructor k
hasMember k hasMember k
hasPostblit k
identifier k identifier k
initSymbol k
isAbstractClass k isAbstractClass k
isAbstractFunction k isAbstractFunction k
isArithmetic k isArithmetic k
isAssociativeArray k isAssociativeArray k
isCopyable k
isDeprecated k isDeprecated k
isDisabled k isDisabled k
isFinalClass k isFinalClass k
@ -32,10 +41,12 @@ isFloating k
isFuture k isFuture k
isIntegral k isIntegral k
isLazy k isLazy k
isModule k
isNested k isNested k
isOut k isOut k
isOverrideFunction k isOverrideFunction k
isPOD k isPOD k
isPackage k
isRef k isRef k
isReturnOnStack k isReturnOnStack k
isSame k isSame k
@ -47,4 +58,6 @@ isUnsigned k
isVirtualFunction k isVirtualFunction k
isVirtualMethod k isVirtualMethod k
isZeroInit k isZeroInit k
parameters k
parent k parent k
toType k