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.typesem

Semantic analysis for D types.
Authors:

Source typesem.d

Type addSTC(Type _this, STC stc);
Apply STCxxxx bits to existing type. Use before semantic analysis is run.
bool isIndexableNonAggregate(Type t);
Determine if type t can be indexed or sliced given that it is not an aggregate with operator overloads.
Parameters:
Type t type to check
Returns:
true if an expression of type t can be e1 in an array expression
AggregateDeclaration isAggregate(Type t);
If the type is a class or struct, returns the symbol for it, else null.
Type isLazyArray(Parameter _this);
Determine if parameter is a lazy array of delegates. If so, return the return type of those delegates. If not, return NULL.
Returns T if the type is one of the following forms: T delegate()[] T delegate()[dim]
ulong sizemask(Type _this);
Return the mask that an integral type will fit into.
Type baseElemOf(Type _this);
If this is a type of static array, return its base element type.
Type nextOf(Type _this);
If this is a type of something, return that something.
void check(Type _this);
Look for bugs in constructing types.
bool needsCopyOrPostblit(Type _this);
true if when type is copied, it needs a copy constructor or postblit applied. Only applies to value types, not ref types.
bool needsDestruction(Type _this);
true if when type goes out of scope, it needs a destructor applied. Only applies to value types, not ref types.
MOD deduceWild(Type _this, Type t, bool isRef);
Compute MOD bits matching this argument type to wild parameter type.
Parameters:
Type _this base parameter type
Type t corresponding parameter type
bool isRef parameter is ref or out
Returns:
MOD bits
bool isBoolean(Type _this);
Returns true if T can be converted to boolean value.
Type toBasetype(Type _this);
If this is a shell around another type, get that other type.
bool hasVoidInitPointers(Type _this);
Detect if type has pointer fields that are initialized to void. Local stack variables with such void fields can remain uninitialized, leading to pointer bugs.
Returns:
true if so
structalign_t alignment(Type _this);
Return alignment to use for this type.
bool hasInvariant(Type _this);
Returns:
true if type has any invariants
bool hasUnsafeBitpatterns(Type _this);
Detect if this is an unsafe type because of the presence of @system members
Returns:
true if so
bool isCopyable(Type t);
Determine if type t is copyable.
Parameters:
Type t type to check
Returns:
true if we can copy it
bool isAssignable(Type t);
When T is mutable,

Given T a, b; Can we bitwise assign: a = b; ?

int mutabilityOfType(bool isRef, Type t);
Determine mutability of indirections in (ref) t.
Returns:
When the type has any mutable indirections, returns 0. When all indirections are immutable, returns 2. Otherwise, when the type has const/inout indirections, returns 1.
Parameters:
bool isRef if true, check ref t; otherwise, check just t
Type t the type that is being checked
void purityLevel(TypeFunction typeFunction);
Set 'purity' field of 'typeFunction'. Do this lazily, as the parameter types might be forward referenced.
bool checkComplexTransition(Type type, Loc loc, Scope* sc);
https://issues.dlang.org/show_bug.cgi?id=14488 Check if the inner most base type is complex or imaginary. Should only give alerts when set to emit transitional messages.
Parameters:
Type type type to check
Loc loc The source location.
Scope* sc scope of the type
Expressions* resolveNamedArgs(TypeFunction tf, ArgumentList argumentList, OutBuffer* buf);
Convert an argumentList, which may contain named arguments, into a list of arguments in the order of the parameter list.
Parameters:
TypeFunction tf function type
ArgumentList argumentList array of function arguments
OutBuffer* buf if not null, append error message to it
Returns:
re-ordered argument list, or null on error
MATCH callMatch(FuncDeclaration fd, TypeFunction tf, Type tthis, ArgumentList argumentList, int flag = 0, void delegate(const(char)*, Loc argloc = Loc.initial) scope errorHelper = null, Scope* sc = null);
'args' are being matched to function type 'tf' Determine match level.
Parameters:
FuncDeclaration fd function being called, if a symbol
TypeFunction tf function type
Type tthis type of this pointer, null if not member function
ArgumentList argumentList arguments to function call
int flag 1: performing a partial ordering match
void delegate(const(char)*, Loc argloc = Loc.initial) scope errorHelper delegate to call for error messages
Scope* sc context
Returns:
MATCHxxxx
void determineTypeProperties(StructDeclaration sd);
Compute cached type properties for TypeStruct
bool hasPointers(Type t);
Return !=0 if type has pointers that need to be scanned by the GC during a collection cycle.
Type getIndirection(Type t);
Returns an indirect type one step from t.
MATCH constConv(Type from, Type to);
Determine if converting 'this' to 'to' is an identity operation, a conversion to const operation, or the types aren't the same.
Returns:
MATCH.exact 'this' == 'to' MATCH.constant 'to' is const MATCH.nomatch conversion to mutable or invariant
Type typeSemantic(Type type, Loc loc, Scope* sc);
Perform semantic analysis on a type.
Parameters:
Type type Type AST node
Loc loc the location of the type
Scope* sc context
Returns:
Type with completed semantic analysis, Terror if errors were encountered
Type merge(Type type);
If an identical type to type is in type.stringtable, return the latter one. Otherwise, add it to type.stringtable. Some types don't get merged and are returned as-is.
Parameters:
Type type Type to check against existing types
Returns:
the type that was merged
Type merge2(Type type);
This version does a merge even if the deco is already computed. Necessary for types that have a deco, but are not merged.
Expression defaultInitLiteral(Type t, Loc loc);
Use when we prefer the default initializer to be a literal, rather than a global immutable variable.
Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int flag, Expression src = null);
Calculate built-in properties which just the type is necessary.
Parameters:
Type t the type for which the property is calculated
Scope* scope_ the scope from which the property is being accessed. Used for visibility checks only.
Loc loc the location where the property is encountered
Identifier ident the identifier of the property
int flag if flag & 1, don't report "not a property" error and just return NULL.
Expression src expression for type t or null.
Returns:
expression representing the property, or null if not a property and (flag & 1)
void resolve(Type mt, Loc loc, Scope* sc, out Expression pe, out Type pt, out Dsymbol ps, bool intypeid = false);
Resolve type 'mt' to either type, symbol, or expression. If errors happened, resolved to Type.terror.
Parameters:
Type mt type to be resolved
Loc loc the location where the type is encountered
Scope* sc the scope of the type
Expression pe is set if t is an expression
Type pt is set if t is a type
Dsymbol ps is set if t is a symbol
bool intypeid true if in type id
Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag flag);
Access the members of the object e. This type is same as e.type.
Parameters:
Type mt type for which the dot expression is used
Scope* sc instantiating scope
Expression e expression to convert
Identifier ident identifier being used
DotExpFlag flag DotExpFlag bit flags
Returns:
resulting expression with e.ident resolved
Expression defaultInit(Type mt, Loc loc, const bool isCfile = false);
Get the default initialization expression for a type.
Parameters:
Type mt the type for which the init expression is returned
Loc loc the location where the expression needs to be evaluated
bool isCfile default initializers are different with C
Returns:
The initialization expression for the type.
Type addStorageClass(Type type, STC stc);
Add storage class modifiers to type.
Type getComplexLibraryType(Loc loc, Scope* sc, TY ty);
Extract complex type from core.stdc.config
Parameters:
Loc loc for error messages
Scope* sc context
TY ty a complex or imaginary type
Returns:
Complex!float, Complex!double, Complex!real or null for error
Covariant covariant(Type src, Type t, STC* pstc = null, bool cppCovariant = false);
Covariant means that 'src' can substitute for 't', i.e. a pure function is a match for an impure type.
Parameters:
Type src source type
Type t type 'src' is covariant with
STC* pstc if not null, store STCxxxx which would make it covariant
bool cppCovariant true if extern(C++) function types should follow C++ covariant rules
Returns:
An enum value of either Covariant.yes or a reason it's not covariant.
STC parameterStorageClass(TypeFunction tf, Type tthis, Parameter p, VarDeclarations* outerVars = null, bool indirect = false);
Take the specified storage class for p, and use the function signature to infer whether STC.scope_ and STC.return_ should be OR'd in. (This will not affect the name mangling.)
Parameters:
TypeFunction tf TypeFunction to use to get the signature from
Type tthis type of this parameter, null if none
Parameter p parameter to this function
VarDeclarations* outerVars context variables p could escape into, if any
bool indirect is this for an indirect or virtual function call?
Returns:
storage class with STC.scope_ or STC.return_ OR'd in
Type constOf(Type type);
Convert to 'const'.
Type immutableOf(Type type);
Convert to 'immutable'.
Type mutableOf(Type type);
Make type mutable. 0 => 0 const => 0 immutable => 0 shared => shared shared const => shared wild => 0 wild const => 0 shared wild => shared shared wild const => shared
Type unSharedOf(Type type);
Make type unshared. 0 => 0 const => const immutable => immutable shared => 0 shared const => const wild => wild wild const => wild const shared wild => wild shared wild const => wild const
Type wildOf(Type type);
Convert to 'wild'.
Type toHeadMutable(const Type t);
Return type with the top level of it being mutable.
Parameters:
Type t type for which the top level mutable version is being returned
Returns:
type version with mutable top level
Type castMod(Type type, MOD mod);
Apply MODxxxx bits to existing type.
Type addMod(Type type, MOD mod);
Add MODxxxx bits to existing type. We're adding, not replacing, so adding const to a shared type => "shared const"
bool isRecursiveAliasThis(ref Type att, Type t);
Check and set 'att' if 't' is a recursive 'alias this' type
The goal is to prevent endless loops when there is a cycle in the alias this chain. Since there is no multiple alias this, the chain either ends in a leaf, or it loops back on itself as some point.

Example S0 -> (S1 -> S2 -> S3 -> S1)

S0 is not a recursive alias this, so this returns false, and a rewrite to S1 can be tried. S1 is a recursive alias this type, but since att is initialized to null, this still returns false, but att1 is set to S1. A rewrite to S2 and S3 can be tried, but when we want to try a rewrite to S1 again, we notice att == t, so we're back at the start of the loop, and this returns true.

Parameters:
Type att type reference used to detect recursion. Should be initialized to null.
Type t type of 'alias this' rewrite to attempt
Returns:
false if the rewrite is safe, true if it would loop back around
uint numberOfElems(Type t, Loc loc);
Compute number of elements for a (possibly multidimensional) static array, or 1 for other types.
Parameters:
Type t static array type
Loc loc for error message
Returns:
number of elements, uint.max on overflow
bool isOpaqueType(Type t);
Returns:
whether t is a struct/class/enum without a body