Browse Source

Generated internals of types nested in templates.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
cpp_module_crash
Dimitar Dobrev 9 years ago
parent
commit
0d5c4539a2
  1. 11
      src/AST/ASTVisitor.cs
  2. 14
      src/AST/Type.cs
  3. 28
      src/AST/TypeExtensions.cs
  4. 3
      src/Core/Parser/ASTConverter.cs
  5. 1
      src/CppParser/AST.cpp
  6. 2
      src/CppParser/AST.h
  7. 8
      src/CppParser/Bindings/CLI/AST.cpp
  8. 6
      src/CppParser/Bindings/CLI/AST.h
  9. 23
      src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs
  10. 23
      src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs
  11. 23
      src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/AST.cs
  12. 23
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs
  13. 23
      src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/AST.cs
  14. 3
      src/CppParser/Parser.cpp
  15. 6
      src/Generator.Tests/AST/TestAST.cs
  16. 20
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  17. 5
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  18. 12
      src/Generator/Passes/CheckIgnoredDecls.cs
  19. 7
      src/Generator/Passes/CleanInvalidDeclNamesPass.cs
  20. 30
      src/Generator/Types/ITypePrinter.cs
  21. 10
      tests/CSharp/CSharp.cs
  22. 3
      tests/CSharp/CSharpTemplates.h

11
src/AST/ASTVisitor.cs

@ -179,16 +179,14 @@ namespace CppSharp.AST
} }
} }
return template.Template.Visit(this); return template.IsDependent ? template.Template.Visit(this) :
template.GetClassTemplateSpecialization().Visit(this);
} }
public virtual bool VisitTemplateParameterType(TemplateParameterType param, public virtual bool VisitTemplateParameterType(TemplateParameterType param,
TypeQualifiers quals) TypeQualifiers quals)
{ {
if (!VisitType(param, quals)) return VisitType(param, quals);
return false;
return true;
} }
public virtual bool VisitTemplateParameterSubstitutionType( public virtual bool VisitTemplateParameterSubstitutionType(
@ -377,6 +375,9 @@ namespace CppSharp.AST
foreach (var templateParameter in template.Parameters) foreach (var templateParameter in template.Parameters)
templateParameter.Visit(this); templateParameter.Visit(this);
foreach (var specialization in template.Specializations)
specialization.Visit(this);
return true; return true;
} }

14
src/AST/Type.cs

