dmd.ob
Flow analysis for Ownership/Borrowing
License
Source: ob.d
Documentation: https://dlang.org/phobos/dmd_escape.html
-
Declaration
voidoblive(FuncDeclarationfuncdecl);Perform ownership/borrowing checks for
funcdecl. Does not modify the AST, just checks for errors. -
Declaration
structObState;Collect the state information.
-
Declaration
Array!size_tvarStack;temporary storage
-
Declaration
Array!boolmutableStack;parallel to varStack[], is type mutable?
-
Declaration
PtrVarState[]varPool;memory pool
-
-
Declaration
structObNode;A node in the function's expression graph, and its edges to predecessors and successors.
-
Declaration
Expressionexp;expression for the node
-
Declaration
ObNodespreds;predecessors
-
Declaration
ObNodessuccs;successors
-
Declaration
ObNode*tryBlock;try-finally block we're inside
-
Declaration
uintindex;indexof this in obnodes -
Declaration
PtrVarState[]gen;new states generated for this node
-
Declaration
PtrVarState[]input;variable states on entry to exp
-
Declaration
PtrVarState[]output;variable states on exit to exp
-
-
Declaration
enumPtrState: ubyte;Pointer variable states:
Discussion
Initial state is not known; ignore for now
Undefined not in a usable state
T* p = void;
Owner mutable pointer
T* p = initializer;
Borrowed scope mutable pointer, borrowed from [p]
T* p = initializer; scope T* b = p;
Readonly scope const pointer, copied from [p]
T* p = initializer; scope const(T)* cp = p;Examples
T* p = initializer; // p is owner T** pp = &p; // pp borrows from p
T* p = initialize; // p is owner T* q = p; // transfer: q is owner, p is undefined -
Declaration
const(char)*toChars(PtrStatestate); -
Declaration
structPtrVarState;Carries the state of a pointer variable.
-
Declaration
BitArraydeps;dependencies
-
Declaration
PtrStatestate;statethe pointer variable is in -
Declaration
voidprint(VarDeclaration[]vars); -
Declaration
voiddepsToBuf(ref OutBufferbuf, const VarDeclaration[]vars);Produce a user-readable comma separated string of the dependencies.
Parameters
OutBufferbufwrite resulting string here
VarDeclaration[]varsarray from which to get the variable names
-
-
Declaration
voidsetLabelStatementExtraFields(DsymbolTablelabtab);Set the
.extrafield for LabelStatements inlabtab[]. -
Declaration
voidtoObNodes(ref ObNodesobnodes, Statements);Convert statement into ObNodes.
-
Declaration
voidinsertFinallyBlockCalls(ref ObNodesobnodes);Insert finally block calls when doing a goto from inside a try block to outside. Done after blocks are generated because then we know all the edges of the graph, but before the pred's are computed.
Parameters
ObNodesobnodesgraph of the function
-
Declaration
voidinsertFinallyBlockGotos(ref ObNodesobnodes);Remove try-finally scaffolding.
Parameters
ObNodesobnodesnodes for the function
-
Declaration
voidnumberNodes(ref ObNodesobnodes);Set the
indexfield of each ObNode to its index in thearray.obnodes[] -
Declaration
voidremoveUnreachable(ref ObNodesobnodes);Remove unreachable nodes and compress them out of
obnodes[].Parameters
ObNodesobnodesarray of nodes
-
Declaration
voidcomputePreds(ref ObNodesobnodes);Compute predecessors.
-
Declaration
boolisTrackableVar(VarDeclarationv);Are we interested in tracking variable
?v -
Declaration
VarDeclarationisTrackableVarExp(Expressione);Are we interested in tracking this expression?
Return Value
variable if so,
nullif not -
Declaration
voidcollectVars(FuncDeclarationfuncdecl, out VarDeclarationsvars);Find the pointer variable declarations in this function, and fill
with them.varsParameters
FuncDeclarationfuncdeclfunction we are in
VarDeclarationsvarsarray to fill in
-
Declaration
voidallocDeps(PtrVarState[]pvss);Allocate BitArrays in PtrVarState. Can be allocated much more efficiently by subdividing a single large array of bits
-
Declaration
voidallocStates(ref ObStateobstate);Allocate state variables foreach node.
-
Declaration
boolisBorrowedPtr(VarDeclarationv);Does
vmeet the definiton of aBorrowedpointer?Return Value
trueif it does -
Declaration
boolisReadonlyPtr(VarDeclarationv);Does
vmeet the definiton of aReadonlypointer?Return Value
trueif it does -
Declaration
voidgenKill(ref ObStateobstate, ObNode*ob);Compute the gen vector for
ob. -
Declaration
PtrStatetoPtrState(VarDeclarationv);Determine the state of a variable based on its type and storage class.
-
Declaration
boolhasPointersToMutableFields(Typet);Does type
contain any pointers to mutable?t -
Declaration
boolhasMutableFields(Typet);Does type
have any mutable fields?t -
Declaration
voiddoDataFlowAnalysis(ref ObStateobstate);Do the data flow analysis (i.e. compute the input[] and output[] vectors for each ObNode).
-
Declaration
voidcheckObErrors(ref ObStateobstate);Check for Ownership/Borrowing errors.
-
Declaration
voidreadVar(ObNode*ob, const size_tvi, boolmutable, PtrVarState[]gen);Read from variable
vi. The beginning of the 'scope' of a variable is when it is first read. Hence, when a read is done, instead of when assignment to the variable is done, the O/B rules are enforced. (Also called "non-lexical scoping".) -
Declaration
voidmakeChildrenUndefined(size_tvi, PtrVarState[]gen);Recursively make Undefined all who list
vias a dependency -
Declaration
voidmakeUndefined(size_tvi, PtrVarState[]gen);Recursively make Undefined
viundefined and all who listvias a dependency -
Declaration
boolisMutableRef(Typet);Is type
a reference to a const or a reference to a mutable?t