Semantic analysis of expressions.
bool
isIdentical(const Expression
_this, const Expression
e);
Identical, not just equal. I.e. NaNs with different bit patterns are not identical
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:OutBufferbuf | append generated string to buffer |
Scope*sc | context |
Expressions*exps | array of Expressions |
Locloc | 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 |
boolexpandTuples | whether tuples should be expanded rather than printed as tuple syntax |
bool
hasRegularCtor(StructDeclaration
sd, bool
ignoreDisabled);
Verifies whether the struct declaration has a constructor that is not a copy constructor. Optionally, it can check whether the struct declaration has a regular constructor, that is not disabled.
Parameters:StructDeclarationsd | struct declaration |
boolignoreDisabled | true to ignore disabled constructors |
Returns:true, if the struct has a regular (optionally, not disabled) constructor, false otherwise.
FuncDeclaration
hasThis(Scope*
sc);
Determine ifthis 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 satisfiesisThis(), otherwisenull
StringExp
semanticString(Scope*
sc, Expression
exp, const char*
s);
Resolveexp as a compile-time known string.
Parameters:Scope*sc | scope |
Expressionexp | Expression which expected as a string |
char*s | What the string is expected for, will be used in error diagnostic. |
Returns:String literal, ornull 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.
TupleDeclaration
isAliasThisTuple(Expression
e);
Expand alias this tuples.
Expression
addressOf(Expression
e);
Take address of expression.
Expression
getField(StructLiteralExp
sle, Type
type, uint
offset);
Gets expression at offset of type. Returns NULL if not found.
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 |
Expressione | the expression the needs to be moved or copied (source) |
Typet | if the struct defines a copy constructor, the type of the destination (can be NULL) |
boolnrvo | true if the generated copy can be treated as NRVO |
boolmove | 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 symbols into the expression it represents.
Parameters:Dsymbols | symbol to resolve |
Locloc | location of use ofs |
Scope*sc | context |
boolhasOverloads | applies ifs 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 whetherf is a generatedDtorDeclaration that hides a user-defined one which passescheck whilef 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:FuncDeclarationf | potentialDtorDeclaration |
Scope*sc | scope |
Locloc | location |
bool function(DtorDeclaration)check | current check (e.g. whether it's pure) |
stringcheckName | the kind of check (e.g."pure") |
void
errorSupplementalInferredAttr(FuncDeclaration
fd, int
maxDepth, bool
deprecation, STC
stc, ErrorSink
eSink);
Print the reason whyfd was inferred@system as a supplemental error
Parameters:FuncDeclarationfd | function to check |
intmaxDepth | up to how many functions deep to report errors |
booldeprecation | print deprecations instead of errors |
STCstc | storage class of attribute to check |
ErrorSinkeSink | 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:Dsymbolsym | the symbol to be checked |
Returns:the symbol whichsym represents (ornull if it doesn't represent aPackage)
Dsymbol
getDsymbol(RootObject
oarg);
If oarg represents a Dsymbol, return that Dsymbol
Parameters:RootObjectoarg | argument to check |
Returns:Dsymbol if a symbol, null if not
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 onexp, gagging semantic errors, but don't resolve alias this on a BinExp when the lhs or rhs has the corresponding type inaliasThisStop (SeeisRecursiveAliasThis).
Parameters:Expressionexp | 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, ornull 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:DotIdExpexp | expression to resolve |
Scope*sc | context |
boolgag | do not emit error messages, just returnnull |
Returns:resolved expression, null if error
Expression
dotTemplateSemanticProp(DotTemplateInstanceExp
exp, Scope*
sc, bool
gag);
Resolvee1.ident!tiargs without seeing UFCS.
Parameters:DotTemplateInstanceExpexp | theDotTemplateInstanceExp to resolve |
Scope*sc | the semantic scope |
boolgag | stop "not a property" error and returnnull. |
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:Expressione | expression to check |
Returns:true if the expression is not valid or hasvoid 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:Expressione | expression to check |
Scope*sc | context |
boolreturnRef | Whether this expression is for areturn statement off aref function, in which case a single level of dereference is allowed (e.g.shared(int)*). |
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, Expression
eorig = null);
Try to convert an expression to be an lvalue.
Give error if we are 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 forx++) |
Expressioneorig | original un-lowered expression for error messages, in case of recursive calls; null means use_this |
Returns:converted expression, orErrorExp on error
Modifiable
checkModifiable(Expression
exp, Scope*
sc, ModifyFlags
flag = ModifyFlags.none);
Parameters:Expressionexp | expression to check if modifiable |
Scope*sc | scope |
ModifyFlagsflag | noError - do not issue error message for invalid modification fieldAssign - 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, Expression
eorig = null);
Similar totoLvalue, but also enforce it is mutable or raise an error.
Parameters:Expression_this | Expression to convert |
Scope*sc | scope |
Expressioneorig | original / un-lowered expression to print in error messages, if null default to_this |
Returns:_this converted to an lvalue, or anErrorExp
bool
checkAddressable(Expression
e, Scope*
sc, const(char)*
action);
This check ensures that the object inexp can have its address taken, or issue a diagnostic error.
Parameters:Expressione | expression to check |
Scope*sc | context |
const(char)*action | for error messages, what the address is needed for (e.g. ref return, indexing an array) |
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 forgetRightThis(). Getsthis of the next outer aggregate.
Parameters:Locloc | location to use for error messages |
Scope*sc | context |
Dsymbols | the parent symbol of the existingthis |
AggregateDeclarationad | struct or class we need the correctthis for |
Expressione1 | existingthis |
Typet | type of the existingthis |
Dsymbolvar | the specific member of ad we're accessing |
boolflag | if true, returnnull instead of throwing an error |
Returns:Expression representing thethis for the var
bool
verifyHookExist(Loc
loc, ref Scope
sc, Identifier
id, string
description, Identifier
module_ = Id.object);
Make sure that the runtime hookid exists.
Parameters:Locloc | location to use for error messages |
Scopesc | current scope |
Identifierid | the hook identifier |
stringdescription | what the hook does |
Identifiermodule_ | what module the hook is located in |
Returns:abool indicating if the hook is present.
Expression
getVarExp(EnumMember
em, Loc
loc, Scope*
sc);
Returnsem as a VariableExp
Parameters:EnumMemberem | the EnumMember to wrap |
Locloc | location of use of em |
Scope*sc | scope of use of em |
Returns:VarExp referenceingem or ErrorExp ifem if disabled/deprecated
Expression
toBoolean(Expression
exp, Scope*
sc);
Try to treatexp as a boolean,
Parameters:Expressionexp | the expression |
Scope*sc | scope to evaluteexp 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 |
Expressionoriginal | original expression, for error messages |
Expressione | resulting expression |
boolerrors | set totrue 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.
Return value forcheckModifiable
Not modifiable
Modifiable (the type is mutable)
Modifiable because it is initialization
Specifies how the checkModify deals with certain situations
Issue error messages on invalid modifications of the variable
No errors are emitted for invalid modifications
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 |
Typet | 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, returnstrue but do not issue an error message.
Parameters:Declarationd | Declaration to check |
Locloc | Location information of the call |
Scope*sc | Scope in which the call occurs |
boolisAliasedDeclaration | iftrue searches overload set |
Returns:true if thisDeclaration is@disabled,false otherwise.
Expression
getConstInitializer(VarDeclaration
vd, bool
needFullType = true);
If variable has a constant expression initializer, get it. Otherwise, return null.
bool
fill(StructDeclaration
sd, Loc
loc, ref Expressions
elements, bool
ctorinit);
Fill out remainder of elements[] with default initializers for fields[].
Parameters:StructDeclarationsd | struct |
Locloc | location |
Expressionselements | explicit arguments which given to construct object. |
boolctorinit | 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 multiplestatic foreach loop variables, an array of tuples is generated. In thise case, the fieldneedExpansion 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:StaticForeachsfe | The 'static foreach'. |
Scope*sc | The current scope. |
void
prepare(StaticForeach
sfe, Scope*
sc);
Performstatic foreach lowerings that are necessary in order to finally expand thestatic foreach usingdmd.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)) { ... }
Dsymbol
searchCtor(AggregateDeclaration
ad);
Look for constructor declaration.
void
markArrayExpModifiable(ArrayExp
ae);
mark ArrayExp on the left side of an assignment recursively as modifiable before semantic analysis to defer potential lowerings into the assignment when the right side of the expression is analyzed, too, i.e.
a[i][j] = 1
is parsed to
AssignExp(ArrayExp(ArrayExp(Id('a'), Id('i')), Id('j')), 1)
ArrayExp is converted to IndexExp during semantic analysis, but the lowering for IndexExp on associative arrays is different for reading or writing. For struct types, it can even depend on the right hand side of an assignment.
Parameters:ArrayExpae | the ArrayExp to mark |
Expression
lowerAAIndexRead(IndexExp
ie, Scope*
sc);
convert an IndexExp on an associative arrayaa[key] to_d_aaGetRvalueX!(K,V)(aa, key)[0]
Parameters:IndexExpie | the IndexExp to lower |
Scope*sc | context |
Returns:on success, the lowered expression that is still an IndexExp with itsloweredFrom field set to the original expression on failure, null is returned
Expression
revertIndexAssignToRvalues(IndexExp
ie, Scope*
sc);
in a multi-dimensional array assignment without the out-most access being to an AA, convert AA accesses back to rvalues
Parameters:IndexExpie | the IndexExp to lower |
Scope*sc | context |
Returns:the lowered expression if the assignment was actually on an associative array, the original expression otherwise, an ErorrExp on failure
Expression
rewriteIndexAssign(BinExp
exp, Scope*
sc, Type[2]
aliasThisStop);
rewrite multi-dimensional array modifying assignments on associative arrays
Parameters:BinExpexp | the assignment expression, AssignExp, ConstructExp, BinAssignExp or PostExp |
Scope*sc | context |
Type[2]aliasThisStop | for recursion check onalias this |
Returns:the lowered expression if the assignment was actually on an associative array, null if no modifying index expression was found on the lhs of the assignemnt
BitFieldDeclaration
isBitField(Expression
e);
Get bitfield from expression.