diff --git a/src/bindgen/bindings.rs b/src/bindgen/bindings.rs index 029cfc66..d5db9925 100644 --- a/src/bindgen/bindings.rs +++ b/src/bindgen/bindings.rs @@ -204,7 +204,7 @@ impl Bindings { pub fn write(&self, file: F) { match self.config.language { - Language::Cxx | Language::C => { + Language::Cxx | Language::C | Language::D => { self.write_with_backend(file, &mut CLikeLanguageBackend::new(&self.config)) } Language::Cython => { diff --git a/src/bindgen/cdecl.rs b/src/bindgen/cdecl.rs index 3ba543ac..b5049516 100644 --- a/src/bindgen/cdecl.rs +++ b/src/bindgen/cdecl.rs @@ -147,7 +147,11 @@ impl CDecl { "error generating cdecl for {:?}", t ); - self.type_name = p.to_repr_c(config).to_string(); + if config.language == Language::D { + self.type_name = p.to_repr_d(config).to_string(); + } else { + self.type_name = p.to_repr_c(config).to_string(); + } } Type::Ptr { ref ty, @@ -213,7 +217,11 @@ impl CDecl { write!(out, "{}", self.type_name); if !self.type_generic_args.is_empty() { - out.write("<"); + if config.language == Language::D { + out.write("!("); + } else { + out.write("<"); + } out.write_horizontal_source_list( language_backend, &self.type_generic_args, @@ -223,7 +231,11 @@ impl CDecl { GenericArgument::Const(ref expr) => write!(out, "{}", expr.as_str()), }, ); - out.write(">"); + if config.language == Language::D { + out.write(")"); + } else { + out.write(">"); + } } // When we have an identifier, put a space between the type and the declarators @@ -233,6 +245,7 @@ impl CDecl { // Write the left part of declarators before the identifier let mut iter_rev = self.declarators.iter().rev().peekable(); + let mut is_functors = false; #[allow(clippy::while_let_on_iterator)] while let Some(declarator) = iter_rev.next() { @@ -244,7 +257,17 @@ impl CDecl { is_nullable, is_ref, } => { - out.write(if is_ref { "&" } else { "*" }); + if config.language == Language::D { + // out.write(if is_ref { "ref " } else { "*" }); + if is_ref { + out.write("ref "); + } else if is_functors { + } else { + out.write("*"); + } + } else { + out.write(if is_ref { "&" } else { "*" }); + } if is_const { out.write("const "); } @@ -254,14 +277,22 @@ impl CDecl { } } } - CDeclarator::Array(..) => { + CDeclarator::Array(ref constant) => { if next_is_pointer { out.write("("); } + if config.language == Language::D { + write!(out, "[{}] ", constant); + } } CDeclarator::Func { .. } => { if next_is_pointer { - out.write("("); + if config.language == Language::D { + out.write(" function"); + is_functors = true; + } else { + out.write("("); + } } } } @@ -269,7 +300,11 @@ impl CDecl { // Write the identifier if let Some(ident) = ident { - write!(out, "{}", ident); + if is_functors { + // out.write(" "); + } else { + write!(out, "{}", ident); + } } // Write the right part of declarators after the identifier @@ -286,7 +321,9 @@ impl CDecl { if last_was_pointer { out.write(")"); } - write!(out, "[{}]", constant); + if config.language != Language::D { + write!(out, "[{}]", constant); + } last_was_pointer = false; } @@ -296,7 +333,9 @@ impl CDecl { never_return, } => { if last_was_pointer { - out.write(")"); + if config.language != Language::D { + out.write(")"); + } } out.write("("); @@ -363,6 +402,12 @@ impl CDecl { out.write_fmt(format_args!(" {}", no_return_attr)); } } + if config.language == Language::D && is_functors { + if let Some(ident) = ident { + write!(out, " {}", ident); + } + } + is_functors = false; last_was_pointer = true; } diff --git a/src/bindgen/config.rs b/src/bindgen/config.rs index 31316503..4985b6f1 100644 --- a/src/bindgen/config.rs +++ b/src/bindgen/config.rs @@ -23,6 +23,7 @@ pub enum Language { Cxx, C, Cython, + D, } impl FromStr for Language { @@ -42,6 +43,9 @@ impl FromStr for Language { "C" => Ok(Language::C), "cython" => Ok(Language::Cython), "Cython" => Ok(Language::Cython), + "d" => Ok(Language::D), + "dlang" => Ok(Language::D), + "D" => Ok(Language::D), _ => Err(format!("Unrecognized Language: '{}'.", s)), } } @@ -54,6 +58,7 @@ impl Language { match self { Language::Cxx | Language::C => "typedef", Language::Cython => "ctypedef", + Language::D => "alias", } } } @@ -166,6 +171,7 @@ pub enum DocumentationStyle { C99, Doxy, Cxx, + D, Auto, } @@ -179,6 +185,7 @@ impl FromStr for DocumentationStyle { "cxx" => Ok(DocumentationStyle::Cxx), "c++" => Ok(DocumentationStyle::Cxx), "doxy" => Ok(DocumentationStyle::Doxy), + "dlang" => Ok(DocumentationStyle::D), "auto" => Ok(DocumentationStyle::Auto), _ => Err(format!("Unrecognized documentation style: '{}'.", s)), } diff --git a/src/bindgen/ir/constant.rs b/src/bindgen/ir/constant.rs index ca6499d8..3fcc89d2 100644 --- a/src/bindgen/ir/constant.rs +++ b/src/bindgen/ir/constant.rs @@ -615,6 +615,7 @@ impl Constant { ) { debug_assert!(self.associated_to.is_some()); debug_assert!(config.language == Language::Cxx); + debug_assert!(config.language == Language::D); debug_assert!(!associated_to_struct.is_transparent); debug_assert!(config.structure.associated_constants_in_body); debug_assert!(config.constant.allow_static_const); @@ -721,6 +722,11 @@ impl Constant { write!(out, " {} # = ", name); language_backend.write_literal(out, value); } + Language::D => { + write!(out, "enum {} = ", name); + language_backend.write_literal(out, value); + out.write(";"); + } } condition.write_after(config, out); diff --git a/src/bindgen/ir/enumeration.rs b/src/bindgen/ir/enumeration.rs index 8927b8be..dba8c25a 100644 --- a/src/bindgen/ir/enumeration.rs +++ b/src/bindgen/ir/enumeration.rs @@ -732,6 +732,27 @@ impl Enum { write!(out, "{}enum {}", config.style.cython_def(), tag_name); } } + Language::D => { + out.write("enum"); + + if self.annotations.must_use(config) { + if let Some(ref anno) = config.enumeration.must_use { + write!(out, " {}", anno) + } + } + + if let Some(note) = self + .annotations + .deprecated_note(config, DeprecatedNoteKind::Enum) + { + write!(out, " {}", note); + } + + write!(out, " {}", tag_name); + if let Some(prim) = size { + write!(out, " : {}", prim); + } + } } out.open_brace(); @@ -748,7 +769,11 @@ impl Enum { out.close_brace(false); write!(out, " {};", tag_name); } else { - out.close_brace(true); + if config.language != Language::D { + out.close_brace(true); + } else { + out.close_brace(false); + } } // Emit typedef specifying the tag enum's size if necessary. @@ -760,7 +785,7 @@ impl Enum { out.write("#ifndef __cplusplus"); } - if config.language != Language::Cxx { + if config.language != Language::Cxx && config.language != Language::D { out.new_line(); write!(out, "{} {} {};", config.language.typedef(), prim, tag_name); } @@ -784,7 +809,7 @@ impl Enum { ) { match config.language { Language::C if config.style.generate_typedef() => out.write("typedef "), - Language::C | Language::Cxx => {} + Language::C | Language::Cxx | Language::D => {} Language::Cython => out.write(config.style.cython_def()), } diff --git a/src/bindgen/ir/generic_path.rs b/src/bindgen/ir/generic_path.rs index 4610641c..1d183ecb 100644 --- a/src/bindgen/ir/generic_path.rs +++ b/src/bindgen/ir/generic_path.rs @@ -145,15 +145,23 @@ impl GenericParams { out: &mut SourceWriter, with_default: bool, ) { - if !self.0.is_empty() && config.language == Language::Cxx { - out.write("template<"); + if (!self.0.is_empty() && config.language == Language::Cxx) || (!self.0.is_empty() && config.language == Language::D) { + out.write(if config.language == Language::D { + "(" + } else { + "template<" + }); for (i, item) in self.0.iter().enumerate() { if i != 0 { out.write(", "); } match item.ty { GenericParamType::Type => { - write!(out, "typename {}", item.name); + if config.language == Language::D { + write!(out, "{}", item.name); + } else { + write!(out, "typename {}", item.name); + } if let Some(GenericArgument::Type(ref ty)) = item.default { write!(out, " = "); cdecl::write_type(language_backend, out, ty, config); @@ -171,8 +179,14 @@ impl GenericParams { } } } - out.write(">"); - out.new_line(); + out.write(if config.language == Language::D { + ")" + } else { + ">" + }); + if config.language != Language::D { + out.new_line(); + } } } diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index 2d0d692a..2dac0634 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -222,6 +222,57 @@ impl PrimitiveType { } } + pub fn to_repr_d(&self, config: &Config) -> &'static str { + match *self { + PrimitiveType::Void => "void", + PrimitiveType::Bool => "bool", + PrimitiveType::Char => "char", + PrimitiveType::SChar => "byte", + PrimitiveType::UChar => "ubyte", + // NOTE: It'd be nice to use a char32_t, but: + // + // * uchar.h is not present on mac (see #423). + // + // * char32_t isn't required to be compatible with Rust's char, as + // the C++ spec only requires it to be the same size as + // uint_least32_t, which is _not_ guaranteed to be 4-bytes. + // + PrimitiveType::Char32 => "uint", + PrimitiveType::Integer { + kind, + signed, + zeroable: _, + } => match (kind, signed) { + (IntKind::Short, true) => "short", + (IntKind::Short, false) => "ushort", + (IntKind::Int, true) => "int", + (IntKind::Int, false) => "uint", + (IntKind::Long, true) => "long", + (IntKind::Long, false) => "ulong", + (IntKind::LongLong, true) => "long long", + (IntKind::LongLong, false) => "ulong long", + (IntKind::SizeT, true) => "long", + (IntKind::SizeT, false) => "ulong", + (IntKind::Size, true) if config.usize_is_size_t => "long", + (IntKind::Size, false) if config.usize_is_size_t => "ulong", + (IntKind::Size, true) => "long", + (IntKind::Size, false) => "ulong", + (IntKind::B8, true) => "byte", + (IntKind::B8, false) => "ubyte", + (IntKind::B16, true) => "short", + (IntKind::B16, false) => "ushort", + (IntKind::B32, true) => "int", + (IntKind::B32, false) => "uint", + (IntKind::B64, true) => "long", + (IntKind::B64, false) => "ulong", + }, + PrimitiveType::Float => "float", + PrimitiveType::Double => "double", + PrimitiveType::PtrDiffT => "long", + PrimitiveType::VaList => "...", + } + } + fn can_cmp_order(&self) -> bool { !matches!(*self, PrimitiveType::Bool) } diff --git a/src/bindgen/language_backend/clike.rs b/src/bindgen/language_backend/clike.rs index b41a3c46..b14dc0ff 100644 --- a/src/bindgen/language_backend/clike.rs +++ b/src/bindgen/language_backend/clike.rs @@ -99,7 +99,11 @@ impl<'a> CLikeLanguageBackend<'a> { for namespace in namespaces { out.new_line(); if open { - write!(out, "namespace {} {{", namespace) + if self.config.language == Language::D { + write!(out, "extern(C++, `{}`) {{", namespace) + } else { + write!(out, "namespace {} {{", namespace) + } } else { write!(out, "}} // namespace {}", namespace) } @@ -349,17 +353,19 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { write!(out, "{}", f); out.new_line(); } - if let Some(f) = self.config.include_guard() { - out.new_line_if_not_start(); - write!(out, "#ifndef {}", f); - out.new_line(); - write!(out, "#define {}", f); - out.new_line(); - } - if self.config.pragma_once { - out.new_line_if_not_start(); - write!(out, "#pragma once"); - out.new_line(); + if self.config.language != Language::D { + if let Some(f) = self.config.include_guard() { + out.new_line_if_not_start(); + write!(out, "#ifndef {}", f); + out.new_line(); + write!(out, "#define {}", f); + out.new_line(); + } + if self.config.pragma_once { + out.new_line_if_not_start(); + write!(out, "#pragma once"); + out.new_line(); + } } if self.config.include_version { out.new_line_if_not_start(); @@ -425,6 +431,18 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { out.new_line(); } } + Language::D => { + // No add druntime moduule for now (works w/o betterC) + out.write("module cbindgen;"); + out.new_line(); + out.new_line(); + out.write(if self.config.cpp_compat { + "@nogc @safe:" + } else { + "@nogc nothrow @safe:" + }); + out.new_line(); + } _ => {} } } @@ -466,7 +484,13 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { } fn write_enum(&mut self, out: &mut SourceWriter, e: &Enum) { - let size = e.repr.ty.map(|ty| ty.to_primitive().to_repr_c(self.config)); + let size = e.repr.ty.map(|ty| { + if self.config.language == Language::D { + ty.to_primitive().to_repr_d(self.config) + } else { + ty.to_primitive().to_repr_c(self.config) + } + }); let has_data = e.tag.is_some(); let inline_tag_field = Enum::inline_tag_field(&e.repr); let tag_name = e.tag_name(); @@ -475,7 +499,9 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { condition.write_before(self.config, out); self.write_documentation(out, &e.documentation); - self.write_generic_param(out, &e.generic_params); + if self.config.language != Language::D { + self.write_generic_param(out, &e.generic_params); + } // If the enum has data, we need to emit a struct or union for the data // and enum for the tag. C++ supports nested type definitions, so we open @@ -532,7 +558,11 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { out.close_brace(false); write!(out, " {};", e.export_name); } else { - out.close_brace(true); + if self.config.language != Language::D { + out.close_brace(true); + } else { + out.close_brace(false); + } } } @@ -545,7 +575,7 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { self.write_documentation(out, &s.documentation); - if !s.is_enum_variant_body { + if !s.is_enum_variant_body && self.config.language != Language::D { self.write_generic_param(out, &s.generic_params); } @@ -594,8 +624,18 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { write!(out, " {}", s.export_name()); } + if self.config.language == Language::D { + self.write_generic_param(out, &s.generic_params); + } + out.open_brace(); + // D & C struct no have default ctor + if self.config.language == Language::D && !self.config.cpp_compat { + out.write("@disable this();"); + out.new_line(); + } + // Emit the pre_body section, if relevant if let Some(body) = self.config.export.pre_body(&s.path) { out.write_raw_block(body); @@ -628,7 +668,11 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { out.close_brace(false); write!(out, " {};", s.export_name()); } else { - out.close_brace(true); + if self.config.language != Language::D { + out.close_brace(true); + } else { + out.close_brace(false); + } } for constant in &s.associated_constants { @@ -645,7 +689,9 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { self.write_documentation(out, &u.documentation); - self.write_generic_param(out, &u.generic_params); + if self.config.language != Language::D { + self.write_generic_param(out, &u.generic_params); + } // The following results in // C++ or C with Tag as style: @@ -679,6 +725,9 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { write!(out, " {}", u.export_name); } + if self.config.language == Language::D { + self.write_generic_param(out, &u.generic_params); + } out.open_brace(); // Emit the pre_body section, if relevant @@ -699,7 +748,11 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { out.close_brace(false); write!(out, " {};", u.export_name); } else { - out.close_brace(true); + if self.config.language != Language::D { + out.close_brace(true); + } else { + out.close_brace(false); + } } condition.write_after(self.config, out); @@ -711,7 +764,9 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { self.write_documentation(out, &o.documentation); - o.generic_params.write_with_default(self, self.config, out); + if self.config.language != Language::D { + o.generic_params.write_with_default(self, self.config, out); + } if self.generate_typedef() { write!( @@ -721,7 +776,13 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { o.export_name() ); } else { - write!(out, "struct {};", o.export_name()); + if self.config.language == Language::D { + write!(out, "struct {}", o.export_name()); + o.generic_params.write_with_default(self, self.config, out); + out.write(";"); + } else { + write!(out, "struct {};", o.export_name()); + } } condition.write_after(self.config, out); @@ -733,11 +794,22 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { self.write_documentation(out, &t.documentation); - self.write_generic_param(out, &t.generic_params); + if self.config.language != Language::D { + self.write_generic_param(out, &t.generic_params); + } if self.config.language == Language::Cxx { write!(out, "using {} = ", t.export_name()); self.write_type(out, &t.aliased); + } else if self.config.language == Language::D { + if t.is_generic() { + write!(out, "alias {}", t.export_name()); + self.write_generic_param(out, &t.generic_params); + out.write(" = "); + } else { + write!(out, "alias {} = ", t.export_name()); + } + self.write_type(out, &t.aliased); } else { write!(out, "{} ", self.config.language.typedef()); self.write_field( @@ -788,6 +860,9 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { DocumentationStyle::Auto if self.config.language == Language::Cxx => { DocumentationStyle::Cxx } + DocumentationStyle::Auto if self.config.language == Language::D => { + DocumentationStyle::D + } DocumentationStyle::Auto => DocumentationStyle::C, // Fallback if `Language` gets extended. other => other, }; @@ -815,6 +890,7 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { DocumentationStyle::Doxy => out.write(" *"), DocumentationStyle::C99 => out.write("//"), DocumentationStyle::Cxx => out.write("///"), + DocumentationStyle::D => out.write("///"), DocumentationStyle::Auto => unreachable!(), // Auto case should always be covered } @@ -883,6 +959,9 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { write!(out, ")"); } Literal::Cast { ref ty, ref value } => { + if self.config.language == Language::D { + out.write("cast"); + } out.write("("); self.write_type(out, ty); out.write(")"); @@ -902,11 +981,15 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { write!(out, "{}", export_name); } - write!(out, "{{"); - if is_constexpr { - out.push_tab(); + if self.config.language == Language::D { + write!(out, "("); } else { - write!(out, " "); + write!(out, "{{"); + if is_constexpr { + out.push_tab(); + } else { + write!(out, " "); + } } // In C++, same order as defined is required. let ordered_fields = out.bindings().struct_field_names(path); @@ -934,6 +1017,8 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { // TODO: Some C++ versions (c++20?) now support designated // initializers, consider generating them. write!(out, "/* .{} = */ ", ordered_key); + } else if self.config.language == Language::D { + write!(out, "{}: ", ordered_key); } else { write!(out, ".{} = ", ordered_key); } @@ -941,13 +1026,17 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { } } } - if is_constexpr { - out.pop_tab(); - out.new_line(); + if self.config.language == Language::D { + write!(out, ")"); } else { - write!(out, " "); + if is_constexpr { + out.pop_tab(); + out.new_line(); + } else { + write!(out, " "); + } + write!(out, " }}"); } - write!(out, "}}"); } } } @@ -977,6 +1066,16 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { out.new_line(); } + if b.config.language == Language::D { + out.new_line(); + if b.config.cpp_compat { + out.write("extern(C++) {"); + } else { + out.write("extern(C) {"); + } + out.new_line(); + } + if b.config.cpp_compatible_c() { out.write("#endif // __cplusplus"); out.new_line(); @@ -1003,6 +1102,16 @@ impl LanguageBackend for CLikeLanguageBackend<'_> { out.new_line(); } + if b.config.language == Language::D { + out.new_line(); + if b.config.cpp_compat { + out.write("} // extern(C++)"); + } else { + out.write("} // extern(C)"); + } + out.new_line(); + } + if b.config.cpp_compatible_c() { out.write("#endif // __cplusplus"); out.new_line(); diff --git a/src/bindgen/library.rs b/src/bindgen/library.rs index 9d61257f..8af0a010 100644 --- a/src/bindgen/library.rs +++ b/src/bindgen/library.rs @@ -69,7 +69,7 @@ impl Library { SortKey::None => { /* keep input order */ } } - if self.config.language != Language::Cxx { + if self.config.language != Language::Cxx && self.config.language != Language::D { self.instantiate_monomorphs(); } self.remove_excluded(); diff --git a/src/bindgen/writer.rs b/src/bindgen/writer.rs index f36757d2..dbf01137 100644 --- a/src/bindgen/writer.rs +++ b/src/bindgen/writer.rs @@ -159,7 +159,7 @@ impl<'a, F: Write> SourceWriter<'a, F> { pub fn open_brace(&mut self) { match self.bindings.config.language { - Language::Cxx | Language::C => match self.bindings.config.braces { + Language::Cxx | Language::C | Language::D => match self.bindings.config.braces { Braces::SameLine => { self.write(" {"); self.push_tab(); @@ -183,7 +183,7 @@ impl<'a, F: Write> SourceWriter<'a, F> { pub fn close_brace(&mut self, semicolon: bool) { self.pop_tab(); match self.bindings.config.language { - Language::Cxx | Language::C => { + Language::Cxx | Language::C | Language::D => { self.new_line(); if semicolon { self.write("};"); diff --git a/src/main.rs b/src/main.rs index a6a1852c..b699483b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -165,7 +165,7 @@ fn main() { .long("lang") .value_name("LANGUAGE") .help("Specify the language to output bindings in") - .value_parser(["c++", "C++", "c", "C", "cython", "Cython"]), + .value_parser(["c++", "C++", "c", "C", "cython", "Cython", "d", "dlang", "D"]), ) .arg( Arg::new("package-version") diff --git a/tests/expectations/abi_string.d b/tests/expectations/abi_string.d new file mode 100644 index 00000000..12388b85 --- /dev/null +++ b/tests/expectations/abi_string.d @@ -0,0 +1,11 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void c(); + +void c_unwind(); + +} // extern(C) diff --git a/tests/expectations/alias.d b/tests/expectations/alias.d new file mode 100644 index 00000000..6505ed4a --- /dev/null +++ b/tests/expectations/alias.d @@ -0,0 +1,35 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum Status : uint { + Ok, + Err, +} + +struct Dep { + @disable this(); + int a; + float b; +} + +struct Foo(X) { + @disable this(); + X a; + X b; + Dep c; +} + +alias IntFoo = Foo!(int); + +alias DoubleFoo = Foo!(double); + +alias Unit = int; + +alias SpecialStatus = Status; + +extern(C) { + +void root(IntFoo x, DoubleFoo y, Unit z, SpecialStatus w); + +} // extern(C) diff --git a/tests/expectations/annotation.d b/tests/expectations/annotation.d new file mode 100644 index 00000000..7ed18ecb --- /dev/null +++ b/tests/expectations/annotation.d @@ -0,0 +1,69 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum C : uint { + X = 2, + Y, +} + +struct A { + @disable this(); + int m0; +} + +struct B { + @disable this(); + int x; + float y; +} + +enum F_Tag : ubyte { + Foo, + Bar, + Baz, +} + +struct Bar_Body { + @disable this(); + F_Tag tag; + ubyte x; + short y; +} + +union F { + F_Tag tag; + struct { + F_Tag foo_tag; + short foo; + }; + Bar_Body bar; +} + +enum H_Tag : ubyte { + Hello, + There, + Everyone, +} + +struct There_Body { + @disable this(); + ubyte x; + short y; +} + +struct H { + H_Tag tag; + union { + struct { + short hello; + }; + There_Body there; + }; +} + +extern(C) { + +void root(A x, B y, C z, F f, H h); + +} // extern(C) diff --git a/tests/expectations/array.d b/tests/expectations/array.d new file mode 100644 index 00000000..8e5113e9 --- /dev/null +++ b/tests/expectations/array.d @@ -0,0 +1,22 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum Foo_Tag { + A, +} + +struct Foo { + Foo_Tag tag; + union { + struct { + float [20] a; + }; + }; +} + +extern(C) { + +void root(Foo a); + +} // extern(C) diff --git a/tests/expectations/asserted_cast.d b/tests/expectations/asserted_cast.d new file mode 100644 index 00000000..3408d78e --- /dev/null +++ b/tests/expectations/asserted_cast.d @@ -0,0 +1,77 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct I; + +enum H_Tag : ubyte { + H_Foo, + H_Bar, + H_Baz, +} + +struct H_Bar_Body { + @disable this(); + ubyte x; + short y; +} + +struct H { + H_Tag tag; + union { + struct { + short foo; + }; + H_Bar_Body bar; + }; +} + +enum J_Tag : ubyte { + J_Foo, + J_Bar, + J_Baz, +} + +struct J_Bar_Body { + @disable this(); + ubyte x; + short y; +} + +struct J { + J_Tag tag; + union { + struct { + short foo; + }; + J_Bar_Body bar; + }; +} + +enum K_Tag : ubyte { + K_Foo, + K_Bar, + K_Baz, +} + +struct K_Bar_Body { + @disable this(); + K_Tag tag; + ubyte x; + short y; +} + +union K { + K_Tag tag; + struct { + K_Tag foo_tag; + short foo; + }; + K_Bar_Body bar; +} + +extern(C) { + +void foo(H h, I i, J j, K k); + +} // extern(C) diff --git a/tests/expectations/assoc_const_conflict.d b/tests/expectations/assoc_const_conflict.d new file mode 100644 index 00000000..74e888ce --- /dev/null +++ b/tests/expectations/assoc_const_conflict.d @@ -0,0 +1,5 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum Foo_FOO = 42; diff --git a/tests/expectations/assoc_constant.d b/tests/expectations/assoc_constant.d new file mode 100644 index 00000000..e3b6a09a --- /dev/null +++ b/tests/expectations/assoc_constant.d @@ -0,0 +1,16 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + +} +enum Foo_GA = 10; +enum Foo_ZO = 3.14; + +extern(C) { + +void root(Foo x); + +} // extern(C) diff --git a/tests/expectations/associated_constant_panic.d b/tests/expectations/associated_constant_panic.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/associated_constant_panic.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/associated_in_body.d b/tests/expectations/associated_in_body.d new file mode 100644 index 00000000..ebf58eab --- /dev/null +++ b/tests/expectations/associated_in_body.d @@ -0,0 +1,26 @@ +module cbindgen; + +@nogc nothrow @safe: + +/// An arbitrary identifier for a native (OS compositor) surface +struct NativeSurfaceId { + @disable this(); + ulong _0; +} +/// A special id for the native surface that is used for debug / profiler overlays. +enum NativeSurfaceId_DEBUG_OVERLAY = NativeSurfaceId(_0: UINT64_MAX); + +struct NativeTileId { + @disable this(); + NativeSurfaceId surface_id; + int x; + int y; +} +/// A special id for the native surface that is used for debug / profiler overlays. +enum NativeTileId_DEBUG_OVERLAY = NativeTileId(surface_id: NativeSurfaceId_DEBUG_OVERLAY, x: 0, y: 0); + +extern(C) { + +void root(AlignFlags flags, NativeTileId tile); + +} // extern(C) diff --git a/tests/expectations/bitfield.d b/tests/expectations/bitfield.d new file mode 100644 index 00000000..4c1e9d6c --- /dev/null +++ b/tests/expectations/bitfield.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct HasBitfields { + @disable this(); + ulong foo: 8; + ulong bar: 56; +} + +extern(C) { + +void root(const HasBitfields*); + +} // extern(C) diff --git a/tests/expectations/bitflags.d b/tests/expectations/bitflags.d new file mode 100644 index 00000000..defa044b --- /dev/null +++ b/tests/expectations/bitflags.d @@ -0,0 +1,17 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct OutOfLine { + @disable this(); + uint _0; +} + +extern(C) { + +void root(AlignFlags flags, + DebugFlags bigger_flags, + LargeFlags largest_flags, + OutOfLine out_of_line); + +} // extern(C) diff --git a/tests/expectations/body.d b/tests/expectations/body.d new file mode 100644 index 00000000..1f1b5ee0 --- /dev/null +++ b/tests/expectations/body.d @@ -0,0 +1,84 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum MyCLikeEnum { + Foo1, + Bar1, + Baz1, +} + +enum MyCLikeEnum_Prepended { + Foo1_Prepended, + Bar1_Prepended, + Baz1_Prepended, +} + +struct MyFancyStruct { + @disable this(); + int i; +} + +enum MyFancyEnum_Tag { + Foo, + Bar, + Baz, +} + +struct MyFancyEnum { + MyFancyEnum_Tag tag; + union { + struct { + int bar; + }; + struct { + int baz; + }; + }; +} + +union MyUnion { + float f; + uint u; +} + +struct MyFancyStruct_Prepended { + @disable this(); + int i; +} + +enum MyFancyEnum_Prepended_Tag { + Foo_Prepended, + Bar_Prepended, + Baz_Prepended, +} + +struct MyFancyEnum_Prepended { + MyFancyEnum_Prepended_Tag tag; + union { + struct { + int bar_prepended; + }; + struct { + int baz_prepended; + }; + }; +} + +union MyUnion_Prepended { + float f; + uint u; +} + +extern(C) { + +void root(MyFancyStruct s, + MyFancyEnum e, + MyCLikeEnum c, + MyUnion u, + MyFancyStruct_Prepended sp, + MyFancyEnum_Prepended ep, + MyCLikeEnum_Prepended cp, + MyUnion_Prepended up); + +} // extern(C) diff --git a/tests/expectations/box.d b/tests/expectations/box.d new file mode 100644 index 00000000..6f179c8c --- /dev/null +++ b/tests/expectations/box.d @@ -0,0 +1,22 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct NotReprC(T = void); + +alias Foo = NotReprC!(int*); + +struct MyStruct { + @disable this(); + int *number; +} + +extern(C) { + +void root(const Foo *a, const MyStruct *with_box); + +void drop_box(int *x); + +void drop_box_opt(int *x); + +} // extern(C) diff --git a/tests/expectations/cdecl.d b/tests/expectations/cdecl.d new file mode 100644 index 00000000..e6c82c2d --- /dev/null +++ b/tests/expectations/cdecl.d @@ -0,0 +1,41 @@ +module cbindgen; + +@nogc nothrow @safe: + +alias A = void function(); + +alias B = void function(); + +alias C = bool function(int, int); + +alias D = bool function function(int)(float); + +alias E = const int([16] * function()); + +alias F = const int*; + +alias G = const int*const *; + +alias H = int*const *; + +alias I = const int([16] *); + +alias J = double function(float); + +alias K = int[16] ; + +alias L = const int*[16] ; + +alias M = bool function[16] (int, int); + +alias N = void function[16] (int, int); + +alias P = void function(int named1st, bool, bool named3rd, int _); + +extern(C) { + +void function() O(); + +void root(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, P p); + +} // extern(C) diff --git a/tests/expectations/cell.d b/tests/expectations/cell.d new file mode 100644 index 00000000..716f21ff --- /dev/null +++ b/tests/expectations/cell.d @@ -0,0 +1,20 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct NotReprC(T = void); + +struct RefCell(T = void); + +alias Foo = NotReprC!(RefCell!(int)); + +struct MyStruct { + @disable this(); + int number; +} + +extern(C) { + +void root(const Foo *a, const MyStruct *with_cell); + +} // extern(C) diff --git a/tests/expectations/cfg.d b/tests/expectations/cfg.d new file mode 100644 index 00000000..880e4948 --- /dev/null +++ b/tests/expectations/cfg.d @@ -0,0 +1,76 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum BarType : uint { + A, + B, + C, +} + +enum FooType : uint { + A, + B, + C, +} + +struct FooHandle { + @disable this(); + FooType ty; + int x; + float y; +} + +enum C_Tag : ubyte { + C1, + C2, + C3, + C5, +} + +struct C5_Body { + @disable this(); + C_Tag tag; + int int_; +} + +union C { + C_Tag tag; + C5_Body c5; +} + +struct BarHandle { + @disable this(); + BarType ty; + int x; + float y; +} + +struct ConditionalField { + @disable this(); + int field; +} + +struct Normal { + @disable this(); + int x; + float y; +} + +extern(C) { + +extern int [2] global_array_with_different_sizes; + +extern int [1] global_array_with_different_sizes; + +void root(FooHandle a, C c); + +void root(BarHandle a, C c); + +void cond(ConditionalField a); + +extern int foo(); + +extern void bar(Normal a); + +} // extern(C) diff --git a/tests/expectations/cfg_2.d b/tests/expectations/cfg_2.d new file mode 100644 index 00000000..4f968f3c --- /dev/null +++ b/tests/expectations/cfg_2.d @@ -0,0 +1,33 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum DEFAULT_X = 8; + +enum DEFAULT_X = 42; + +struct Foo { + @disable this(); + int x; +} + +struct Bar { + @disable this(); + Foo y; +} + +struct Bar { + @disable this(); + Foo z; +} + +struct Root { + @disable this(); + Bar w; +} + +extern(C) { + +void root(Root a); + +} // extern(C) diff --git a/tests/expectations/cfg_field.d b/tests/expectations/cfg_field.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/cfg_field.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/char.d b/tests/expectations/char.d new file mode 100644 index 00000000..4de849ba --- /dev/null +++ b/tests/expectations/char.d @@ -0,0 +1,14 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + uint a; +} + +extern(C) { + +void root(Foo a); + +} // extern(C) diff --git a/tests/expectations/const_conflict.d b/tests/expectations/const_conflict.d new file mode 100644 index 00000000..74e888ce --- /dev/null +++ b/tests/expectations/const_conflict.d @@ -0,0 +1,5 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum Foo_FOO = 42; diff --git a/tests/expectations/const_generics.d b/tests/expectations/const_generics.d new file mode 100644 index 00000000..0e5d74e6 --- /dev/null +++ b/tests/expectations/const_generics.d @@ -0,0 +1,19 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum TITLE_SIZE = 80; + +alias CArrayString(ulong CAP) = byte[CAP] ; + +struct Book { + @disable this(); + CArrayString!(TITLE_SIZE) title; + CArrayString!(40) author; +} + +extern(C) { + +void root(Book *a); + +} // extern(C) diff --git a/tests/expectations/const_generics_arrayvec.d b/tests/expectations/const_generics_arrayvec.d new file mode 100644 index 00000000..85eab3e4 --- /dev/null +++ b/tests/expectations/const_generics_arrayvec.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct ArrayVec(T, ulong CAP) { + @disable this(); + T [CAP] xs; + uint len; +} + +extern(C) { + +int push(ArrayVec!(ubyte*, 100) *v, ubyte *elem); + +} // extern(C) diff --git a/tests/expectations/const_generics_bool.d b/tests/expectations/const_generics_bool.d new file mode 100644 index 00000000..19fed2bf --- /dev/null +++ b/tests/expectations/const_generics_bool.d @@ -0,0 +1,32 @@ +module cbindgen; + +@nogc nothrow @safe: + +alias Str = const char*; + +struct HashTable(K, V, bool IS_MAP) { + @disable this(); + ulong num_buckets; + ulong capacity; + ubyte *occupied; + K *keys; + V *vals; +} + +alias MySet = HashTable!(Str, char, false); + +alias SetCallback = void function(Str key); + +alias MapCallback = void function(Str key, ulong val); + +extern(C) { + +MySet *new_set(); + +void set_for_each(const MySet *set, SetCallback callback); + +HashTable!(Str, ulong, true) *new_map(); + +void map_for_each(const HashTable!(Str, ulong, true) *map, MapCallback callback); + +} // extern(C) diff --git a/tests/expectations/const_generics_byte.d b/tests/expectations/const_generics_byte.d new file mode 100644 index 00000000..5c99cadb --- /dev/null +++ b/tests/expectations/const_generics_byte.d @@ -0,0 +1,19 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Parser(ubyte OPEN, ubyte CLOSE) { + @disable this(); + ubyte *buf; + ulong len; +} + +extern(C) { + +void init_parens_parser(Parser!(40, 41) *p, ubyte *buf, ulong len); + +void destroy_parens_parser(Parser!(40, 41) *p); + +void init_braces_parser(Parser!(123, 125) *p, ubyte *buf, ulong len); + +} // extern(C) diff --git a/tests/expectations/const_generics_char.d b/tests/expectations/const_generics_char.d new file mode 100644 index 00000000..efad1dff --- /dev/null +++ b/tests/expectations/const_generics_char.d @@ -0,0 +1,16 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct TakeUntil(uint V) { + @disable this(); + const ubyte *start; + ulong len; + ulong point; +} + +extern(C) { + +TakeUntil!(0) until_nul(const ubyte *start, ulong len); + +} // extern(C) diff --git a/tests/expectations/const_generics_constant.d b/tests/expectations/const_generics_constant.d new file mode 100644 index 00000000..83c6789a --- /dev/null +++ b/tests/expectations/const_generics_constant.d @@ -0,0 +1,24 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum FONT_WEIGHT_FRACTION_BITS = 6; + +struct FixedPoint(ushort FRACTION_BITS) { + @disable this(); + ushort value; +} + +alias FontWeightFixedPoint = FixedPoint!(FONT_WEIGHT_FRACTION_BITS); + +struct FontWeight { + @disable this(); + FontWeightFixedPoint _0; +} +enum FontWeight_NORMAL = FontWeight(_0: FontWeightFixedPoint(value: (400 << FONT_WEIGHT_FRACTION_BITS))); + +extern(C) { + +void root(FontWeight w); + +} // extern(C) diff --git a/tests/expectations/const_generics_thru.d b/tests/expectations/const_generics_thru.d new file mode 100644 index 00000000..48584239 --- /dev/null +++ b/tests/expectations/const_generics_thru.d @@ -0,0 +1,21 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Inner(ulong N) { + @disable this(); + ubyte [N] bytes; +} + +struct Outer(ulong N) { + @disable this(); + Inner!(N) inner; +} + +extern(C) { + +Outer!(1) one(); + +Outer!(2) two(); + +} // extern(C) diff --git a/tests/expectations/const_transparent.d b/tests/expectations/const_transparent.d new file mode 100644 index 00000000..7f58dd2a --- /dev/null +++ b/tests/expectations/const_transparent.d @@ -0,0 +1,22 @@ +module cbindgen; + +@nogc nothrow @safe: + +alias Wrapper(T) = T; + +alias TransparentStruct = ubyte; +enum TransparentStruct_ASSOC_STRUCT_FOO = 1; +enum TransparentStruct_ASSOC_STRUCT_BAR = 2; +enum TransparentStruct_ASSOC_STRUCT_BAZ = 3; + +alias TransparentTupleStruct = ubyte; + +alias TransparentStructWithErasedField(T) = Wrapper!(T); + +enum STRUCT_FOO = 4; + +enum STRUCT_BAR = 5; + +enum STRUCT_BAZ = 6; + +enum COMPLEX = 7; diff --git a/tests/expectations/constant.d b/tests/expectations/constant.d new file mode 100644 index 00000000..b0f7674c --- /dev/null +++ b/tests/expectations/constant.d @@ -0,0 +1,53 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum FOO = 10; + +enum DELIMITER = ':'; + +enum LEFTCURLY = '{'; + +enum QUOTE = '\''; + +enum TAB = '\t'; + +enum NEWLINE = '\n'; + +enum HEART = U'\U00002764'; + +enum EQUID = U'\U00010083'; + +enum ZOM = 3.14; + +/// A single-line doc comment. +enum POS_ONE = 1; + +/// A +/// multi-line +/// doc +/// comment. +enum NEG_ONE = -1; + +enum SHIFT = 3; + +enum XBOOL = 1; + +enum XFALSE = ((0 << SHIFT) | XBOOL); + +enum XTRUE = (1 << (SHIFT | XBOOL)); + +enum CAST = cast(ubyte)'A'; + +enum DOUBLE_CAST = cast(uint)cast(float)1; + +struct Foo { + @disable this(); + int [FOO] x; +} + +extern(C) { + +void root(Foo x); + +} // extern(C) diff --git a/tests/expectations/constant_big.d b/tests/expectations/constant_big.d new file mode 100644 index 00000000..0e86a414 --- /dev/null +++ b/tests/expectations/constant_big.d @@ -0,0 +1,11 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum UNSIGNED_NEEDS_ULL_SUFFIX = 9223372036854775808ull; + +enum UNSIGNED_DOESNT_NEED_ULL_SUFFIX = 8070450532247928832; + +enum SIGNED_NEEDS_ULL_SUFFIX = -9223372036854775808ull; + +enum SIGNED_DOESNT_NEED_ULL_SUFFIX = -9223372036854775807; diff --git a/tests/expectations/constant_constexpr.d b/tests/expectations/constant_constexpr.d new file mode 100644 index 00000000..a699dc18 --- /dev/null +++ b/tests/expectations/constant_constexpr.d @@ -0,0 +1,19 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum CONSTANT_I64 = 216; + +enum CONSTANT_FLOAT32 = 312.292; + +enum DELIMITER = ':'; + +enum LEFTCURLY = '{'; + +struct Foo { + @disable this(); + int x; +} +enum Foo_CONSTANT_I64_BODY = 216; + +enum SomeFoo = Foo(x: 99); diff --git a/tests/expectations/constant_sort_name.d b/tests/expectations/constant_sort_name.d new file mode 100644 index 00000000..b520ba50 --- /dev/null +++ b/tests/expectations/constant_sort_name.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum B = 0; + +enum A = 0; + +extern(C) { + +extern const ubyte D; + +extern const ubyte C; + +} // extern(C) diff --git a/tests/expectations/constant_sort_none.d b/tests/expectations/constant_sort_none.d new file mode 100644 index 00000000..b520ba50 --- /dev/null +++ b/tests/expectations/constant_sort_none.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum B = 0; + +enum A = 0; + +extern(C) { + +extern const ubyte D; + +extern const ubyte C; + +} // extern(C) diff --git a/tests/expectations/constant_user_defined_type.d b/tests/expectations/constant_user_defined_type.d new file mode 100644 index 00000000..085902f8 --- /dev/null +++ b/tests/expectations/constant_user_defined_type.d @@ -0,0 +1,20 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum E { + V, +} + +struct S { + @disable this(); + ubyte field; +} + +alias A = ubyte; + +enum C1 = S(field: 0); + +enum C2 = V; + +enum C3 = 0; diff --git a/tests/expectations/custom_header.d b/tests/expectations/custom_header.d new file mode 100644 index 00000000..ee46455f --- /dev/null +++ b/tests/expectations/custom_header.d @@ -0,0 +1,9 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void root(); + +} // extern(C) diff --git a/tests/expectations/cython_options.d b/tests/expectations/cython_options.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/cython_options.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/decl_name_conflicting.d b/tests/expectations/decl_name_conflicting.d new file mode 100644 index 00000000..af27ca32 --- /dev/null +++ b/tests/expectations/decl_name_conflicting.d @@ -0,0 +1,19 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum BindingType : uint { + Buffer = 0, + NotBuffer = 1, +} + +struct BindGroupLayoutEntry { + @disable this(); + BindingType ty; +} + +extern(C) { + +void root(BindGroupLayoutEntry entry); + +} // extern(C) diff --git a/tests/expectations/dep_v2.d b/tests/expectations/dep_v2.d new file mode 100644 index 00000000..c1991e63 --- /dev/null +++ b/tests/expectations/dep_v2.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct dep_struct { + @disable this(); + uint x; + double y; +} + +extern(C) { + +uint get_x(const dep_struct *dep_struct); + +} // extern(C) diff --git a/tests/expectations/deprecated.d b/tests/expectations/deprecated.d new file mode 100644 index 00000000..48ccf6cd --- /dev/null +++ b/tests/expectations/deprecated.d @@ -0,0 +1,79 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum DeprecatedEnum : int { + A = 0, +} + +enum DeprecatedEnumWithNote : int { + B = 0, +} + +enum EnumWithDeprecatedVariants : int { + C = 0, + D = 1, + E = 2, + F = 3, +} + +struct DeprecatedStruct { + @disable this(); + int a; +} + +struct DeprecatedStructWithNote { + @disable this(); + int a; +} + +enum EnumWithDeprecatedStructVariants_Tag : ubyte { + Foo, + Bar, + Baz, +} + +struct Bar_Body { + @disable this(); + EnumWithDeprecatedStructVariants_Tag tag; + ubyte x; + short y; +} + +struct Baz_Body { + @disable this(); + EnumWithDeprecatedStructVariants_Tag tag; + ubyte x; + ubyte y; +} + +union EnumWithDeprecatedStructVariants { + EnumWithDeprecatedStructVariants_Tag tag; + struct { + EnumWithDeprecatedStructVariants_Tag foo_tag; + short foo; + }; + Bar_Body bar; + Baz_Body baz; +} + +extern(C) { + +void deprecated_without_note(); + +void deprecated_without_bracket(); + +void deprecated_with_note(); + +void deprecated_with_note_and_since(); + +void deprecated_with_note_which_requires_to_be_escaped(); + +void dummy(DeprecatedEnum a, + DeprecatedEnumWithNote b, + EnumWithDeprecatedVariants c, + DeprecatedStruct d, + DeprecatedStructWithNote e, + EnumWithDeprecatedStructVariants f); + +} // extern(C) diff --git a/tests/expectations/derive_eq.d b/tests/expectations/derive_eq.d new file mode 100644 index 00000000..d4b4c2f6 --- /dev/null +++ b/tests/expectations/derive_eq.d @@ -0,0 +1,49 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + bool a; + int b; +} + +enum Bar_Tag : ubyte { + Baz, + Bazz, + FooNamed, + FooParen, +} + +struct Bazz_Body { + @disable this(); + Bar_Tag tag; + Foo named; +} + +struct FooNamed_Body { + @disable this(); + Bar_Tag tag; + int different; + uint fields; +} + +struct FooParen_Body { + @disable this(); + Bar_Tag tag; + int _0; + Foo _1; +} + +union Bar { + Bar_Tag tag; + Bazz_Body bazz; + FooNamed_Body foo_named; + FooParen_Body foo_paren; +} + +extern(C) { + +Foo root(Bar aBar); + +} // extern(C) diff --git a/tests/expectations/derive_ostream.d b/tests/expectations/derive_ostream.d new file mode 100644 index 00000000..3a71a4de --- /dev/null +++ b/tests/expectations/derive_ostream.d @@ -0,0 +1,94 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum C : uint { + X = 2, + Y, +} + +struct A { + @disable this(); + int _0; +} + +struct B { + @disable this(); + int x; + float y; +} + +struct D { + @disable this(); + ubyte List; + ulong Of; + B Things; +} + +enum F_Tag : ubyte { + Foo, + Bar, + Baz, +} + +struct Bar_Body { + @disable this(); + F_Tag tag; + ubyte x; + short y; +} + +union F { + F_Tag tag; + struct { + F_Tag foo_tag; + short foo; + }; + Bar_Body bar; +} + +enum H_Tag : ubyte { + Hello, + There, + Everyone, +} + +struct There_Body { + @disable this(); + ubyte x; + short y; +} + +struct H { + H_Tag tag; + union { + struct { + short hello; + }; + There_Body there; + }; +} + +enum I_Tag : ubyte { + ThereAgain, + SomethingElse, +} + +struct ThereAgain_Body { + @disable this(); + ubyte x; + short y; +} + +struct I { + I_Tag tag; + union { + ThereAgain_Body there_again; + }; +} + +extern(C) { + +void root(A a, B b, C c, D d, F f, H h, I i); + +} // extern(C) diff --git a/tests/expectations/destructor_and_copy_ctor.d b/tests/expectations/destructor_and_copy_ctor.d new file mode 100644 index 00000000..b1e4a2b5 --- /dev/null +++ b/tests/expectations/destructor_and_copy_ctor.d @@ -0,0 +1,191 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum FillRule : ubyte { + A, + B, +} + +/// This will have a destructor manually implemented via variant_body, and +/// similarly a Drop impl in Rust. +struct OwnedSlice(T) { + @disable this(); + ulong len; + T *ptr; +} + +struct Polygon(LengthPercentage) { + @disable this(); + FillRule fill; + OwnedSlice!(LengthPercentage) coordinates; +} + +enum Foo_Tag : ubyte { + Bar, + Polygon1, + Slice1, + Slice2, + Slice3, + Slice4, +} + +struct Slice3_Body(T) { + @disable this(); + FillRule fill; + OwnedSlice!(T) coords; +} + +struct Slice4_Body(T) { + @disable this(); + FillRule fill; + OwnedSlice!(int) coords; +} + +struct Foo { + Foo_Tag tag; + union { + struct { + Polygon!(T) polygon1; + }; + struct { + OwnedSlice!(T) slice1; + }; + struct { + OwnedSlice!(int) slice2; + }; + Slice3_Body slice3; + Slice4_Body slice4; + }; +} + +enum Baz_Tag : ubyte { + Bar2, + Polygon21, + Slice21, + Slice22, + Slice23, + Slice24, +} + +struct Slice23_Body(T) { + @disable this(); + Baz_Tag tag; + FillRule fill; + OwnedSlice!(T) coords; +} + +struct Slice24_Body(T) { + @disable this(); + Baz_Tag tag; + FillRule fill; + OwnedSlice!(int) coords; +} + +union Baz { + Baz_Tag tag; + struct { + Baz_Tag polygon21_tag; + Polygon!(T) polygon21; + }; + struct { + Baz_Tag slice21_tag; + OwnedSlice!(T) slice21; + }; + struct { + Baz_Tag slice22_tag; + OwnedSlice!(int) slice22; + }; + Slice23_Body slice23; + Slice24_Body slice24; +} + +enum Taz_Tag : ubyte { + Bar3, + Taz1, + Taz3, +} + +union Taz { + Taz_Tag tag; + struct { + Taz_Tag taz1_tag; + int taz1; + }; + struct { + Taz_Tag taz3_tag; + OwnedSlice!(int) taz3; + }; +} + +enum Tazz_Tag : ubyte { + Bar4, + Taz2, +} + +union Tazz { + Tazz_Tag tag; + struct { + Tazz_Tag taz2_tag; + int taz2; + }; +} + +enum Tazzz_Tag : ubyte { + Bar5, + Taz5, +} + +union Tazzz { + Tazzz_Tag tag; + struct { + Tazzz_Tag taz5_tag; + int taz5; + }; +} + +enum Tazzzz_Tag : ubyte { + Taz6, + Taz7, +} + +union Tazzzz { + Tazzzz_Tag tag; + struct { + Tazzzz_Tag taz6_tag; + int taz6; + }; + struct { + Tazzzz_Tag taz7_tag; + uint taz7; + }; +} + +enum Qux_Tag : ubyte { + Qux1, + Qux2, +} + +union Qux { + Qux_Tag tag; + struct { + Qux_Tag qux1_tag; + int qux1; + }; + struct { + Qux_Tag qux2_tag; + uint qux2; + }; +} + +extern(C) { + +void root(const Foo!(uint) *a, + const Baz!(int) *b, + const Taz *c, + Tazz d, + const Tazzz *e, + const Tazzzz *f, + const Qux *g); + +} // extern(C) diff --git a/tests/expectations/display_list.d b/tests/expectations/display_list.d new file mode 100644 index 00000000..037ecce9 --- /dev/null +++ b/tests/expectations/display_list.d @@ -0,0 +1,51 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Rect { + @disable this(); + float x; + float y; + float w; + float h; +} + +struct Color { + @disable this(); + ubyte r; + ubyte g; + ubyte b; + ubyte a; +} + +enum DisplayItem_Tag : ubyte { + Fill, + Image, + ClearScreen, +} + +struct Fill_Body { + @disable this(); + DisplayItem_Tag tag; + Rect _0; + Color _1; +} + +struct Image_Body { + @disable this(); + DisplayItem_Tag tag; + uint id; + Rect bounds; +} + +union DisplayItem { + DisplayItem_Tag tag; + Fill_Body fill; + Image_Body image; +} + +extern(C) { + +bool push_item(DisplayItem item); + +} // extern(C) diff --git a/tests/expectations/doclength_short.d b/tests/expectations/doclength_short.d new file mode 100644 index 00000000..02dfc41c --- /dev/null +++ b/tests/expectations/doclength_short.d @@ -0,0 +1,20 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +/// The root of all evil. +/// +/// But at least it contains some more documentation as someone would expect +/// from a simple test case like this. Though, this shouldn't appear in the +/// output. +void root(); + +/// A little above the root, and a lot more visible, with a run-on sentence +/// to test going over the first line. +/// +/// Still not here, though. +void trunk(); + +} // extern(C) diff --git a/tests/expectations/docstyle_auto.d b/tests/expectations/docstyle_auto.d new file mode 100644 index 00000000..4efdab29 --- /dev/null +++ b/tests/expectations/docstyle_auto.d @@ -0,0 +1,10 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +/// The root of all evil. +void root(); + +} // extern(C) diff --git a/tests/expectations/docstyle_c99.d b/tests/expectations/docstyle_c99.d new file mode 100644 index 00000000..4efdab29 --- /dev/null +++ b/tests/expectations/docstyle_c99.d @@ -0,0 +1,10 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +/// The root of all evil. +void root(); + +} // extern(C) diff --git a/tests/expectations/docstyle_doxy.d b/tests/expectations/docstyle_doxy.d new file mode 100644 index 00000000..4efdab29 --- /dev/null +++ b/tests/expectations/docstyle_doxy.d @@ -0,0 +1,10 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +/// The root of all evil. +void root(); + +} // extern(C) diff --git a/tests/expectations/documentation.d b/tests/expectations/documentation.d new file mode 100644 index 00000000..4ba0abcc --- /dev/null +++ b/tests/expectations/documentation.d @@ -0,0 +1,30 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +/// Some docs. +extern const uint FOO; + +/// The root of all evil. +/// +/// But at least it contains some more documentation as someone would expect +/// from a simple test case like this. +/// +/// # Hint +/// +/// Always ensure that everything is properly documented, even if you feel lazy. +/// **Sometimes** it is also helpful to include some markdown formatting. +/// +/// //////////////////////////////////////////////////////////////////////////// +/// +/// Attention: +/// +/// Rust is going to trim all leading `/` symbols. If you want to use them as a +/// marker you need to add at least a single whitespace inbetween the tripple +/// slash doc-comment marker and the rest. +/// +void root(); + +} // extern(C) diff --git a/tests/expectations/documentation_attr.d b/tests/expectations/documentation_attr.d new file mode 100644 index 00000000..40db79aa --- /dev/null +++ b/tests/expectations/documentation_attr.d @@ -0,0 +1,21 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +///With doc attr, each attr contribute to one line of document +///like this one with a new line character at its end +///and this one as well. So they are in the same paragraph +/// +///Line ends with one new line should not break +/// +///Line ends with two spaces and a new line +///should break to next line +/// +///Line ends with two new lines +/// +///Should break to next paragraph +void root(); + +} // extern(C) diff --git a/tests/expectations/enum.d b/tests/expectations/enum.d new file mode 100644 index 00000000..61aeebcd --- /dev/null +++ b/tests/expectations/enum.d @@ -0,0 +1,229 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum A : ulong { + a1 = 0, + a2 = 2, + a3, + a4 = 5, +} + +enum B : uint { + b1 = 0, + b2 = 2, + b3, + b4 = 5, +} + +enum C : ushort { + c1 = 0, + c2 = 2, + c3, + c4 = 5, +} + +enum D : ubyte { + d1 = 0, + d2 = 2, + d3, + d4 = 5, +} + +enum E : ulong { + e1 = 0, + e2 = 2, + e3, + e4 = 5, +} + +enum F : long { + f1 = 0, + f2 = 2, + f3, + f4 = 5, +} + +enum L { + l1, + l2, + l3, + l4, +} + +enum M : byte { + m1 = -1, + m2 = 0, + m3 = 1, +} + +enum N { + n1, + n2, + n3, + n4, +} + +enum O : byte { + o1, + o2, + o3, + o4, +} + +struct J; + +struct K; + +struct Opaque; + +enum G_Tag : ubyte { + Foo, + Bar, + Baz, +} + +struct Bar_Body { + @disable this(); + G_Tag tag; + ubyte x; + short y; +} + +union G { + G_Tag tag; + struct { + G_Tag foo_tag; + short foo; + }; + Bar_Body bar; +} + +enum H_Tag { + H_Foo, + H_Bar, + H_Baz, +} + +struct H_Bar_Body { + @disable this(); + ubyte x; + short y; +} + +struct H { + H_Tag tag; + union { + struct { + short foo; + }; + H_Bar_Body bar; + }; +} + +enum I_Tag : ubyte { + I_Foo, + I_Bar, + I_Baz, +} + +struct I_Bar_Body { + @disable this(); + ubyte x; + short y; +} + +struct I { + I_Tag tag; + union { + struct { + short foo; + }; + I_Bar_Body bar; + }; +} + +enum P_Tag : ubyte { + P0, + P1, +} + +struct P1_Body { + @disable this(); + ubyte _0; + ubyte _1; + ubyte _2; +} + +struct P { + P_Tag tag; + union { + struct { + ubyte p0; + }; + P1_Body p1; + }; +} + +enum Q_Tag { + Ok, + Err, +} + +struct Q { + Q_Tag tag; + union { + struct { + uint *ok; + }; + struct { + uint err; + }; + }; +} + +enum R_Tag { + IRFoo, + IRBar, + IRBaz, +} + +struct IRBar_Body { + @disable this(); + ubyte x; + short y; +} + +struct R { + R_Tag tag; + union { + struct { + short IRFoo; + }; + IRBar_Body IRBar; + }; +} + +extern(C) { + +void root(Opaque *opaque, + A a, + B b, + C c, + D d, + E e, + F f, + G g, + H h, + I i, + J j, + K k, + L l, + M m, + N n, + O o, + P p, + Q q, + R r); + +} // extern(C) diff --git a/tests/expectations/enum_discriminant.d b/tests/expectations/enum_discriminant.d new file mode 100644 index 00000000..6bd53a20 --- /dev/null +++ b/tests/expectations/enum_discriminant.d @@ -0,0 +1,21 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum FOUR = 4; + +enum E : byte { + A = 1, + B = -1, + C = (1 + 2), + D = FOUR, + F = 5, + G = cast(byte)54, + H = cast(byte)false, +} + +extern(C) { + +void root(const E*); + +} // extern(C) diff --git a/tests/expectations/enum_self.d b/tests/expectations/enum_self.d new file mode 100644 index 00000000..3e1ef9d6 --- /dev/null +++ b/tests/expectations/enum_self.d @@ -0,0 +1,32 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo(T) { + @disable this(); + const int *something; +} + +enum Bar_Tag : ubyte { + Min, + Max, + Other, +} + +union Bar { + Bar_Tag tag; + struct { + Bar_Tag min_tag; + Foo!(Bar) min; + }; + struct { + Bar_Tag max_tag; + Foo!(Bar) max; + }; +} + +extern(C) { + +void root(Bar b); + +} // extern(C) diff --git a/tests/expectations/euclid.compat.d b/tests/expectations/euclid.compat.d new file mode 100644 index 00000000..4623e044 --- /dev/null +++ b/tests/expectations/euclid.compat.d @@ -0,0 +1,89 @@ +module cbindgen; + +@nogc @safe: + +struct LayoutUnit; + +struct UnknownUnit; + +struct TypedLength(T, Unit) { + T _0; +} + +alias Length(T) = TypedLength!(T, UnknownUnit); + +alias LayoutLength = TypedLength!(float, LayoutUnit); + +struct TypedSideOffsets2D(T, U) { + T top; + T right; + T bottom; + T left; +} + +alias SideOffsets2D(T) = TypedSideOffsets2D!(T, UnknownUnit); + +alias LayoutSideOffsets2D = TypedSideOffsets2D!(float, LayoutUnit); + +struct TypedSize2D(T, U) { + T width; + T height; +} + +alias Size2D(T) = TypedSize2D!(T, UnknownUnit); + +alias LayoutSize2D = TypedSize2D!(float, LayoutUnit); + +struct TypedPoint2D(T, U) { + T x; + T y; +} + +alias Point2D(T) = TypedPoint2D!(T, UnknownUnit); + +alias LayoutPoint2D = TypedPoint2D!(float, LayoutUnit); + +struct TypedRect(T, U) { + TypedPoint2D!(T, U) origin; + TypedSize2D!(T, U) size; +} + +alias Rect(T) = TypedRect!(T, UnknownUnit); + +alias LayoutRect = TypedRect!(float, LayoutUnit); + +struct TypedTransform2D(T, Src, Dst) { + T m11; + T m12; + T m21; + T m22; + T m31; + T m32; +} + +extern(C++) { + +void root(TypedLength!(float, UnknownUnit) length_a, + TypedLength!(float, LayoutUnit) length_b, + Length!(float) length_c, + LayoutLength length_d, + TypedSideOffsets2D!(float, UnknownUnit) side_offsets_a, + TypedSideOffsets2D!(float, LayoutUnit) side_offsets_b, + SideOffsets2D!(float) side_offsets_c, + LayoutSideOffsets2D side_offsets_d, + TypedSize2D!(float, UnknownUnit) size_a, + TypedSize2D!(float, LayoutUnit) size_b, + Size2D!(float) size_c, + LayoutSize2D size_d, + TypedPoint2D!(float, UnknownUnit) point_a, + TypedPoint2D!(float, LayoutUnit) point_b, + Point2D!(float) point_c, + LayoutPoint2D point_d, + TypedRect!(float, UnknownUnit) rect_a, + TypedRect!(float, LayoutUnit) rect_b, + Rect!(float) rect_c, + LayoutRect rect_d, + TypedTransform2D!(float, UnknownUnit, LayoutUnit) transform_a, + TypedTransform2D!(float, LayoutUnit, UnknownUnit) transform_b); + +} // extern(C++) diff --git a/tests/expectations/euclid.d b/tests/expectations/euclid.d new file mode 100644 index 00000000..072e43bc --- /dev/null +++ b/tests/expectations/euclid.d @@ -0,0 +1,95 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct LayoutUnit; + +struct UnknownUnit; + +struct TypedLength(T, Unit) { + @disable this(); + T _0; +} + +alias Length(T) = TypedLength!(T, UnknownUnit); + +alias LayoutLength = TypedLength!(float, LayoutUnit); + +struct TypedSideOffsets2D(T, U) { + @disable this(); + T top; + T right; + T bottom; + T left; +} + +alias SideOffsets2D(T) = TypedSideOffsets2D!(T, UnknownUnit); + +alias LayoutSideOffsets2D = TypedSideOffsets2D!(float, LayoutUnit); + +struct TypedSize2D(T, U) { + @disable this(); + T width; + T height; +} + +alias Size2D(T) = TypedSize2D!(T, UnknownUnit); + +alias LayoutSize2D = TypedSize2D!(float, LayoutUnit); + +struct TypedPoint2D(T, U) { + @disable this(); + T x; + T y; +} + +alias Point2D(T) = TypedPoint2D!(T, UnknownUnit); + +alias LayoutPoint2D = TypedPoint2D!(float, LayoutUnit); + +struct TypedRect(T, U) { + @disable this(); + TypedPoint2D!(T, U) origin; + TypedSize2D!(T, U) size; +} + +alias Rect(T) = TypedRect!(T, UnknownUnit); + +alias LayoutRect = TypedRect!(float, LayoutUnit); + +struct TypedTransform2D(T, Src, Dst) { + @disable this(); + T m11; + T m12; + T m21; + T m22; + T m31; + T m32; +} + +extern(C) { + +void root(TypedLength!(float, UnknownUnit) length_a, + TypedLength!(float, LayoutUnit) length_b, + Length!(float) length_c, + LayoutLength length_d, + TypedSideOffsets2D!(float, UnknownUnit) side_offsets_a, + TypedSideOffsets2D!(float, LayoutUnit) side_offsets_b, + SideOffsets2D!(float) side_offsets_c, + LayoutSideOffsets2D side_offsets_d, + TypedSize2D!(float, UnknownUnit) size_a, + TypedSize2D!(float, LayoutUnit) size_b, + Size2D!(float) size_c, + LayoutSize2D size_d, + TypedPoint2D!(float, UnknownUnit) point_a, + TypedPoint2D!(float, LayoutUnit) point_b, + Point2D!(float) point_c, + LayoutPoint2D point_d, + TypedRect!(float, UnknownUnit) rect_a, + TypedRect!(float, LayoutUnit) rect_b, + Rect!(float) rect_c, + LayoutRect rect_d, + TypedTransform2D!(float, UnknownUnit, LayoutUnit) transform_a, + TypedTransform2D!(float, LayoutUnit, UnknownUnit) transform_b); + +} // extern(C) diff --git a/tests/expectations/exclude_generic_monomorph.d b/tests/expectations/exclude_generic_monomorph.d new file mode 100644 index 00000000..c4656424 --- /dev/null +++ b/tests/expectations/exclude_generic_monomorph.d @@ -0,0 +1,18 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Option(T = void); + +alias Foo = ulong; + +struct Bar { + @disable this(); + Option!(Foo) foo; +} + +extern(C) { + +void root(Bar f); + +} // extern(C) diff --git a/tests/expectations/expand.d b/tests/expectations/expand.d new file mode 100644 index 00000000..4497bbef --- /dev/null +++ b/tests/expectations/expand.d @@ -0,0 +1,14 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + +} + +extern(C) { + +void root(Foo a); + +} // extern(C) diff --git a/tests/expectations/expand_default_features.d b/tests/expectations/expand_default_features.d new file mode 100644 index 00000000..a3aca1f2 --- /dev/null +++ b/tests/expectations/expand_default_features.d @@ -0,0 +1,16 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + +} + +extern(C) { + +void extra_debug_fn(); + +void root(Foo a); + +} // extern(C) diff --git a/tests/expectations/expand_dep.d b/tests/expectations/expand_dep.d new file mode 100644 index 00000000..c1991e63 --- /dev/null +++ b/tests/expectations/expand_dep.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct dep_struct { + @disable this(); + uint x; + double y; +} + +extern(C) { + +uint get_x(const dep_struct *dep_struct); + +} // extern(C) diff --git a/tests/expectations/expand_dep_v2.d b/tests/expectations/expand_dep_v2.d new file mode 100644 index 00000000..c1991e63 --- /dev/null +++ b/tests/expectations/expand_dep_v2.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct dep_struct { + @disable this(); + uint x; + double y; +} + +extern(C) { + +uint get_x(const dep_struct *dep_struct); + +} // extern(C) diff --git a/tests/expectations/expand_features.d b/tests/expectations/expand_features.d new file mode 100644 index 00000000..4f913ffc --- /dev/null +++ b/tests/expectations/expand_features.d @@ -0,0 +1,18 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + +} + +extern(C) { + +void extra_debug_fn(); + +void cbindgen(); + +void root(Foo a); + +} // extern(C) diff --git a/tests/expectations/expand_no_default_features.d b/tests/expectations/expand_no_default_features.d new file mode 100644 index 00000000..4497bbef --- /dev/null +++ b/tests/expectations/expand_no_default_features.d @@ -0,0 +1,14 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + +} + +extern(C) { + +void root(Foo a); + +} // extern(C) diff --git a/tests/expectations/export_name.d b/tests/expectations/export_name.d new file mode 100644 index 00000000..b09a56f6 --- /dev/null +++ b/tests/expectations/export_name.d @@ -0,0 +1,11 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void do_the_thing_with_export_name(); + +void do_the_thing_with_unsafe_export_name(); + +} // extern(C) diff --git a/tests/expectations/extern.d b/tests/expectations/extern.d new file mode 100644 index 00000000..3875e0dd --- /dev/null +++ b/tests/expectations/extern.d @@ -0,0 +1,19 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Normal { + @disable this(); + int x; + float y; +} + +extern(C) { + +extern int foo(); + +extern void bar(Normal a); + +extern int baz(); + +} // extern(C) diff --git a/tests/expectations/extern_2.d b/tests/expectations/extern_2.d new file mode 100644 index 00000000..7f3c3533 --- /dev/null +++ b/tests/expectations/extern_2.d @@ -0,0 +1,11 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void first(); + +void second(); + +} // extern(C) diff --git a/tests/expectations/external_workspace_child.d b/tests/expectations/external_workspace_child.d new file mode 100644 index 00000000..401f2fbe --- /dev/null +++ b/tests/expectations/external_workspace_child.d @@ -0,0 +1,14 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct ExtType { + @disable this(); + uint data; +} + +extern(C) { + +void consume_ext(ExtType _ext); + +} // extern(C) diff --git a/tests/expectations/fns.d b/tests/expectations/fns.d new file mode 100644 index 00000000..27dba558 --- /dev/null +++ b/tests/expectations/fns.d @@ -0,0 +1,20 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Fns { + @disable this(); + void function() noArgs; + void function(int) anonymousArg; + int function() returnsNumber; + byte function(int first, short snd) namedArgs; + byte function(int _, short named, long _1) namedArgsWildcards; +} + +extern(C) { + +void root(Fns _fns); + +void no_return(); + +} // extern(C) diff --git a/tests/expectations/forward_declaration.d b/tests/expectations/forward_declaration.d new file mode 100644 index 00000000..5ff10a57 --- /dev/null +++ b/tests/expectations/forward_declaration.d @@ -0,0 +1,34 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct StructInfo { + @disable this(); + const TypeInfo *const *fields; + ulong num_fields; +} + +enum TypeData_Tag { + Primitive, + Struct, +} + +struct TypeData { + TypeData_Tag tag; + union { + struct { + StructInfo struct_; + }; + }; +} + +struct TypeInfo { + @disable this(); + TypeData data; +} + +extern(C) { + +void root(TypeInfo x); + +} // extern(C) diff --git a/tests/expectations/function_args.d b/tests/expectations/function_args.d new file mode 100644 index 00000000..e85de831 --- /dev/null +++ b/tests/expectations/function_args.d @@ -0,0 +1,13 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void unnamed(const ulong*); + +void pointer_test(const ulong *a); + +void print_from_rust(); + +} // extern(C) diff --git a/tests/expectations/function_noreturn.d b/tests/expectations/function_noreturn.d new file mode 100644 index 00000000..605bd408 --- /dev/null +++ b/tests/expectations/function_noreturn.d @@ -0,0 +1,16 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Example { + @disable this(); + void function(ulong, ulong) f; +} + +extern(C) { + +void loop_forever(); + +ubyte normal_return(Example arg, void function(ubyte) other); + +} // extern(C) diff --git a/tests/expectations/function_ptr.d b/tests/expectations/function_ptr.d new file mode 100644 index 00000000..0fea1ce6 --- /dev/null +++ b/tests/expectations/function_ptr.d @@ -0,0 +1,13 @@ +module cbindgen; + +@nogc nothrow @safe: + +alias MyCallback = void function(ulong a, ulong b); + +alias MyOtherCallback = void function(ulong a, ulong lot, ulong of, ulong args, ulong and_then_some); + +extern(C) { + +void my_function(MyCallback a, MyOtherCallback b); + +} // extern(C) diff --git a/tests/expectations/function_sort_name.d b/tests/expectations/function_sort_name.d new file mode 100644 index 00000000..86c2133e --- /dev/null +++ b/tests/expectations/function_sort_name.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void C(); + +void B(); + +void D(); + +void A(); + +} // extern(C) diff --git a/tests/expectations/function_sort_none.d b/tests/expectations/function_sort_none.d new file mode 100644 index 00000000..86c2133e --- /dev/null +++ b/tests/expectations/function_sort_none.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void C(); + +void B(); + +void D(); + +void A(); + +} // extern(C) diff --git a/tests/expectations/generic_defaults.d b/tests/expectations/generic_defaults.d new file mode 100644 index 00000000..27d9f6bc --- /dev/null +++ b/tests/expectations/generic_defaults.d @@ -0,0 +1,19 @@ +module cbindgen; + +@nogc nothrow @safe: + +alias Foo(T, P = void) = T; + +struct Bar(T, P) { + @disable this(); + Foo!(T) f; + P p; +} + +alias Baz(T) = Foo!(T); + +extern(C) { + +void foo_root(Foo!(short) f, Bar!(int, uint) b, Baz!(long) z); + +} // extern(C) diff --git a/tests/expectations/generic_pointer.d b/tests/expectations/generic_pointer.d new file mode 100644 index 00000000..ce6fdb15 --- /dev/null +++ b/tests/expectations/generic_pointer.d @@ -0,0 +1,18 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo(T) { + @disable this(); + T a; +} + +alias Boo = Foo!(ubyte*); + +extern(C) { + +void root(Boo x); + +void my_function(Foo!(ubyte[4] ) x); + +} // extern(C) diff --git a/tests/expectations/global_attr.d b/tests/expectations/global_attr.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/global_attr.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/global_variable.d b/tests/expectations/global_variable.d new file mode 100644 index 00000000..bb6bb438 --- /dev/null +++ b/tests/expectations/global_variable.d @@ -0,0 +1,11 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +extern char [128] MUT_GLOBAL_ARRAY; + +extern const char [128] CONST_GLOBAL_ARRAY; + +} // extern(C) diff --git a/tests/expectations/ignore.d b/tests/expectations/ignore.d new file mode 100644 index 00000000..1f432cc1 --- /dev/null +++ b/tests/expectations/ignore.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum NO_IGNORE_CONST = 0; + +enum NoIgnoreStructWithImpl_NO_IGNORE_INNER_CONST = 0; + +extern(C) { + +void no_ignore_root(); + +void no_ignore_associated_method(); + +} // extern(C) diff --git a/tests/expectations/include.d b/tests/expectations/include.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/include.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/include_guard.d b/tests/expectations/include_guard.d new file mode 100644 index 00000000..ee46455f --- /dev/null +++ b/tests/expectations/include_guard.d @@ -0,0 +1,9 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void root(); + +} // extern(C) diff --git a/tests/expectations/include_item.d b/tests/expectations/include_item.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/include_item.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/include_specific.d b/tests/expectations/include_specific.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/include_specific.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/infinite_recursion_typedef_monomorph.d b/tests/expectations/infinite_recursion_typedef_monomorph.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/infinite_recursion_typedef_monomorph.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/inner_mod.d b/tests/expectations/inner_mod.d new file mode 100644 index 00000000..90d82235 --- /dev/null +++ b/tests/expectations/inner_mod.d @@ -0,0 +1,14 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + float x; +} + +extern(C) { + +void root(Foo a); + +} // extern(C) diff --git a/tests/expectations/item_types.d b/tests/expectations/item_types.d new file mode 100644 index 00000000..55f92fcb --- /dev/null +++ b/tests/expectations/item_types.d @@ -0,0 +1,11 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum MY_CONST = 4; + +extern(C) { + +void ExternFunction(); + +} // extern(C) diff --git a/tests/expectations/item_types_renamed.d b/tests/expectations/item_types_renamed.d new file mode 100644 index 00000000..55f92fcb --- /dev/null +++ b/tests/expectations/item_types_renamed.d @@ -0,0 +1,11 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum MY_CONST = 4; + +extern(C) { + +void ExternFunction(); + +} // extern(C) diff --git a/tests/expectations/layout.d b/tests/expectations/layout.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/layout.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/layout_aligned_opaque.d b/tests/expectations/layout_aligned_opaque.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/layout_aligned_opaque.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/layout_packed_opaque.d b/tests/expectations/layout_packed_opaque.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/layout_packed_opaque.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/lifetime_arg.d b/tests/expectations/lifetime_arg.d new file mode 100644 index 00000000..e71425d1 --- /dev/null +++ b/tests/expectations/lifetime_arg.d @@ -0,0 +1,28 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct A { + @disable this(); + const int *data; +} + +enum E_Tag { + V, + U, +} + +struct E { + E_Tag tag; + union { + struct { + const ubyte *u; + }; + }; +} + +extern(C) { + +void root(A _a, E _e); + +} // extern(C) diff --git a/tests/expectations/linestyle_cr.d b/tests/expectations/linestyle_cr.d new file mode 100644 index 00000000..73ac378c --- /dev/null +++ b/tests/expectations/linestyle_cr.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Dummy { + @disable this(); + int x; + float y; +} + +extern(C) { + +void root(Dummy d); + +} // extern(C) diff --git a/tests/expectations/linestyle_crlf.d b/tests/expectations/linestyle_crlf.d new file mode 100644 index 00000000..73ac378c --- /dev/null +++ b/tests/expectations/linestyle_crlf.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Dummy { + @disable this(); + int x; + float y; +} + +extern(C) { + +void root(Dummy d); + +} // extern(C) diff --git a/tests/expectations/linestyle_lf.d b/tests/expectations/linestyle_lf.d new file mode 100644 index 00000000..73ac378c --- /dev/null +++ b/tests/expectations/linestyle_lf.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Dummy { + @disable this(); + int x; + float y; +} + +extern(C) { + +void root(Dummy d); + +} // extern(C) diff --git a/tests/expectations/literal_target.d b/tests/expectations/literal_target.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/literal_target.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/mangle.d b/tests/expectations/mangle.d new file mode 100644 index 00000000..c0bde939 --- /dev/null +++ b/tests/expectations/mangle.d @@ -0,0 +1,23 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum Bar { + Bar_Some, + Bar_Thing, +} + +struct Foo(T) { + @disable this(); + T a; +} + +alias Boo = Foo!(ubyte); + +extern(C) { + +void root(Boo x, Bar y); + +void unsafe_root(Boo x, Bar y); + +} // extern(C) diff --git a/tests/expectations/manuallydrop.d b/tests/expectations/manuallydrop.d new file mode 100644 index 00000000..dc82df5b --- /dev/null +++ b/tests/expectations/manuallydrop.d @@ -0,0 +1,26 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct NotReprC(T = void); + +struct Point { + @disable this(); + int x; + int y; +} + +alias Foo = NotReprC!(Point); + +struct MyStruct { + @disable this(); + Point point; +} + +extern(C) { + +void root(const Foo *a, const MyStruct *with_manual_drop); + +void take(Point with_manual_drop); + +} // extern(C) diff --git a/tests/expectations/maybeuninit.d b/tests/expectations/maybeuninit.d new file mode 100644 index 00000000..de6f732b --- /dev/null +++ b/tests/expectations/maybeuninit.d @@ -0,0 +1,18 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct NotReprC(T = void); + +alias Foo = NotReprC!(const int*); + +struct MyStruct { + @disable this(); + const int *number; +} + +extern(C) { + +void root(const Foo *a, const MyStruct *with_maybe_uninit); + +} // extern(C) diff --git a/tests/expectations/mod_2015.d b/tests/expectations/mod_2015.d new file mode 100644 index 00000000..4923cb68 --- /dev/null +++ b/tests/expectations/mod_2015.d @@ -0,0 +1,18 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum EXPORT_ME_TOO = 42; + +struct ExportMe { + @disable this(); + ulong val; +} + +extern(C) { + +void export_me(ExportMe *val); + +void from_really_nested_mod(); + +} // extern(C) diff --git a/tests/expectations/mod_2018.d b/tests/expectations/mod_2018.d new file mode 100644 index 00000000..a956899c --- /dev/null +++ b/tests/expectations/mod_2018.d @@ -0,0 +1,25 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum EXPORT_ME_TOO = 42; + +struct ExportMe { + @disable this(); + ulong val; +} + +struct ExportMe2 { + @disable this(); + ulong val; +} + +extern(C) { + +void export_me(ExportMe *val); + +void export_me_2(ExportMe2*); + +void from_really_nested_mod(); + +} // extern(C) diff --git a/tests/expectations/mod_attr.d b/tests/expectations/mod_attr.d new file mode 100644 index 00000000..bea28775 --- /dev/null +++ b/tests/expectations/mod_attr.d @@ -0,0 +1,43 @@ +#if 0 +DEF FOO = 0 +DEF BAR = 0 +#endif + + +module cbindgen; + +@nogc nothrow @safe: + +#if defined(FOO) +enum FOO = 1; +#endif + +#if defined(BAR) +enum BAR = 2; +#endif + +#if defined(FOO) +struct Foo { + @disable this(); + +} +#endif + +#if defined(BAR) +struct Bar { + @disable this(); + +} +#endif + +extern(C) { + +#if defined(FOO) +void foo(const Foo *foo); +#endif + +#if defined(BAR) +void bar(const Bar *bar); +#endif + +} // extern(C) diff --git a/tests/expectations/mod_path.d b/tests/expectations/mod_path.d new file mode 100644 index 00000000..a4d05971 --- /dev/null +++ b/tests/expectations/mod_path.d @@ -0,0 +1,16 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum EXPORT_ME_TOO = 42; + +struct ExportMe { + @disable this(); + ulong val; +} + +extern(C) { + +void export_me(ExportMe *val); + +} // extern(C) diff --git a/tests/expectations/monomorph_1.d b/tests/expectations/monomorph_1.d new file mode 100644 index 00000000..e75b9f00 --- /dev/null +++ b/tests/expectations/monomorph_1.d @@ -0,0 +1,31 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Bar(T = void); + +struct Foo(T) { + @disable this(); + const T *data; +} + +struct Tuple(T, E) { + @disable this(); + const T *a; + const E *b; +} + +alias Indirection(T) = Tuple!(T, float); + +extern(C) { + +void root(Foo!(int) a, + Foo!(float) b, + Bar!(float) c, + Foo!(Bar!(float)) d, + Bar!(Foo!(float)) e, + Bar!(Bar!(float)) f, + Tuple!(Foo!(float), float) g, + Indirection!(float) h); + +} // extern(C) diff --git a/tests/expectations/monomorph_2.d b/tests/expectations/monomorph_2.d new file mode 100644 index 00000000..f2d93b2d --- /dev/null +++ b/tests/expectations/monomorph_2.d @@ -0,0 +1,21 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct A; + +struct B; + +struct List(T) { + @disable this(); + T *members; + ulong count; +} + +extern(C) { + +void foo(List!(A) a); + +void bar(List!(B) b); + +} // extern(C) diff --git a/tests/expectations/monomorph_3.d b/tests/expectations/monomorph_3.d new file mode 100644 index 00000000..e702cc9d --- /dev/null +++ b/tests/expectations/monomorph_3.d @@ -0,0 +1,29 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Bar(T = void); + +union Foo(T) { + const T *data; +} + +union Tuple(T, E) { + const T *a; + const E *b; +} + +alias Indirection(T) = Tuple!(T, float); + +extern(C) { + +void root(Foo!(int) a, + Foo!(float) b, + Bar!(float) c, + Foo!(Bar!(float)) d, + Bar!(Foo!(float)) e, + Bar!(Bar!(float)) f, + Tuple!(Foo!(float), float) g, + Indirection!(float) h); + +} // extern(C) diff --git a/tests/expectations/must_use.d b/tests/expectations/must_use.d new file mode 100644 index 00000000..17b53d82 --- /dev/null +++ b/tests/expectations/must_use.d @@ -0,0 +1,28 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum MaybeOwnedPtr_Tag : ubyte { + Owned, + None, +} + +struct MaybeOwnedPtr { + MaybeOwnedPtr_Tag tag; + union { + struct { + T *owned; + }; + }; +} + +struct OwnedPtr(T) { + @disable this(); + T *ptr; +} + +extern(C) { + +MaybeOwnedPtr!(int) maybe_consume(OwnedPtr!(int) input); + +} // extern(C) diff --git a/tests/expectations/namespace_constant.d b/tests/expectations/namespace_constant.d new file mode 100644 index 00000000..a2f86b07 --- /dev/null +++ b/tests/expectations/namespace_constant.d @@ -0,0 +1,18 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum FOO = 10; + +enum ZOM = 3.14; + +struct Foo { + @disable this(); + int [FOO] x; +} + +extern(C) { + +void root(Foo x); + +} // extern(C) diff --git a/tests/expectations/namespaces_constant.d b/tests/expectations/namespaces_constant.d new file mode 100644 index 00000000..a2f86b07 --- /dev/null +++ b/tests/expectations/namespaces_constant.d @@ -0,0 +1,18 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum FOO = 10; + +enum ZOM = 3.14; + +struct Foo { + @disable this(); + int [FOO] x; +} + +extern(C) { + +void root(Foo x); + +} // extern(C) diff --git a/tests/expectations/nested_import.d b/tests/expectations/nested_import.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/nested_import.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/no_includes.d b/tests/expectations/no_includes.d new file mode 100644 index 00000000..ee46455f --- /dev/null +++ b/tests/expectations/no_includes.d @@ -0,0 +1,9 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void root(); + +} // extern(C) diff --git a/tests/expectations/non_pub_extern.d b/tests/expectations/non_pub_extern.d new file mode 100644 index 00000000..5cc89edb --- /dev/null +++ b/tests/expectations/non_pub_extern.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +extern const uint FIRST; + +extern const uint RENAMED; + +void first(); + +void renamed(); + +} // extern(C) diff --git a/tests/expectations/nonnull.d b/tests/expectations/nonnull.d new file mode 100644 index 00000000..de091493 --- /dev/null +++ b/tests/expectations/nonnull.d @@ -0,0 +1,24 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Opaque; + +struct Foo(T) { + @disable this(); + float *a; + T *b; + Opaque *c; + T **d; + float **e; + Opaque **f; + T *g; + int *h; + int **i; +} + +extern(C) { + +void root(int *arg, Foo!(ulong) *foo, Opaque **d); + +} // extern(C) diff --git a/tests/expectations/nonnull_attribute.d b/tests/expectations/nonnull_attribute.d new file mode 100644 index 00000000..3dab9002 --- /dev/null +++ b/tests/expectations/nonnull_attribute.d @@ -0,0 +1,48 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Opaque; + +struct References { + @disable this(); + const Opaque *a; + Opaque *b; + const Opaque *c; + Opaque *d; +} + +struct Pointers(T) { + @disable this(); + float *a; + T *b; + Opaque *c; + T **d; + float **e; + Opaque **f; + T *g; + int *h; + int **i; + const T *j; + T *k; +} + +extern(C) { + +void value_arg(References arg); + +void mutltiple_args(int *arg, Pointers!(ulong) *foo, Opaque **d); + +void ref_arg(const Pointers!(ulong) *arg); + +void mut_ref_arg(Pointers!(ulong) *arg); + +void optional_ref_arg(const Pointers!(ulong) *arg); + +void optional_mut_ref_arg(Pointers!(ulong) *arg); + +void nullable_const_ptr(const Pointers!(ulong) *arg); + +void nullable_mut_ptr(Pointers!(ulong) *arg); + +} // extern(C) diff --git a/tests/expectations/nonzero.d b/tests/expectations/nonzero.d new file mode 100644 index 00000000..90090a9e --- /dev/null +++ b/tests/expectations/nonzero.d @@ -0,0 +1,61 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Option(T = void); + +struct NonZeroAliases { + @disable this(); + ubyte a; + ushort b; + uint c; + ulong d; + byte e; + short f; + int g; + long h; + long i; + const Option!(long) *j; +} + +struct NonZeroGenerics { + @disable this(); + ubyte a; + ushort b; + uint c; + ulong d; + byte e; + short f; + int g; + long h; + long i; + const Option!(long) *j; +} + +extern(C) { + +void root_nonzero_aliases(NonZeroAliases test, + ubyte a, + ushort b, + uint c, + ulong d, + byte e, + short f, + int g, + long h, + long i, + const Option!(long) *j); + +void root_nonzero_generics(NonZeroGenerics test, + ubyte a, + ushort b, + uint c, + ulong d, + byte e, + short f, + int g, + long h, + long i, + const Option!(long) *j); + +} // extern(C) diff --git a/tests/expectations/opaque.d b/tests/expectations/opaque.d new file mode 100644 index 00000000..0b6f4f96 --- /dev/null +++ b/tests/expectations/opaque.d @@ -0,0 +1,20 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct HashMap(K = void, V = void, Hasher = void); + +struct Result(T = void, E = void); + +/// Fast hash map used internally. +alias FastHashMap(K, V) = HashMap!(K, V, BuildHasherDefault!(DefaultHasher)); + +alias Foo = FastHashMap!(int, int); + +alias Bar = Result!(Foo); + +extern(C) { + +void root(const Foo *a, const Bar *b); + +} // extern(C) diff --git a/tests/expectations/package_version.d b/tests/expectations/package_version.d new file mode 100644 index 00000000..3a312b74 --- /dev/null +++ b/tests/expectations/package_version.d @@ -0,0 +1,16 @@ +/* Package version: 0.1.0 */ + +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + ulong bar; +} + +extern(C) { + +void doit(const Foo*); + +} // extern(C) diff --git a/tests/expectations/pin.d b/tests/expectations/pin.d new file mode 100644 index 00000000..955944d1 --- /dev/null +++ b/tests/expectations/pin.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct PinTest { + @disable this(); + int *pinned_box; + int *pinned_ref; +} + +extern(C) { + +void root(int *s, PinTest p); + +} // extern(C) diff --git a/tests/expectations/pragma_once.d b/tests/expectations/pragma_once.d new file mode 100644 index 00000000..ee46455f --- /dev/null +++ b/tests/expectations/pragma_once.d @@ -0,0 +1,9 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void root(); + +} // extern(C) diff --git a/tests/expectations/prefix.d b/tests/expectations/prefix.d new file mode 100644 index 00000000..ecbbad69 --- /dev/null +++ b/tests/expectations/prefix.d @@ -0,0 +1,33 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum LEN = 22; + +enum X = (22 << 22); + +enum Y = (X + X); + +alias NamedLenArray = int[LEN] ; + +alias ValuedLenArray = int[22] ; + +enum AbsoluteFontWeight_Tag : ubyte { + Weight, + Normal, + Bold, +} + +union AbsoluteFontWeight { + AbsoluteFontWeight_Tag tag; + struct { + AbsoluteFontWeight_Tag weight_tag; + float weight; + }; +} + +extern(C) { + +void root(NamedLenArray x, ValuedLenArray y, AbsoluteFontWeight z); + +} // extern(C) diff --git a/tests/expectations/prefixed_struct_literal.d b/tests/expectations/prefixed_struct_literal.d new file mode 100644 index 00000000..8b7cb776 --- /dev/null +++ b/tests/expectations/prefixed_struct_literal.d @@ -0,0 +1,18 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + int a; + uint b; +} +enum Foo_FOO = Foo(a: 42, b: 47); + +enum BAR = Foo(a: 42, b: 1337); + +extern(C) { + +void root(Foo x); + +} // extern(C) diff --git a/tests/expectations/prefixed_struct_literal_deep.d b/tests/expectations/prefixed_struct_literal_deep.d new file mode 100644 index 00000000..43583385 --- /dev/null +++ b/tests/expectations/prefixed_struct_literal_deep.d @@ -0,0 +1,23 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Bar { + @disable this(); + int a; +} + +struct Foo { + @disable this(); + int a; + uint b; + Bar bar; +} + +enum VAL = Foo(a: 42, b: 1337, bar: Bar(a: 323)); + +extern(C) { + +void root(Foo x); + +} // extern(C) diff --git a/tests/expectations/ptrs_as_arrays.d b/tests/expectations/ptrs_as_arrays.d new file mode 100644 index 00000000..55249221 --- /dev/null +++ b/tests/expectations/ptrs_as_arrays.d @@ -0,0 +1,17 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void ptr_as_array(uint n, const uint [3] arg, const ulong *v); + +void ptr_as_array1(uint n, const uint [3] arg, ulong [4] v); + +void ptr_as_array2(uint n, uint [] arg, const ulong [] v); + +void ptr_as_array_wrong_syntax(uint *arg, const uint *v, const uint*); + +void ptr_as_array_unnamed(uint*, const uint*); + +} // extern(C) diff --git a/tests/expectations/raw_ident.d b/tests/expectations/raw_ident.d new file mode 100644 index 00000000..ca5218b0 --- /dev/null +++ b/tests/expectations/raw_ident.d @@ -0,0 +1,21 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum Enum : ubyte { + a, + b, +} + +struct Struct { + @disable this(); + Enum field; +} + +extern(C) { + +extern const Enum STATIC; + +void fn(Struct arg); + +} // extern(C) diff --git a/tests/expectations/raw_lines.d b/tests/expectations/raw_lines.d new file mode 100644 index 00000000..ee46455f --- /dev/null +++ b/tests/expectations/raw_lines.d @@ -0,0 +1,9 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void root(); + +} // extern(C) diff --git a/tests/expectations/rename.d b/tests/expectations/rename.d new file mode 100644 index 00000000..9cb863f5 --- /dev/null +++ b/tests/expectations/rename.d @@ -0,0 +1,37 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum H = 10; + +enum E : ubyte { + x = 0, + y = 1, +} + +struct A; + +struct C; + +struct B { + @disable this(); + int x; + float y; +} + +union D { + int x; + float y; +} + +alias F = A; + +enum I = cast(long)cast(F*)10; + +extern(C) { + +extern const int G; + +void root(const A *a, B b, C c, D d, E e, F f); + +} // extern(C) diff --git a/tests/expectations/rename_case.d b/tests/expectations/rename_case.d new file mode 100644 index 00000000..f58b704e --- /dev/null +++ b/tests/expectations/rename_case.d @@ -0,0 +1,19 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void test_camel_case(int fooBar); + +void test_pascal_case(int FooBar); + +void test_snake_case(int foo_bar); + +void test_screaming_snake_case(int FOO_BAR); + +void test_gecko_case(int aFooBar); + +void test_prefix(int prefix_foo_bar); + +} // extern(C) diff --git a/tests/expectations/rename_crate.d b/tests/expectations/rename_crate.d new file mode 100644 index 00000000..1d4f8b9a --- /dev/null +++ b/tests/expectations/rename_crate.d @@ -0,0 +1,49 @@ +#if 0 +DEF DEFINE_FREEBSD = 0 +#endif + + +module cbindgen; + +@nogc nothrow @safe: + +struct Foo { + @disable this(); + int x; +} + +struct RenamedTy { + @disable this(); + ulong y; +} + +#if !defined(DEFINE_FREEBSD) +struct NoExternTy { + @disable this(); + ubyte field; +} +#endif + +#if !defined(DEFINE_FREEBSD) +struct ContainsNoExternTy { + @disable this(); + NoExternTy field; +} +#endif + +#if defined(DEFINE_FREEBSD) +struct ContainsNoExternTy { + @disable this(); + ulong field; +} +#endif + +extern(C) { + +void root(Foo a); + +void renamed_func(RenamedTy a); + +void no_extern_func(ContainsNoExternTy a); + +} // extern(C) diff --git a/tests/expectations/renaming_overrides_prefixing.d b/tests/expectations/renaming_overrides_prefixing.d new file mode 100644 index 00000000..9c6fe59d --- /dev/null +++ b/tests/expectations/renaming_overrides_prefixing.d @@ -0,0 +1,17 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct A; + +struct B { + @disable this(); + int x; + float y; +} + +extern(C) { + +void root(const A *a, B b); + +} // extern(C) diff --git a/tests/expectations/reserved.d b/tests/expectations/reserved.d new file mode 100644 index 00000000..7057f940 --- /dev/null +++ b/tests/expectations/reserved.d @@ -0,0 +1,72 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct A { + @disable this(); + int namespace_; + float float_; +} + +struct B { + @disable this(); + int namespace_; + float float_; +} + +enum C_Tag : ubyte { + D, +} + +struct D_Body { + @disable this(); + int namespace_; + float float_; +} + +struct C { + C_Tag tag; + union { + D_Body d; + }; +} + +enum E_Tag : ubyte { + Double, + Float, +} + +struct E { + E_Tag tag; + union { + struct { + double double_; + }; + struct { + float float_; + }; + }; +} + +enum F_Tag : ubyte { + double_, + float_, +} + +struct F { + F_Tag tag; + union { + struct { + double double_; + }; + struct { + float float_; + }; + }; +} + +extern(C) { + +void root(A a, B b, C c, E e, F f, int namespace_, float float_); + +} // extern(C) diff --git a/tests/expectations/sentinel.d b/tests/expectations/sentinel.d new file mode 100644 index 00000000..184fc0ec --- /dev/null +++ b/tests/expectations/sentinel.d @@ -0,0 +1,45 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum A : ubyte { + A1, + A2, + A3, +} + +enum B : ubyte { + B1, + B2, + B3, +} + +enum C_Tag : ubyte { + C1, + C2, + C3, +} + +struct C1_Body { + @disable this(); + C_Tag tag; + uint a; +} + +struct C2_Body { + @disable this(); + C_Tag tag; + uint b; +} + +union C { + C_Tag tag; + C1_Body c1; + C2_Body c2; +} + +extern(C) { + +void root(A a, B b, C c); + +} // extern(C) diff --git a/tests/expectations/simplify_option_ptr.d b/tests/expectations/simplify_option_ptr.d new file mode 100644 index 00000000..5b9e1aeb --- /dev/null +++ b/tests/expectations/simplify_option_ptr.d @@ -0,0 +1,33 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Opaque; + +struct Option(T = void); + +struct Foo { + @disable this(); + const Opaque *x; + Opaque *y; + void function() z; + void function() zz; +} + +union Bar { + const Opaque *x; + Opaque *y; + void function() z; + void function() zz; +} + +extern(C) { + +void root(const Opaque *a, + Opaque *b, + Foo c, + Bar d, + Option!(Opaque*) *e, + void function(const Opaque*) f); + +} // extern(C) diff --git a/tests/expectations/size_types.d b/tests/expectations/size_types.d new file mode 100644 index 00000000..3b85d69a --- /dev/null +++ b/tests/expectations/size_types.d @@ -0,0 +1,21 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum IE : long { + IV, +} + +enum UE : ulong { + UV, +} + +alias Usize = ulong; + +alias Isize = long; + +extern(C) { + +void root(Usize, Isize, UE, IE); + +} // extern(C) diff --git a/tests/expectations/static.d b/tests/expectations/static.d new file mode 100644 index 00000000..5caa1dae --- /dev/null +++ b/tests/expectations/static.d @@ -0,0 +1,22 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Bar; + +struct Foo { + @disable this(); + +} + +extern(C) { + +extern const int NUMBER; + +extern Foo FOO; + +extern const Bar BAR; + +void root(); + +} // extern(C) diff --git a/tests/expectations/std_lib.d b/tests/expectations/std_lib.d new file mode 100644 index 00000000..85834b1e --- /dev/null +++ b/tests/expectations/std_lib.d @@ -0,0 +1,17 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Option(T = void); + +struct Result(T = void, E = void); + +struct String; + +struct Vec(T = void); + +extern(C) { + +void root(const Vec!(String) *a, const Option!(int) *b, const Result!(int, String) *c); + +} // extern(C) diff --git a/tests/expectations/struct.d b/tests/expectations/struct.d new file mode 100644 index 00000000..ada5e530 --- /dev/null +++ b/tests/expectations/struct.d @@ -0,0 +1,35 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Opaque; + +struct Normal { + @disable this(); + int x; + float y; +} + +struct NormalWithZST { + @disable this(); + int x; + float y; +} + +struct TupleRenamed { + @disable this(); + int m0; + float m1; +} + +struct TupleNamed { + @disable this(); + int x; + float y; +} + +extern(C) { + +void root(Opaque *a, Normal b, NormalWithZST c, TupleRenamed d, TupleNamed e); + +} // extern(C) diff --git a/tests/expectations/struct_literal.d b/tests/expectations/struct_literal.d new file mode 100644 index 00000000..d3b69a61 --- /dev/null +++ b/tests/expectations/struct_literal.d @@ -0,0 +1,25 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Bar; + +struct Foo { + @disable this(); + int a; + uint b; +} +enum Foo_FOO = Foo(a: 42, b: 47); +enum Foo_FOO2 = Foo(a: 42, b: 47); +enum Foo_FOO3 = Foo(a: 42, b: 47); + + +enum BAR = Foo(a: 42, b: 1337); + + + +extern(C) { + +void root(Foo x, Bar bar); + +} // extern(C) diff --git a/tests/expectations/struct_literal_order.d b/tests/expectations/struct_literal_order.d new file mode 100644 index 00000000..aac8278f --- /dev/null +++ b/tests/expectations/struct_literal_order.d @@ -0,0 +1,29 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct ABC { + @disable this(); + float a; + uint b; + uint c; +} +enum ABC_abc = ABC(a: 1.0, b: 2, c: 3); +enum ABC_bac = ABC(a: 1.0, b: 2, c: 3); +enum ABC_cba = ABC(a: 1.0, b: 2, c: 3); + +struct BAC { + @disable this(); + uint b; + float a; + int c; +} +enum BAC_abc = BAC(b: 1, a: 2.0, c: 3); +enum BAC_bac = BAC(b: 1, a: 2.0, c: 3); +enum BAC_cba = BAC(b: 1, a: 2.0, c: 3); + +extern(C) { + +void root(ABC a1, BAC a2); + +} // extern(C) diff --git a/tests/expectations/struct_self.d b/tests/expectations/struct_self.d new file mode 100644 index 00000000..180f322b --- /dev/null +++ b/tests/expectations/struct_self.d @@ -0,0 +1,20 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo(T) { + @disable this(); + const int *something; +} + +struct Bar { + @disable this(); + int something; + Foo!(Bar) subexpressions; +} + +extern(C) { + +void root(Bar b); + +} // extern(C) diff --git a/tests/expectations/style_crash.d b/tests/expectations/style_crash.d new file mode 100644 index 00000000..d89634ea --- /dev/null +++ b/tests/expectations/style_crash.d @@ -0,0 +1,3 @@ +module cbindgen; + +@nogc nothrow @safe: diff --git a/tests/expectations/swift_name.d b/tests/expectations/swift_name.d new file mode 100644 index 00000000..7dd17f74 --- /dev/null +++ b/tests/expectations/swift_name.d @@ -0,0 +1,57 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Opaque; + +struct SelfTypeTestStruct { + @disable this(); + ubyte times; +} + +struct PointerToOpaque { + @disable this(); + Opaque *ptr; +} + +extern(C) { + +void rust_print_hello_world(); + +void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self); + +void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self); + +void SelfTypeTestStruct_should_not_exist_box(SelfTypeTestStruct *self); + +SelfTypeTestStruct *SelfTypeTestStruct_should_not_exist_return_box(); + +void SelfTypeTestStruct_should_exist_annotated_self(SelfTypeTestStruct self); + +void SelfTypeTestStruct_should_exist_annotated_mut_self(SelfTypeTestStruct self); + +void SelfTypeTestStruct_should_exist_annotated_by_name(SelfTypeTestStruct self); + +void SelfTypeTestStruct_should_exist_annotated_mut_by_name(SelfTypeTestStruct self); + +void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self); + +void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self); + +void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct); + +void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct); + +void unnamed_argument(SelfTypeTestStruct*); + +void free_function_should_not_exist_box(SelfTypeTestStruct *boxed); + +void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct); + +void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct); + +PointerToOpaque PointerToOpaque_create(ubyte times); + +void PointerToOpaque_sayHello(PointerToOpaque self); + +} // extern(C) diff --git a/tests/expectations/transform_op.d b/tests/expectations/transform_op.d new file mode 100644 index 00000000..d11569a8 --- /dev/null +++ b/tests/expectations/transform_op.d @@ -0,0 +1,107 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Point(T) { + @disable this(); + T x; + T y; +} + +enum Foo_Tag : ubyte { + Foo, + Bar, + Baz, + Bazz, +} + +struct Foo_Body(T) { + @disable this(); + Foo_Tag tag; + int x; + Point!(T) y; + Point!(float) z; +} + +union Foo { + Foo_Tag tag; + Foo_Body foo; + struct { + Foo_Tag bar_tag; + T bar; + }; + struct { + Foo_Tag baz_tag; + Point!(T) baz; + }; +} + +enum Bar_Tag { + Bar1, + Bar2, + Bar3, + Bar4, +} + +struct Bar1_Body(T) { + @disable this(); + int x; + Point!(T) y; + Point!(float) z; + int function(int) u; +} + +struct Bar { + Bar_Tag tag; + union { + Bar1_Body bar1; + struct { + T bar2; + }; + struct { + Point!(T) bar3; + }; + }; +} + +enum Baz_Tag : ubyte { + Baz1, + Baz2, + Baz3, +} + +union Baz { + Baz_Tag tag; + struct { + Baz_Tag baz1_tag; + Bar!(uint) baz1; + }; + struct { + Baz_Tag baz2_tag; + Point!(int) baz2; + }; +} + +enum Taz_Tag : ubyte { + Taz1, + Taz2, + Taz3, +} + +struct Taz { + Taz_Tag tag; + union { + struct { + Bar!(uint) taz1; + }; + struct { + Baz taz2; + }; + }; +} + +extern(C) { + +void foo(const Foo!(int) *foo, const Bar!(int) *bar, const Baz *baz, const Taz *taz); + +} // extern(C) diff --git a/tests/expectations/transparent.d b/tests/expectations/transparent.d new file mode 100644 index 00000000..667a4805 --- /dev/null +++ b/tests/expectations/transparent.d @@ -0,0 +1,44 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct DummyStruct; + +struct EnumWithAssociatedConstantInImpl; + +alias TransparentComplexWrappingStructTuple = DummyStruct; + +alias TransparentPrimitiveWrappingStructTuple = uint; + +alias TransparentComplexWrappingStructure = DummyStruct; + +alias TransparentPrimitiveWrappingStructure = uint; + +alias TransparentComplexWrapper(T) = DummyStruct; + +alias TransparentPrimitiveWrapper(T) = uint; + +alias TransparentPrimitiveWithAssociatedConstants = uint; +enum TransparentPrimitiveWithAssociatedConstants_ZERO = 0; +enum TransparentPrimitiveWithAssociatedConstants_ONE = 1; + +struct TransparentEmptyStructure { + @disable this(); + +} + +enum EnumWithAssociatedConstantInImpl_TEN = 10; + +extern(C) { + +void root(TransparentComplexWrappingStructTuple a, + TransparentPrimitiveWrappingStructTuple b, + TransparentComplexWrappingStructure c, + TransparentPrimitiveWrappingStructure d, + TransparentComplexWrapper!(int) e, + TransparentPrimitiveWrapper!(int) f, + TransparentPrimitiveWithAssociatedConstants g, + TransparentEmptyStructure h, + EnumWithAssociatedConstantInImpl i); + +} // extern(C) diff --git a/tests/expectations/typedef.d b/tests/expectations/typedef.d new file mode 100644 index 00000000..210e10cf --- /dev/null +++ b/tests/expectations/typedef.d @@ -0,0 +1,17 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo(T, U) { + @disable this(); + T x; + U y; +} + +alias IntFoo(T) = Foo!(int, T); + +extern(C) { + +void root(IntFoo!(int) a); + +} // extern(C) diff --git a/tests/expectations/union.d b/tests/expectations/union.d new file mode 100644 index 00000000..0deacd81 --- /dev/null +++ b/tests/expectations/union.d @@ -0,0 +1,21 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Opaque; + +union Normal { + int x; + float y; +} + +union NormalWithZST { + int x; + float y; +} + +extern(C) { + +void root(Opaque *a, Normal b, NormalWithZST c); + +} // extern(C) diff --git a/tests/expectations/union_self.d b/tests/expectations/union_self.d new file mode 100644 index 00000000..5ba03aff --- /dev/null +++ b/tests/expectations/union_self.d @@ -0,0 +1,19 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct Foo(T) { + @disable this(); + const int *something; +} + +union Bar { + int something; + Foo!(Bar) subexpressions; +} + +extern(C) { + +void root(Bar b); + +} // extern(C) diff --git a/tests/expectations/using_namespaces.d b/tests/expectations/using_namespaces.d new file mode 100644 index 00000000..ee46455f --- /dev/null +++ b/tests/expectations/using_namespaces.d @@ -0,0 +1,9 @@ +module cbindgen; + +@nogc nothrow @safe: + +extern(C) { + +void root(); + +} // extern(C) diff --git a/tests/expectations/va_list.d b/tests/expectations/va_list.d new file mode 100644 index 00000000..703ec923 --- /dev/null +++ b/tests/expectations/va_list.d @@ -0,0 +1,27 @@ +module cbindgen; + +@nogc nothrow @safe: + +alias VaListFnPtr = int function(int count, ...); + +alias VaListFnPtr2 = int function(int count, ...); + +struct Interface(T) { + @disable this(); + T fn1; +} + +extern(C) { + +int va_list_test(int count, ...); + +int va_list_test2(int count, ...); + +void va_list_fn_ptrs(int function(int count, ...) fn1, + int function(int count, ...) fn2, + VaListFnPtr fn3, + VaListFnPtr2 fn4, + Interface!(int function(int count, ...)) fn5, + Interface!(int function(int count, ...)) fn6); + +} // extern(C) diff --git a/tests/expectations/workspace.d b/tests/expectations/workspace.d new file mode 100644 index 00000000..3f7f362e --- /dev/null +++ b/tests/expectations/workspace.d @@ -0,0 +1,16 @@ +module cbindgen; + +@nogc nothrow @safe: + +enum EXT_CONST = 0; + +struct ExtType { + @disable this(); + uint data; +} + +extern(C) { + +void consume_ext(ExtType _ext); + +} // extern(C) diff --git a/tests/expectations/zst.d b/tests/expectations/zst.d new file mode 100644 index 00000000..f77473da --- /dev/null +++ b/tests/expectations/zst.d @@ -0,0 +1,15 @@ +module cbindgen; + +@nogc nothrow @safe: + +struct TraitObject { + @disable this(); + void *data; + void *vtable; +} + +extern(C) { + +void *root(const void *ptr, TraitObject t); + +} // extern(C) diff --git a/tests/tests.rs b/tests/tests.rs index eebabefb..5cc2b504 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -59,6 +59,9 @@ fn run_cbindgen( Language::Cython => { command.arg("--lang").arg("cython"); } + Language::D => { + command.arg("--lang").arg("d"); + } } if package_version { @@ -123,6 +126,7 @@ fn compile( Language::Cxx => env::var("CXX").unwrap_or_else(|_| "g++".to_owned()), Language::C => env::var("CC").unwrap_or_else(|_| "gcc".to_owned()), Language::Cython => env::var("CYTHON").unwrap_or_else(|_| "cython".to_owned()), + Language::D => env::var("DC").unwrap_or_else(|_| "dmd".to_owned()), }; let file_name = cbindgen_output @@ -185,6 +189,17 @@ fn compile( command.arg("-o").arg(&object); command.arg(cbindgen_output); } + Language::D => { + if !skip_warning_as_error { + command.arg("-w"); + } else { + command.arg("-wi"); + } + command.arg("-extern-std=c++17"); + command.arg("-O"); + command.arg("-of").arg(&object); + command.arg("-c").arg(cbindgen_output); + } } println!("Running: {:?}", command); @@ -230,6 +245,7 @@ fn run_compile_test( // is extension-sensitive and won't work on them, so we use implementation files (`.pyx`) // in the test suite. Language::Cython => ".pyx", + Language::D => ".d", }; let skip_warning_as_error = name.rfind(SKIP_WARNING_AS_ERROR_SUFFIX).is_some(); @@ -356,6 +372,16 @@ fn test_file(name: &'static str, filename: &'static str) { &mut HashSet::new(), false, ); + run_compile_test( + name, + test, + tmp_dir, + Language::D, + /* cpp_compat = */ false, + None, + &mut HashSet::new(), + false, + ); // `Style::Both` should be identical to `Style::Tag` for Cython. let mut cbindgen_outputs = HashSet::new();