Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.
dmd.clone
Builds struct member functions if needed and not defined by the user.
Includes opEquals, opAssign, post blit, copy constructor and destructor.
Authors:
License:
Source clone.d
Documentation https://dlang.org/phobos/dmd_clone.html
- pure @safe STC
mergeFuncAttrs
(STCs1
, const FuncDeclarationf
); - Merge function attributes pure, nothrow, @safe, @nogc, and @disable from f into s1.Parameters:
STC s1
storage class to merge into FuncDeclaration f
function Returns:merged storage class - FuncDeclaration
hasIdentityOpAssign
(AggregateDeclarationad
, Scope*sc
); - Check given aggregate actually has an identity opAssign or not.Parameters:
AggregateDeclaration ad
struct or class Scope* sc
current scope Returns:if found, returns FuncDeclaration of opAssign, otherwise null - FuncDeclaration
buildOpAssign
(StructDeclarationsd
, Scope*sc
); - Build opAssign for a struct.The generated opAssign function has the following signature:
ref S opAssign(S s) // S is the name of the `struct`
The opAssign function will be built for a struct S if the following constraints are met:- S does not have an identity opAssign defined.
- S has at least one of the following members: a postblit (user-defined or) generated for fields that have a defined postblit
- S does not have any non-mutable fields.
S __swap = void; __swap = this; // bit copy this = s; // bit copy __swap.dtor();
Otherwise, if S defines a postblit, the generated code for opAssign is:this = s;
Note that the parameter to the generated opAssign is passed by value, which means that the postblit is going to be called (if it is defined) in both of the above situations before entering the body of opAssign. The assignments in the above generated function bodies are blit expressions, so they can be regarded as memcpys (opAssign is not called as this will result in an infinite recursion; the postblit is not called because it has already been called when the parameter was passed by value). If S does not have a postblit or a destructor, but contains at least one field that defines an opAssign function (which is not disabled), then the body will make member-wise assignments:this.field1 = s.field1; this.field2 = s.field2; ...;
In this situation, the assignemnts are actual assign expressions (opAssign is used if defined).Parameters:StructDeclaration sd
struct to generate opAssign for Scope* sc
context Returns:generated opAssign function, or null if it is not needed - bool
needOpEquals
(StructDeclarationsd
); - We need an opEquals for the struct if any field has an opEquals and a user-specified one does not exist.Parameters:
StructDeclaration sd
struct to check Returns:true if need to generate one - FuncDeclaration
buildOpEquals
(StructDeclarationsd
, Scope*sc
); - Build opEquals for struct. const bool opEquals(const S s) { ... }By fixing https://issues.dlang.org/show_bug.cgi?id=3789 opEquals is changed to be never implicitly generated. Now, struct objects comparison s1 == s2 is translated to: s1.tupleof == s2.tupleof to calculate structural equality. See opOverloadEquals.
- FuncDeclaration
buildXopEquals
(StructDeclarationsd
, Scope*sc
); - Build __xopEquals for TypeInfo_Struct bool __xopEquals(ref const S p) const { return this == p; }This is called by TypeInfo.equals(p1, p2). If the struct does not support const objects comparison, it will throw "not implemented" Error in runtime.
- FuncDeclaration
buildXopCmp
(StructDeclarationsd
, Scope*sc
); - Build __xopCmp for TypeInfo_Struct int __xopCmp(ref const S p) const { return this.opCmp(p); }This is called by TypeInfo.compare(p1, p2). If the struct does not support const objects comparison, it will throw "not implemented" Error in runtime.
- FuncDeclaration
buildXtoHash
(StructDeclarationsd
, Scope*sc
); - Build _xtoHash for non-bitwise hashing static hash_t xtoHash(ref const S p) nothrow @trusted;
- void
buildDtors
(AggregateDeclarationad
, Scope*sc
); - Create aggregate destructor for struct/class by aggregating all the destructors in userDtors[] with the destructors for all the members. Sets ad's fieldDtor, aggrDtor, dtor and tidtor fields.Parameters:
AggregateDeclaration ad
struct or class to build destructor for Scope* sc
context Note Close similarity with StructDeclaration::buildPostBlit(), and the ordering changes (runs backward instead of forwards).
- FuncDeclaration
buildInv
(AggregateDeclarationad
, Scope*sc
); - Create inclusive invariant for struct/class by aggregating all the invariants in invs[].
void __invariant() const [pure nothrow @trusted] { invs[0](), invs[1](), ...; }
Parameters:AggregateDeclaration ad
aggregate for creating invariant Scope* sc
context Returns:generated invariant, null if not needed - FuncDeclaration
buildPostBlit
(StructDeclarationsd
, Scope*sc
); - Create inclusive postblit for struct by aggregating all the postblits in postblits[] with the postblits for all the members. Note the close similarity with AggregateDeclaration::buildDtor(), and the ordering changes (runs forward instead of backwards).Parameters:
StructDeclaration sd
struct to create postblit for Scope* sc
context Returns:generated postblit, or null if not - void
needCopyOrMoveCtor
(StructDeclarationsd
, out boolhasCopyCtor
, out boolhasMoveCtor
, out boolneedCopyCtor
, out boolneedMoveCtor
); - Determine if a copy constructor is needed for struct sd, if the following conditions are met:
- sd does not define a copy constructor
- at least one field of sd defines a copy constructor
Parameters:StructDeclaration sd
the struct for which the copy constructor is generated bool hasCopyCtor
set to true if a copy constructor is already present bool hasMoveCtor
set to true if a move constructor is already present bool needCopyCtor
set to true if a copy constructor is not present, but needed bool needMoveCtor
set to true if a move constructor is not present, but needed Returns:true if one needs to be generated false otherwise - void
buildCopyOrMoveCtor
(StructDeclarationsd
, Scope*sc
, boolmove
); - Generates a copy constructor if needCopyCtor() returns true. The generated copy constructor will be of the form: this(ref return scope inout(S) rhs) inout { this.field1 = rhs.field1; this.field2 = rhs.field2; ... }Parameters:
StructDeclaration sd
the struct for which the constructor is generated Scope* sc
the scope where the constructor is generated bool move
true means generate the move constructor, otherwise copy constructor
Copyright © 1999-2025 by the D Language Foundation | Page generated by
Ddoc on Sun Apr 13 05:29:04 2025