@ -634,6 +634,18 @@ namespace CppSharp.AST
public Type Desugared; public Type Desugared;
public ClassTemplateSpecialization GetClassTemplateSpecialization()
{
var tagType = Desugared as TagType;
if (tagType != null)
return (ClassTemplateSpecialization) tagType.Declaration;
var injectedClassNameType = (InjectedClassNameType) Desugared;
var injectedSpecializationType = (TemplateSpecializationType)
injectedClassNameType.InjectedSpecializationType.Type;
return injectedSpecializationType.GetClassTemplateSpecialization();
}
public override T Visit<T>(ITypeVisitor<T> visitor, public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers()) TypeQualifiers quals = new TypeQualifiers())
{ {
@ -777,6 +789,8 @@ namespace CppSharp.AST
Class = type.Class; Class = type.Class;
} }
public QualifiedType InjectedSpecializationType { get; set; }
public override T Visit<T>(ITypeVisitor<T> visitor, public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers()) TypeQualifiers quals = new TypeQualifiers())
{ {

28
src/AST/TypeExtensions.cs

@ -120,20 +120,28 @@
{ {
t = t.Desugar(); t = t.Desugar();
var tag = t as TagType; TagType tagType = null;
if (tag != null) var type = t as TemplateSpecializationType;
if (type != null)
{ {
decl = tag.Declaration as T; if (type.IsDependent)
return decl != null; {
var templatedClass = ((ClassTemplate) type.Template).TemplatedClass;
decl = templatedClass.CompleteDeclaration == null
? templatedClass as T
: (T) templatedClass.CompleteDeclaration;
return decl != null;
}
tagType = (TagType) type.Desugared;
}
else
{
tagType = t as TagType;
} }
var type = t as TemplateSpecializationType; if (tagType != null)
if (type != null)
{ {
var templatedClass = ((ClassTemplate)type.Template).TemplatedClass; decl = tagType.Declaration as T;
decl = templatedClass.CompleteDeclaration == null
? templatedClass as T
: (T) templatedClass.CompleteDeclaration;
return decl != null; return decl != null;
} }

3
src/Core/Parser/ASTConverter.cs

@ -586,9 +586,8 @@ namespace CppSharp
public override AST.Type VisitInjectedClassName(InjectedClassNameType type) public override AST.Type VisitInjectedClassName(InjectedClassNameType type)
{ {
var _type = new CppSharp.AST.InjectedClassNameType(); var _type = new CppSharp.AST.InjectedClassNameType();
_type.TemplateSpecialization = Visit(type.TemplateSpecialization)
as AST.TemplateSpecializationType;
_type.Class = declConverter.Visit(type.Class) as AST.Class; _type.Class = declConverter.Visit(type.Class) as AST.Class;
_type.InjectedSpecializationType = VisitQualified(type.InjectedSpecializationType);
VisitType(type, _type); VisitType(type, _type);
return _type; return _type;
} }

1
src/CppParser/AST.cpp

@ -153,7 +153,6 @@ TemplateParameterSubstitutionType::TemplateParameterSubstitutionType()
InjectedClassNameType::InjectedClassNameType() InjectedClassNameType::InjectedClassNameType()
: Type(TypeKind::InjectedClassName) : Type(TypeKind::InjectedClassName)
, TemplateSpecialization(0)
, Class(0) , Class(0)
{ {
} }

2
src/CppParser/AST.h

@ -220,7 +220,7 @@ class CS_API InjectedClassNameType : public Type
{ {
public: public:
InjectedClassNameType(); InjectedClassNameType();
TemplateSpecializationType* TemplateSpecialization; QualifiedType InjectedSpecializationType;
CppSharp::CppParser::AST::Class* Class; CppSharp::CppParser::AST::Class* Class;
}; };

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

@ -950,14 +950,14 @@ CppSharp::Parser::AST::InjectedClassNameType::InjectedClassNameType(CppSharp::Pa
NativePtr = new ::CppSharp::CppParser::AST::InjectedClassNameType(arg0); NativePtr = new ::CppSharp::CppParser::AST::InjectedClassNameType(arg0);
} }
CppSharp::Parser::AST::TemplateSpecializationType^ CppSharp::Parser::AST::InjectedClassNameType::TemplateSpecialization::get() CppSharp::Parser::AST::QualifiedType^ CppSharp::Parser::AST::InjectedClassNameType::InjectedSpecializationType::get()
{ {
return (((::CppSharp::CppParser::AST::InjectedClassNameType*)NativePtr)->TemplateSpecialization == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::TemplateSpecializationType((::CppSharp::CppParser::AST::TemplateSpecializationType*)((::CppSharp::CppParser::AST::InjectedClassNameType*)NativePtr)->TemplateSpecialization); return (&((::CppSharp::CppParser::AST::InjectedClassNameType*)NativePtr)->InjectedSpecializationType == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::QualifiedType((::CppSharp::CppParser::AST::QualifiedType*)&((::CppSharp::CppParser::AST::InjectedClassNameType*)NativePtr)->InjectedSpecializationType);
} }
void CppSharp::Parser::AST::InjectedClassNameType::TemplateSpecialization::set(CppSharp::Parser::AST::TemplateSpecializationType^ value) void CppSharp::Parser::AST::InjectedClassNameType::InjectedSpecializationType::set(CppSharp::Parser::AST::QualifiedType^ value)
{ {
((::CppSharp::CppParser::AST::InjectedClassNameType*)NativePtr)->TemplateSpecialization = (::CppSharp::CppParser::AST::TemplateSpecializationType*)value->NativePtr; ((::CppSharp::CppParser::AST::InjectedClassNameType*)NativePtr)->InjectedSpecializationType = *(::CppSharp::CppParser::AST::QualifiedType*)value->NativePtr;
} }
CppSharp::Parser::AST::Class^ CppSharp::Parser::AST::InjectedClassNameType::Class::get() CppSharp::Parser::AST::Class^ CppSharp::Parser::AST::InjectedClassNameType::Class::get()

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

@ -844,10 +844,10 @@ namespace CppSharp
~InjectedClassNameType(); ~InjectedClassNameType();
property CppSharp::Parser::AST::TemplateSpecializationType^ TemplateSpecialization property CppSharp::Parser::AST::QualifiedType^ InjectedSpecializationType
{ {
CppSharp::Parser::AST::TemplateSpecializationType^ get(); CppSharp::Parser::AST::QualifiedType^ get();
void set(CppSharp::Parser::AST::TemplateSpecializationType^); void set(CppSharp::Parser::AST::QualifiedType^);
} }
property CppSharp::Parser::AST::Class^ Class property CppSharp::Parser::AST::Class^ Class

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

@ -2184,7 +2184,7 @@ namespace CppSharp
public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable
{ {
[StructLayout(LayoutKind.Explicit, Size = 16)] [StructLayout(LayoutKind.Explicit, Size = 20)]
public new partial struct Internal public new partial struct Internal
{ {
[FieldOffset(0)] [FieldOffset(0)]
@ -2194,9 +2194,9 @@ namespace CppSharp
public byte IsDependent; public byte IsDependent;
[FieldOffset(8)] [FieldOffset(8)]
public global::System.IntPtr TemplateSpecialization; public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType;
[FieldOffset(12)] [FieldOffset(16)]
public global::System.IntPtr Class; public global::System.IntPtr Class;
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
@ -2222,7 +2222,7 @@ namespace CppSharp
private static void* __CopyValue(InjectedClassNameType.Internal native) private static void* __CopyValue(InjectedClassNameType.Internal native)
{ {
var ret = Marshal.AllocHGlobal(16); var ret = Marshal.AllocHGlobal(20);
CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native)); CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native));
return ret.ToPointer(); return ret.ToPointer();
} }
@ -2246,7 +2246,7 @@ namespace CppSharp
public InjectedClassNameType() public InjectedClassNameType()
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(16); __Instance = Marshal.AllocHGlobal(20);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment)); Internal.ctor_0((__Instance + __PointerAdjustment));
@ -2255,7 +2255,7 @@ namespace CppSharp
public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0)
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(16); __Instance = Marshal.AllocHGlobal(20);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
if (ReferenceEquals(_0, null)) if (ReferenceEquals(_0, null))
@ -2264,21 +2264,16 @@ namespace CppSharp
Internal.cctor_2((__Instance + __PointerAdjustment), arg0); Internal.cctor_2((__Instance + __PointerAdjustment), arg0);
} }
public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType
{ {
get get
{ {
CppSharp.Parser.AST.TemplateSpecializationType __result0; return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType);
if (((Internal*) __Instance)->TemplateSpecialization == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->TemplateSpecialization))
__result0 = (CppSharp.Parser.AST.TemplateSpecializationType) CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap[((Internal*) __Instance)->TemplateSpecialization];
else __result0 = CppSharp.Parser.AST.TemplateSpecializationType.__CreateInstance(((Internal*) __Instance)->TemplateSpecialization);
return __result0;
} }
set set
{ {
((Internal*) __Instance)->TemplateSpecialization = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance; ((Internal*) __Instance)->InjectedSpecializationType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
} }
} }

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

