New type GenericArguments represents actual arguments to generics.
This commit is contained in:
parent
798cfab52b
commit
13c0a4a2e8
@ -5,7 +5,7 @@
|
||||
use std::io::Write;
|
||||
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationType;
|
||||
use crate::bindgen::ir::{ArrayLength, Function, Type};
|
||||
use crate::bindgen::ir::{ArrayLength, Function, GenericArgument, Type};
|
||||
use crate::bindgen::writer::{ListType, SourceWriter};
|
||||
use crate::bindgen::{Config, Language};
|
||||
|
||||
@ -35,7 +35,7 @@ impl CDeclarator {
|
||||
struct CDecl {
|
||||
type_qualifers: String,
|
||||
type_name: String,
|
||||
type_generic_args: Vec<Type>,
|
||||
type_generic_args: Vec<GenericArgument>,
|
||||
declarators: Vec<CDeclarator>,
|
||||
type_ctype: Option<DeclarationType>,
|
||||
}
|
||||
|
@ -10,8 +10,9 @@ use crate::bindgen::config::{Config, Language};
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use crate::bindgen::dependencies::Dependencies;
|
||||
use crate::bindgen::ir::{
|
||||
AnnotationSet, AnnotationValue, Cfg, ConditionWrite, Documentation, Field, GenericParams,
|
||||
GenericPath, Item, ItemContainer, Literal, Path, Repr, ReprStyle, Struct, ToCondition, Type,
|
||||
AnnotationSet, AnnotationValue, Cfg, ConditionWrite, Documentation, Field, GenericArgument,
|
||||
GenericParams, GenericPath, Item, ItemContainer, Literal, Path, Repr, ReprStyle, Struct,
|
||||
ToCondition, Type,
|
||||
};
|
||||
use crate::bindgen::library::Library;
|
||||
use crate::bindgen::mangle;
|
||||
@ -61,8 +62,8 @@ impl VariantBody {
|
||||
|
||||
fn specialize(
|
||||
&self,
|
||||
generic_values: &[Type],
|
||||
mappings: &[(&Path, &Type)],
|
||||
generic_values: &[GenericArgument],
|
||||
mappings: &[(&Path, &GenericArgument)],
|
||||
config: &Config,
|
||||
) -> Self {
|
||||
match *self {
|
||||
@ -265,8 +266,8 @@ impl EnumVariant {
|
||||
|
||||
fn specialize(
|
||||
&self,
|
||||
generic_values: &[Type],
|
||||
mappings: &[(&Path, &Type)],
|
||||
generic_values: &[GenericArgument],
|
||||
mappings: &[(&Path, &GenericArgument)],
|
||||
config: &Config,
|
||||
) -> Self {
|
||||
Self::new(
|
||||
@ -611,7 +612,7 @@ impl Item for Enum {
|
||||
|
||||
fn instantiate_monomorph(
|
||||
&self,
|
||||
generic_values: &[Type],
|
||||
generic_values: &[GenericArgument],
|
||||
library: &Library,
|
||||
out: &mut Monomorphs,
|
||||
) {
|
||||
|
@ -5,7 +5,7 @@ use syn::ext::IdentExt;
|
||||
|
||||
use crate::bindgen::config::{Config, Language};
|
||||
use crate::bindgen::declarationtyperesolver::{DeclarationType, DeclarationTypeResolver};
|
||||
use crate::bindgen::ir::{Path, Type};
|
||||
use crate::bindgen::ir::{ArrayLength, Path, Type};
|
||||
use crate::bindgen::utilities::IterHelpers;
|
||||
use crate::bindgen::writer::{Source, SourceWriter};
|
||||
|
||||
@ -19,7 +19,8 @@ impl GenericParams {
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|x| match *x {
|
||||
syn::GenericParam::Type(syn::TypeParam { ref ident, .. }) => {
|
||||
syn::GenericParam::Type(syn::TypeParam { ref ident, .. })
|
||||
| syn::GenericParam::Const(syn::ConstParam { ref ident, .. }) => {
|
||||
Some(Path::new(ident.unraw().to_string()))
|
||||
}
|
||||
_ => None,
|
||||
@ -69,16 +70,52 @@ impl Source for GenericParams {
|
||||
}
|
||||
}
|
||||
|
||||
/// A (non-lifetime) argument passed to a generic, either a type or a constant expression.
|
||||
///
|
||||
/// Note: Both arguments in a type like `Array<T, N>` are represented as
|
||||
/// `GenericArgument::Type`s, even if `N` is actually the name of a const. This
|
||||
/// is a consequence of `syn::GenericArgument` doing the same thing.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum GenericArgument {
|
||||
Type(Type),
|
||||
Const(ArrayLength),
|
||||
}
|
||||
|
||||
impl GenericArgument {
|
||||
pub fn specialize(&self, mappings: &[(&Path, &GenericArgument)]) -> GenericArgument {
|
||||
match *self {
|
||||
GenericArgument::Type(ref ty) => GenericArgument::Type(ty.specialize(mappings)),
|
||||
GenericArgument::Const(ref expr) => GenericArgument::Const(expr.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rename_for_config(&mut self, config: &Config, generic_params: &GenericParams) {
|
||||
match *self {
|
||||
GenericArgument::Type(ref mut ty) => ty.rename_for_config(config, generic_params),
|
||||
GenericArgument::Const(ref mut expr) => expr.rename_for_config(config),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Source for GenericArgument {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
match *self {
|
||||
GenericArgument::Type(ref ty) => ty.write(config, out),
|
||||
GenericArgument::Const(ref expr) => expr.write(config, out),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct GenericPath {
|
||||
path: Path,
|
||||
export_name: String,
|
||||
generics: Vec<Type>,
|
||||
generics: Vec<GenericArgument>,
|
||||
ctype: Option<DeclarationType>,
|
||||
}
|
||||
|
||||
impl GenericPath {
|
||||
pub fn new(path: Path, generics: Vec<Type>) -> Self {
|
||||
pub fn new(path: Path, generics: Vec<GenericArgument>) -> Self {
|
||||
let export_name = path.name().to_owned();
|
||||
Self {
|
||||
path,
|
||||
@ -103,11 +140,11 @@ impl GenericPath {
|
||||
&self.path
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &[Type] {
|
||||
pub fn generics(&self) -> &[GenericArgument] {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut [Type] {
|
||||
pub fn generics_mut(&mut self) -> &mut [GenericArgument] {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
@ -123,6 +160,10 @@ impl GenericPath {
|
||||
&self.export_name
|
||||
}
|
||||
|
||||
pub fn is_single_identifier(&self) -> bool {
|
||||
self.generics.is_empty()
|
||||
}
|
||||
|
||||
pub fn rename_for_config(&mut self, config: &Config, generic_params: &GenericParams) {
|
||||
for generic in &mut self.generics {
|
||||
generic.rename_for_config(config, generic_params);
|
||||
@ -156,8 +197,11 @@ impl GenericPath {
|
||||
ref args,
|
||||
..
|
||||
}) => args.iter().try_skip_map(|x| match *x {
|
||||
syn::GenericArgument::Type(ref x) => Type::load(x),
|
||||
syn::GenericArgument::Type(ref x) => Ok(Type::load(x)?.map(GenericArgument::Type)),
|
||||
syn::GenericArgument::Lifetime(_) => Ok(None),
|
||||
syn::GenericArgument::Const(ref x) => {
|
||||
Ok(Some(GenericArgument::Const(ArrayLength::load(x)?)))
|
||||
}
|
||||
_ => Err(format!("can't handle generic argument {:?}", x)),
|
||||
})?,
|
||||
syn::PathArguments::Parenthesized(_) => {
|
||||
|
@ -9,7 +9,8 @@ use crate::bindgen::config::Config;
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use crate::bindgen::dependencies::Dependencies;
|
||||
use crate::bindgen::ir::{
|
||||
AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Path, Static, Struct, Type, Typedef, Union,
|
||||
AnnotationSet, Cfg, Constant, Enum, GenericArgument, OpaqueItem, Path, Static, Struct, Typedef,
|
||||
Union,
|
||||
};
|
||||
use crate::bindgen::library::Library;
|
||||
use crate::bindgen::monomorph::Monomorphs;
|
||||
@ -37,7 +38,12 @@ pub trait Item {
|
||||
}
|
||||
fn rename_for_config(&mut self, _config: &Config) {}
|
||||
fn add_dependencies(&self, _library: &Library, _out: &mut Dependencies) {}
|
||||
fn instantiate_monomorph(&self, _generics: &[Type], _library: &Library, _out: &mut Monomorphs) {
|
||||
fn instantiate_monomorph(
|
||||
&self,
|
||||
_generics: &[GenericArgument],
|
||||
_library: &Library,
|
||||
_out: &mut Monomorphs,
|
||||
) {
|
||||
unreachable!("Cannot instantiate {} as a generic.", self.name())
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ use crate::bindgen::config::{Config, Language};
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use crate::bindgen::dependencies::Dependencies;
|
||||
use crate::bindgen::ir::{
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Path,
|
||||
ToCondition, Type,
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericArgument, GenericParams, Item,
|
||||
ItemContainer, Path, ToCondition,
|
||||
};
|
||||
use crate::bindgen::library::Library;
|
||||
use crate::bindgen::mangle;
|
||||
@ -98,7 +98,7 @@ impl Item for OpaqueItem {
|
||||
|
||||
fn instantiate_monomorph(
|
||||
&self,
|
||||
generic_values: &[Type],
|
||||
generic_values: &[GenericArgument],
|
||||
library: &Library,
|
||||
out: &mut Monomorphs,
|
||||
) {
|
||||
|
@ -10,8 +10,9 @@ use crate::bindgen::config::{Config, Language, LayoutConfig};
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use crate::bindgen::dependencies::Dependencies;
|
||||
use crate::bindgen::ir::{
|
||||
AnnotationSet, Cfg, ConditionWrite, Constant, Documentation, Field, GenericParams, Item,
|
||||
ItemContainer, Path, Repr, ReprAlign, ReprStyle, ToCondition, Type, Typedef,
|
||||
AnnotationSet, Cfg, ConditionWrite, Constant, Documentation, Field, GenericArgument,
|
||||
GenericParams, Item, ItemContainer, Path, Repr, ReprAlign, ReprStyle, ToCondition, Type,
|
||||
Typedef,
|
||||
};
|
||||
use crate::bindgen::library::Library;
|
||||
use crate::bindgen::mangle;
|
||||
@ -174,8 +175,8 @@ impl Struct {
|
||||
|
||||
pub fn specialize(
|
||||
&self,
|
||||
generic_values: &[Type],
|
||||
mappings: &[(&Path, &Type)],
|
||||
generic_values: &[GenericArgument],
|
||||
mappings: &[(&Path, &GenericArgument)],
|
||||
config: &Config,
|
||||
) -> Self {
|
||||
let mangled_path = mangle::mangle_path(&self.path, generic_values, &config.export.mangle);
|
||||
@ -365,7 +366,7 @@ impl Item for Struct {
|
||||
|
||||
fn instantiate_monomorph(
|
||||
&self,
|
||||
generic_values: &[Type],
|
||||
generic_values: &[GenericArgument],
|
||||
library: &Library,
|
||||
out: &mut Monomorphs,
|
||||
) {
|
||||
|
@ -11,7 +11,7 @@ use crate::bindgen::cdecl;
|
||||
use crate::bindgen::config::{Config, Language};
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use crate::bindgen::dependencies::Dependencies;
|
||||
use crate::bindgen::ir::{GenericParams, GenericPath, Path};
|
||||
use crate::bindgen::ir::{GenericArgument, GenericParams, GenericPath, Path};
|
||||
use crate::bindgen::library::Library;
|
||||
use crate::bindgen::monomorph::Monomorphs;
|
||||
use crate::bindgen::utilities::IterHelpers;
|
||||
@ -320,16 +320,64 @@ pub enum ArrayLength {
|
||||
|
||||
impl ArrayLength {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
match *self {
|
||||
ArrayLength::Name(ref string) | ArrayLength::Value(ref string) => string,
|
||||
}
|
||||
}
|
||||
|
||||
fn rename_for_config(&mut self, config: &Config) {
|
||||
pub fn rename_for_config(&mut self, config: &Config) {
|
||||
if let ArrayLength::Name(ref mut name) = self {
|
||||
config.export.rename(name);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(expr: &syn::Expr) -> Result<Self, String> {
|
||||
match *expr {
|
||||
syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Int(ref len),
|
||||
..
|
||||
}) => Ok(ArrayLength::Value(len.base10_digits().to_string())),
|
||||
syn::Expr::Path(ref path) => {
|
||||
let generic_path = GenericPath::load(&path.path)?;
|
||||
Ok(ArrayLength::Name(generic_path.export_name().to_owned()))
|
||||
}
|
||||
_ => Err(format!("can't handle const expression {:?}", expr)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn specialize(&self, mappings: &[(&Path, &GenericArgument)]) -> ArrayLength {
|
||||
match *self {
|
||||
ArrayLength::Name(ref name) => {
|
||||
let path = Path::new(name);
|
||||
for &(param, value) in mappings {
|
||||
if path == *param {
|
||||
match *value {
|
||||
GenericArgument::Type(Type::Path(ref path))
|
||||
if path.is_single_identifier() =>
|
||||
{
|
||||
// This happens when the generic argument is a path.
|
||||
return ArrayLength::Name(path.name().to_string());
|
||||
}
|
||||
GenericArgument::Const(ref expr) => {
|
||||
return expr.clone();
|
||||
}
|
||||
_ => {
|
||||
// unsupported argument type - really should be an error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayLength::Value(_) => {}
|
||||
}
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Source for ArrayLength {
|
||||
fn write<F: Write>(&self, _config: &Config, out: &mut SourceWriter<F>) {
|
||||
write!(out, "{}", self.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
@ -415,28 +463,7 @@ impl Type {
|
||||
}
|
||||
}
|
||||
syn::Type::Array(syn::TypeArray {
|
||||
ref elem,
|
||||
len: syn::Expr::Path(ref path),
|
||||
..
|
||||
}) => {
|
||||
let converted = Type::load(elem)?;
|
||||
|
||||
let converted = match converted {
|
||||
Some(converted) => converted,
|
||||
None => return Err("Cannot have an array of zero sized types.".to_owned()),
|
||||
};
|
||||
let generic_path = GenericPath::load(&path.path)?;
|
||||
let len = ArrayLength::Name(generic_path.export_name().to_owned());
|
||||
Type::Array(Box::new(converted), len)
|
||||
}
|
||||
syn::Type::Array(syn::TypeArray {
|
||||
ref elem,
|
||||
len:
|
||||
syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Int(ref len),
|
||||
..
|
||||
}),
|
||||
..
|
||||
ref elem, ref len, ..
|
||||
}) => {
|
||||
let converted = Type::load(elem)?;
|
||||
|
||||
@ -445,8 +472,7 @@ impl Type {
|
||||
None => return Err("Cannot have an array of zero sized types.".to_owned()),
|
||||
};
|
||||
|
||||
let len = ArrayLength::Value(len.base10_digits().to_string());
|
||||
// panic!("panic -> value: {:?}", len);
|
||||
let len = ArrayLength::load(len)?;
|
||||
Type::Array(Box::new(converted), len)
|
||||
}
|
||||
syn::Type::BareFn(ref function) => {
|
||||
@ -609,7 +635,11 @@ impl Type {
|
||||
return None;
|
||||
}
|
||||
|
||||
let unsimplified_generic = &path.generics()[0];
|
||||
let unsimplified_generic = match path.generics()[0] {
|
||||
GenericArgument::Type(ref ty) => ty,
|
||||
GenericArgument::Const(_) => return None,
|
||||
};
|
||||
|
||||
let generic = match unsimplified_generic.simplified_type(config) {
|
||||
Some(generic) => Cow::Owned(generic),
|
||||
None => Cow::Borrowed(unsimplified_generic),
|
||||
@ -663,7 +693,10 @@ impl Type {
|
||||
Type::Array(ref mut ty, ..) | Type::Ptr { ref mut ty, .. } => visitor(ty),
|
||||
Type::Path(ref mut path) => {
|
||||
for generic in path.generics_mut() {
|
||||
visitor(generic);
|
||||
match *generic {
|
||||
GenericArgument::Type(ref mut ty) => visitor(ty),
|
||||
GenericArgument::Const(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Type::Primitive(..) => {}
|
||||
@ -701,7 +734,7 @@ impl Type {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn specialize(&self, mappings: &[(&Path, &Type)]) -> Type {
|
||||
pub fn specialize(&self, mappings: &[(&Path, &GenericArgument)]) -> Type {
|
||||
match *self {
|
||||
Type::Ptr {
|
||||
ref ty,
|
||||
@ -717,7 +750,9 @@ impl Type {
|
||||
Type::Path(ref generic_path) => {
|
||||
for &(param, value) in mappings {
|
||||
if generic_path.path() == param {
|
||||
return value.clone();
|
||||
if let GenericArgument::Type(ref ty) = *value {
|
||||
return ty.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -732,9 +767,10 @@ impl Type {
|
||||
Type::Path(specialized)
|
||||
}
|
||||
Type::Primitive(ref primitive) => Type::Primitive(primitive.clone()),
|
||||
Type::Array(ref ty, ref constant) => {
|
||||
Type::Array(Box::new(ty.specialize(mappings)), constant.clone())
|
||||
}
|
||||
Type::Array(ref ty, ref constant) => Type::Array(
|
||||
Box::new(ty.specialize(mappings)),
|
||||
constant.specialize(mappings),
|
||||
),
|
||||
Type::FuncPtr {
|
||||
ref ret,
|
||||
ref args,
|
||||
@ -763,7 +799,9 @@ impl Type {
|
||||
}
|
||||
Type::Path(ref generic) => {
|
||||
for generic_value in generic.generics() {
|
||||
generic_value.add_dependencies_ignoring_generics(generic_params, library, out);
|
||||
if let GenericArgument::Type(ref ty) = *generic_value {
|
||||
ty.add_dependencies_ignoring_generics(generic_params, library, out);
|
||||
}
|
||||
}
|
||||
let path = generic.path();
|
||||
if !generic_params.contains(path) {
|
||||
|
@ -11,8 +11,8 @@ use crate::bindgen::config::{Config, Language};
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use crate::bindgen::dependencies::Dependencies;
|
||||
use crate::bindgen::ir::{
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, Field, GenericParams, Item, ItemContainer,
|
||||
Path, ToCondition, Type,
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, Field, GenericArgument, GenericParams, Item,
|
||||
ItemContainer, Path, ToCondition, Type,
|
||||
};
|
||||
use crate::bindgen::library::Library;
|
||||
use crate::bindgen::mangle;
|
||||
@ -155,7 +155,7 @@ impl Item for Typedef {
|
||||
|
||||
fn instantiate_monomorph(
|
||||
&self,
|
||||
generic_values: &[Type],
|
||||
generic_values: &[GenericArgument],
|
||||
library: &Library,
|
||||
out: &mut Monomorphs,
|
||||
) {
|
||||
|
@ -10,8 +10,8 @@ use crate::bindgen::config::{Config, Language, LayoutConfig};
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use crate::bindgen::dependencies::Dependencies;
|
||||
use crate::bindgen::ir::{
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, Field, GenericParams, Item, ItemContainer,
|
||||
Path, Repr, ReprAlign, ReprStyle, ToCondition, Type,
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, Field, GenericArgument, GenericParams, Item,
|
||||
ItemContainer, Path, Repr, ReprAlign, ReprStyle, ToCondition,
|
||||
};
|
||||
use crate::bindgen::library::Library;
|
||||
use crate::bindgen::mangle;
|
||||
@ -223,7 +223,7 @@ impl Item for Union {
|
||||
|
||||
fn instantiate_monomorph(
|
||||
&self,
|
||||
generic_values: &[Type],
|
||||
generic_values: &[GenericArgument],
|
||||
library: &Library,
|
||||
out: &mut Monomorphs,
|
||||
) {
|
||||
|
@ -3,14 +3,18 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::bindgen::config::MangleConfig;
|
||||
use crate::bindgen::ir::{Path, Type};
|
||||
use crate::bindgen::ir::{ArrayLength, GenericArgument, GenericPath, Path, Type};
|
||||
use crate::bindgen::rename::IdentifierType;
|
||||
|
||||
pub fn mangle_path(path: &Path, generic_values: &[Type], config: &MangleConfig) -> Path {
|
||||
pub fn mangle_path(path: &Path, generic_values: &[GenericArgument], config: &MangleConfig) -> Path {
|
||||
Path::new(mangle_name(path.name(), generic_values, config))
|
||||
}
|
||||
|
||||
pub fn mangle_name(name: &str, generic_values: &[Type], config: &MangleConfig) -> String {
|
||||
pub fn mangle_name(
|
||||
name: &str,
|
||||
generic_values: &[GenericArgument],
|
||||
config: &MangleConfig,
|
||||
) -> String {
|
||||
Mangler::new(name, generic_values, /* last = */ true, config).mangle()
|
||||
}
|
||||
|
||||
@ -27,7 +31,7 @@ enum Separator {
|
||||
|
||||
struct Mangler<'a> {
|
||||
input: &'a str,
|
||||
generic_values: &'a [Type],
|
||||
generic_values: &'a [GenericArgument],
|
||||
output: String,
|
||||
last: bool,
|
||||
config: &'a MangleConfig,
|
||||
@ -36,7 +40,7 @@ struct Mangler<'a> {
|
||||
impl<'a> Mangler<'a> {
|
||||
fn new(
|
||||
input: &'a str,
|
||||
generic_values: &'a [Type],
|
||||
generic_values: &'a [GenericArgument],
|
||||
last: bool,
|
||||
config: &'a MangleConfig,
|
||||
) -> Self {
|
||||
@ -64,6 +68,20 @@ impl<'a> Mangler<'a> {
|
||||
self.output.extend(std::iter::repeat(separator).take(count));
|
||||
}
|
||||
|
||||
fn append_mangled_argument(&mut self, arg: &GenericArgument, last: bool) {
|
||||
match *arg {
|
||||
GenericArgument::Type(ref ty) => self.append_mangled_type(ty, last),
|
||||
GenericArgument::Const(ArrayLength::Name(ref name)) => {
|
||||
// This must behave the same as a GenericArgument::Type,
|
||||
// because const arguments are commonly represented as Types;
|
||||
// see the comment on `enum GenericArgument`.
|
||||
let fake_ty = Type::Path(GenericPath::new(Path::new(name), vec![]));
|
||||
self.append_mangled_type(&fake_ty, last);
|
||||
}
|
||||
GenericArgument::Const(ArrayLength::Value(ref val)) => self.output.push_str(val),
|
||||
}
|
||||
}
|
||||
|
||||
fn append_mangled_type(&mut self, ty: &Type, last: bool) {
|
||||
match *ty {
|
||||
Type::Path(ref generic) => {
|
||||
@ -128,12 +146,12 @@ impl<'a> Mangler<'a> {
|
||||
}
|
||||
|
||||
self.push(Separator::OpeningAngleBracket);
|
||||
for (i, ty) in self.generic_values.iter().enumerate() {
|
||||
for (i, arg) in self.generic_values.iter().enumerate() {
|
||||
if i != 0 {
|
||||
self.push(Separator::Comma);
|
||||
}
|
||||
let last = self.last && i == self.generic_values.len() - 1;
|
||||
self.append_mangled_type(ty, last);
|
||||
self.append_mangled_argument(arg, last);
|
||||
}
|
||||
|
||||
// Skip writing the trailing '>' mangling when possible
|
||||
@ -148,22 +166,22 @@ fn generics() {
|
||||
use crate::bindgen::ir::{GenericPath, PrimitiveType};
|
||||
use crate::bindgen::rename::RenameRule::{self, PascalCase};
|
||||
|
||||
fn float() -> Type {
|
||||
Type::Primitive(PrimitiveType::Float)
|
||||
fn float() -> GenericArgument {
|
||||
GenericArgument::Type(Type::Primitive(PrimitiveType::Float))
|
||||
}
|
||||
|
||||
fn c_char() -> Type {
|
||||
Type::Primitive(PrimitiveType::Char)
|
||||
fn c_char() -> GenericArgument {
|
||||
GenericArgument::Type(Type::Primitive(PrimitiveType::Char))
|
||||
}
|
||||
|
||||
fn path(path: &str) -> Type {
|
||||
fn path(path: &str) -> GenericArgument {
|
||||
generic_path(path, &[])
|
||||
}
|
||||
|
||||
fn generic_path(path: &str, generics: &[Type]) -> Type {
|
||||
fn generic_path(path: &str, arguments: &[GenericArgument]) -> GenericArgument {
|
||||
let path = Path::new(path);
|
||||
let generic_path = GenericPath::new(path, generics.to_owned());
|
||||
Type::Path(generic_path)
|
||||
let generic_path = GenericPath::new(path, arguments.to_owned());
|
||||
GenericArgument::Type(Type::Path(generic_path))
|
||||
}
|
||||
|
||||
// Foo<f32> => Foo_f32
|
||||
@ -288,4 +306,43 @@ fn generics() {
|
||||
),
|
||||
Path::new("FooBarTBarE")
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mangle_path(
|
||||
&Path::new("Top"),
|
||||
&[GenericArgument::Const(ArrayLength::Value("40".to_string()))],
|
||||
&MangleConfig::default(),
|
||||
),
|
||||
Path::new("Top_40")
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mangle_path(
|
||||
&Path::new("Top"),
|
||||
&[GenericArgument::Const(ArrayLength::Name("N".to_string()))],
|
||||
&MangleConfig::default(),
|
||||
),
|
||||
Path::new("Top_N")
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mangle_path(
|
||||
&Path::new("Top"),
|
||||
&[generic_path("N", &[])],
|
||||
&MangleConfig::default(),
|
||||
),
|
||||
Path::new("Top_N")
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mangle_path(
|
||||
&Path::new("Foo"),
|
||||
&[
|
||||
float(),
|
||||
GenericArgument::Const(ArrayLength::Value("40".to_string()))
|
||||
],
|
||||
&MangleConfig::default(),
|
||||
),
|
||||
Path::new("Foo_f32__40")
|
||||
);
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
|
||||
use crate::bindgen::ir::{Enum, GenericPath, OpaqueItem, Path, Struct, Type, Typedef, Union};
|
||||
use crate::bindgen::ir::{
|
||||
Enum, GenericArgument, GenericPath, OpaqueItem, Path, Struct, Typedef, Union,
|
||||
};
|
||||
use crate::bindgen::library::Library;
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
@ -28,9 +30,9 @@ impl Monomorphs {
|
||||
library: &Library,
|
||||
generic: &Struct,
|
||||
monomorph: Struct,
|
||||
parameters: Vec<Type>,
|
||||
arguments: Vec<GenericArgument>,
|
||||
) {
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), parameters);
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), arguments);
|
||||
|
||||
debug_assert!(generic.generic_params.len() > 0);
|
||||
debug_assert!(!self.contains(&replacement_path));
|
||||
@ -48,9 +50,9 @@ impl Monomorphs {
|
||||
library: &Library,
|
||||
generic: &Enum,
|
||||
monomorph: Enum,
|
||||
parameters: Vec<Type>,
|
||||
arguments: Vec<GenericArgument>,
|
||||
) {
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), parameters);
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), arguments);
|
||||
|
||||
debug_assert!(generic.generic_params.len() > 0);
|
||||
debug_assert!(!self.contains(&replacement_path));
|
||||
@ -68,9 +70,9 @@ impl Monomorphs {
|
||||
library: &Library,
|
||||
generic: &Union,
|
||||
monomorph: Union,
|
||||
parameters: Vec<Type>,
|
||||
arguments: Vec<GenericArgument>,
|
||||
) {
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), parameters);
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), arguments);
|
||||
|
||||
debug_assert!(generic.generic_params.len() > 0);
|
||||
debug_assert!(!self.contains(&replacement_path));
|
||||
@ -87,9 +89,9 @@ impl Monomorphs {
|
||||
&mut self,
|
||||
generic: &OpaqueItem,
|
||||
monomorph: OpaqueItem,
|
||||
parameters: Vec<Type>,
|
||||
arguments: Vec<GenericArgument>,
|
||||
) {
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), parameters);
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), arguments);
|
||||
|
||||
debug_assert!(generic.generic_params.len() > 0);
|
||||
debug_assert!(!self.contains(&replacement_path));
|
||||
@ -104,9 +106,9 @@ impl Monomorphs {
|
||||
library: &Library,
|
||||
generic: &Typedef,
|
||||
monomorph: Typedef,
|
||||
parameters: Vec<Type>,
|
||||
arguments: Vec<GenericArgument>,
|
||||
) {
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), parameters);
|
||||
let replacement_path = GenericPath::new(generic.path.clone(), arguments);
|
||||
|
||||
debug_assert!(generic.generic_params.len() > 0);
|
||||
debug_assert!(!self.contains(&replacement_path));
|
||||
|
Loading…
x
Reference in New Issue
Block a user