Coverage Report

Created: 2026-11-11 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/cpp_demangle-0.5.1/src/subs.rs
Line
Count
Source
1
//! Types dealing with the substitutions table.
2
3
use super::DemangleWrite;
4
use crate::ast;
5
use alloc::vec::Vec;
6
use core::fmt;
7
use core::iter::FromIterator;
8
use core::ops::Deref;
9
10
/// An enumeration of all of the types that can end up in the substitution
11
/// table.
12
#[doc(hidden)]
13
#[derive(Clone, Debug, PartialEq, Eq)]
14
#[allow(clippy::large_enum_variant)]
15
pub enum Substitutable {
16
    /// An `<unscoped-template-name>` production.
17
    UnscopedTemplateName(ast::UnscopedTemplateName),
18
19
    /// A `<type>` production.
20
    Type(ast::Type),
21
22
    /// A `<template-template-param>` production.
23
    TemplateTemplateParam(ast::TemplateTemplateParam),
24
25
    /// An `<unresolved-type>` production.
26
    UnresolvedType(ast::UnresolvedType),
27
28
    /// A `<prefix>` production.
29
    Prefix(ast::Prefix),
30
}
31
32
impl<'subs, W> ast::Demangle<'subs, W> for Substitutable
33
where
34
    W: 'subs + DemangleWrite,
35
{
36
82.9k
    fn demangle<'prev, 'ctx>(
37
82.9k
        &'subs self,
38
82.9k
        ctx: &'ctx mut ast::DemangleContext<'subs, W>,
39
82.9k
        scope: Option<ast::ArgScopeStack<'prev, 'subs>>,
40
82.9k
    ) -> fmt::Result {
41
82.9k
        match *self {
42
106
            Substitutable::UnscopedTemplateName(ref name) => name.demangle(ctx, scope),
43
82.8k
            Substitutable::Type(ref ty) => ty.demangle(ctx, scope),
44
0
            Substitutable::TemplateTemplateParam(ref ttp) => ttp.demangle(ctx, scope),
45
0
            Substitutable::UnresolvedType(ref ty) => ty.demangle(ctx, scope),
46
0
            Substitutable::Prefix(ref prefix) => prefix.demangle(ctx, scope),
47
        }
48
82.9k
    }
<cpp_demangle::subs::Substitutable as cpp_demangle::ast::Demangle<symbolic_demangle::BoundedString>>::demangle
Line
Count
Source
36
82.9k
    fn demangle<'prev, 'ctx>(
37
82.9k
        &'subs self,
38
82.9k
        ctx: &'ctx mut ast::DemangleContext<'subs, W>,
39
82.9k
        scope: Option<ast::ArgScopeStack<'prev, 'subs>>,
40
82.9k
    ) -> fmt::Result {
41
82.9k
        match *self {
42
106
            Substitutable::UnscopedTemplateName(ref name) => name.demangle(ctx, scope),
43
82.8k
            Substitutable::Type(ref ty) => ty.demangle(ctx, scope),
44
0
            Substitutable::TemplateTemplateParam(ref ttp) => ttp.demangle(ctx, scope),
45
0
            Substitutable::UnresolvedType(ref ty) => ty.demangle(ctx, scope),
46
0
            Substitutable::Prefix(ref prefix) => prefix.demangle(ctx, scope),
47
        }
48
82.9k
    }
Unexecuted instantiation: <cpp_demangle::subs::Substitutable as cpp_demangle::ast::Demangle<_>>::demangle
49
}
50
51
impl<'a> ast::GetLeafName<'a> for Substitutable {
52
92
    fn get_leaf_name(&'a self, subs: &'a SubstitutionTable) -> Option<ast::LeafName<'a>> {
53
92
        match *self {
54
67
            Substitutable::UnscopedTemplateName(ref name) => name.get_leaf_name(subs),
55
0
            Substitutable::Prefix(ref prefix) => prefix.get_leaf_name(subs),
56
25
            Substitutable::Type(ref ty) => ty.get_leaf_name(subs),
57
0
            _ => None,
58
        }
59
92
    }
60
}
61
62
impl ast::IsCtorDtorConversion for Substitutable {
63
0
    fn is_ctor_dtor_conversion(&self, subs: &SubstitutionTable) -> bool {
64
0
        match *self {
65
0
            Substitutable::Prefix(ref prefix) => prefix.is_ctor_dtor_conversion(subs),
66
0
            _ => false,
67
        }
68
0
    }
69
}
70
71
/// The table of substitutable components that we have parsed thus far, and for
72
/// which there are potential back-references.
73
#[doc(hidden)]
74
#[derive(Clone, Default, PartialEq, Eq)]
75
pub struct SubstitutionTable {
76
    substitutions: Vec<Substitutable>,
77
    // There are components which are typically candidates for substitution, but
78
    // in some particular circumstances are not. Instances of such components
79
    // which are not candidates for substitution end up in this part of the
80
    // table. See `<prefix>` parsing for further details.
81
    non_substitutions: Vec<Substitutable>,
82
}
83
84
impl fmt::Debug for SubstitutionTable {
85
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86
0
        f.pad("SubstitutionTable ")?;
87
0
        f.debug_map()
88
0
            .entries(self.substitutions.iter().enumerate())
89
0
            .finish()?;
90
0
        f.pad(" non_substitutions ")?;
91
0
        f.debug_map()
92
0
            .entries(self.non_substitutions.iter().enumerate())
93
0
            .finish()
94
0
    }
95
}
96
97
impl SubstitutionTable {
98
    /// Construct a new `SubstitutionTable`.
99
15.3k
    pub fn new() -> SubstitutionTable {
100
15.3k
        Default::default()
101
15.3k
    }
102
103
    /// Insert a freshly-parsed substitutable component into the table and
104
    /// return the index at which it now lives.
105
1.33M
    pub fn insert(&mut self, entity: Substitutable) -> usize {
106
1.33M
        let idx = self.substitutions.len();
107
1.33M
        log!("SubstitutionTable::insert @ {}: {:?}", idx, entity);
108
1.33M
        self.substitutions.push(entity);
109
1.33M
        idx
110
1.33M
    }
111
112
    /// Insert a an entity into the table that is not a candidate for
113
    /// substitution.
114
1.18k
    pub fn insert_non_substitution(&mut self, entity: Substitutable) -> usize {
115
1.18k
        let idx = self.non_substitutions.len();
116
1.18k
        self.non_substitutions.push(entity);
117
1.18k
        idx
118
1.18k
    }
119
120
    /// Does this substitution table contain a component at the given index?
121
22.6k
    pub fn contains(&self, idx: usize) -> bool {
122
22.6k
        idx < self.substitutions.len()
123
22.6k
    }
124
125
    /// Get the type referenced by the given handle, or None if there is no such
126
    /// entry, or there is an entry that is not a type.
127
8.22k
    pub fn get_type(&self, handle: &ast::TypeHandle) -> Option<&ast::Type> {
128
8.22k
        if let ast::TypeHandle::BackReference(idx) = *handle {
129
8.05k
            self.substitutions.get(idx).and_then(|s| match *s {
130
8.05k
                Substitutable::Type(ref ty) => Some(ty),
131
0
                _ => None,
132
8.05k
            })
133
        } else {
134
168
            None
135
        }
136
8.22k
    }
137
138
    /// Remove the last entry from the substitutions table and return it, or
139
    /// `None` if the table is empty.
140
0
    pub fn pop(&mut self) -> Option<Substitutable> {
141
0
        log!("SubstitutionTable::pop @ {}: {:?}", self.len(), self.last());
142
0
        self.substitutions.pop()
143
0
    }
144
145
    /// Get the `idx`th entity that is not a candidate for substitution. Panics
146
    /// if `idx` is out of bounds.
147
0
    pub fn non_substitution(&self, idx: usize) -> &Substitutable {
148
0
        &self.non_substitutions[idx]
149
0
    }
150
151
    /// Get the `idx`th entity that is not a candidate for substitution. Returns
152
    /// `None` if `idx` is out of bounds.
153
1.18k
    pub fn get_non_substitution(&self, idx: usize) -> Option<&Substitutable> {
154
1.18k
        self.non_substitutions.get(idx)
155
1.18k
    }
156
}
157
158
impl FromIterator<Substitutable> for SubstitutionTable {
159
0
    fn from_iter<I: IntoIterator<Item = Substitutable>>(iter: I) -> Self {
160
0
        SubstitutionTable {
161
0
            substitutions: Vec::from_iter(iter),
162
0
            non_substitutions: vec![],
163
0
        }
164
0
    }
165
}
166
167
impl Deref for SubstitutionTable {
168
    type Target = [Substitutable];
169
170
83.0k
    fn deref(&self) -> &Self::Target {
171
83.0k
        &self.substitutions[..]
172
83.0k
    }
173
}