@ -2184,7 +2184,7 @@ namespace CppSharp
public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable
{ {
[StructLayout(LayoutKind.Explicit, Size = 16)] [StructLayout(LayoutKind.Explicit, Size = 20)]
public new partial struct Internal public new partial struct Internal
{ {
[FieldOffset(0)] [FieldOffset(0)]
@ -2194,9 +2194,9 @@ namespace CppSharp
public byte IsDependent; public byte IsDependent;
[FieldOffset(8)] [FieldOffset(8)]
public global::System.IntPtr TemplateSpecialization; public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType;
[FieldOffset(12)] [FieldOffset(16)]
public global::System.IntPtr Class; public global::System.IntPtr Class;
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
@ -2222,7 +2222,7 @@ namespace CppSharp
private static void* __CopyValue(InjectedClassNameType.Internal native) private static void* __CopyValue(InjectedClassNameType.Internal native)
{ {
var ret = Marshal.AllocHGlobal(16); var ret = Marshal.AllocHGlobal(20);
CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native)); CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native));
return ret.ToPointer(); return ret.ToPointer();
} }
@ -2246,7 +2246,7 @@ namespace CppSharp
public InjectedClassNameType() public InjectedClassNameType()
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(16); __Instance = Marshal.AllocHGlobal(20);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment)); Internal.ctor_0((__Instance + __PointerAdjustment));
@ -2255,7 +2255,7 @@ namespace CppSharp
public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0)
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(16); __Instance = Marshal.AllocHGlobal(20);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
if (ReferenceEquals(_0, null)) if (ReferenceEquals(_0, null))
@ -2264,21 +2264,16 @@ namespace CppSharp
Internal.cctor_2((__Instance + __PointerAdjustment), arg0); Internal.cctor_2((__Instance + __PointerAdjustment), arg0);
} }
public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType
{ {
get get
{ {
CppSharp.Parser.AST.TemplateSpecializationType __result0; return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType);
if (((Internal*) __Instance)->TemplateSpecialization == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->TemplateSpecialization))
__result0 = (CppSharp.Parser.AST.TemplateSpecializationType) CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap[((Internal*) __Instance)->TemplateSpecialization];
else __result0 = CppSharp.Parser.AST.TemplateSpecializationType.__CreateInstance(((Internal*) __Instance)->TemplateSpecialization);
return __result0;
} }
set set
{ {
((Internal*) __Instance)->TemplateSpecialization = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance; ((Internal*) __Instance)->InjectedSpecializationType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
} }
} }

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

