@@ -462,20 +462,46 @@ private newtype TStoreChain =
462462 )
463463 }
464464
465+ /**
466+ * A `StoreChain` represents a series of field lookups that compute the destination of a store.
467+ * For example, given an assignment such as `a.b.c = x`, there are two `StoreChain`s:
468+ * One corresponding to the field `b`, and one corresponding to the field `c`. Here, `b` is the parent
469+ * `StoreChain` of `c`.
470+ */
465471private class StoreChain extends TStoreChain {
466472 string toString ( ) { none ( ) }
467473
468- StoreChainConsCons getParent ( ) { none ( ) }
474+ /**
475+ * Gets the parent of this `StoreChain`, if any. For example, for the assignment
476+ * ```
477+ * a.b.c = x;
478+ * ```
479+ * the parent of `c` is `b`, and `b` has no parent.
480+ */
481+ final StoreChainConsCons getParent ( ) { result .getChild ( ) = this }
469482
483+ /** Gets the child of this `StoreChain`, if any. */
470484 StoreChain getChild ( ) { none ( ) }
471485
486+ /**
487+ * Gets the instruction that receives flow from the outermost `StoreChain` of this chain (i.e.,
488+ * the `StoreChain` with no parent).
489+ */
472490 StoreChainEndInstruction getEndInstruction ( ) { none ( ) }
473491
492+ /**
493+ * Gets the instruction that flows to the innermost `StoreChain` of this chain (i.e.,
494+ * the `StoreChain` with no child).
495+ */
474496 Instruction getBeginInstruction ( ) { none ( ) }
475497
498+ /** Gets the `FieldAddressInstruction` of this `StoreChain` */
476499 FieldAddressInstruction getFieldInstruction ( ) { none ( ) }
477500
501+ /** Gets the `FieldAddressInstruction` of any `StoreChain` in this chain. */
478502 FieldAddressInstruction getAFieldInstruction ( ) { none ( ) }
503+
504+ final Location getLocation ( ) { result = getFieldInstruction ( ) .getLocation ( ) }
479505}
480506
481507private class StoreChainConsNil extends StoreChain , TStoreChainConsNil {
@@ -486,8 +512,6 @@ private class StoreChainConsNil extends StoreChain, TStoreChainConsNil {
486512
487513 override string toString ( ) { result = fi .getField ( ) .toString ( ) }
488514
489- override StoreChainConsCons getParent ( ) { result = TStoreChainConsCons ( _, this ) }
490-
491515 override StoreChainEndInstruction getEndInstruction ( ) { result = end }
492516
493517 override Instruction getBeginInstruction ( ) { result = end .getBeginInstruction ( ) }
@@ -505,8 +529,6 @@ private class StoreChainConsCons extends StoreChain, TStoreChainConsCons {
505529
506530 override string toString ( ) { result = fi .getField ( ) .toString ( ) + "." + next .toString ( ) }
507531
508- override StoreChainConsCons getParent ( ) { result .getChild ( ) = this }
509-
510532 override StoreChain getChild ( ) { result = next }
511533
512534 override FieldAddressInstruction getFieldInstruction ( ) { result = fi }
@@ -563,18 +585,34 @@ private class LoadChainEndInstructionLoad extends LoadChainEndInstruction, LoadI
563585 override Instruction getReadValue ( ) { result = getSourceValueOperand ( ) .getAnyDef ( ) }
564586}
565587
588+ /**
589+ * A `LoadChain` represents a series of field lookups that compute the source address of a load.
590+ * For example, given the field lookup in `f(a.b.c)`, there are two `LoadChains`s:
591+ * One corresponding to the field `b`, and one corresponding to the field `c`. Here, `b` is the parent
592+ * `LoadChain` of `c`.
593+ */
566594private class LoadChain extends TLoadChain {
567595 string toString ( ) { none ( ) }
568596
597+ /**
598+ * Gets the instruction that receives flow from the innermost `LoadChain` of this chain (i.e.,
599+ * the `LoadChain` with no child).
600+ */
569601 LoadChainEndInstruction getEndInstruction ( ) { none ( ) }
570602
603+ /**
604+ * Gets the parent of this `LoadChain`, if any. For example in `f(a.b.c)` the parent of `c` is `b`,
605+ * and `b` has no parent.
606+ */
571607 final LoadChainConsCons getParent ( ) { result .getChild ( ) = this }
572608
609+ /** Gets the child of this `LoadChain`, if any. */
573610 LoadChain getChild ( ) { none ( ) }
574611
612+ /** Gets the `FieldAddressInstruction` of this `LoadChain` */
575613 FieldAddressInstruction getFieldInstruction ( ) { none ( ) }
576614
577- Location getLocation ( ) { none ( ) }
615+ final Location getLocation ( ) { result = getFieldInstruction ( ) . getLocation ( ) }
578616}
579617
580618private class LoadChainConsNil extends LoadChain , TLoadChainConsNil {
@@ -588,8 +626,6 @@ private class LoadChainConsNil extends LoadChain, TLoadChainConsNil {
588626 override LoadChainEndInstruction getEndInstruction ( ) { result = end }
589627
590628 override FieldAddressInstruction getFieldInstruction ( ) { result = fi }
591-
592- override Location getLocation ( ) { result = fi .getLocation ( ) }
593629}
594630
595631private class LoadChainConsCons extends LoadChain , TLoadChainConsCons {
@@ -605,11 +641,21 @@ private class LoadChainConsCons extends LoadChain, TLoadChainConsCons {
605641 override LoadChain getChild ( ) { result = next }
606642
607643 override FieldAddressInstruction getFieldInstruction ( ) { result = fi }
608-
609- override Location getLocation ( ) { result = fi .getLocation ( ) }
610644}
611645
612- /** `StoreNode` also extends `ReadStepNode` to participate in reverse read steps. */
646+ /**
647+ * A dataflow node generated by a partial definition.
648+ * The `StoreNode` class extends `ReadStepNode` to participate in reverse read steps.
649+ * A reverse read is a store step that is "inferred" by the DataFlow library. For example in the
650+ * assignment:
651+ * ```
652+ * a.b.c = x;
653+ * ```
654+ * Here, the access path after the store must reflect that a value has been stored into the field `c` of
655+ * the object at field `b`. The field `c` is added to the access path through a `storeStep`, and the
656+ * field `b` is inferred by the DataFlow library because there's a read step (reading the field `b`) from
657+ * the pre update node for `b.c` to the pre update node for `c`.
658+ */
613659private class StoreNode extends TStoreNode , StoreStepNode , ReadStepNode , PartialDefinitionNode {
614660 StoreChain storeChain ;
615661
@@ -649,6 +695,7 @@ private class StoreNode extends TStoreNode, StoreStepNode, ReadStepNode, Partial
649695 }
650696}
651697
698+ /** A dataflow node generated by loading from an address computed by a sequence of fields lookups. */
652699private class LoadNode extends TLoadNode , ReadStepNode {
653700 LoadChain loadChain ;
654701
0 commit comments