pub struct GraphConverter<'tcx, 'a, C> {
generator: &'a SPDGGenerator<'tcx>,
target: &'a FnToAnalyze,
dep_graph: Rc<DepGraph<'tcx>>,
def_id: DefId,
known_def_ids: &'a mut C,
types: HashMap<Node, Vec<DefId>>,
index_map: Box<[Node]>,
spdg: SPDGImpl,
marker_assignments: HashMap<Node, HashSet<Identifier>>,
call_string_resolver: CallStringResolver<'tcx, 'a>,
stats: SPDGStats,
}
Expand description
Structure responsible for converting one DepGraph
into an SPDG
.
Intended usage is to call Self::new_with_flowistry
to initialize, then
Self::make_spdg
to convert.
Fields§
§generator: &'a SPDGGenerator<'tcx>
The parent generator
target: &'a FnToAnalyze
Information about the function this PDG belongs to
dep_graph: Rc<DepGraph<'tcx>>
The flowistry graph we are converting
def_id: DefId
Same as the ID stored in self.target, but as a local def id
known_def_ids: &'a mut C
Where we write every DefId
we encounter into.
types: HashMap<Node, Vec<DefId>>
A map of which nodes are of which (marked) type. We build this up during conversion.
index_map: Box<[Node]>
Mapping from old node indices to new node indices. Use
Self::register_node
to insert and Self::new_node_for
to query.
spdg: SPDGImpl
The converted graph we are creating
marker_assignments: HashMap<Node, HashSet<Identifier>>
§call_string_resolver: CallStringResolver<'tcx, 'a>
§stats: SPDGStats
Implementations§
Source§impl<'a, 'tcx, C: Extend<DefId>> GraphConverter<'tcx, 'a, C>
impl<'a, 'tcx, C: Extend<DefId>> GraphConverter<'tcx, 'a, C>
Sourcepub fn new_with_flowistry(
generator: &'a SPDGGenerator<'tcx>,
known_def_ids: &'a mut C,
target: &'a FnToAnalyze,
) -> Result<Self>
pub fn new_with_flowistry( generator: &'a SPDGGenerator<'tcx>, known_def_ids: &'a mut C, target: &'a FnToAnalyze, ) -> Result<Self>
Initialize a new converter by creating an initial PDG using flowistry.
fn tcx(&self) -> TyCtxt<'tcx>
fn marker_ctx(&self) -> &MarkerCtx<'tcx>
Sourcefn entrypoint_is_async(&self) -> bool
fn entrypoint_is_async(&self) -> bool
Is the top-level function (entrypoint) an async fn
Sourcefn register_node(&mut self, old: Node, new: NodeInfo) -> Node
fn register_node(&mut self, old: Node, new: NodeInfo) -> Node
Insert this node into the converted graph, return it’s auto-assigned id
and register it as corresponding to old
in the initial graph. Fails if
there is already a node registered as corresponding to old
.
Sourcefn new_node_for(&self, old: Node) -> Node
fn new_node_for(&self, old: Node) -> Node
Get the id of the new node that was registered for this old node.
fn register_markers( &mut self, node: Node, markers: impl IntoIterator<Item = Identifier>, )
Sourcefn node_annotations(&mut self, old_node: Node, weight: &DepNode<'tcx>)
fn node_annotations(&mut self, old_node: Node, weight: &DepNode<'tcx>)
Find direct annotations on this node and register them in the marker map.
Sourcefn determine_place_type(
&self,
at: CallString,
place: PlaceRef<'tcx>,
span: Span,
) -> Option<PlaceTy<'tcx>>
fn determine_place_type( &self, at: CallString, place: PlaceRef<'tcx>, span: Span, ) -> Option<PlaceTy<'tcx>>
Reconstruct the type for the data this node represents.
Sourcefn register_annotations_for_function(
&mut self,
node: Node,
function: DefId,
filter: impl FnMut(&MarkerAnnotation) -> bool,
)
fn register_annotations_for_function( &mut self, node: Node, function: DefId, filter: impl FnMut(&MarkerAnnotation) -> bool, )
Fetch annotations item identified by this id
.
The callback is used to filter out annotations where the “refinement”
doesn’t match. The idea is that the caller of this function knows
whether they are looking for annotations on an argument or return of a
function identified by this id
or on a type and the callback should be
used to enforce this.
Sourcefn handle_node_types(&mut self, old_node: Node, weight: &DepNode<'tcx>)
fn handle_node_types(&mut self, old_node: Node, weight: &DepNode<'tcx>)
Check if this node is of a marked type and register that type.
Sourcefn create_flowistry_graph(
generator: &SPDGGenerator<'tcx>,
local_def_id: LocalDefId,
) -> Result<(DepGraph<'tcx>, SPDGStats)>
fn create_flowistry_graph( generator: &SPDGGenerator<'tcx>, local_def_id: LocalDefId, ) -> Result<(DepGraph<'tcx>, SPDGStats)>
Create an initial flowistry graph for the function identified by
local_def_id
.
fn body_cache(&self) -> &BodyCache<'tcx>
Sourcefn make_spdg_impl(&mut self)
fn make_spdg_impl(&mut self)
This initializes the fields spdg
and index_map
and should be called first
Sourcefn type_is_marked(
&'a self,
typ: PlaceTy<'tcx>,
deep: bool,
) -> impl Iterator<Item = TypeId> + 'a
fn type_is_marked( &'a self, typ: PlaceTy<'tcx>, deep: bool, ) -> impl Iterator<Item = TypeId> + 'a
Return the (sub)types of this type that are marked.
Sourcefn try_as_root(&self, at: CallString) -> Option<GlobalLocation>
fn try_as_root(&self, at: CallString) -> Option<GlobalLocation>
Similar to CallString::is_at_root
, but takes into account top-level
async functions
Sourcefn determine_return(&self) -> Box<[Node]>
fn determine_return(&self) -> Box<[Node]>
Try to find the node corresponding to the values returned from this controller.
TODO: Include mutable inputs
Sourcefn determine_arguments(&self) -> Box<[Node]>
fn determine_arguments(&self) -> Box<[Node]>
Determine the set if nodes corresponding to the inputs to the entrypoint. The order is guaranteed to be the same as the source-level function declaration.
Auto Trait Implementations§
impl<'tcx, 'a, C> !Freeze for GraphConverter<'tcx, 'a, C>
impl<'tcx, 'a, C> !RefUnwindSafe for GraphConverter<'tcx, 'a, C>
impl<'tcx, 'a, C> !Send for GraphConverter<'tcx, 'a, C>
impl<'tcx, 'a, C> !Sync for GraphConverter<'tcx, 'a, C>
impl<'tcx, 'a, C> Unpin for GraphConverter<'tcx, 'a, C>
impl<'tcx, 'a, C> !UnwindSafe for GraphConverter<'tcx, 'a, C>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more