diff --git a/src/AST/ASTVisitor.cs b/src/AST/ASTVisitor.cs index 13eb2310..53704967 100644 --- a/src/AST/ASTVisitor.cs +++ b/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, TypeQualifiers quals) { - if (!VisitType(param, quals)) - return false; - - return true; + return VisitType(param, quals); } public virtual bool VisitTemplateParameterSubstitutionType( @@ -377,6 +375,9 @@ namespace CppSharp.AST foreach (var templateParameter in template.Parameters) templateParameter.Visit(this); + foreach (var specialization in template.Specializations) + specialization.Visit(this); + return true; } diff --git a/src/AST/Type.cs b/src/AST/Type.cs index 91192834..5ea1a0e1 100644 --- a/src/AST/Type.cs +++ b/src/AST/Type.cs @@ -634,6 +634,18 @@ namespace CppSharp.AST 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(ITypeVisitor visitor, TypeQualifiers quals = new TypeQualifiers()) { @@ -777,6 +789,8 @@ namespace CppSharp.AST Class = type.Class; } + public QualifiedType InjectedSpecializationType { get; set; } + public override T Visit(ITypeVisitor visitor, TypeQualifiers quals = new TypeQualifiers()) { diff --git a/src/AST/TypeExtensions.cs b/src/AST/TypeExtensions.cs index f4691cf4..3b2f78ff 100644 --- a/src/AST/TypeExtensions.cs +++ b/src/AST/TypeExtensions.cs @@ -120,20 +120,28 @@ { t = t.Desugar(); - var tag = t as TagType; - if (tag != null) + TagType tagType = null; + var type = t as TemplateSpecializationType; + if (type != null) { - decl = tag.Declaration as T; - return decl != null; + if (type.IsDependent) + { + 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 (type != null) + if (tagType != null) { - var templatedClass = ((ClassTemplate)type.Template).TemplatedClass; - decl = templatedClass.CompleteDeclaration == null - ? templatedClass as T - : (T) templatedClass.CompleteDeclaration; + decl = tagType.Declaration as T; return decl != null; } diff --git a/src/Core/Parser/ASTConverter.cs b/src/Core/Parser/ASTConverter.cs index aad0ebb0..b2d6422d 100644 --- a/src/Core/Parser/ASTConverter.cs +++ b/src/Core/Parser/ASTConverter.cs @@ -586,9 +586,8 @@ namespace CppSharp public override AST.Type VisitInjectedClassName(InjectedClassNameType type) { var _type = new CppSharp.AST.InjectedClassNameType(); - _type.TemplateSpecialization = Visit(type.TemplateSpecialization) - as AST.TemplateSpecializationType; _type.Class = declConverter.Visit(type.Class) as AST.Class; + _type.InjectedSpecializationType = VisitQualified(type.InjectedSpecializationType); VisitType(type, _type); return _type; } diff --git a/src/CppParser/AST.cpp b/src/CppParser/AST.cpp index dad6ce88..f0b2fe24 100644 --- a/src/CppParser/AST.cpp +++ b/src/CppParser/AST.cpp @@ -153,7 +153,6 @@ TemplateParameterSubstitutionType::TemplateParameterSubstitutionType() InjectedClassNameType::InjectedClassNameType() : Type(TypeKind::InjectedClassName) - , TemplateSpecialization(0) , Class(0) { } diff --git a/src/CppParser/AST.h b/src/CppParser/AST.h index b667e61d..fb299bb6 100644 --- a/src/CppParser/AST.h +++ b/src/CppParser/AST.h @@ -220,7 +220,7 @@ class CS_API InjectedClassNameType : public Type { public: InjectedClassNameType(); - TemplateSpecializationType* TemplateSpecialization; + QualifiedType InjectedSpecializationType; CppSharp::CppParser::AST::Class* Class; }; diff --git a/src/CppParser/Bindings/CLI/AST.cpp b/src/CppParser/Bindings/CLI/AST.cpp index db820536..d821d652 100644 --- a/src/CppParser/Bindings/CLI/AST.cpp +++ b/src/CppParser/Bindings/CLI/AST.cpp @@ -950,14 +950,14 @@ CppSharp::Parser::AST::InjectedClassNameType::InjectedClassNameType(CppSharp::Pa 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() diff --git a/src/CppParser/Bindings/CLI/AST.h b/src/CppParser/Bindings/CLI/AST.h index 4e82fbd5..c566f6f9 100644 --- a/src/CppParser/Bindings/CLI/AST.h +++ b/src/CppParser/Bindings/CLI/AST.h @@ -844,10 +844,10 @@ namespace CppSharp ~InjectedClassNameType(); - property CppSharp::Parser::AST::TemplateSpecializationType^ TemplateSpecialization + property CppSharp::Parser::AST::QualifiedType^ InjectedSpecializationType { - CppSharp::Parser::AST::TemplateSpecializationType^ get(); - void set(CppSharp::Parser::AST::TemplateSpecializationType^); + CppSharp::Parser::AST::QualifiedType^ get(); + void set(CppSharp::Parser::AST::QualifiedType^); } property CppSharp::Parser::AST::Class^ Class diff --git a/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs b/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs index 03c30df5..b123241a 100644 --- a/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/AST.cs +++ b/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 { - [StructLayout(LayoutKind.Explicit, Size = 16)] + [StructLayout(LayoutKind.Explicit, Size = 20)] public new partial struct Internal { [FieldOffset(0)] @@ -2194,9 +2194,9 @@ namespace CppSharp public byte IsDependent; [FieldOffset(8)] - public global::System.IntPtr TemplateSpecialization; + public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType; - [FieldOffset(12)] + [FieldOffset(16)] public global::System.IntPtr Class; [SuppressUnmanagedCodeSecurity] @@ -2222,7 +2222,7 @@ namespace CppSharp 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)); return ret.ToPointer(); } @@ -2246,7 +2246,7 @@ namespace CppSharp public InjectedClassNameType() : this((void*) null) { - __Instance = Marshal.AllocHGlobal(16); + __Instance = Marshal.AllocHGlobal(20); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; Internal.ctor_0((__Instance + __PointerAdjustment)); @@ -2255,7 +2255,7 @@ namespace CppSharp public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) : this((void*) null) { - __Instance = Marshal.AllocHGlobal(16); + __Instance = Marshal.AllocHGlobal(20); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; if (ReferenceEquals(_0, null)) @@ -2264,21 +2264,16 @@ namespace CppSharp Internal.cctor_2((__Instance + __PointerAdjustment), arg0); } - public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization + public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType { get { - CppSharp.Parser.AST.TemplateSpecializationType __result0; - 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; + return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType); } 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); } } diff --git a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs index 51405a3e..fb6c2d12 100644 --- a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/AST.cs +++ b/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 { - [StructLayout(LayoutKind.Explicit, Size = 16)] + [StructLayout(LayoutKind.Explicit, Size = 20)] public new partial struct Internal { [FieldOffset(0)] @@ -2194,9 +2194,9 @@ namespace CppSharp public byte IsDependent; [FieldOffset(8)] - public global::System.IntPtr TemplateSpecialization; + public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType; - [FieldOffset(12)] + [FieldOffset(16)] public global::System.IntPtr Class; [SuppressUnmanagedCodeSecurity] @@ -2222,7 +2222,7 @@ namespace CppSharp 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)); return ret.ToPointer(); } @@ -2246,7 +2246,7 @@ namespace CppSharp public InjectedClassNameType() : this((void*) null) { - __Instance = Marshal.AllocHGlobal(16); + __Instance = Marshal.AllocHGlobal(20); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; Internal.ctor_0((__Instance + __PointerAdjustment)); @@ -2255,7 +2255,7 @@ namespace CppSharp public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) : this((void*) null) { - __Instance = Marshal.AllocHGlobal(16); + __Instance = Marshal.AllocHGlobal(20); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; if (ReferenceEquals(_0, null)) @@ -2264,21 +2264,16 @@ namespace CppSharp Internal.cctor_2((__Instance + __PointerAdjustment), arg0); } - public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization + public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType { get { - CppSharp.Parser.AST.TemplateSpecializationType __result0; - 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; + return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType); } 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); } } diff --git a/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/AST.cs b/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/AST.cs index 21935bca..f07e0272 100644 --- a/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/AST.cs +++ b/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 { - [StructLayout(LayoutKind.Explicit, Size = 24)] + [StructLayout(LayoutKind.Explicit, Size = 32)] public new partial struct Internal { [FieldOffset(0)] @@ -2194,9 +2194,9 @@ namespace CppSharp public byte IsDependent; [FieldOffset(8)] - public global::System.IntPtr TemplateSpecialization; + public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType; - [FieldOffset(16)] + [FieldOffset(24)] public global::System.IntPtr Class; [SuppressUnmanagedCodeSecurity] @@ -2222,7 +2222,7 @@ namespace CppSharp 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)); return ret.ToPointer(); } @@ -2246,7 +2246,7 @@ namespace CppSharp public InjectedClassNameType() : this((void*) null) { - __Instance = Marshal.AllocHGlobal(24); + __Instance = Marshal.AllocHGlobal(32); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; Internal.ctor_0((__Instance + __PointerAdjustment)); @@ -2255,7 +2255,7 @@ namespace CppSharp public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) : this((void*) null) { - __Instance = Marshal.AllocHGlobal(24); + __Instance = Marshal.AllocHGlobal(32); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; if (ReferenceEquals(_0, null)) @@ -2264,21 +2264,16 @@ namespace CppSharp Internal.cctor_2((__Instance + __PointerAdjustment), arg0); } - public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization + public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType { get { - CppSharp.Parser.AST.TemplateSpecializationType __result0; - 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; + return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType); } 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); } } diff --git a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs index dc82185a..3d6fccc3 100644 --- a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/AST.cs +++ b/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 { - [StructLayout(LayoutKind.Explicit, Size = 24)] + [StructLayout(LayoutKind.Explicit, Size = 32)] public new partial struct Internal { [FieldOffset(0)] @@ -2194,9 +2194,9 @@ namespace CppSharp public byte IsDependent; [FieldOffset(8)] - public global::System.IntPtr TemplateSpecialization; + public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType; - [FieldOffset(16)] + [FieldOffset(24)] public global::System.IntPtr Class; [SuppressUnmanagedCodeSecurity] @@ -2222,7 +2222,7 @@ namespace CppSharp 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)); return ret.ToPointer(); } @@ -2246,7 +2246,7 @@ namespace CppSharp public InjectedClassNameType() : this((void*) null) { - __Instance = Marshal.AllocHGlobal(24); + __Instance = Marshal.AllocHGlobal(32); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; Internal.ctor_0((__Instance + __PointerAdjustment)); @@ -2255,7 +2255,7 @@ namespace CppSharp public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) : this((void*) null) { - __Instance = Marshal.AllocHGlobal(24); + __Instance = Marshal.AllocHGlobal(32); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; if (ReferenceEquals(_0, null)) @@ -2264,21 +2264,16 @@ namespace CppSharp Internal.cctor_2((__Instance + __PointerAdjustment), arg0); } - public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization + public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType { get { - CppSharp.Parser.AST.TemplateSpecializationType __result0; - 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; + return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType); } 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); } } diff --git a/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/AST.cs b/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/AST.cs index fea9b0f3..7e5baff5 100644 --- a/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/AST.cs +++ b/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 { - [StructLayout(LayoutKind.Explicit, Size = 24)] + [StructLayout(LayoutKind.Explicit, Size = 32)] public new partial struct Internal { [FieldOffset(0)] @@ -2194,9 +2194,9 @@ namespace CppSharp public byte IsDependent; [FieldOffset(8)] - public global::System.IntPtr TemplateSpecialization; + public CppSharp.Parser.AST.QualifiedType.Internal InjectedSpecializationType; - [FieldOffset(16)] + [FieldOffset(24)] public global::System.IntPtr Class; [SuppressUnmanagedCodeSecurity] @@ -2222,7 +2222,7 @@ namespace CppSharp 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)); return ret.ToPointer(); } @@ -2246,7 +2246,7 @@ namespace CppSharp public InjectedClassNameType() : this((void*) null) { - __Instance = Marshal.AllocHGlobal(24); + __Instance = Marshal.AllocHGlobal(32); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; Internal.ctor_0((__Instance + __PointerAdjustment)); @@ -2255,7 +2255,7 @@ namespace CppSharp public InjectedClassNameType(CppSharp.Parser.AST.InjectedClassNameType _0) : this((void*) null) { - __Instance = Marshal.AllocHGlobal(24); + __Instance = Marshal.AllocHGlobal(32); __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; if (ReferenceEquals(_0, null)) @@ -2264,21 +2264,16 @@ namespace CppSharp Internal.cctor_2((__Instance + __PointerAdjustment), arg0); } - public CppSharp.Parser.AST.TemplateSpecializationType TemplateSpecialization + public CppSharp.Parser.AST.QualifiedType InjectedSpecializationType { get { - CppSharp.Parser.AST.TemplateSpecializationType __result0; - 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; + return CppSharp.Parser.AST.QualifiedType.__CreateInstance(((Internal*) __Instance)->InjectedSpecializationType); } 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); } } diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 26bbdaa7..c4c503f9 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -2093,6 +2093,9 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL, auto ICNT = new InjectedClassNameType(); ICNT->Class = static_cast(WalkDeclaration( ICN->getDecl(), 0, /*IgnoreSystemDecls=*/false)); + ICNT->InjectedSpecializationType = GetQualifiedType( + ICN->getInjectedSpecializationType(), + WalkType(ICN->getInjectedSpecializationType())); Ty = ICNT; break; diff --git a/src/Generator.Tests/AST/TestAST.cs b/src/Generator.Tests/AST/TestAST.cs index 057a1356..58b3eb90 100644 --- a/src/Generator.Tests/AST/TestAST.cs +++ b/src/Generator.Tests/AST/TestAST.cs @@ -234,9 +234,9 @@ namespace CppSharp.Generator.Tests.AST Assert.AreEqual(1, integerInst.Arguments.Count); var intArgument = integerInst.Arguments[0]; Assert.AreEqual(new BuiltinType(PrimitiveType.Int), intArgument.Type.Type); - Class classTemplate; - Assert.IsTrue(typeDef.Type.TryGetClass(out classTemplate)); - Assert.AreEqual(classTemplate, template.TemplatedClass); + ClassTemplateSpecialization classTemplateSpecialization; + Assert.IsTrue(typeDef.Type.TryGetDeclaration(out classTemplateSpecialization)); + Assert.AreSame(classTemplateSpecialization.TemplatedDecl.TemplatedClass, template.TemplatedClass); } [Test] diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index cf6e6601..0aba7900 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -315,11 +315,25 @@ namespace CppSharp.Generators.CSharp PushBlock(CSharpBlockKind.Namespace); WriteLine("namespace {0}", classTemplate.Name); WriteStartBraceIndent(); + + IList specializations; if (classTemplate.TemplatedClass.Fields.Any(f => f.IsDependent && !f.Type.IsAddress())) - foreach (var specialization in classTemplate.Specializations) - GenerateClassInternals(specialization); + specializations = classTemplate.Specializations; 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(); PopBlock(NewLineKind.BeforeNextBlock); } diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index fcb2ea30..a081b0c9 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -387,6 +387,11 @@ namespace CppSharp.Generators.CSharp { if (ContextKind != CSharpTypePrinterContextKind.Native) 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); } diff --git a/src/Generator/Passes/CheckIgnoredDecls.cs b/src/Generator/Passes/CheckIgnoredDecls.cs index 037f08a5..50439032 100644 --- a/src/Generator/Passes/CheckIgnoredDecls.cs +++ b/src/Generator/Passes/CheckIgnoredDecls.cs @@ -28,6 +28,18 @@ namespace CppSharp.Passes 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) { if (AlreadyVisited(decl)) diff --git a/src/Generator/Passes/CleanInvalidDeclNamesPass.cs b/src/Generator/Passes/CleanInvalidDeclNamesPass.cs index 6c9804f6..01631112 100644 --- a/src/Generator/Passes/CleanInvalidDeclNamesPass.cs +++ b/src/Generator/Passes/CleanInvalidDeclNamesPass.cs @@ -63,6 +63,13 @@ namespace CppSharp.Passes base.VisitClassDecl(@class); 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)) { StringBuilder str = new StringBuilder(); diff --git a/src/Generator/Types/ITypePrinter.cs b/src/Generator/Types/ITypePrinter.cs index 6ea44a81..742bba69 100644 --- a/src/Generator/Types/ITypePrinter.cs +++ b/src/Generator/Types/ITypePrinter.cs @@ -25,25 +25,27 @@ namespace CppSharp.Types public string GetTemplateParameterList() { - var paramsList = new List(); if (Kind == TypePrinterContextKind.Template) { - var template = Declaration as Template; - paramsList = template.Parameters.Select(param => param.Name) - .ToList(); + var template = (Template) Declaration; + return string.Join(", ", template.Parameters.Select(p => p.Name)); } + + var type = Type.Desugar(); + IEnumerable templateArgs; + var templateSpecializationType = type as TemplateSpecializationType; + if (templateSpecializationType != null) + templateArgs = templateSpecializationType.Arguments; else + templateArgs = ((ClassTemplateSpecialization) ((TagType) type).Declaration).Arguments; + + var paramsList = new List(); + foreach (var arg in templateArgs.Where(a => a.Kind == TemplateArgument.ArgumentKind.Type)) { - var type = Type.Desugar() as TemplateSpecializationType; - foreach (var arg in type.Arguments) - { - if (arg.Kind != TemplateArgument.ArgumentKind.Type) - continue; - var argType = arg.Type.Type.IsPointerToPrimitiveType() - ? new CILType(typeof(System.IntPtr)) - : arg.Type.Type; - paramsList.Add(argType.ToString()); - } + var argType = arg.Type.Type.IsPointerToPrimitiveType() + ? new CILType(typeof(System.IntPtr)) + : arg.Type.Type; + paramsList.Add(argType.ToString()); } return string.Join(", ", paramsList); diff --git a/tests/CSharp/CSharp.cs b/tests/CSharp/CSharp.cs index e6be507d..c02c0d95 100644 --- a/tests/CSharp/CSharp.cs +++ b/tests/CSharp/CSharp.cs @@ -21,8 +21,14 @@ namespace CppSharp.Tests public override Type CSharpSignatureType(CSharpTypePrinterContext ctx) { - var templateArgument = ((TemplateSpecializationType) ctx.Type.Desugar()).Arguments[0]; - return templateArgument.Type.Type; + var type = ctx.Type.Desugar(); + 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) diff --git a/tests/CSharp/CSharpTemplates.h b/tests/CSharp/CSharpTemplates.h index fc55cd01..175d201d 100644 --- a/tests/CSharp/CSharpTemplates.h +++ b/tests/CSharp/CSharpTemplates.h @@ -20,6 +20,9 @@ class DLL_API DependentValueFields { private: T field; + union { + int unionField; + }; }; template