@ -2184,7 +2184,7 @@ namespace CppSharp
public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable
{ {
[StructLayout(LayoutKind.Explicit, Size = 24)] [StructLayout(LayoutKind.Explicit, Size = 32)]
public new partial struct Internal public new partial struct Internal
{ {
[FieldOffset(0)] [FieldOffset(0)]
@ -2194,9 +2194,9 @@ namespace CppSharp
public byte IsDependent; public byte IsDependent;
[FieldOffset(8)] [FieldOffset(8)]
public global::System.IntPtr TemplateSpecialization; public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType;
[FieldOffset(16)] [FieldOffset(24)]
public global::System.IntPtr Class; public global::System.IntPtr Class;
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
@ -2222,7 +2222,7 @@ namespace CppSharp
private static void* __CopyValue(InjectedClassNameType.Internal native) private static void* __CopyValue(InjectedClassNameType.Internal native)
{ {
var ret = Marshal.AllocHGlobal(24); var ret = Marshal.AllocHGlobal(32);
CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native)); CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native));
return ret.ToPointer(); return ret.ToPointer();
} }
@ -2246,7 +2246,7 @@ namespace CppSharp
public InjectedClassNameType() public InjectedClassNameType()
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(24); __Instance = Marshal.AllocHGlobal(32);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment)); Internal.ctor_0((__Instance + __PointerAdjustment));
@ -2255,7 +2255,7 @@ namespace CppSharp
public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0)
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(24); __Instance = Marshal.AllocHGlobal(32);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
if (ReferenceEquals(_0, null)) if (ReferenceEquals(_0, null))
@ -2264,21 +2264,16 @@ namespace CppSharp
Internal.cctor_2((__Instance + __PointerAdjustment), arg0); Internal.cctor_2((__Instance + __PointerAdjustment), arg0);
} }
public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType
{ {
get get
{ {
CppSharp.Parser.AST.TemplateSpecializationType __result0; return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType);
if (((Internal*) __Instance)->TemplateSpecialization == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->TemplateSpecialization))
__result0 = (CppSharp.Parser.AST.TemplateSpecializationType) CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap[((Internal*) __Instance)->TemplateSpecialization];
else __result0 = CppSharp.Parser.AST.TemplateSpecializationType.__CreateInstance(((Internal*) __Instance)->TemplateSpecialization);
return __result0;
} }
set set
{ {
((Internal*) __Instance)->TemplateSpecialization = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance; ((Internal*) __Instance)->InjectedSpecializationType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
} }
} }

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

