Skip to content

Commit dd8daf5

Browse files
committed
Support most of the unspecced-but-used-in-clang subobject expression.
Fixes #273
1 parent 39ffd11 commit dd8daf5

File tree

2 files changed

+141
-2
lines changed

2 files changed

+141
-2
lines changed

src/ast.rs

Lines changed: 136 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5427,6 +5427,7 @@ where
54275427
/// ::= at <type> # alignof (type)
54285428
/// ::= az <expression> # alignof (expression)
54295429
/// ::= nx <expression> # noexcept (expression)
5430+
/// ::= so <subobject-expr>
54305431
/// ::= <template-param>
54315432
/// ::= <function-param>
54325433
/// ::= dt <expression> <unresolved-name> # expr.name
@@ -5537,6 +5538,9 @@ pub enum Expression {
55375538
/// `noexcept (expression)`
55385539
Noexcept(Box<Expression>),
55395540

5541+
/// Subobject expression,
5542+
Subobject(SubobjectExpr),
5543+
55405544
/// A named template parameter.
55415545
TemplateParam(TemplateParam),
55425546

@@ -5693,6 +5697,11 @@ impl Parse for Expression {
56935697
let expr = Expression::Noexcept(Box::new(expr));
56945698
return Ok((expr, tail));
56955699
}
5700+
b"so" => {
5701+
let (expr, tail) = SubobjectExpr::parse(ctx, subs, tail)?;
5702+
let expr = Expression::Subobject(expr);
5703+
return Ok((expr, tail));
5704+
}
56965705
b"dt" => {
56975706
let (expr, tail) = Expression::parse(ctx, subs, tail)?;
56985707
let (name, tail) = MemberName::parse(ctx, subs, tail)?;
@@ -6152,6 +6161,7 @@ where
61526161
write!(ctx, ")")?;
61536162
Ok(())
61546163
}
6164+
Expression::Subobject(ref expr) => expr.demangle(ctx, scope),
61556165
Expression::TemplateParam(ref param) => param.demangle(ctx, scope),
61566166
Expression::FunctionParam(ref param) => param.demangle(ctx, scope),
61576167
Expression::Member(ref expr, ref name) => {
@@ -7751,6 +7761,65 @@ where
77517761
Ok(())
77527762
}
77537763
}
7764+
7765+
/// The subobject expression production.
7766+
///
7767+
/// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
7768+
/// <union-selector> ::= _ [<number>]
7769+
///
7770+
/// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
7771+
/// But it has been shipping in clang for some time.
7772+
#[derive(Clone, Debug, PartialEq, Eq)]
7773+
pub struct SubobjectExpr {
7774+
ty: TypeHandle,
7775+
expr: Box<Expression>,
7776+
offset: isize,
7777+
}
7778+
7779+
impl Parse for SubobjectExpr {
7780+
fn parse<'a, 'b>(
7781+
ctx: &'a ParseContext,
7782+
subs: &'a mut SubstitutionTable,
7783+
input: IndexStr<'b>,
7784+
) -> Result<(SubobjectExpr, IndexStr<'b>)> {
7785+
try_begin_parse!("SubobjectExpr", ctx, input);
7786+
7787+
let (ty, tail) = TypeHandle::parse(ctx, subs, input)?;
7788+
let (expr, tail) = Expression::parse(ctx, subs, tail)?;
7789+
let (offset, tail) = parse_number(10, true, tail).unwrap_or((0, tail));
7790+
7791+
// XXXkhuey handle union-selector and [p]
7792+
let tail = consume(b"E", tail)?;
7793+
Ok((
7794+
SubobjectExpr {
7795+
ty: ty,
7796+
expr: Box::new(expr),
7797+
offset: offset,
7798+
},
7799+
tail,
7800+
))
7801+
}
7802+
}
7803+
7804+
impl<'subs, W> Demangle<'subs, W> for SubobjectExpr
7805+
where
7806+
W: 'subs + DemangleWrite,
7807+
{
7808+
#[inline]
7809+
fn demangle<'prev, 'ctx>(
7810+
&'subs self,
7811+
ctx: &'ctx mut DemangleContext<'subs, W>,
7812+
scope: Option<ArgScopeStack<'prev, 'subs>>,
7813+
) -> fmt::Result {
7814+
let ctx = try_begin_demangle!(self, ctx, scope);
7815+
7816+
self.expr.demangle(ctx, scope)?;
7817+
write!(ctx, ".<")?;
7818+
self.ty.demangle(ctx, scope)?;
7819+
write!(ctx, " at offset {}>", self.offset)
7820+
}
7821+
}
7822+
77547823
/// Expect and consume the given byte str, and return the advanced `IndexStr` if
77557824
/// we saw the expectation. Otherwise return an error of kind
77567825
/// `error::Error::UnexpectedText` if the input doesn't match, or
@@ -7866,8 +7935,8 @@ mod tests {
78667935
FunctionType, GlobalCtorDtor, Identifier, Initializer, LambdaSig, LocalName, MangledName,
78677936
MemberName, Name, NestedName, NonSubstitution, Number, NvOffset, OperatorName, Parse,
78687937
ParseContext, PointerToMemberType, Prefix, PrefixHandle, RefQualifier, ResourceName, SeqId,
7869-
SimpleId, SimpleOperatorName, SourceName, SpecialName, StandardBuiltinType, Substitution,
7870-
TaggedName, TemplateArg, TemplateArgs, TemplateParam, TemplateTemplateParam,
7938+
SimpleId, SimpleOperatorName, SourceName, SpecialName, StandardBuiltinType, SubobjectExpr,
7939+
Substitution, TaggedName, TemplateArg, TemplateArgs, TemplateParam, TemplateTemplateParam,
78717940
TemplateTemplateParamHandle, Type, TypeHandle, UnnamedTypeName, UnqualifiedName,
78727941
UnresolvedName, UnresolvedQualifierLevel, UnresolvedType, UnresolvedTypeHandle,
78737942
UnscopedName, UnscopedTemplateName, UnscopedTemplateNameHandle, VOffset, VectorType,
@@ -11370,4 +11439,69 @@ mod tests {
1137011439
}
1137111440
});
1137211441
}
11442+
11443+
#[test]
11444+
fn parse_subobject_expr() {
11445+
assert_parse!(SubobjectExpr {
11446+
with subs [] => {
11447+
Ok => {
11448+
"PKcL_Z3FooEE..." => {
11449+
SubobjectExpr {
11450+
ty: TypeHandle::BackReference(1),
11451+
expr: Box::new(Expression::Primary(
11452+
ExprPrimary::External(
11453+
MangledName::Encoding(
11454+
Encoding::Data(
11455+
Name::Unscoped(
11456+
UnscopedName::Unqualified(
11457+
UnqualifiedName::Source(
11458+
SourceName(
11459+
Identifier {
11460+
start: 7,
11461+
end: 10,
11462+
}
11463+
)
11464+
)
11465+
)
11466+
)
11467+
),
11468+
vec![]
11469+
)
11470+
)
11471+
)),
11472+
offset: 0,
11473+
},
11474+
b"...",
11475+
[
11476+
Substitutable::Type(
11477+
Type::Qualified(
11478+
CvQualifiers {
11479+
restrict: false,
11480+
volatile: false,
11481+
const_: true,
11482+
},
11483+
TypeHandle::Builtin(
11484+
BuiltinType::Standard(
11485+
StandardBuiltinType::Char,
11486+
),
11487+
),
11488+
)
11489+
),
11490+
Substitutable::Type(
11491+
Type::PointerTo(
11492+
TypeHandle::BackReference(
11493+
0,
11494+
),
11495+
),
11496+
)
11497+
]
11498+
}
11499+
}
11500+
Err => {
11501+
"" => Error::UnexpectedEnd,
11502+
"" => Error::UnexpectedEnd,
11503+
}
11504+
}
11505+
});
11506+
}
1137311507
}

tests/tests.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,3 +605,8 @@ demangles!(
605605
_Z14WasmMemoryCopyIPhPDoFPvS1_PKvmEjEiP9JSContextT_mT1_S9_S9_T0_,
606606
"int WasmMemoryCopy<unsigned char*, void* (*)(void*, void const*, unsigned long) noexcept, unsigned int>(JSContext*, unsigned char*, unsigned long, unsigned int, unsigned int, unsigned int, void* (*)(void*, void const*, unsigned long) noexcept)"
607607
);
608+
609+
demangles!(
610+
_ZN7mozilla10extensions7AtomSet3GetIXadsoPKcL_ZNS0_16WILDCARD_SCHEMESEEEEEE8nsresultR6RefPtrIS1_E,
611+
"nsresult mozilla::extensions::AtomSet::Get<&(mozilla::extensions::WILDCARD_SCHEMES.<char const* at offset 0>)>(RefPtr<mozilla::extensions::AtomSet>&)"
612+
);

0 commit comments

Comments
 (0)