Browse Source

Fixed the generated C# when an incomplete class is forwarded more than once.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/816/head
realvictorprm 8 years ago committed by Dimitar Dobrev
parent
commit
10c86a2a10
  1. 2
      src/AST/Declaration.cs
  2. 1
      src/CppParser/AST.cpp
  3. 1
      src/CppParser/AST.h
  4. 26
      src/CppParser/Bindings/CLI/AST.cpp
  5. 11
      src/CppParser/Bindings/CLI/AST.h
  6. 12092
      src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs
  7. 8
      src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/Std.cs
  8. 11932
      src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs
  9. 6
      src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/Std.cs
  10. 12724
      src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs
  11. 12228
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs
  12. 9
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/Std.cs
  13. 12104
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs
  14. 9
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu/Std.cs
  15. 12040
      src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs
  16. 6
      src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/Std.cs
  17. 6
      src/CppParser/Parser.cpp
  18. 3
      src/CppParser/Parser.h
  19. 3
      src/Generator/Passes/RenamePass.cs
  20. 25
      src/Generator/Passes/ResolveIncompleteDeclsPass.cs
  21. 7
      src/Parser/ASTConverter.cs
  22. 4
      tests/CSharp/AnotherUnit.h
  23. 16
      tests/CSharp/CSharp.Tests.cs
  24. 28
      tests/CSharp/CSharp.cpp
  25. 14
      tests/CSharp/CSharp.h

2
src/AST/Declaration.cs

@ -317,6 +317,8 @@ namespace CppSharp.AST
public List<Attribute> Attributes { get; private set; } public List<Attribute> Attributes { get; private set; }
public List<Declaration> Redeclarations { get; } = new List<Declaration>();
protected Declaration() protected Declaration()
{ {
Access = AccessSpecifier.Public; Access = AccessSpecifier.Public;

1
src/CppParser/AST.cpp

@ -281,6 +281,7 @@ DEF_STRING(Declaration, Name)
DEF_STRING(Declaration, USR) DEF_STRING(Declaration, USR)
DEF_STRING(Declaration, DebugText) DEF_STRING(Declaration, DebugText)
DEF_VECTOR(Declaration, PreprocessedEntity*, PreprocessedEntities) DEF_VECTOR(Declaration, PreprocessedEntity*, PreprocessedEntities)
DEF_VECTOR(Declaration, Declaration*, Redeclarations)
DeclarationContext::DeclarationContext(DeclarationKind kind) DeclarationContext::DeclarationContext(DeclarationKind kind)
: Declaration(kind) : Declaration(kind)

1
src/CppParser/AST.h

@ -483,6 +483,7 @@ public:
Declaration* completeDeclaration; Declaration* completeDeclaration;
unsigned definitionOrder; unsigned definitionOrder;
VECTOR(PreprocessedEntity*, PreprocessedEntities) VECTOR(PreprocessedEntity*, PreprocessedEntities)
VECTOR(Declaration*, Redeclarations)
void* originalPtr; void* originalPtr;
RawComment* comment; RawComment* comment;
}; };

26
src/CppParser/Bindings/CLI/AST.cpp