@ -2184,7 +2184,7 @@ namespace CppSharp
public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable
{ {
[StructLayout(LayoutKind.Explicit, Size = 24)] [StructLayout(LayoutKind.Explicit, Size = 32)]
public new partial struct Internal public new partial struct Internal
{ {
[FieldOffset(0)] [FieldOffset(0)]
@ -2194,9 +2194,9 @@ namespace CppSharp
public byte IsDependent; public byte IsDependent;
[FieldOffset(8)] [FieldOffset(8)]
public global::System.IntPtr TemplateSpecialization; public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType;
[FieldOffset(16)] [FieldOffset(24)]
public global::System.IntPtr Class; public global::System.IntPtr Class;
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
@ -2222,7 +2222,7 @@ namespace CppSharp
private static void* __CopyValue(InjectedClassNameType.Internal native) private static void* __CopyValue(InjectedClassNameType.Internal native)
{ {
var ret = Marshal.AllocHGlobal(24); var ret = Marshal.AllocHGlobal(32);
CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native)); CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native));
return ret.ToPointer(); return ret.ToPointer();
} }
@ -2246,7 +2246,7 @@ namespace CppSharp
public InjectedClassNameType() public InjectedClassNameType()
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(24); __Instance = Marshal.AllocHGlobal(32);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment)); Internal.ctor_0((__Instance + __PointerAdjustment));
@ -2255,7 +2255,7 @@ namespace CppSharp
public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0)
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(24); __Instance = Marshal.AllocHGlobal(32);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
if (ReferenceEquals(_0, null)) if (ReferenceEquals(_0, null))
@ -2264,21 +2264,16 @@ namespace CppSharp
Internal.cctor_2((__Instance + __PointerAdjustment), arg0); Internal.cctor_2((__Instance + __PointerAdjustment), arg0);
} }
public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType
{ {
get get
{ {
CppSharp.Parser.AST.TemplateSpecializationType __result0; return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType);
if (((Internal*) __Instance)->TemplateSpecialization == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->TemplateSpecialization))
__result0 = (CppSharp.Parser.AST.TemplateSpecializationType) CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap[((Internal*) __Instance)->TemplateSpecialization];
else __result0 = CppSharp.Parser.AST.TemplateSpecializationType.__CreateInstance(((Internal*) __Instance)->TemplateSpecialization);
return __result0;
} }
set set
{ {
((Internal*) __Instance)->TemplateSpecialization = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance; ((Internal*) __Instance)->InjectedSpecializationType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
} }
} }

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

@ -2184,7 +2184,7 @@ namespace CppSharp
public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable public unsafe partial class InjectedClassNameType : CppSharp.Parser.AST.Type, IDisposable
{ {
[StructLayout(LayoutKind.Explicit, Size = 24)] [StructLayout(LayoutKind.Explicit, Size = 32)]
public new partial struct Internal public new partial struct Internal
{ {
[FieldOffset(0)] [FieldOffset(0)]
@ -2194,9 +2194,9 @@ namespace CppSharp
public byte IsDependent; public byte IsDependent;
[FieldOffset(8)] [FieldOffset(8)]
public global::System.IntPtr TemplateSpecialization; public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType;
[FieldOffset(16)] [FieldOffset(24)]
public global::System.IntPtr Class; public global::System.IntPtr Class;
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
@ -2222,7 +2222,7 @@ namespace CppSharp
private static void* __CopyValue(InjectedClassNameType.Internal native) private static void* __CopyValue(InjectedClassNameType.Internal native)
{ {
var ret = Marshal.AllocHGlobal(24); var ret = Marshal.AllocHGlobal(32);
CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native)); CppSharp.Parser.AST.InjectedClassNameType.Internal.cctor_2(ret, new global::System.IntPtr(&native));
return ret.ToPointer(); return ret.ToPointer();
} }
@ -2246,7 +2246,7 @@ namespace CppSharp
public InjectedClassNameType() public InjectedClassNameType()
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(24); __Instance = Marshal.AllocHGlobal(32);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
Internal.ctor_0((__Instance + __PointerAdjustment)); Internal.ctor_0((__Instance + __PointerAdjustment));
@ -2255,7 +2255,7 @@ namespace CppSharp
public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0)
: this((void*) null) : this((void*) null)
{ {
__Instance = Marshal.AllocHGlobal(24); __Instance = Marshal.AllocHGlobal(32);
__ownsNativeInstance = true; __ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this; NativeToManagedMap[__Instance] = this;
if (ReferenceEquals(_0, null)) if (ReferenceEquals(_0, null))
@ -2264,21 +2264,16 @@ namespace CppSharp
Internal.cctor_2((__Instance + __PointerAdjustment), arg0); Internal.cctor_2((__Instance + __PointerAdjustment), arg0);
} }
public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType
{ {
get get
{ {
CppSharp.Parser.AST.TemplateSpecializationType __result0; return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType);
if (((Internal*) __Instance)->TemplateSpecialization == IntPtr.Zero) __result0 = null;
else if (CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap.ContainsKey(((Internal*) __Instance)->TemplateSpecialization))
__result0 = (CppSharp.Parser.AST.TemplateSpecializationType) CppSharp.Parser.AST.TemplateSpecializationType.NativeToManagedMap[((Internal*) __Instance)->TemplateSpecialization];
else __result0 = CppSharp.Parser.AST.TemplateSpecializationType.__CreateInstance(((Internal*) __Instance)->TemplateSpecialization);
return __result0;
} }
set set
{ {
((Internal*) __Instance)->TemplateSpecialization = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.__Instance; ((Internal*) __Instance)->InjectedSpecializationType = ReferenceEquals(value, null) ? new CppSharp.Parser.AST.QualifiedType.Internal() : *(CppSharp.Parser.AST.QualifiedType.Internal*) (value.__Instance);
} }
} }

