summaryrefslogtreecommitdiff
path: root/src/codegen/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r--src/codegen/mod.rs37
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)