@ -1898,6 +1898,26 @@ void CppSharp::Parser::AST::Declaration::ClearPreprocessedEntities()
((::CppSharp::CppParser::AST::Declaration*)NativePtr)->clearPreprocessedEntities(); ((::CppSharp::CppParser::AST::Declaration*)NativePtr)->clearPreprocessedEntities();
} }
CppSharp::Parser::AST::Declaration^ CppSharp::Parser::AST::Declaration::GetRedeclarations(unsigned int i)
{
auto __ret = ((::CppSharp::CppParser::AST::Declaration*)NativePtr)->getRedeclarations(i);
if (__ret == nullptr) return nullptr;
return (__ret == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::Declaration((::CppSharp::CppParser::AST::Declaration*)__ret);
}
void CppSharp::Parser::AST::Declaration::AddRedeclarations(CppSharp::Parser::AST::Declaration^ s)
{
if (ReferenceEquals(s, nullptr))
throw gcnew ::System::ArgumentNullException("s", "Cannot be null because it is a C++ reference (&).");
auto __arg0 = (::CppSharp::CppParser::AST::Declaration*)s->NativePtr;
((::CppSharp::CppParser::AST::Declaration*)NativePtr)->addRedeclarations(__arg0);
}
void CppSharp::Parser::AST::Declaration::ClearRedeclarations()
{
((::CppSharp::CppParser::AST::Declaration*)NativePtr)->clearRedeclarations();
}
CppSharp::Parser::AST::Declaration::operator CppSharp::Parser::AST::Declaration^(CppSharp::Parser::AST::DeclarationKind kind) CppSharp::Parser::AST::Declaration::operator CppSharp::Parser::AST::Declaration^(CppSharp::Parser::AST::DeclarationKind kind)
{ {
auto __arg0 = (::CppSharp::CppParser::AST::DeclarationKind)kind; auto __arg0 = (::CppSharp::CppParser::AST::DeclarationKind)kind;
@ -2096,6 +2116,12 @@ unsigned int CppSharp::Parser::AST::Declaration::PreprocessedEntitiesCount::get(
return __ret; return __ret;
} }
unsigned int CppSharp::Parser::AST::Declaration::RedeclarationsCount::get()
{
auto __ret = ((::CppSharp::CppParser::AST::Declaration*)NativePtr)->getRedeclarationsCount();
return __ret;
}
CppSharp::Parser::AST::DeclarationContext::DeclarationContext(::CppSharp::CppParser::AST::DeclarationContext* native) CppSharp::Parser::AST::DeclarationContext::DeclarationContext(::CppSharp::CppParser::AST::DeclarationContext* native)
: CppSharp::Parser::AST::Declaration((::CppSharp::CppParser::AST::Declaration*)native) : CppSharp::Parser::AST::Declaration((::CppSharp::CppParser::AST::Declaration*)native)
{ {

11
src/CppParser/Bindings/CLI/AST.h

@ -1489,12 +1489,23 @@ namespace CppSharp
unsigned int get(); unsigned int get();
} }
property unsigned int RedeclarationsCount
{
unsigned int get();
}
CppSharp::Parser::AST::PreprocessedEntity^ GetPreprocessedEntities(unsigned int i); CppSharp::Parser::AST::PreprocessedEntity^ GetPreprocessedEntities(unsigned int i);
void AddPreprocessedEntities(CppSharp::Parser::AST::PreprocessedEntity^ s); void AddPreprocessedEntities(CppSharp::Parser::AST::PreprocessedEntity^ s);
void ClearPreprocessedEntities(); void ClearPreprocessedEntities();
CppSharp::Parser::AST::Declaration^ GetRedeclarations(unsigned int i);
void AddRedeclarations(CppSharp::Parser::AST::Declaration^ s);
void ClearRedeclarations();
static operator CppSharp::Parser::AST::Declaration^(CppSharp::Parser::AST::DeclarationKind kind); static operator CppSharp::Parser::AST::Declaration^(CppSharp::Parser::AST::DeclarationKind kind);
protected: protected:

12092
src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs

File diff suppressed because it is too large Load Diff

8
src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/Std.cs

@ -153,7 +153,7 @@ namespace Std
public unsafe partial struct __Internal public unsafe partial struct __Internal
{ {
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
[DllImport("Std-templates", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl, [DllImport("Std-symbols", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZNSt3__19allocatorIcEC2Ev")] EntryPoint="_ZNSt3__19allocatorIcEC2Ev")]
internal static extern void ctorc__N_std_N___1_S_allocator__C_0(global::System.IntPtr instance); internal static extern void ctorc__N_std_N___1_S_allocator__C_0(global::System.IntPtr instance);
} }
@ -1266,7 +1266,7 @@ namespace Std
public unsafe partial struct __Internal public unsafe partial struct __Internal
{ {
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
[DllImport("Std-templates", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl, [DllImport("Std-symbols", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZNSt3__111char_traitsIcE3eofEv")] EntryPoint="_ZNSt3__111char_traitsIcE3eofEv")]
internal static extern int Eofc__N_std_N___1_S_char_traits__C_0(); internal static extern int Eofc__N_std_N___1_S_char_traits__C_0();
} }
@ -1346,12 +1346,12 @@ namespace Std
internal global::Std.__1.CompressedPair.__Internal __r_; internal global::Std.__1.CompressedPair.__Internal __r_;
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
[DllImport("Std-templates", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl, [DllImport("Std-symbols", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev")] EntryPoint="_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev")]
internal static extern void dtorc__N_std_N___1_S_basic_string__C___N_std_N___1_S_char_traits__C___N_std_N___1_S_allocator__C_0(global::System.IntPtr instance); internal static extern void dtorc__N_std_N___1_S_basic_string__C___N_std_N___1_S_char_traits__C___N_std_N___1_S_allocator__C_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
[DllImport("Std-templates", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl, [DllImport("Std-symbols", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strEv")] EntryPoint="_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strEv")]
internal static extern global::System.IntPtr CStrc__N_std_N___1_S_basic_string__C___N_std_N___1_S_char_traits__C___N_std_N___1_S_allocator__C_0(global::System.IntPtr instance); internal static extern global::System.IntPtr CStrc__N_std_N___1_S_basic_string__C___N_std_N___1_S_char_traits__C___N_std_N___1_S_allocator__C_0(global::System.IntPtr instance);
} }

11932
src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs

File diff suppressed because it is too large Load Diff

6
src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/Std.cs

@ -202,21 +202,21 @@ namespace Std
} }
[StructLayout(LayoutKind.Explicit, Size = 12)] [StructLayout(LayoutKind.Explicit, Size = 12)]
public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_BlockContentComment___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1 public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_Declaration___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1
{ {
[FieldOffset(0)] [FieldOffset(0)]
internal global::Std.VectorVal.__Internal _Myval2; internal global::Std.VectorVal.__Internal _Myval2;
} }
[StructLayout(LayoutKind.Explicit, Size = 12)] [StructLayout(LayoutKind.Explicit, Size = 12)]
public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_Parameter___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1 public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_BlockContentComment___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1
{ {
[FieldOffset(0)] [FieldOffset(0)]
internal global::Std.VectorVal.__Internal _Myval2; internal global::Std.VectorVal.__Internal _Myval2;
} }
[StructLayout(LayoutKind.Explicit, Size = 12)] [StructLayout(LayoutKind.Explicit, Size = 12)]
public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_Declaration___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1 public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_Parameter___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1
{ {
[FieldOffset(0)] [FieldOffset(0)]
internal global::Std.VectorVal.__Internal _Myval2; internal global::Std.VectorVal.__Internal _Myval2;

12724
src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs

File diff suppressed because it is too large Load Diff

12228
src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs

File diff suppressed because it is too large Load Diff

9
src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/Std.cs

@ -749,10 +749,13 @@ namespace Std
Marshal.FreeHGlobal(__Instance); Marshal.FreeHGlobal(__Instance);
} }
public string CStr() public string CStr
{ {
var __ret = global::Std.Cxx11.BasicString.__Internal.CStrc__N_std_N___cxx11_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C_0((__Instance + __PointerAdjustment)); get
return Marshal.PtrToStringAnsi(__ret); {
var __ret = global::Std.Cxx11.BasicString.__Internal.CStrc__N_std_N___cxx11_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C_0((__Instance + __PointerAdjustment));
return Marshal.PtrToStringAnsi(__ret);
}
} }
} }

12104
src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs

File diff suppressed because it is too large Load Diff

9
src/CppParser/Bindings/CSharp/x86_64-linux-gnu/Std.cs

@ -740,10 +740,13 @@ namespace Std
Marshal.FreeHGlobal(__Instance); Marshal.FreeHGlobal(__Instance);
} }
public string CStr() public string CStr
{ {
var __ret = global::Std.BasicString.__Internal.CStrc__N_std_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C_0((__Instance + __PointerAdjustment)); get
return Marshal.PtrToStringAnsi(__ret); {
var __ret = global::Std.BasicString.__Internal.CStrc__N_std_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C_0((__Instance + __PointerAdjustment));
return Marshal.PtrToStringAnsi(__ret);
}
} }
} }

12040
src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs

File diff suppressed because it is too large Load Diff

6
src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/Std.cs

@ -202,21 +202,21 @@ namespace Std
} }
[StructLayout(LayoutKind.Explicit, Size = 24)] [StructLayout(LayoutKind.Explicit, Size = 24)]
public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_BlockContentComment___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1 public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_Declaration___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1
{ {
[FieldOffset(0)] [FieldOffset(0)]
internal global::Std.VectorVal.__Internal _Myval2; internal global::Std.VectorVal.__Internal _Myval2;
} }
[StructLayout(LayoutKind.Explicit, Size = 24)] [StructLayout(LayoutKind.Explicit, Size = 24)]
public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_Parameter___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1 public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_BlockContentComment___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1
{ {
[FieldOffset(0)] [FieldOffset(0)]
internal global::Std.VectorVal.__Internal _Myval2; internal global::Std.VectorVal.__Internal _Myval2;
} }
[StructLayout(LayoutKind.Explicit, Size = 24)] [StructLayout(LayoutKind.Explicit, Size = 24)]
public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_Declaration___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1 public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_Parameter___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1
{ {
[FieldOffset(0)] [FieldOffset(0)]
internal global::Std.VectorVal.__Internal _Myval2; internal global::Std.VectorVal.__Internal _Myval2;

6
src/CppParser/Parser.cpp

@ -3489,7 +3489,7 @@ Declaration* Parser::WalkDeclarationDef(clang::Decl* D)
} }
Declaration* Parser::WalkDeclaration(const clang::Decl* D, Declaration* Parser::WalkDeclaration(const clang::Decl* D,
bool CanBeDefinition) bool CanBeDefinition, bool WalkRedecls)
{ {
using namespace clang; using namespace clang;
@ -3541,6 +3541,10 @@ Declaration* Parser::WalkDeclaration(const clang::Decl* D,
auto Class = WalkRecordCXX(RD); auto Class = WalkRecordCXX(RD);
if (WalkRedecls)
for (auto redecl : RD->redecls())
Class->Redeclarations.push_back(WalkDeclaration(redecl, CanBeDefinition, false));
// We store a definition order index into the declarations. // We store a definition order index into the declarations.
// This is needed because declarations are added to their contexts as // This is needed because declarations are added to their contexts as
// soon as they are referenced and we need to know the original order // soon as they are referenced and we need to know the original order

3
src/CppParser/Parser.h

@ -61,7 +61,8 @@ public:
private: private:
// AST traversers // AST traversers
void WalkAST(); void WalkAST();
Declaration* WalkDeclaration(const clang::Decl* D, bool CanBeDefinition = false); Declaration* WalkDeclaration(const clang::Decl* D, bool CanBeDefinition = false,
bool WalkDeclarations = true);
Declaration* WalkDeclarationDef(clang::Decl* D); Declaration* WalkDeclarationDef(clang::Decl* D);
Enumeration* WalkEnum(const clang::EnumDecl* ED); Enumeration* WalkEnum(const clang::EnumDecl* ED);
Enumeration::Item* WalkEnumItem(clang::EnumConstantDecl* ECD); Enumeration::Item* WalkEnumItem(clang::EnumConstantDecl* ECD);

3
src/Generator/Passes/RenamePass.cs

@ -219,7 +219,8 @@ namespace CppSharp.Passes
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
base.VisitClassDecl(@class); if (!base.VisitClassDecl(@class))
return false;
foreach (var property in @class.Properties.OrderByDescending(p => p.Access)) foreach (var property in @class.Properties.OrderByDescending(p => p.Access))
VisitProperty(property); VisitProperty(property);

25
src/Generator/Passes/ResolveIncompleteDeclsPass.cs

@ -1,5 +1,6 @@
using System.Linq; using System.Linq;
using CppSharp.AST; using CppSharp.AST;
using System.Collections.Generic;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
@ -68,8 +69,16 @@ namespace CppSharp.Passes
return; return;
var @class = declaration as Class; var @class = declaration as Class;
if (@class != null && @class.IsOpaque) return; var redecls = @class?.Redeclarations;
if (@class != null && @class.IsOpaque)
{
if (redecls.Count == 0 ||
(redecls.Last() == @class && !redecls.Exists(decl => !decl.IsIncomplete)))
return;
duplicateClasses.Add(@class);
}
declaration.CompleteDeclaration = declaration.CompleteDeclaration =
ASTContext.FindCompleteClass(declaration.QualifiedName); ASTContext.FindCompleteClass(declaration.QualifiedName);
@ -80,5 +89,17 @@ namespace CppSharp.Passes
declaration.Name); declaration.Name);
} }
} }
public override bool VisitASTContext(ASTContext c)
{
base.VisitASTContext(c);
foreach (var duplicateClass in duplicateClasses)
duplicateClass.Namespace.Declarations.Remove(duplicateClass);
return true;
}
private HashSet<Declaration> duplicateClasses = new HashSet<Declaration>();
} }
} }

