diff options
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r-- | src/codegen/mod.rs | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 4ebc48bf..17789e19 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -16,6 +16,7 @@ use ir::layout::Layout; use ir::annotations::FieldAccessorKind; use std::ops; +use std::borrow::Cow; use std::mem; use std::collections::BTreeSet; use std::collections::HashSet; @@ -41,7 +42,7 @@ struct CodegenResult { /// The set of generated function/var names, needed because in C/C++ is legal to /// do something like: /// - /// ``` + /// ```c++ /// extern "C" { /// void foo(); /// extern int bar; @@ -341,6 +342,12 @@ impl CodeGenerator for Type { return; } TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item), + TypeKind::TemplateAlias(inner, _) => { + // NB: The inner Alias will pick the correct + // applicable_template_args. + let inner_item = ctx.resolve_item(inner); + inner_item.expect_type().codegen(ctx, result, inner_item); + } TypeKind::Alias(ref spelling, inner) => { let inner_item = ctx.resolve_item(inner); let name = item.canonical_name(ctx); @@ -1226,6 +1233,9 @@ impl CodeGenerator for Enum { result.push(constant); } + // Used to mangle the constants we generate in the unnamed-enum case. + let mut parent_canonical_name = None; + // A map where we keep a value -> variant relation. let mut seen_values = HashMap::<_, String>::new(); let enum_ty = item.expect_type(); @@ -1258,11 +1268,21 @@ impl CodeGenerator for Enum { if enum_ty.name().is_none() { // NB: if we want to do this for other kind of nested // enums we can probably mangle the name. - if item.is_toplevel(ctx) { - add_constant(enum_ty, &name, &variant_name, - &variant_name, enum_rust_ty.clone(), - result); - } + let mangled_name = if item.is_toplevel(ctx) { + variant_name.clone() + } else { + if parent_canonical_name.is_none() { + parent_canonical_name = Some(item.parent_id().canonical_name(ctx)); + } + + Cow::Owned( + format!("{}_{}", parent_canonical_name.as_ref().unwrap(), + variant_name)) + }; + + add_constant(enum_ty, &name, &mangled_name, + &variant_name, enum_rust_ty.clone(), + result); } entry.insert(variant_name.into_owned()); @@ -1361,6 +1381,7 @@ impl ToRustTy for Type { let path = item.canonical_path(ctx); aster::AstBuilder::new().ty().path().ids(path).build() } + TypeKind::TemplateAlias(inner, ref template_args) | TypeKind::TemplateRef(inner, ref template_args) => { // PS: Sorry for the duplication here. let mut inner_ty = inner.to_rust_ty(ctx).unwrap(); @@ -1423,7 +1444,8 @@ impl ToRustTy for Type { if inner_ty.canonical_type(ctx).is_function() { ty } else { - ty.to_ptr(inner.expect_type().is_const(), ctx.span()) + let is_const = self.is_const() || inner.expect_type().is_const(); + ty.to_ptr(is_const, ctx.span()) } } TypeKind::Named(..) => { @@ -1618,6 +1640,7 @@ impl TypeCollector for Type { TypeKind::Pointer(inner) | TypeKind::Reference(inner) | TypeKind::Array(inner, _) | + TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(_, inner) | TypeKind::Named(_, Some(inner)) | TypeKind::ResolvedTypeRef(inner) |