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

Semantic analysis of expressions.

Specification ($LINK2 https://dlang.org/spec/expression.html, Expressions)

Authors:
bool expressionsToString(ref OutBuffer buf, Scope* sc, Expressions* exps, Loc loc, const(char)* fmt, bool expandTuples);
Perform semantic analysis and CTFE on expressions to produce a string.
Parameters:
OutBuffer buf append generated string to buffer
Scope* sc context
Expressions* exps array of Expressions
Loc loc location of the pragma / mixin where this conversion was requested, for supplemental error
const(char)* fmt format string for supplemental error. May contain 1 %s which prints the faulty expression
bool expandTuples whether tuples should be expanded rather than printed as tuple syntax
Returns:
true on error
FuncDeclaration hasThis(Scope* sc);
Determine if this is available by walking up the enclosing scopes until a function is found.
Parameters:
Scope* sc where to start looking for the enclosing function
Returns:
Found function if it satisfies isThis(), otherwise null
StringExp semanticString(Scope* sc, Expression exp, const char* s);
Resolve exp as a compile-time known string.
Parameters:
Scope* sc scope
Expression exp Expression which expected as a string
char* s What the string is expected for, will be used in error diagnostic.
Returns:
String literal, or null if error happens.
StringExp toUTF8(StringExp se, Scope* sc);
Convert string to char[].
Expression incompatibleTypes(BinExp e, Scope* sc = null);
The types for a binary expression are incompatible. Print error message.
Returns:
ErrorExp
TupleDeclaration isAliasThisTuple(Expression e);
Expand alias this tuples.
Expression resolveOpDollar(Scope* sc, ArrayExp ae, out Expression pe0);
Runs semantic on ae.arguments. Declares temporary variables if '$' was used.
Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, ref Expression pe0);
Runs semantic on se.lwr and se.upr. Declares a temporary variable if '$' was used.
Returns:
ae, or ErrorExp if errors occurred
bool arrayExpressionSemantic(Expression[] exps, Scope* sc, bool preserveErrors = false);
Perform semantic() on an array of Expressions.
Expression doCopyOrMove(Scope* sc, Expression e, Type t, bool nrvo, bool move = false);
Handle the postblit call on lvalue, or the move of rvalue.
Parameters:
Scope* sc the scope where the expression is encountered
Expression e the expression the needs to be moved or copied (source)
Type t if the struct defines a copy constructor, the type of the destination (can be NULL)
bool nrvo true if the generated copy can be treated as NRVO
bool move true to allow a move constructor to be used, false to prevent infinite recursion
Returns:
The expression that copy constructs or moves the value.
Expression valueNoDtor(Expression e);
If we want the value of this expression, but do not want to call the destructor on it.
Expression resolvePropertiesOnly(Scope* sc, Expression e1);
If e1 is a property function (template), resolve it.
Expression symbolToExp(Dsymbol s, Loc loc, Scope* sc, bool hasOverloads);
Turn symbol s into the expression it represents.
Parameters:
Dsymbol s symbol to resolve
Loc loc location of use of s
Scope* sc context
bool hasOverloads applies if s represents a function. true means it's overloaded and will be resolved later, false means it's the exact function symbol.
Returns:
s turned into an expression, ErrorExp if an error occurred
void checkOverriddenDtor(FuncDeclaration f, Scope* sc, Loc loc, scope bool function(DtorDeclaration) check, const string checkName);
Checks whether f is a generated DtorDeclaration that hides a user-defined one which passes check while f doesn't (e.g. when the user defined dtor is pure but the generated dtor is not). In that case the method will identify and print all members causing the attribute missmatch.
Parameters:
FuncDeclaration f potential DtorDeclaration
Scope* sc scope
Loc loc location
bool function(DtorDeclaration) check current check (e.g. whether it's pure)
string checkName the kind of check (e.g. "pure")
void errorSupplementalInferredAttr(FuncDeclaration fd, int maxDepth, bool deprecation, STC stc, ErrorSink eSink);
Print the reason why fd was inferred @system as a supplemental error
Parameters:
FuncDeclaration fd function to check
int maxDepth up to how many functions deep to report errors
bool deprecation print deprecations instead of errors
STC stc storage class of attribute to check
ErrorSink eSink where the error messages go
Package resolveIsPackage(Dsymbol sym);
Determines whether a symbol represents a module or package (Used as a helper for is(type == module) and is(type == package))
Parameters:
Dsymbol sym the symbol to be checked
Returns:
the symbol which sym represents (or null if it doesn't represent a Package)
Expression trySemantic(Expression exp, Scope* sc);
Try to run semantic routines. If they fail, return NULL.
Expression trySemanticAliasThis(Expression exp, Scope* sc, Type[2] aliasThisStop);
Try expression semantic on exp, gagging semantic errors, but don't resolve alias this on a BinExp when the lhs or rhs has the corresponding type in aliasThisStop (See isRecursiveAliasThis).
Parameters:
Expression exp expression to try semantic on
Scope* sc scope
Type[2] aliasThisStop pair of recursive alias this types to stop endless recursion
Returns:
exp after expression semantic, or null on error
Expression unaSemantic(UnaExp e, Scope* sc);
Helper function for easy error propagation. If error occurs, returns ErrorExp. Otherwise returns NULL.
Expression binSemantic(BinExp e, Scope* sc);
Helper function for easy error propagation. If error occurs, returns ErrorExp. Otherwise returns NULL.
Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag);
Resolve properties, i.e. e1.ident, without seeing UFCS.
Parameters:
DotIdExp exp expression to resolve
Scope* sc context
bool gag do not emit error messages, just return null
Returns:
resolved expression, null if error
Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, bool gag);
Resolve e1.ident!tiargs without seeing UFCS.
Parameters:
DotTemplateInstanceExp exp the DotTemplateInstanceExp to resolve
Scope* sc the semantic scope
bool gag stop "not a property" error and return null.
Returns:
null if error or not found, or the resolved expression.
bool checkValue(Expression e);
Check that the expression has a valid value. If not, generates an error "... has no value".`
Parameters:
Expression e expression to check
Returns:
true if the expression is not valid or has void type.
bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false);
If expression is shared, check that we can access it. Give error message if not.
Parameters:
Expression e expression to check
Scope* sc context
bool returnRef Whether this expression is for a return statement off a ref function, in which case a single level of dereference is allowed (e.g. shared(int)*).
Returns:
true on error
Expression resolveLoc(Expression exp, Loc loc, Scope* sc);
Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__, _FILE_FULL_PATH__ to loc.
Expression addDtorHook(Expression e, Scope* sc);
Destructors are attached to VarDeclarations. Hence, if expression returns a temp that needs a destructor, make sure and create a VarDeclaration for that temp.
Expression toLvalue(Expression _this, Scope* sc, const(char)* action);
Try to convert an expression to be an lvalue.
Give error if we're not an lvalue.
Parameters:
Expression _this expression to convert
Scope* sc scope
const(char)* action for error messages, what the lvalue is needed for (e.g. take address of for &x, modify for x++)
Returns:
converted expression, or ErrorExp on error
Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag = ModifyFlags.none);

Parameters sc: scope flag: 1: do not issue error message for invalid modification 2: the exp is a DotVarExp and a subfield of the leftmost variable is modified

Returns:
Whether the type is modifiable
Expression modifiableLvalue(Expression _this, Scope* sc);
Similar to toLvalue, but also enforce it is mutable or raise an error.
Parameters:
Expression _this Expression to convert
Scope* sc scope
Returns:
_this converted to an lvalue, or an ErrorExp
bool checkAddressable(Expression e, Scope* sc);
This check ensures that the object in exp can have its address taken, or issue a diagnostic error.
Parameters:
Expression e expression to check
Scope* sc context
Returns:
true if the expression is addressable
Expression getThisSkipNestedFuncs(Loc loc, Scope* sc, Dsymbol s, AggregateDeclaration ad, Expression e1, Type t, Dsymbol var, bool flag = false);
Helper function for getRightThis(). Gets this of the next outer aggregate.
Parameters:
Loc loc location to use for error messages
Scope* sc context
Dsymbol s the parent symbol of the existing this
AggregateDeclaration ad struct or class we need the correct this for
Expression e1 existing this
Type t type of the existing this
Dsymbol var the specific member of ad we're accessing
bool flag if true, return null instead of throwing an error
Returns:
Expression representing the this for the var
bool verifyHookExist(Loc loc, ref Scope sc, Identifier id, string description, Identifier module_ = Id.object);
Make sure that the runtime hook id exists.
Parameters:
Loc loc location to use for error messages
Scope sc current scope
Identifier id the hook identifier
string description what the hook does
Identifier module_ what module the hook is located in
Returns:
a bool indicating if the hook is present.
Expression getVarExp(EnumMember em, Loc loc, Scope* sc);
Returns em as a VariableExp
Parameters:
EnumMember em the EnumMember to wrap
Loc loc location of use of em
Scope* sc scope of use of em
Returns:
VarExp referenceing em or ErrorExp if em if disabled/deprecated
Expression toBoolean(Expression exp, Scope* sc);
Try to treat exp as a boolean,
Parameters:
Expression exp the expression
Scope* sc scope to evalute exp in
Returns:
Modified expression on success, ErrorExp on error
bool evalStaticCondition(Scope* sc, Expression original, Expression e, out bool errors, Expressions* negatives = null);
Semantically analyze and then evaluate a static condition at compile time. This is special because short circuit operators &&, || and ?: at the top level are not semantically analyzed if the result of the expression is not necessary.
Parameters:
Scope* sc instantiating scope
Expression original original expression, for error messages
Expression e resulting expression
bool errors set to true if errors occurred
Expressions* negatives array to store negative clauses
Returns:
true if evaluates to true
bool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad, size_t iStart = 0);
Check to see the aggregate type is nested and its context pointer is accessible from the current scope. Returns true if error occurs.
enum Modifiable: int;
Return value for checkModifiable
no
Not modifiable
yes
Modifiable (the type is mutable)
initialization
Modifiable because it is initialization
enum ModifyFlags: int;
Specifies how the checkModify deals with certain situations
none
Issue error messages on invalid modifications of the variable
noError
No errors are emitted for invalid modifications
fieldAssign
The modification occurs for a subfield of the current variable
void semanticTypeInfo(Scope* sc, Type t);
Request additional semantic analysis for TypeInfo generation.
Parameters:
Scope* sc context
Type t type that TypeInfo is being generated for
bool checkDisabled(Declaration d, Loc loc, Scope* sc, bool isAliasedDeclaration = false);
Issue an error if an attempt to call a disabled method is made
If the declaration is disabled but inside a disabled function, returns true but do not issue an error message.
Parameters:
Declaration d Declaration to check
Loc loc Location information of the call
Scope* sc Scope in which the call occurs
bool isAliasedDeclaration if true searches overload set
Returns:
true if this Declaration is @disabled, false otherwise.
bool fill(StructDeclaration sd, Loc loc, ref Expressions elements, bool ctorinit);
Fill out remainder of elements[] with default initializers for fields[].
Parameters:
StructDeclaration sd struct
Loc loc location
Expressions elements explicit arguments which given to construct object.
bool ctorinit true if the elements will be used for default initialization.
Returns:
false if any errors occur. Otherwise, returns true and the missing arguments will be pushed in elements[].
void lowerNonArrayAggregate(StaticForeach sfe, Scope* sc);
Lower any aggregate that is not an array to an array using a regular foreach loop within CTFE. If there are multiple static foreach loop variables, an array of tuples is generated. In thise case, the field needExpansion is set to true to indicate that the static foreach loop expansion will need to expand the tuples into multiple variables.
For example, static foreach (x; range) { ... } is lowered to:
static foreach (x; { typeof({ foreach (x; range) return x; }())[] _res; foreach (x; range) _res ~= x; return _res; }()) { ... }
Finally, call lowerArrayAggregate to turn the produced array into an expression tuple.
Parameters:
StaticForeach sfe The 'static foreach'.
Scope* sc The current scope.
void prepare(StaticForeach sfe, Scope* sc);
Perform static foreach lowerings that are necessary in order to finally expand the static foreach using dmd.statementsem.makeTupleForeach.
void lowerArrayAggregate(StaticForeach sfe, Scope* sc);
Turn an aggregate which is an array into an expression tuple of its elements. I.e., lower static foreach (x; [1, 2, 3, 4]) { ... } to static foreach (x; AliasSeq!(1, 2, 3, 4)) { ... }