7
src/Parser/ASTConverter.cs

@ -955,6 +955,13 @@ namespace CppSharp
_decl.OriginalPtr = originalPtr; _decl.OriginalPtr = originalPtr;
NativeObjects.Add(decl); NativeObjects.Add(decl);
for (uint i = 0; i < decl.RedeclarationsCount; i++)
{
var redecl = decl.GetRedeclarations(i);
_decl.Redeclarations.Add(Visit(redecl));
}
} }
public void VisitDeclContext(DeclarationContext ctx, AST.DeclarationContext _ctx) public void VisitDeclContext(DeclarationContext ctx, AST.DeclarationContext _ctx)

4
tests/CSharp/AnotherUnit.h

@ -3,6 +3,10 @@
void DLL_API functionInAnotherUnit(); void DLL_API functionInAnotherUnit();
struct DLL_API ForwardDeclaredStruct;
struct DLL_API DuplicateDeclaredStruct;
template <typename T> template <typename T>
class TemplateInAnotherUnit class TemplateInAnotherUnit
{ {

16
tests/CSharp/CSharp.Tests.cs

@ -706,4 +706,20 @@ public unsafe class CSharpTests : GeneratorTestFixture
Assert.IsNotNull(incompleteStruct); Assert.IsNotNull(incompleteStruct);
Assert.DoesNotThrow(() => CSharp.CSharp.UseIncompleteStruct(incompleteStruct)); Assert.DoesNotThrow(() => CSharp.CSharp.UseIncompleteStruct(incompleteStruct));
} }
[Test]
public void TestForwardDeclaredStruct()
{
var forwardDeclaredStruct = CSharp.CSharp.CreateForwardDeclaredStruct(10);
var i = CSharp.CSharp.UseForwardDeclaredStruct(forwardDeclaredStruct);
Assert.AreEqual(forwardDeclaredStruct.I, i);
}
[Test]
public void TestDuplicateDeclaredIncompleteStruct()
{
var duplicateDeclaredIncompleteStruct = CSharp.CSharp.CreateDuplicateDeclaredStruct(10);
var i = CSharp.CSharp.UseDuplicateDeclaredStruct(duplicateDeclaredIncompleteStruct);
Assert.AreEqual(10, i);
}
} }