3
src/CppParser/Parser.cpp

@ -2093,6 +2093,9 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL,
auto ICNT = new InjectedClassNameType(); auto ICNT = new InjectedClassNameType();
ICNT->Class = static_cast<Class*>(WalkDeclaration( ICNT->Class = static_cast<Class*>(WalkDeclaration(
ICN->getDecl(), 0, /*IgnoreSystemDecls=*/false)); ICN->getDecl(), 0, /*IgnoreSystemDecls=*/false));
ICNT->InjectedSpecializationType = GetQualifiedType(
ICN->getInjectedSpecializationType(),
WalkType(ICN->getInjectedSpecializationType()));
Ty = ICNT; Ty = ICNT;
break; break;

6
src/Generator.Tests/AST/TestAST.cs

@ -234,9 +234,9 @@ namespace CppSharp.Generator.Tests.AST
Assert.AreEqual(1, integerInst.Arguments.Count); Assert.AreEqual(1, integerInst.Arguments.Count);
var intArgument = integerInst.Arguments[0]; var intArgument = integerInst.Arguments[0];
Assert.AreEqual(new BuiltinType(PrimitiveType.Int), intArgument.Type.Type); Assert.AreEqual(new BuiltinType(PrimitiveType.Int), intArgument.Type.Type);
Class classTemplate; ClassTemplateSpecialization classTemplateSpecialization;
Assert.IsTrue(typeDef.Type.TryGetClass(out classTemplate)); Assert.IsTrue(typeDef.Type.TryGetDeclaration(out classTemplateSpecialization));
Assert.AreEqual(classTemplate, template.TemplatedClass); Assert.AreSame(classTemplateSpecialization.TemplatedDecl.TemplatedClass, template.TemplatedClass);
} }
[Test] [Test]

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

@ -315,11 +315,25 @@ namespace CppSharp.Generators.CSharp
PushBlock(CSharpBlockKind.Namespace); PushBlock(CSharpBlockKind.Namespace);
WriteLine("namespace {0}", classTemplate.Name); WriteLine("namespace {0}", classTemplate.Name);
WriteStartBraceIndent(); WriteStartBraceIndent();
IList<ClassTemplateSpecialization> specializations;
if (classTemplate.TemplatedClass.Fields.Any(f => f.IsDependent && !f.Type.IsAddress())) if (classTemplate.TemplatedClass.Fields.Any(f => f.IsDependent && !f.Type.IsAddress()))
foreach (var specialization in classTemplate.Specializations) specializations = classTemplate.Specializations;
GenerateClassInternals(specialization);
else else
GenerateClassInternals(classTemplate.Specializations[0]); specializations = new[] { classTemplate.Specializations[0] };
foreach (var nestedClass in specializations[0].Classes.Where(c => !c.IsDependent))
{
GenerateClassProlog(nestedClass);
NewLine();
WriteStartBraceIndent();
GenerateClassInternals(nestedClass);
WriteCloseBraceIndent();
}
NewLine();
foreach (var specialization in specializations)
GenerateClassInternals(specialization);
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }

5
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -387,6 +387,11 @@ namespace CppSharp.Generators.CSharp
{ {
if (ContextKind != CSharpTypePrinterContextKind.Native) if (ContextKind != CSharpTypePrinterContextKind.Native)
return GetNestedQualifiedName(decl); return GetNestedQualifiedName(decl);
// HACK: we can actually get the specialization directly by using TemplateSpecializationType.GetClassTemplateSpecialization()
// however, that returns the original specialisation which Clang places in the original name-space
// so if we specialise a template located in a dependency, we get uncompilable code
// so let's get the specialisation object from the current name-space by matching by name and template arguments
// this will be fixed when we have support for generating multiple libraries from a single AST
return GetTemplateSpecializationInternal(template); return GetTemplateSpecializationInternal(template);
} }

