Browse Source

Filled in all missing v-table pointers in record layouts.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/667/head
Dimitar Dobrev 9 years ago
parent
commit
c4c2ef21ce
  1. 18
      src/AST/ClassLayout.cs
  2. 3
      src/AST/Field.cs
  3. 28
      src/AST/LayoutField.cs
  4. 11
      src/Core/Parser/ASTConverter.cs
  5. 13
      src/CppParser/AST.cpp
  6. 8
      src/CppParser/AST.h
  7. 42
      src/CppParser/Bindings/CLI/AST.cpp
  8. 24
      src/CppParser/Bindings/CLI/AST.h
  9. 93
      src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs
  10. 93
      src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs
  11. 93
      src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/AST.cs
  12. 93
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs
  13. 93
      src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/AST.cs
  14. 56
      src/CppParser/Parser.cpp
  15. 3
      src/CppParser/Parser.h
  16. 17
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  17. 110
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  18. 4
      src/Generator/Passes/CheckDuplicatedNamesPass.cs
  19. 4
      src/Generator/Passes/CleanInvalidDeclNamesPass.cs

18
src/AST/ClassLayout.cs

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace CppSharp.AST
{
@ -132,5 +134,19 @@ namespace CppSharp.AST @@ -132,5 +134,19 @@ namespace CppSharp.AST
public int Alignment;
public int Size;
public int DataSize;
public IList<LayoutField> VTablePointers
{
get
{
if (vTablePointers == null)
{
vTablePointers = new List<LayoutField>(Fields.Where(f => f.IsVTablePtr));
}
return vTablePointers;
}
}
private List<LayoutField> vTablePointers;
}
}

3
src/AST/Field.cs

@ -10,8 +10,6 @@ namespace CppSharp.AST @@ -10,8 +10,6 @@ namespace CppSharp.AST
public Class Class { get; set; }
public Expression Expression { get; set; }
public bool IsBitField { get; set; }
public uint BitWidth { get; set; }
@ -31,7 +29,6 @@ namespace CppSharp.AST @@ -31,7 +29,6 @@ namespace CppSharp.AST
{
QualifiedType = field.QualifiedType;
Class = field.Class;
Expression = field.Expression;
IsBitField = field.IsBitField;
BitWidth = field.BitWidth;
}

28
src/AST/LayoutField.cs

@ -1,28 +1,20 @@ @@ -1,28 +1,20 @@
namespace CppSharp.AST
using System;
namespace CppSharp.AST
{
public class LayoutField
{
public LayoutField(uint offset, Field field)
{
Field = field;
Offset = offset;
}
public DeclarationContext Namespace { get; set; }
public uint Offset { get; set; }
public string Name
{
get { return name ?? Field.OriginalName; }
set { name = value; }
}
public Field Field { get; set; }
public QualifiedType QualifiedType { get; set; }
public string Name { get; set; }
public IntPtr FieldPtr { get; set; }
public bool IsVTablePtr { get { return FieldPtr == IntPtr.Zero; } }
public Expression Expression { get; set; }
public override string ToString()
{
return string.Format("{0} | {1}", Offset, Field.OriginalName);
return string.Format("{0} | {1}", Offset, Name);
}
private string name;
}
}

11
src/Core/Parser/ASTConverter.cs

@ -687,7 +687,7 @@ namespace CppSharp @@ -687,7 +687,7 @@ namespace CppSharp
public HashSet<IDisposable> NativeObjects { get; private set; }
public override AST.Declaration Visit(Parser.AST.Declaration decl)
public override AST.Declaration Visit(Declaration decl)
{
if (decl == null)
return null;
@ -1348,8 +1348,13 @@ namespace CppSharp @@ -1348,8 +1348,13 @@ namespace CppSharp
for (uint i = 0; i < layout.FieldsCount; i++)
{
var field = layout.getFields(i);
_layout.Fields.Add(new AST.LayoutField(field.Offset,
(AST.Field) Visit(field.Field)));
var _field = new AST.LayoutField();
_field.Namespace = (AST.DeclarationContext) Visit(field._Namespace);
_field.Offset = field.Offset;
_field.Name = field.Name;
_field.QualifiedType = typeConverter.VisitQualified(field.QualifiedType);
_field.FieldPtr = field.FieldPtr;
_layout.Fields.Add(_field);
}
return _layout;

13
src/CppParser/AST.cpp

@ -189,10 +189,21 @@ VFTableInfo::VFTableInfo(const VFTableInfo& rhs) : VBTableIndex(rhs.VBTableIndex @@ -189,10 +189,21 @@ VFTableInfo::VFTableInfo(const VFTableInfo& rhs) : VBTableIndex(rhs.VBTableIndex
VFPtrOffset(rhs.VFPtrOffset), VFPtrFullOffset(rhs.VFPtrFullOffset),
Layout(rhs.Layout) {}
LayoutField::LayoutField() {}
LayoutField::LayoutField() : _Namespace(0), Offset(0), FieldPtr(0) {}
LayoutField::LayoutField(const LayoutField & other)
: _Namespace(other._Namespace)
, Offset(other.Offset)
, Name(other.Name)
, QualifiedType(other.QualifiedType)
, FieldPtr(other.FieldPtr)
{
}
LayoutField::~LayoutField() {}
DEF_STRING(LayoutField, Name)
ClassLayout::ClassLayout() : ABI(CppAbi::Itanium), HasOwnVFPtr(false),
VBPtrOffset(0), Alignment(0), Size(0), DataSize(0) {}

8
src/CppParser/AST.h

@ -315,15 +315,19 @@ struct CS_API VFTableInfo @@ -315,15 +315,19 @@ struct CS_API VFTableInfo
VTableLayout Layout;
};
class Field;
class DeclarationContext;
class CS_API LayoutField
{
public:
LayoutField();
LayoutField(const LayoutField& other);
~LayoutField();
DeclarationContext* _Namespace;
unsigned Offset;
Field* Field;
STRING(Name)
QualifiedType QualifiedType;
void* FieldPtr;
};
struct CS_API ClassLayout

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

@ -1333,6 +1333,30 @@ void CppSharp::Parser::AST::LayoutField::__Instance::set(System::IntPtr object) @@ -1333,6 +1333,30 @@ void CppSharp::Parser::AST::LayoutField::__Instance::set(System::IntPtr object)
NativePtr = (::CppSharp::CppParser::AST::LayoutField*)object.ToPointer();
}
System::String^ CppSharp::Parser::AST::LayoutField::Name::get()
{
auto __ret = ((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->getName();
if (__ret == nullptr) return nullptr;
return (__ret == 0 ? nullptr : clix::marshalString<clix::E_UTF8>(__ret));
}
void CppSharp::Parser::AST::LayoutField::Name::set(System::String^ s)
{
auto ___arg0 = clix::marshalString<clix::E_UTF8>(s);
auto __arg0 = ___arg0.c_str();
((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->setName(__arg0);
}
CppSharp::Parser::AST::DeclarationContext^ CppSharp::Parser::AST::LayoutField::_Namespace::get()
{
return (((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->_Namespace == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::DeclarationContext((::CppSharp::CppParser::AST::DeclarationContext*)((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->_Namespace);
}
void CppSharp::Parser::AST::LayoutField::_Namespace::set(CppSharp::Parser::AST::DeclarationContext^ value)
{
((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->_Namespace = (::CppSharp::CppParser::AST::DeclarationContext*)value->NativePtr;
}
unsigned int CppSharp::Parser::AST::LayoutField::Offset::get()
{
return ((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->Offset;
@ -1343,14 +1367,24 @@ void CppSharp::Parser::AST::LayoutField::Offset::set(unsigned int value) @@ -1343,14 +1367,24 @@ void CppSharp::Parser::AST::LayoutField::Offset::set(unsigned int value)
((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->Offset = value;
}
CppSharp::Parser::AST::Field^ CppSharp::Parser::AST::LayoutField::Field::get()
CppSharp::Parser::AST::QualifiedType^ CppSharp::Parser::AST::LayoutField::QualifiedType::get()
{
return (&((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->QualifiedType == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::QualifiedType((::CppSharp::CppParser::AST::QualifiedType*)&((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->QualifiedType);
}
void CppSharp::Parser::AST::LayoutField::QualifiedType::set(CppSharp::Parser::AST::QualifiedType^ value)
{
((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->QualifiedType = *(::CppSharp::CppParser::AST::QualifiedType*)value->NativePtr;
}
::System::IntPtr CppSharp::Parser::AST::LayoutField::FieldPtr::get()
{
return (((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->Field == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::Field((::CppSharp::CppParser::AST::Field*)((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->Field);
return ::System::IntPtr(((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->FieldPtr);
}
void CppSharp::Parser::AST::LayoutField::Field::set(CppSharp::Parser::AST::Field^ value)
void CppSharp::Parser::AST::LayoutField::FieldPtr::set(::System::IntPtr value)
{
((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->Field = (::CppSharp::CppParser::AST::Field*)value->NativePtr;
((::CppSharp::CppParser::AST::LayoutField*)NativePtr)->FieldPtr = (void*)value;
}
CppSharp::Parser::AST::ClassLayout::ClassLayout(::CppSharp::CppParser::AST::ClassLayout* native)

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

@ -1046,16 +1046,34 @@ namespace CppSharp @@ -1046,16 +1046,34 @@ namespace CppSharp
~LayoutField();
property System::String^ Name
{
System::String^ get();
void set(System::String^);
}
property CppSharp::Parser::AST::DeclarationContext^ _Namespace
{
CppSharp::Parser::AST::DeclarationContext^ get();
void set(CppSharp::Parser::AST::DeclarationContext^);
}
property unsigned int Offset
{
unsigned int get();
void set(unsigned int);
}
property CppSharp::Parser::AST::Field^ Field
property CppSharp::Parser::AST::QualifiedType^ QualifiedType
{
CppSharp::Parser::AST::QualifiedType^ get();
void set(CppSharp::Parser::AST::QualifiedType^);
}
property ::System::IntPtr FieldPtr
{
CppSharp::Parser::AST::Field^ get();
void set(CppSharp::Parser::AST::Field^);
::System::IntPtr get();
void set(::System::IntPtr);
}
protected:

93
src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs

@ -2987,14 +2987,20 @@ namespace CppSharp @@ -2987,14 +2987,20 @@ namespace CppSharp
public unsafe partial class LayoutField : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 8)]
[StructLayout(LayoutKind.Explicit, Size = 32)]
public partial struct Internal
{
[FieldOffset(0)]
public uint Offset;
public global::System.IntPtr _Namespace;
[FieldOffset(4)]
public global::System.IntPtr Field;
public uint Offset;
[FieldOffset(20)]
public CppSharp.Parser.AST.QualifiedType.Internal QualifiedType;
[FieldOffset(28)]
public global::System.IntPtr FieldPtr;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
@ -3010,6 +3016,16 @@ namespace CppSharp @@ -3010,6 +3016,16 @@ namespace CppSharp
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutFieldD2Ev")]
internal static extern void dtor_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutField7getNameEv")]
internal static extern global::System.IntPtr getName_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutField7setNameEPKc")]
internal static extern void setName_0(global::System.IntPtr instance, global::System.IntPtr s);
}
public global::System.IntPtr __Instance { get; protected set; }
@ -3032,8 +3048,8 @@ namespace CppSharp @@ -3032,8 +3048,8 @@ namespace CppSharp
private static void* __CopyValue(LayoutField.Internal native)
{
var ret = Marshal.AllocHGlobal(8);
*(LayoutField.Internal*) ret = native;
var ret = Marshal.AllocHGlobal(32);
CppSharp.Parser.AST.LayoutField.Internal.cctor_1(ret, new global::System.IntPtr(&native));
return ret.ToPointer();
}
@ -3053,7 +3069,7 @@ namespace CppSharp @@ -3053,7 +3069,7 @@ namespace CppSharp
public LayoutField()
{
__Instance = Marshal.AllocHGlobal(8);
__Instance = Marshal.AllocHGlobal(32);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment));
@ -3061,10 +3077,13 @@ namespace CppSharp @@ -3061,10 +3077,13 @@ namespace CppSharp
public LayoutField(CppSharp.Parser.AST.LayoutField _0)
{
__Instance = Marshal.AllocHGlobal(8);
__Instance = Marshal.AllocHGlobal(32);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
*((LayoutField.Internal*) __Instance) = *((LayoutField.Internal*) _0.__Instance);
if (ReferenceEquals(_0, null))
throw new global::System.ArgumentNullException("_0", "Cannot be null because it is a C++ reference (&).");
var __arg0 = _0.__Instance;
Internal.cctor_1((__Instance + __PointerAdjustment), __arg0);
}
public void Dispose()
@ -3081,6 +3100,40 @@ namespace CppSharp @@ -3081,6 +3100,40 @@ namespace CppSharp
Marshal.FreeHGlobal(__Instance);
}
public string Name
{
get
{
var __ret = Internal.getName_0((__Instance + __PointerAdjustment));
return Marshal.PtrToStringAnsi(__ret);
}
set
{
var __arg0 = Marshal.StringToHGlobalAnsi(value);
Internal.setName_0((__Instance + __PointerAdjustment), __arg0);
Marshal.FreeHGlobal(__arg0);
}
}
public CppSharp.Parser.AST.DeclarationContext _Namespace
{
get
{
CppSharp.Parser.AST.DeclarationContext __result0;
if (((Internal*) __Instance)->_Namespace == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->_Namespace))
__result0 = (CppSharp.Parser.AST.DeclarationContext) CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap[((Internal*) __Instance)->_Namespace];
else __result0 = CppSharp.Parser.AST.DeclarationContext.__CreateInstance(((Internal*) __Instance)->_Namespace);
return __result0;
}
set
{
((Internal*) __Instance)->_Namespace = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
}
}
public uint Offset
{
get
@ -3094,21 +3147,29 @@ namespace CppSharp @@ -3094,21 +3147,29 @@ namespace CppSharp
}
}
public CppSharp.Parser.AST.Field Field
public CppSharp.Parser.AST.QualifiedType QualifiedType
{
get
{
CppSharp.Parser.AST.Field __result0;
if (((Internal*) __Instance)->Field == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.Field.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->Field))
__result0 = (CppSharp.Parser.AST.Field) CppSharp.Parser.AST.Field.NativeToManagedMap[((Internal*) __Instance)->Field];
else __result0 = CppSharp.Parser.AST.Field.__CreateInstance(((Internal*) __Instance)->Field);
return __result0;
return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->QualifiedType);
}
set
{
((Internal*) __Instance)->QualifiedType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
}
}
public global::System.IntPtr FieldPtr
{
get
{
return ((Internal*) __Instance)->FieldPtr;
}
set
{
((Internal*) __Instance)->Field = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
((Internal*) __Instance)->FieldPtr = (global::System.IntPtr) value;
}
}
}

93
src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs

@ -2987,14 +2987,20 @@ namespace CppSharp @@ -2987,14 +2987,20 @@ namespace CppSharp
public unsafe partial class LayoutField : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 8)]
[StructLayout(LayoutKind.Explicit, Size = 44)]
public partial struct Internal
{
[FieldOffset(0)]
public uint Offset;
public global::System.IntPtr _Namespace;
[FieldOffset(4)]
public global::System.IntPtr Field;
public uint Offset;
[FieldOffset(32)]
public CppSharp.Parser.AST.QualifiedType.Internal QualifiedType;
[FieldOffset(40)]
public global::System.IntPtr FieldPtr;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
@ -3010,6 +3016,16 @@ namespace CppSharp @@ -3010,6 +3016,16 @@ namespace CppSharp
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
EntryPoint="??1LayoutField@AST@CppParser@CppSharp@@QAE@XZ")]
internal static extern void dtor_0(global::System.IntPtr instance, int delete);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
EntryPoint="?getName@LayoutField@AST@CppParser@CppSharp@@QAEPBDXZ")]
internal static extern global::System.IntPtr getName_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
EntryPoint="?setName@LayoutField@AST@CppParser@CppSharp@@QAEXPBD@Z")]
internal static extern void setName_0(global::System.IntPtr instance, global::System.IntPtr s);
}
public global::System.IntPtr __Instance { get; protected set; }
@ -3032,8 +3048,8 @@ namespace CppSharp @@ -3032,8 +3048,8 @@ namespace CppSharp
private static void* __CopyValue(LayoutField.Internal native)
{
var ret = Marshal.AllocHGlobal(8);
*(LayoutField.Internal*) ret = native;
var ret = Marshal.AllocHGlobal(44);
CppSharp.Parser.AST.LayoutField.Internal.cctor_1(ret, new global::System.IntPtr(&native));
return ret.ToPointer();
}
@ -3053,7 +3069,7 @@ namespace CppSharp @@ -3053,7 +3069,7 @@ namespace CppSharp
public LayoutField()
{
__Instance = Marshal.AllocHGlobal(8);
__Instance = Marshal.AllocHGlobal(44);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment));
@ -3061,10 +3077,13 @@ namespace CppSharp @@ -3061,10 +3077,13 @@ namespace CppSharp
public LayoutField(CppSharp.Parser.AST.LayoutField _0)
{
__Instance = Marshal.AllocHGlobal(8);
__Instance = Marshal.AllocHGlobal(44);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
*((LayoutField.Internal*) __Instance) = *((LayoutField.Internal*) _0.__Instance);
if (ReferenceEquals(_0, null))
throw new global::System.ArgumentNullException("_0", "Cannot be null because it is a C++ reference (&).");
var __arg0 = _0.__Instance;
Internal.cctor_1((__Instance + __PointerAdjustment), __arg0);
}
public void Dispose()
@ -3081,6 +3100,40 @@ namespace CppSharp @@ -3081,6 +3100,40 @@ namespace CppSharp
Marshal.FreeHGlobal(__Instance);
}
public string Name
{
get
{
var __ret = Internal.getName_0((__Instance + __PointerAdjustment));
return Marshal.PtrToStringAnsi(__ret);
}
set
{
var __arg0 = Marshal.StringToHGlobalAnsi(value);
Internal.setName_0((__Instance + __PointerAdjustment), __arg0);
Marshal.FreeHGlobal(__arg0);
}
}
public CppSharp.Parser.AST.DeclarationContext _Namespace
{
get
{
CppSharp.Parser.AST.DeclarationContext __result0;
if (((Internal*) __Instance)->_Namespace == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->_Namespace))
__result0 = (CppSharp.Parser.AST.DeclarationContext) CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap[((Internal*) __Instance)->_Namespace];
else __result0 = CppSharp.Parser.AST.DeclarationContext.__CreateInstance(((Internal*) __Instance)->_Namespace);
return __result0;
}
set
{
((Internal*) __Instance)->_Namespace = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
}
}
public uint Offset
{
get
@ -3094,21 +3147,29 @@ namespace CppSharp @@ -3094,21 +3147,29 @@ namespace CppSharp
}
}
public CppSharp.Parser.AST.Field Field
public CppSharp.Parser.AST.QualifiedType QualifiedType
{
get
{
CppSharp.Parser.AST.Field __result0;
if (((Internal*) __Instance)->Field == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.Field.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->Field))
__result0 = (CppSharp.Parser.AST.Field) CppSharp.Parser.AST.Field.NativeToManagedMap[((Internal*) __Instance)->Field];
else __result0 = CppSharp.Parser.AST.Field.__CreateInstance(((Internal*) __Instance)->Field);
return __result0;
return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->QualifiedType);
}
set
{
((Internal*) __Instance)->QualifiedType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
}
}
public global::System.IntPtr FieldPtr
{
get
{
return ((Internal*) __Instance)->FieldPtr;
}
set
{
((Internal*) __Instance)->Field = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
((Internal*) __Instance)->FieldPtr = (global::System.IntPtr) value;
}
}
}

93
src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/AST.cs

@ -2986,14 +2986,20 @@ namespace CppSharp @@ -2986,14 +2986,20 @@ namespace CppSharp
public unsafe partial class LayoutField : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 16)]
[StructLayout(LayoutKind.Explicit, Size = 64)]
public partial struct Internal
{
[FieldOffset(0)]
public uint Offset;
public global::System.IntPtr _Namespace;
[FieldOffset(8)]
public global::System.IntPtr Field;
public uint Offset;
[FieldOffset(40)]
public CppSharp.Parser.AST.QualifiedType.Internal QualifiedType;
[FieldOffset(56)]
public global::System.IntPtr FieldPtr;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
@ -3009,6 +3015,16 @@ namespace CppSharp @@ -3009,6 +3015,16 @@ namespace CppSharp
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutFieldD2Ev")]
internal static extern void dtor_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutField7getNameEv")]
internal static extern global::System.IntPtr getName_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutField7setNameEPKc")]
internal static extern void setName_0(global::System.IntPtr instance, global::System.IntPtr s);
}
public global::System.IntPtr __Instance { get; protected set; }
@ -3031,8 +3047,8 @@ namespace CppSharp @@ -3031,8 +3047,8 @@ namespace CppSharp
private static void* __CopyValue(LayoutField.Internal native)
{
var ret = Marshal.AllocHGlobal(16);
*(LayoutField.Internal*) ret = native;
var ret = Marshal.AllocHGlobal(64);
CppSharp.Parser.AST.LayoutField.Internal.cctor_1(ret, new global::System.IntPtr(&native));
return ret.ToPointer();
}
@ -3052,7 +3068,7 @@ namespace CppSharp @@ -3052,7 +3068,7 @@ namespace CppSharp
public LayoutField()
{
__Instance = Marshal.AllocHGlobal(16);
__Instance = Marshal.AllocHGlobal(64);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment));
@ -3060,10 +3076,13 @@ namespace CppSharp @@ -3060,10 +3076,13 @@ namespace CppSharp
public LayoutField(CppSharp.Parser.AST.LayoutField _0)
{
__Instance = Marshal.AllocHGlobal(16);
__Instance = Marshal.AllocHGlobal(64);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
*((LayoutField.Internal*) __Instance) = *((LayoutField.Internal*) _0.__Instance);
if (ReferenceEquals(_0, null))
throw new global::System.ArgumentNullException("_0", "Cannot be null because it is a C++ reference (&).");
var __arg0 = _0.__Instance;
Internal.cctor_1((__Instance + __PointerAdjustment), __arg0);
}
public void Dispose()
@ -3080,6 +3099,40 @@ namespace CppSharp @@ -3080,6 +3099,40 @@ namespace CppSharp
Marshal.FreeHGlobal(__Instance);
}
public string Name
{
get
{
var __ret = Internal.getName_0((__Instance + __PointerAdjustment));
return Marshal.PtrToStringAnsi(__ret);
}
set
{
var __arg0 = Marshal.StringToHGlobalAnsi(value);
Internal.setName_0((__Instance + __PointerAdjustment), __arg0);
Marshal.FreeHGlobal(__arg0);
}
}
public CppSharp.Parser.AST.DeclarationContext _Namespace
{
get
{
CppSharp.Parser.AST.DeclarationContext __result0;
if (((Internal*) __Instance)->_Namespace == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->_Namespace))
__result0 = (CppSharp.Parser.AST.DeclarationContext) CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap[((Internal*) __Instance)->_Namespace];
else __result0 = CppSharp.Parser.AST.DeclarationContext.__CreateInstance(((Internal*) __Instance)->_Namespace);
return __result0;
}
set
{
((Internal*) __Instance)->_Namespace = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
}
}
public uint Offset
{
get
@ -3093,21 +3146,29 @@ namespace CppSharp @@ -3093,21 +3146,29 @@ namespace CppSharp
}
}
public CppSharp.Parser.AST.Field Field
public CppSharp.Parser.AST.QualifiedType QualifiedType
{
get
{
CppSharp.Parser.AST.Field __result0;
if (((Internal*) __Instance)->Field == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.Field.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->Field))
__result0 = (CppSharp.Parser.AST.Field) CppSharp.Parser.AST.Field.NativeToManagedMap[((Internal*) __Instance)->Field];
else __result0 = CppSharp.Parser.AST.Field.__CreateInstance(((Internal*) __Instance)->Field);
return __result0;
return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->QualifiedType);
}
set
{
((Internal*) __Instance)->QualifiedType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
}
}
public global::System.IntPtr FieldPtr
{
get
{
return ((Internal*) __Instance)->FieldPtr;
}
set
{
((Internal*) __Instance)->Field = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
((Internal*) __Instance)->FieldPtr = (global::System.IntPtr) value;
}
}
}

93
src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs

@ -2986,14 +2986,20 @@ namespace CppSharp @@ -2986,14 +2986,20 @@ namespace CppSharp
public unsafe partial class LayoutField : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 16)]
[StructLayout(LayoutKind.Explicit, Size = 48)]
public partial struct Internal
{
[FieldOffset(0)]
public uint Offset;
public global::System.IntPtr _Namespace;
[FieldOffset(8)]
public global::System.IntPtr Field;
public uint Offset;
[FieldOffset(24)]
public CppSharp.Parser.AST.QualifiedType.Internal QualifiedType;
[FieldOffset(40)]
public global::System.IntPtr FieldPtr;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
@ -3009,6 +3015,16 @@ namespace CppSharp @@ -3009,6 +3015,16 @@ namespace CppSharp
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutFieldD2Ev")]
internal static extern void dtor_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutField7getNameEv")]
internal static extern global::System.IntPtr getName_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser3AST11LayoutField7setNameEPKc")]
internal static extern void setName_0(global::System.IntPtr instance, global::System.IntPtr s);
}
public global::System.IntPtr __Instance { get; protected set; }
@ -3031,8 +3047,8 @@ namespace CppSharp @@ -3031,8 +3047,8 @@ namespace CppSharp
private static void* __CopyValue(LayoutField.Internal native)
{
var ret = Marshal.AllocHGlobal(16);
*(LayoutField.Internal*) ret = native;
var ret = Marshal.AllocHGlobal(48);
CppSharp.Parser.AST.LayoutField.Internal.cctor_1(ret, new global::System.IntPtr(&native));
return ret.ToPointer();
}
@ -3052,7 +3068,7 @@ namespace CppSharp @@ -3052,7 +3068,7 @@ namespace CppSharp
public LayoutField()
{
__Instance = Marshal.AllocHGlobal(16);
__Instance = Marshal.AllocHGlobal(48);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment));
@ -3060,10 +3076,13 @@ namespace CppSharp @@ -3060,10 +3076,13 @@ namespace CppSharp
public LayoutField(CppSharp.Parser.AST.LayoutField _0)
{
__Instance = Marshal.AllocHGlobal(16);
__Instance = Marshal.AllocHGlobal(48);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
*((LayoutField.Internal*) __Instance) = *((LayoutField.Internal*) _0.__Instance);
if (ReferenceEquals(_0, null))
throw new global::System.ArgumentNullException("_0", "Cannot be null because it is a C++ reference (&).");
var __arg0 = _0.__Instance;
Internal.cctor_1((__Instance + __PointerAdjustment), __arg0);
}
public void Dispose()
@ -3080,6 +3099,40 @@ namespace CppSharp @@ -3080,6 +3099,40 @@ namespace CppSharp
Marshal.FreeHGlobal(__Instance);
}
public string Name
{
get
{
var __ret = Internal.getName_0((__Instance + __PointerAdjustment));
return Marshal.PtrToStringAnsi(__ret);
}
set
{
var __arg0 = Marshal.StringToHGlobalAnsi(value);
Internal.setName_0((__Instance + __PointerAdjustment), __arg0);
Marshal.FreeHGlobal(__arg0);
}
}
public CppSharp.Parser.AST.DeclarationContext _Namespace
{
get
{
CppSharp.Parser.AST.DeclarationContext __result0;
if (((Internal*) __Instance)->_Namespace == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->_Namespace))
__result0 = (CppSharp.Parser.AST.DeclarationContext) CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap[((Internal*) __Instance)->_Namespace];
else __result0 = CppSharp.Parser.AST.DeclarationContext.__CreateInstance(((Internal*) __Instance)->_Namespace);
return __result0;
}
set
{
((Internal*) __Instance)->_Namespace = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
}
}
public uint Offset
{
get
@ -3093,21 +3146,29 @@ namespace CppSharp @@ -3093,21 +3146,29 @@ namespace CppSharp
}
}
public CppSharp.Parser.AST.Field Field
public CppSharp.Parser.AST.QualifiedType QualifiedType
{
get
{
CppSharp.Parser.AST.Field __result0;
if (((Internal*) __Instance)->Field == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.Field.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->Field))
__result0 = (CppSharp.Parser.AST.Field) CppSharp.Parser.AST.Field.NativeToManagedMap[((Internal*) __Instance)->Field];
else __result0 = CppSharp.Parser.AST.Field.__CreateInstance(((Internal*) __Instance)->Field);
return __result0;
return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->QualifiedType);
}
set
{
((Internal*) __Instance)->QualifiedType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
}
}
public global::System.IntPtr FieldPtr
{
get
{
return ((Internal*) __Instance)->FieldPtr;
}
set
{
((Internal*) __Instance)->Field = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
((Internal*) __Instance)->FieldPtr = (global::System.IntPtr) value;
}
}
}

93
src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/AST.cs

@ -2987,14 +2987,20 @@ namespace CppSharp @@ -2987,14 +2987,20 @@ namespace CppSharp
public unsafe partial class LayoutField : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 16)]
[StructLayout(LayoutKind.Explicit, Size = 72)]
public partial struct Internal
{
[FieldOffset(0)]
public uint Offset;
public global::System.IntPtr _Namespace;
[FieldOffset(8)]
public global::System.IntPtr Field;
public uint Offset;
[FieldOffset(48)]
public CppSharp.Parser.AST.QualifiedType.Internal QualifiedType;
[FieldOffset(64)]
public global::System.IntPtr FieldPtr;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
@ -3010,6 +3016,16 @@ namespace CppSharp @@ -3010,6 +3016,16 @@ namespace CppSharp
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="??1LayoutField@AST@CppParser@CppSharp@@QEAA@XZ")]
internal static extern void dtor_0(global::System.IntPtr instance, int delete);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="?getName@LayoutField@AST@CppParser@CppSharp@@QEAAPEBDXZ")]
internal static extern global::System.IntPtr getName_0(global::System.IntPtr instance);
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="?setName@LayoutField@AST@CppParser@CppSharp@@QEAAXPEBD@Z")]
internal static extern void setName_0(global::System.IntPtr instance, global::System.IntPtr s);
}
public global::System.IntPtr __Instance { get; protected set; }
@ -3032,8 +3048,8 @@ namespace CppSharp @@ -3032,8 +3048,8 @@ namespace CppSharp
private static void* __CopyValue(LayoutField.Internal native)
{
var ret = Marshal.AllocHGlobal(16);
*(LayoutField.Internal*) ret = native;
var ret = Marshal.AllocHGlobal(72);
CppSharp.Parser.AST.LayoutField.Internal.cctor_1(ret, new global::System.IntPtr(&native));
return ret.ToPointer();
}
@ -3053,7 +3069,7 @@ namespace CppSharp @@ -3053,7 +3069,7 @@ namespace CppSharp
public LayoutField()
{
__Instance = Marshal.AllocHGlobal(16);
__Instance = Marshal.AllocHGlobal(72);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment));
@ -3061,10 +3077,13 @@ namespace CppSharp @@ -3061,10 +3077,13 @@ namespace CppSharp
public LayoutField(CppSharp.Parser.AST.LayoutField _0)
{
__Instance = Marshal.AllocHGlobal(16);
__Instance = Marshal.AllocHGlobal(72);
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
*((LayoutField.Internal*) __Instance) = *((LayoutField.Internal*) _0.__Instance);
if (ReferenceEquals(_0, null))
throw new global::System.ArgumentNullException("_0", "Cannot be null because it is a C++ reference (&).");
var __arg0 = _0.__Instance;
Internal.cctor_1((__Instance + __PointerAdjustment), __arg0);
}
public void Dispose()
@ -3081,6 +3100,40 @@ namespace CppSharp @@ -3081,6 +3100,40 @@ namespace CppSharp
Marshal.FreeHGlobal(__Instance);
}
public string Name
{
get
{
var __ret = Internal.getName_0((__Instance + __PointerAdjustment));
return Marshal.PtrToStringAnsi(__ret);
}
set
{
var __arg0 = Marshal.StringToHGlobalAnsi(value);
Internal.setName_0((__Instance + __PointerAdjustment), __arg0);
Marshal.FreeHGlobal(__arg0);
}
}
public CppSharp.Parser.AST.DeclarationContext _Namespace
{
get
{
CppSharp.Parser.AST.DeclarationContext __result0;
if (((Internal*) __Instance)->_Namespace == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->_Namespace))
__result0 = (CppSharp.Parser.AST.DeclarationContext) CppSharp.Parser.AST.DeclarationContext.NativeToManagedMap[((Internal*) __Instance)->_Namespace];
else __result0 = CppSharp.Parser.AST.DeclarationContext.__CreateInstance(((Internal*) __Instance)->_Namespace);
return __result0;
}
set
{
((Internal*) __Instance)->_Namespace = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
}
}
public uint Offset
{
get
@ -3094,21 +3147,29 @@ namespace CppSharp @@ -3094,21 +3147,29 @@ namespace CppSharp
}
}
public CppSharp.Parser.AST.Field Field
public CppSharp.Parser.AST.QualifiedType QualifiedType
{
get
{
CppSharp.Parser.AST.Field __result0;
if (((Internal*) __Instance)->Field == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.Field.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->Field))
__result0 = (CppSharp.Parser.AST.Field) CppSharp.Parser.AST.Field.NativeToManagedMap[((Internal*) __Instance)->Field];
else __result0 = CppSharp.Parser.AST.Field.__CreateInstance(((Internal*) __Instance)->Field);
return __result0;
return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->QualifiedType);
}
set
{
((Internal*) __Instance)->QualifiedType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
}
}
public global::System.IntPtr FieldPtr
{
get
{
return ((Internal*) __Instance)->FieldPtr;
}
set
{
((Internal*) __Instance)->Field = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance;
((Internal*) __Instance)->FieldPtr = (global::System.IntPtr) value;
}
}
}

56
src/CppParser/Parser.cpp

@ -82,7 +82,18 @@ std::string GetCurrentLibraryDir() @@ -82,7 +82,18 @@ std::string GetCurrentLibraryDir()
#endif
}
void Parser::ReadLayoutFields(Class* Class, const clang::RecordDecl *RD,
LayoutField Parser::WalkVTablePointer(Class* Class,
const clang::CharUnits& Offset, const std::string& prefix)
{
LayoutField LayoutField;
LayoutField.Offset = Offset.getQuantity();
LayoutField._Namespace = Class;
LayoutField.Name = prefix + "_" + Class->Name;
LayoutField.QualifiedType = GetQualifiedType(C->getASTContext().VoidPtrTy);
return LayoutField;
}
void Parser::ReadLayoutFields(Class* Class, const clang::RecordDecl* RD,
clang::CharUnits Offset, bool IncludeVirtualBases)
{
using namespace clang;
@ -90,8 +101,26 @@ void Parser::ReadLayoutFields(Class* Class, const clang::RecordDecl *RD, @@ -90,8 +101,26 @@ void Parser::ReadLayoutFields(Class* Class, const clang::RecordDecl *RD,
const auto &Layout = C->getASTContext().getASTRecordLayout(RD);
auto CXXRD = dyn_cast<CXXRecordDecl>(RD);
auto Parent = static_cast<AST::Class*>(
WalkDeclaration(RD, /*IgnoreSystemDecls =*/false));
// Dump bases.
if (CXXRD) {
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
bool HasOwnVFPtr = Layout.hasOwnVFPtr();
bool HasOwnVBPtr = Layout.hasOwnVBPtr();
// Vtable pointer.
if (CXXRD->isDynamicClass() && !PrimaryBase &&
!C->getASTContext().getTargetInfo().getCXXABI().isMicrosoft()) {
auto VPtr = WalkVTablePointer(Parent, Offset, "vptr");
Class->Layout->Fields.push_back(VPtr);
}
else if (HasOwnVFPtr) {
auto VTPtr = WalkVTablePointer(Parent, Offset, "vfptr");
Class->Layout->Fields.push_back(VTPtr);
}
// Collect nvbases.
SmallVector<const CXXRecordDecl *, 4> Bases;
for (const CXXBaseSpecifier &Base : CXXRD->bases()) {
@ -113,30 +142,39 @@ void Parser::ReadLayoutFields(Class* Class, const clang::RecordDecl *RD, @@ -113,30 +142,39 @@ void Parser::ReadLayoutFields(Class* Class, const clang::RecordDecl *RD,
ReadLayoutFields(Class, Base, BaseOffset,
/*IncludeVirtualBases=*/false);
}
// vbptr (for Microsoft C++ ABI)
if (HasOwnVBPtr) {
auto VBPtr = WalkVTablePointer(Parent,
Offset + Layout.getVBPtrOffset(), "vbptr");
Class->Layout->Fields.push_back(VBPtr);
}
}
// Dump fields.
uint64_t FieldNo = 0;
for (RecordDecl::field_iterator I = RD->field_begin(),
E = RD->field_end(); I != E; ++I, ++FieldNo) {
const FieldDecl &Field = **I;
auto Field = *I;
uint64_t LocalFieldOffsetInBits = Layout.getFieldOffset(FieldNo);
CharUnits FieldOffset =
Offset + C->getASTContext().toCharUnitsFromBits(LocalFieldOffsetInBits);
// Recursively dump fields of record type.
if (auto RT = Field.getType()->getAs<RecordType>())
if (auto RT = Field->getType()->getAs<RecordType>())
{
auto TU = GetTranslationUnit(RT->getDecl());
if (TU->IsSystemHeader)
continue;
}
auto Parent = WalkDeclaration(RD, /*IgnoreSystemDecls =*/false);
auto F = WalkFieldCXX(&Field, static_cast<AST::Class*>(Parent));
auto F = WalkFieldCXX(Field, Parent);
LayoutField LayoutField;
LayoutField._Namespace = F->_Namespace;
LayoutField.Offset = FieldOffset.getQuantity();
LayoutField.Field = F;
LayoutField.Name = F->Name;
LayoutField.QualifiedType = GetQualifiedType(Field->getType());
LayoutField.FieldPtr = (void*)Field;
Class->Layout->Fields.push_back(LayoutField);
}
@ -151,6 +189,12 @@ void Parser::ReadLayoutFields(Class* Class, const clang::RecordDecl *RD, @@ -151,6 +189,12 @@ void Parser::ReadLayoutFields(Class* Class, const clang::RecordDecl *RD,
CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
if (VtorDisps.find(VBase)->second.hasVtorDisp()) {
auto VtorDisp = WalkVTablePointer(Parent,
VBaseOffset - CharUnits::fromQuantity(4), "vtordisp");
Class->Layout->Fields.push_back(VtorDisp);
}
ReadLayoutFields(Class, VBase, VBaseOffset,
/*IncludeVirtualBases=*/false);
}

3
src/CppParser/Parser.h

@ -98,7 +98,8 @@ private: @@ -98,7 +98,8 @@ private:
std::vector<TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL);
void WalkVTable(const clang::CXXRecordDecl* RD, Class* C);
QualifiedType GetQualifiedType(clang::QualType qual, clang::TypeLoc* TL = 0);
void ReadLayoutFields(Class * Class, const clang::RecordDecl * RD, clang::CharUnits Offset, bool IncludeVirtualBases);
void ReadLayoutFields(Class* Class, const clang::RecordDecl* RD, clang::CharUnits Offset, bool IncludeVirtualBases);
LayoutField WalkVTablePointer(Class* Class, const clang::CharUnits& Offset, const std::string& prefix);
VTableLayout WalkVTableLayout(const clang::VTableLayout& VTLayout);
VTableComponent WalkVTableComponent(const clang::VTableComponent& Component);
PreprocessedEntity* WalkPreprocessedEntity(Declaration* Decl,

17
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -439,9 +439,9 @@ namespace CppSharp.Generators.CLI @@ -439,9 +439,9 @@ namespace CppSharp.Generators.CLI
PushIndent();
// check for value types because some of the ignored fields may back properties;
// not the case for ref types because the NativePtr pattern is used there
foreach (var field in @class.Layout.Fields.Where(f => !ASTUtils.CheckIgnoreField(f.Field)))
foreach (var field in @class.Fields.Where(f => !ASTUtils.CheckIgnoreField(f)))
{
var property = @class.Properties.FirstOrDefault(p => p.Field == field.Field);
var property = @class.Properties.FirstOrDefault(p => p.Field == field);
if (property != null && !property.IsInRefTypeAndBackedByValueClassField())
{
GenerateField(@class, field);
@ -450,15 +450,16 @@ namespace CppSharp.Generators.CLI @@ -450,15 +450,16 @@ namespace CppSharp.Generators.CLI
PopIndent();
}
private void GenerateField(Class @class, LayoutField layoutField)
private void GenerateField(Class @class, Field field)
{
PushBlock(CLIBlockKind.Field, layoutField.Field);
PushBlock(CLIBlockKind.Field, field);
GenerateDeclarationCommon(layoutField.Field);
GenerateDeclarationCommon(field);
if (@class.IsUnion)
WriteLine("[System::Runtime::InteropServices::FieldOffset({0})]",
layoutField.Offset);
WriteLine("{0} {1};", layoutField.Field.Type, layoutField.Field.Name);
@class.Layout.Fields.Single(
f => f.Namespace == @class && f.FieldPtr == field.OriginalPtr).Offset);
WriteLine("{0} {1};", field.Type, field.Name);
PopBlock();
}
@ -630,7 +631,7 @@ namespace CppSharp.Generators.CLI @@ -630,7 +631,7 @@ namespace CppSharp.Generators.CLI
{
if (prop.IsInRefTypeAndBackedByValueClassField())
{
GenerateField(@class, @class.Layout.Fields.Single(f => f.Field == prop.Field));
GenerateField(@class, prop.Field);
continue;
}

110
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -601,8 +601,6 @@ namespace CppSharp.Generators.CSharp @@ -601,8 +601,6 @@ namespace CppSharp.Generators.CSharp
TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
if (@class.IsDynamic)
GenerateVTablePointers(@class);
foreach (var field in @class.Layout.Fields)
GenerateClassInternalsField(field);
if (@class.IsGenerated && !(@class is ClassTemplateSpecialization))
@ -791,16 +789,15 @@ namespace CppSharp.Generators.CSharp @@ -791,16 +789,15 @@ namespace CppSharp.Generators.CSharp
}
}
private void GenerateClassInternalsField(LayoutField layoutField)
private void GenerateClassInternalsField(LayoutField field)
{
// we do not support dependent fields yet, see https://github.com/mono/CppSharp/issues/197
Declaration decl;
var field = layoutField.Field;
field.Type.TryGetDeclaration(out decl);
field.QualifiedType.Type.TryGetDeclaration(out decl);
if (decl != null && decl.TranslationUnit.IsSystemHeader)
return;
var safeIdentifier = Helpers.SafeIdentifier(layoutField.Name);
var safeIdentifier = Helpers.SafeIdentifier(field.Name);
if(safeIdentifier.All(c => c.Equals('_')))
{
@ -809,13 +806,13 @@ namespace CppSharp.Generators.CSharp @@ -809,13 +806,13 @@ namespace CppSharp.Generators.CSharp
PushBlock(CSharpBlockKind.Field);
WriteLine("[FieldOffset({0})]", layoutField.Offset);
WriteLine("[FieldOffset({0})]", field.Offset);
TypePrinter.PushMarshalKind(CSharpMarshalKind.NativeField);
var fieldTypePrinted = field.QualifiedType.CSharpType(TypePrinter);
TypePrinter.PopMarshalKind();
var fieldType = field.Type.Desugar().IsAddress() ?
var fieldType = field.QualifiedType.Type.Desugar().IsAddress() ?
CSharpTypePrinter.IntPtrType : fieldTypePrinted.Type;
var fieldName = safeIdentifier;
@ -837,22 +834,23 @@ namespace CppSharp.Generators.CSharp @@ -837,22 +834,23 @@ namespace CppSharp.Generators.CSharp
// Workaround a bug in Mono when handling fixed arrays in P/Invoke declarations.
// https://bugzilla.xamarin.com/show_bug.cgi?id=33571
var arrayType = field.Type.Desugar() as ArrayType;
var arrayType = field.QualifiedType.Type.Desugar() as ArrayType;
if (arrayType != null && arrayType.SizeType == ArrayType.ArraySize.Constant &&
arrayType.Size > 0)
{
for (var i = 1; i < arrayType.Size; ++i)
{
var dummy = new Field
var dummy = new LayoutField
{
Namespace = field.Namespace,
Offset = (uint) (field.Offset + i * arrayType.ElementSize / 8),
QualifiedType = new QualifiedType(arrayType.Type),
Name = string.Format("{0}_{1}_{2}", Helpers.DummyIdentifier,
safeIdentifier, i),
QualifiedType = new QualifiedType(arrayType.Type),
Namespace = field.Namespace
FieldPtr = field.FieldPtr
};
GenerateClassInternalsField(new LayoutField(
(uint) (layoutField.Offset + i * arrayType.ElementSize / 8), dummy));
GenerateClassInternalsField(dummy);
}
}
}
@ -975,7 +973,7 @@ namespace CppSharp.Generators.CSharp @@ -975,7 +973,7 @@ namespace CppSharp.Generators.CSharp
}
else
{
var name = @class.Layout.Fields.First(f => f.Field == field).Name;
var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name;
ctx.ReturnVarName = string.Format("{0}{1}{2}",
@class.IsValueType
? Helpers.InstanceField
@ -1027,7 +1025,8 @@ namespace CppSharp.Generators.CSharp @@ -1027,7 +1025,8 @@ namespace CppSharp.Generators.CSharp
type = originalType.ToString();
}
var name = ((Class) field.Namespace).Layout.Fields.First(f => f.Field == field).Name;
var name = ((Class) field.Namespace).Layout.Fields.First(
f => f.FieldPtr == field.OriginalPtr).Name;
WriteLine(string.Format("fixed ({0} {1} = {2}.{3})",
type, arrPtrIden, Helpers.InstanceField, Helpers.SafeIdentifier(name)));
WriteStartBraceIndent();
@ -1118,7 +1117,7 @@ namespace CppSharp.Generators.CSharp @@ -1118,7 +1117,7 @@ namespace CppSharp.Generators.CSharp
NewLine();
WriteStartBraceIndent();
var name = @class.Layout.Fields.First(f => f.Field == field).Name;
var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name;
var ctx = new CSharpMarshalContext(Driver)
{
Kind = CSharpMarshalKind.NativeField,
@ -1300,7 +1299,7 @@ namespace CppSharp.Generators.CSharp @@ -1300,7 +1299,7 @@ namespace CppSharp.Generators.CSharp
ArrayType arrayType = prop.Type as ArrayType;
if (arrayType != null && arrayType.Type.IsPointerToPrimitiveType() && prop.Field != null)
{
var name = @class.Layout.Fields.First(f => f.Field == prop.Field).Name;
var name = @class.Layout.Fields.First(f => f.FieldPtr == prop.Field.OriginalPtr).Name;
GenerateClassField(prop.Field);
WriteLine("private bool {0};",
GeneratedIdentifier(string.Format("{0}Initialised", name)));
@ -1443,7 +1442,7 @@ namespace CppSharp.Generators.CSharp @@ -1443,7 +1442,7 @@ namespace CppSharp.Generators.CSharp
WriteLine("var native = (Internal*) {0}.ToPointer();", Helpers.InstanceIdentifier);
NewLine();
SaveOriginalVTablePointers(@class.Layout.VFTables);
SaveOriginalVTablePointers(@class.Layout.VTablePointers);
NewLine();
@ -1510,13 +1509,16 @@ namespace CppSharp.Generators.CSharp @@ -1510,13 +1509,16 @@ namespace CppSharp.Generators.CSharp
AllocateNewVTablesItanium(@class, wrappedEntries, destructorOnly);
}
private void SaveOriginalVTablePointers(IEnumerable<VFTableInfo> vfTables)
private void SaveOriginalVTablePointers(IList<LayoutField> vTablePtrs)
{
if (Driver.Options.IsMicrosoftAbi)
WriteLine("__OriginalVTables = new void*[] {{ {0} }};",
string.Join(", ", vfTables.Select((v, i) => string.Format("((Internal*) native)->vfptr{0}.ToPointer()", i))));
string.Join(", ",
vTablePtrs.Select(v => string.Format("((Internal*) native)->{0}.ToPointer()", v.Name))));
else
WriteLine("__OriginalVTables = new void*[] { ((Internal*) native)->vfptr0.ToPointer() };");
WriteLine(
"__OriginalVTables = new void*[] {{ ((Internal*) native)->{0}.ToPointer() }};",
vTablePtrs[0].Name);
}
private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries,
@ -1525,23 +1527,24 @@ namespace CppSharp.Generators.CSharp @@ -1525,23 +1527,24 @@ namespace CppSharp.Generators.CSharp
var managedVTables = destructorOnly ? "__ManagedVTablesDtorOnly" : "__ManagedVTables";
WriteLine("{0} = new void*[{1}];", managedVTables, @class.Layout.VFTables.Count);
for (int tableIndex = 0; tableIndex < @class.Layout.VFTables.Count; tableIndex++)
for (int i = 0; i < @class.Layout.VFTables.Count; i++)
{
var vfptr = @class.Layout.VFTables[tableIndex];
var vfptr = @class.Layout.VFTables[i];
var size = vfptr.Layout.Components.Count;
WriteLine("var vfptr{0} = Marshal.AllocHGlobal({1} * {2});",
tableIndex, size, Driver.TargetInfo.PointerWidth / 8);
WriteLine("{0}[{1}] = vfptr{1}.ToPointer();", managedVTables, tableIndex);
i, size, Driver.TargetInfo.PointerWidth / 8);
WriteLine("{0}[{1}] = vfptr{1}.ToPointer();", managedVTables, i);
AllocateNewVTableEntries(vfptr.Layout.Components, wrappedEntries, tableIndex,
destructorOnly);
AllocateNewVTableEntries(vfptr.Layout.Components, wrappedEntries,
@class.Layout.VTablePointers[i].Name, i, destructorOnly);
}
WriteCloseBraceIndent();
NewLine();
for (var i = 0; i < @class.Layout.VFTables.Count; i++)
WriteLine("native->vfptr{0} = new IntPtr({1}[{0}]);", i, managedVTables);
for (int i = 0; i < @class.Layout.VTablePointers.Count; i++)
WriteLine("native->{0} = new IntPtr({1}[{2}]);",
@class.Layout.VTablePointers[i].Name, managedVTables, i);
}
private void AllocateNewVTablesItanium(Class @class, IList<VTableComponent> wrappedEntries,
@ -1558,16 +1561,17 @@ namespace CppSharp.Generators.CSharp @@ -1558,16 +1561,17 @@ namespace CppSharp.Generators.CSharp
WriteLine("{0}[0] = vfptr0.ToPointer();", managedVTables);
AllocateNewVTableEntries(@class.Layout.Layout.Components,
wrappedEntries, 0, destructorOnly);
wrappedEntries, @class.Layout.VTablePointers[0].Name, 0, destructorOnly);
WriteCloseBraceIndent();
NewLine();
WriteLine("native->vfptr0 = new IntPtr({0}[0]);", managedVTables);
WriteLine("native->{0} = new IntPtr({1}[0]);",
@class.Layout.VTablePointers[0].Name, managedVTables);
}
private void AllocateNewVTableEntries(IList<VTableComponent> entries,
IList<VTableComponent> wrappedEntries, int tableIndex, bool destructorOnly)
IList<VTableComponent> wrappedEntries, string vptr, int tableIndex, bool destructorOnly)
{
var pointerSize = Driver.TargetInfo.PointerWidth / 8;
for (var i = 0; i < entries.Count; i++)
@ -1576,7 +1580,7 @@ namespace CppSharp.Generators.CSharp @@ -1576,7 +1580,7 @@ namespace CppSharp.Generators.CSharp
var offset = pointerSize
* (i - (Options.IsMicrosoftAbi ? 0 : VTables.ItaniumOffsetToTopAndRTTI));
var nativeVftableEntry = string.Format("*(void**)(native->vfptr{0} + {1})", tableIndex, offset);
var nativeVftableEntry = string.Format("*(void**)(native->{0} + {1})", vptr, offset);
var managedVftableEntry = string.Format("*(void**)(vfptr{0} + {1})", tableIndex, offset);
if ((entry.Kind == VTableComponentKind.FunctionPointer ||
@ -1761,32 +1765,6 @@ namespace CppSharp.Generators.CSharp @@ -1761,32 +1765,6 @@ namespace CppSharp.Generators.CSharp
return string.Format("_{0}Delegate", nativeId);
}
public void GenerateVTablePointers(Class @class)
{
if (Options.IsMicrosoftAbi)
{
var index = 0;
foreach (var info in @class.Layout.VFTables)
{
PushBlock(CSharpBlockKind.InternalsClassField);
WriteLine("[FieldOffset({0})]", info.VFPtrFullOffset);
WriteLine("public global::System.IntPtr vfptr{0};", index++);
PopBlock(NewLineKind.BeforeNextBlock);
}
}
else
{
PushBlock(CSharpBlockKind.InternalsClassField);
WriteLine("[FieldOffset(0)]");
WriteLine("public global::System.IntPtr vfptr0;");
PopBlock(NewLineKind.BeforeNextBlock);
}
}
#endregion
#region Events
@ -1994,12 +1972,12 @@ namespace CppSharp.Generators.CSharp @@ -1994,12 +1972,12 @@ namespace CppSharp.Generators.CSharp
if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0)
{
if (Options.IsMicrosoftAbi)
for (var i = 0; i < @class.Layout.VFTables.Count; i++)
WriteLine("((Internal*) {0})->vfptr{1} = new global::System.IntPtr(__OriginalVTables[{1}]);",
Helpers.InstanceIdentifier, i);
for (var i = 0; i < @class.Layout.VTablePointers.Count; i++)
WriteLine("((Internal*) {0})->{1} = new global::System.IntPtr(__OriginalVTables[{2}]);",
Helpers.InstanceIdentifier, @class.Layout.VTablePointers[i].Name, i);
else
WriteLine("((Internal*) {0})->vfptr0 = new global::System.IntPtr(__OriginalVTables[0]);",
Helpers.InstanceIdentifier);
WriteLine("((Internal*) {0})->{1} = new global::System.IntPtr(__OriginalVTables[0]);",
Helpers.InstanceIdentifier, @class.Layout.VTablePointers[0].Name);
}
}
@ -2095,7 +2073,7 @@ namespace CppSharp.Generators.CSharp @@ -2095,7 +2073,7 @@ namespace CppSharp.Generators.CSharp
}
if (@class.IsAbstractImpl || hasVTables)
SaveOriginalVTablePointers(@class.Layout.VFTables);
SaveOriginalVTablePointers(@class.Layout.VTablePointers);
if (setupVTables)
{

4
src/Generator/Passes/CheckDuplicatedNamesPass.cs

@ -169,11 +169,11 @@ namespace CppSharp.Passes @@ -169,11 +169,11 @@ namespace CppSharp.Passes
if (!@class.IsDependent)
{
foreach (var fields in @class.Layout.Fields.GroupBy(
f => f.Field.OriginalName).Select(g => g.ToList()))
f => f.Name).Select(g => g.ToList()))
{
for (var i = 1; i < fields.Count; i++)
{
var name = fields[i].Field.OriginalName;
var name = fields[i].Name;
fields[i].Name = (string.IsNullOrEmpty(name) ? "__" : name) + i;
}
}

4
src/Generator/Passes/CleanInvalidDeclNamesPass.cs

@ -63,6 +63,10 @@ namespace CppSharp.Passes @@ -63,6 +63,10 @@ namespace CppSharp.Passes
base.VisitClassDecl(@class);
uniqueName = currentUniqueName;
if (!@class.IsDependent)
foreach (var field in @class.Layout.Fields.Where(f => string.IsNullOrEmpty(f.Name)))
field.Name = @class.Name == "_" ? "__" : "_";
if (@class is ClassTemplateSpecialization &&
!(from c in @class.Namespace.Classes
where c.Name == @class.Name && !(@class is ClassTemplateSpecialization) &&

Loading…
Cancel
Save