28
tests/CSharp/CSharp.cpp

@ -1322,3 +1322,31 @@ DLL_API void useIncompleteStruct(IncompleteStruct * a)
{ {
return; return;
} }
struct DuplicateDeclaredStruct {
int i = 0;
};
DLL_API ForwardDeclaredStruct* createForwardDeclaredStruct(int i)
{
auto ptr = new ForwardDeclaredStruct();
ptr->i = i;
return ptr;
}
DLL_API int useForwardDeclaredStruct(ForwardDeclaredStruct* s)
{
return s->i;
}
DLL_API DuplicateDeclaredStruct* createDuplicateDeclaredStruct(int i)
{
auto ptr = new DuplicateDeclaredStruct();
ptr->i = i;
return ptr;
}
DLL_API int useDuplicateDeclaredStruct(DuplicateDeclaredStruct* s)
{
return s->i;
}

14
tests/CSharp/CSharp.h

@ -1157,4 +1157,16 @@ struct CompleteIncompleteStruct;
typedef struct IncompleteStruct IncompleteStruct; typedef struct IncompleteStruct IncompleteStruct;
DLL_API IncompleteStruct* createIncompleteStruct(); DLL_API IncompleteStruct* createIncompleteStruct();
DLL_API void useIncompleteStruct(IncompleteStruct* a); DLL_API void useIncompleteStruct(IncompleteStruct* a);
struct DLL_API DuplicateDeclaredStruct;
DLL_API DuplicateDeclaredStruct* createDuplicateDeclaredStruct(int i);
DLL_API int useDuplicateDeclaredStruct(DuplicateDeclaredStruct* s);
struct DLL_API ForwardDeclaredStruct {
int i = 0;
};
DLL_API ForwardDeclaredStruct* createForwardDeclaredStruct(int i);
DLL_API int useForwardDeclaredStruct(ForwardDeclaredStruct* s);
Loading…
Cancel
Save