12
src/Generator/Passes/CheckIgnoredDecls.cs

@ -28,6 +28,18 @@ namespace CppSharp.Passes
return true; return true;
} }
public override bool VisitClassTemplateDecl(ClassTemplate template)
{
if (!base.VisitClassTemplateDecl(template))
return false;
// templates are not supported yet
foreach (var specialization in template.Specializations)
specialization.ExplicitlyIgnore();
return true;
}
public override bool VisitDeclaration(Declaration decl) public override bool VisitDeclaration(Declaration decl)
{ {
if (AlreadyVisited(decl)) if (AlreadyVisited(decl))

7
src/Generator/Passes/CleanInvalidDeclNamesPass.cs

@ -63,6 +63,13 @@ namespace CppSharp.Passes
base.VisitClassDecl(@class); base.VisitClassDecl(@class);
uniqueName = currentUniqueName; uniqueName = currentUniqueName;
if (@class is ClassTemplateSpecialization &&
!(from c in @class.Namespace.Classes
where c.Name == @class.Name && !(@class is ClassTemplateSpecialization) &&
c != ((ClassTemplateSpecialization) @class).TemplatedDecl.TemplatedClass
select c).Any())
return true;
if (@class.Namespace.Classes.Any(d => d != @class && d.Name == @class.Name)) if (@class.Namespace.Classes.Any(d => d != @class && d.Name == @class.Name))
{ {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();

30
src/Generator/Types/ITypePrinter.cs

@ -25,25 +25,27 @@ namespace CppSharp.Types
public string GetTemplateParameterList() public string GetTemplateParameterList()
{ {
var paramsList = new List<string>();
if (Kind == TypePrinterContextKind.Template) if (Kind == TypePrinterContextKind.Template)
{ {
var template = Declaration as Template; var template = (Template) Declaration;
paramsList = template.Parameters.Select(param => param.Name) return string.Join(", ", template.Parameters.Select(p => p.Name));
.ToList();
} }
var type = Type.Desugar();
IEnumerable<TemplateArgument> templateArgs;
var templateSpecializationType = type as TemplateSpecializationType;
if (templateSpecializationType != null)
templateArgs = templateSpecializationType.Arguments;
else else
templateArgs = ((ClassTemplateSpecialization) ((TagType) type).Declaration).Arguments;
var paramsList = new List<string>();
foreach (var arg in templateArgs.Where(a => a.Kind == TemplateArgument.ArgumentKind.Type))
{ {
var type = Type.Desugar() as TemplateSpecializationType; var argType = arg.Type.Type.IsPointerToPrimitiveType()
foreach (var arg in type.Arguments) ? new CILType(typeof(System.IntPtr))
{ : arg.Type.Type;
if (arg.Kind != TemplateArgument.ArgumentKind.Type) paramsList.Add(argType.ToString());
continue;
var argType = arg.Type.Type.IsPointerToPrimitiveType()
? new CILType(typeof(System.IntPtr))
: arg.Type.Type;
paramsList.Add(argType.ToString());
}
} }
return string.Join(", ", paramsList); return string.Join(", ", paramsList);

10
tests/CSharp/CSharp.cs

@ -21,8 +21,14 @@ namespace CppSharp.Tests
public override Type CSharpSignatureType(CSharpTypePrinterContext ctx) public override Type CSharpSignatureType(CSharpTypePrinterContext ctx)
{ {
var templateArgument = ((TemplateSpecializationType) ctx.Type.Desugar()).Arguments[0]; var type = ctx.Type.Desugar();
return templateArgument.Type.Type; ClassTemplateSpecialization classTemplateSpecialization;
var templateSpecializationType = type as TemplateSpecializationType;
if (templateSpecializationType != null)
classTemplateSpecialization = templateSpecializationType.GetClassTemplateSpecialization();
else
classTemplateSpecialization = (ClassTemplateSpecialization) ((TagType) type).Declaration;
return classTemplateSpecialization.Arguments[0].Type.Type;
} }
public override string CSharpSignature(CSharpTypePrinterContext ctx) public override string CSharpSignature(CSharpTypePrinterContext ctx)

3
tests/CSharp/CSharpTemplates.h

@ -20,6 +20,9 @@ class DLL_API DependentValueFields
{ {
private: private:
T field; T field;
union {
int unionField;
};
}; };
template <typename T> template <typename T>

Loading…
Cancel
Save