tamer: asg: Hoist Root from Ident into Object
This was always the intent, but I didn't have a higher-level object yet. This removes all the awkwardness that existed with working the root in as an identifier. DEV-11864main
parent
6252758730
commit
958a707e02
|
@ -118,7 +118,7 @@ impl Asg {
|
|||
// Automatically add the root which will be used to determine what
|
||||
// identifiers ought to be retained by the final program.
|
||||
// This is not indexed and is not accessable by name.
|
||||
let root_node = graph.add_node(Some(Ident::Root.into()));
|
||||
let root_node = graph.add_node(Some(Object::Root));
|
||||
|
||||
Self {
|
||||
graph,
|
||||
|
|
|
@ -75,18 +75,6 @@ pub enum Ident {
|
|||
/// [linker][crate::ld] to put them into the correct order for the
|
||||
/// final executable.
|
||||
IdentFragment(SymbolId, IdentKind, Source, FragmentText),
|
||||
|
||||
/// Represents the root of all reachable identifiers.
|
||||
///
|
||||
/// Any identifier not reachable from the root will not be linked into
|
||||
/// the final executable.
|
||||
///
|
||||
/// There should be only one identifier of this kind.
|
||||
///
|
||||
/// TODO: This is _not_ an identifier;
|
||||
/// once the ASG supports other types,
|
||||
/// do not associate with identifiers.
|
||||
Root,
|
||||
}
|
||||
|
||||
impl Ident {
|
||||
|
@ -97,11 +85,6 @@ impl Ident {
|
|||
| Self::Ident(name, ..)
|
||||
| Self::Extern(name, ..)
|
||||
| Self::IdentFragment(name, ..) => *name,
|
||||
|
||||
// This should never be called,
|
||||
// and can go away when we can stop pretending that the root
|
||||
// is an identifier.
|
||||
Self::Root => unimplemented!("Ident::name for Root"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,8 +100,6 @@ impl Ident {
|
|||
Self::Ident(_, kind, ..)
|
||||
| Self::Extern(_, kind, ..)
|
||||
| Self::IdentFragment(_, kind, ..) => Some(kind),
|
||||
|
||||
Self::Root => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +110,7 @@ impl Ident {
|
|||
/// [`None`] is returned.
|
||||
pub fn src(&self) -> Option<&Source> {
|
||||
match self {
|
||||
Self::Missing(..) | Self::Extern(..) | Self::Root => None,
|
||||
Self::Missing(..) | Self::Extern(..) => None,
|
||||
|
||||
Self::Ident(_, _, src, ..) | Self::IdentFragment(_, _, src, ..) => {
|
||||
Some(src)
|
||||
|
@ -143,10 +124,7 @@ impl Ident {
|
|||
/// [`None`] is returned.
|
||||
pub fn fragment(&self) -> Option<FragmentText> {
|
||||
match self {
|
||||
Self::Missing(..)
|
||||
| Self::Ident(..)
|
||||
| Self::Extern(..)
|
||||
| Self::Root => None,
|
||||
Self::Missing(..) | Self::Ident(..) | Self::Extern(..) => None,
|
||||
|
||||
Self::IdentFragment(_, _, _, text) => Some(*text),
|
||||
}
|
||||
|
@ -309,11 +287,6 @@ impl Ident {
|
|||
}
|
||||
|
||||
Ident::Ident(..) | Ident::IdentFragment(..) => Ok(self),
|
||||
|
||||
// This should never be called.
|
||||
Ident::Root => {
|
||||
unimplemented!("Ident::resolved on Root")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,15 @@ use super::Ident;
|
|||
/// Some object on the ASG.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Object {
|
||||
/// Represents the root of all reachable identifiers.
|
||||
///
|
||||
/// Any identifier not reachable from the root will not be linked into
|
||||
/// the final executable.
|
||||
///
|
||||
/// There should be only one object of this kind.
|
||||
Root,
|
||||
|
||||
/// Identifier (a named object).
|
||||
Ident(Ident),
|
||||
}
|
||||
|
||||
|
@ -33,6 +42,7 @@ impl Object {
|
|||
pub fn as_ident_ref(&self) -> Option<&Ident> {
|
||||
match self {
|
||||
Self::Ident(ident) => Some(ident),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +57,7 @@ impl Object {
|
|||
pub fn unwrap_ident(self) -> Ident {
|
||||
match self {
|
||||
Self::Ident(ident) => ident,
|
||||
x => panic!("internal error: expected Ident, found {x:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +72,7 @@ impl Object {
|
|||
pub fn unwrap_ident_ref(&self) -> &Ident {
|
||||
match self {
|
||||
Self::Ident(ident) => ident,
|
||||
x => panic!("internal error: expected Ident, found {x:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ pub fn xmle(package_path: &str, output: &str) -> Result<(), TameldError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: This needs to be further generalized.
|
||||
pub fn graphml(package_path: &str, output: &str) -> Result<(), TameldError> {
|
||||
let mut fs = VisitOnceFilesystem::new();
|
||||
let mut depgraph = LinkerAsg::with_capacity(65536, 65536);
|
||||
|
@ -150,6 +151,12 @@ pub fn graphml(package_path: &str, output: &str) -> Result<(), TameldError> {
|
|||
format!("{}", generated),
|
||||
)
|
||||
}
|
||||
// TODO: We want these filtered.
|
||||
Some(_) => (
|
||||
String::from("non-ident"),
|
||||
"non-ident".into(),
|
||||
"false".into(),
|
||||
),
|
||||
None => (
|
||||
String::from("missing"),
|
||||
"missing".into(),
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
use super::section::{SectionsError, XmleSections};
|
||||
use crate::{
|
||||
asg::{Asg, Ident, IdentKind, ObjectRef},
|
||||
asg::{Asg, Ident, IdentKind, Object, ObjectRef},
|
||||
sym::{st, GlobalSymbolResolve, SymbolId},
|
||||
};
|
||||
use petgraph::visit::DfsPostOrder;
|
||||
|
@ -54,8 +54,10 @@ where
|
|||
dest.push(get_ident(asg, st::L_RETMAP_UUUHEAD))?;
|
||||
|
||||
while let Some(index) = dfs.next(&asg.graph) {
|
||||
let ident = asg.get(index).expect("missing node");
|
||||
dest.push(ident.unwrap_ident_ref())?;
|
||||
match asg.get(index).expect("missing object") {
|
||||
Object::Root => (),
|
||||
Object::Ident(ident) => dest.push(ident)?,
|
||||
}
|
||||
}
|
||||
|
||||
dest.push(get_ident(asg, st::L_MAP_UUUTAIL))?;
|
||||
|
@ -287,10 +289,6 @@ mod test {
|
|||
asg.get_ident(adepdep),
|
||||
asg.get_ident(adep),
|
||||
asg.get_ident(a),
|
||||
// TODO: This will go away once Root is no longer considered
|
||||
// an identifier.
|
||||
// The real Sections filters this out.
|
||||
Some(&Ident::Root),
|
||||
// Static tail
|
||||
asg.lookup(st::L_MAP_UUUTAIL.into())
|
||||
.and_then(|id| asg.get_ident(id)),
|
||||
|
|
|
@ -106,11 +106,6 @@ impl<'a> Sections<'a> {
|
|||
|
||||
impl<'a> XmleSections<'a> for Sections<'a> {
|
||||
fn push(&mut self, ident: &'a Ident) -> PushResult {
|
||||
// TODO: This can go away once we stop treating root as an ident
|
||||
if matches!(ident, Ident::Root) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.deps.push(ident);
|
||||
|
||||
// TODO: This cannot happen, so use an API without Option.
|
||||
|
@ -309,16 +304,6 @@ mod test {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: This can be removed once we no longer treat Root as an
|
||||
// identifier.
|
||||
#[test]
|
||||
fn push_ignores_root() {
|
||||
let mut sut = Sut::new();
|
||||
|
||||
sut.push(&Ident::Root).unwrap();
|
||||
assert!(sut.take_deps().is_empty());
|
||||
}
|
||||
|
||||
// Certain identifiers have no fragments because the code is associated
|
||||
// with their parents (for now, anyway).
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue