From ff1abf360feca8501ce091212ecc5d94d91c9126 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sun, 30 Jul 2017 16:11:38 +0300 Subject: [PATCH] Ensured all fields in class layouts are checked for specialisations. Signed-off-by: Dimitar Dobrev --- .../Bindings/CSharp/i686-pc-win32-msvc/Std.cs | 21 ----- .../CSharp/x86_64-pc-win32-msvc/Std.cs | 21 ----- src/Generator/AST/Utils.cs | 89 ++++++++++++++----- .../Passes/TrimSpecializationsPass.cs | 19 ++-- 4 files changed, 79 insertions(+), 71 deletions(-) diff --git a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/Std.cs b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/Std.cs index 67c33846..d26c8044 100644 --- a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/Std.cs +++ b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/Std.cs @@ -162,27 +162,6 @@ namespace Std internal global::Std.StringVal.__Internal _Myval2; } - [StructLayout(LayoutKind.Explicit, Size = 24)] - public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator__W___N_std_S__String_val____N_std_S__Simple_types__W_Vb1 - { - [FieldOffset(0)] - internal global::Std.StringVal.__Internal _Myval2; - } - - [StructLayout(LayoutKind.Explicit, Size = 24)] - public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator__q___N_std_S__String_val____N_std_S__Simple_types__q_Vb1 - { - [FieldOffset(0)] - internal global::Std.StringVal.__Internal _Myval2; - } - - [StructLayout(LayoutKind.Explicit, Size = 24)] - public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator__w___N_std_S__String_val____N_std_S__Simple_types__w_Vb1 - { - [FieldOffset(0)] - internal global::Std.StringVal.__Internal _Myval2; - } - [StructLayout(LayoutKind.Explicit, Size = 12)] public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_PreprocessedEntity___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1 { diff --git a/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/Std.cs b/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/Std.cs index 23c5ab9a..474f8bc0 100644 --- a/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/Std.cs +++ b/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/Std.cs @@ -162,27 +162,6 @@ namespace Std internal global::Std.StringVal.__Internal _Myval2; } - [StructLayout(LayoutKind.Explicit, Size = 32)] - public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator__W___N_std_S__String_val____N_std_S__Simple_types__W_Vb1 - { - [FieldOffset(0)] - internal global::Std.StringVal.__Internal _Myval2; - } - - [StructLayout(LayoutKind.Explicit, Size = 32)] - public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator__q___N_std_S__String_val____N_std_S__Simple_types__q_Vb1 - { - [FieldOffset(0)] - internal global::Std.StringVal.__Internal _Myval2; - } - - [StructLayout(LayoutKind.Explicit, Size = 32)] - public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator__w___N_std_S__String_val____N_std_S__Simple_types__w_Vb1 - { - [FieldOffset(0)] - internal global::Std.StringVal.__Internal _Myval2; - } - [StructLayout(LayoutKind.Explicit, Size = 24)] public unsafe partial struct __Internalc__N_std_S__Compressed_pair____N_std_S__Wrap_alloc____N_std_S_allocator_____N_CppSharp_N_CppParser_N_AST_S_PreprocessedEntity___N_std_S__Vector_val____N_std_S__Simple_types__S2__Vb1 { diff --git a/src/Generator/AST/Utils.cs b/src/Generator/AST/Utils.cs index e403b028..bce8b389 100644 --- a/src/Generator/AST/Utils.cs +++ b/src/Generator/AST/Utils.cs @@ -90,38 +90,19 @@ namespace CppSharp.AST { type = type.Desugar(); type = (type.GetFinalPointee() ?? type).Desugar(); - ClassTemplateSpecialization specialization; - type.TryGetDeclaration(out specialization); + ClassTemplateSpecialization specialization = GetParentSpecialization(type); if (specialization == null) return; - TypeMap typeMap; - typeMaps.FindTypeMap(specialization, out typeMap); - - if ((!internalOnly && (((specialization.Ignore || - specialization.TemplatedDecl.TemplatedClass.Ignore) && typeMap == null) || - specialization.Arguments.Any(a => UnsupportedTemplateArgument( - specialization, a, typeMaps)))) || - specialization.IsIncomplete || - (!internalOnly && specialization.TemplatedDecl.TemplatedClass.IsIncomplete) || - specialization is ClassTemplatePartialSpecialization || - container.Namespace == specialization) + if (IsSpecializationNeeded(container, typeMaps, internalOnly, specialization)) return; - while (container.Namespace != null) + if (!internalOnly) { - if (container.Namespace == specialization) + if (IsSpecializationSelfContained(specialization, container)) return; - container = container.Namespace; - } - if (!internalOnly && typeMaps.FindTypeMap(specialization, out typeMap)) - { - var typePrinterContext = new TypePrinterContext { Type = type }; - var mappedTo = typeMap.CSharpSignatureType(typePrinterContext); - mappedTo = mappedTo.Desugar(); - mappedTo = (mappedTo.GetFinalPointee() ?? mappedTo); - if (mappedTo.IsPrimitiveType() || mappedTo.IsPointerToPrimitiveType() || mappedTo.IsEnum()) + if (IsMappedToPrimitive(typeMaps, type, specialization)) return; } @@ -169,6 +150,66 @@ namespace CppSharp.AST a.Type.Type.Visit(typeIgnoreChecker); return typeIgnoreChecker.IsIgnored; } + + private static bool IsSpecializationNeeded(Declaration container, + ITypeMapDatabase typeMaps, bool internalOnly, + ClassTemplateSpecialization specialization) + { + TypeMap typeMap; + typeMaps.FindTypeMap(specialization, out typeMap); + + return (!internalOnly && (((specialization.Ignore || + specialization.TemplatedDecl.TemplatedClass.Ignore) && typeMap == null) || + specialization.Arguments.Any(a => UnsupportedTemplateArgument( + specialization, a, typeMaps)) || + container.Namespace == specialization)) || + specialization.IsIncomplete || + (!internalOnly && specialization.TemplatedDecl.TemplatedClass.IsIncomplete) || + specialization is ClassTemplatePartialSpecialization; + } + + private static ClassTemplateSpecialization GetParentSpecialization(Type type) + { + Declaration declaration; + if (type.TryGetDeclaration(out declaration)) + { + ClassTemplateSpecialization specialization = null; + do + { + specialization = declaration as ClassTemplateSpecialization; + declaration = declaration.Namespace; + } while (declaration != null && specialization == null); + return specialization; + } + return null; + } + + private static bool IsSpecializationSelfContained( + ClassTemplateSpecialization specialization, Declaration container) + { + while (container.Namespace != null) + { + if (container.Namespace == specialization) + return true; + container = container.Namespace; + } + return false; + } + + private static bool IsMappedToPrimitive(ITypeMapDatabase typeMaps, + Type type, ClassTemplateSpecialization specialization) + { + TypeMap typeMap; + if (!typeMaps.FindTypeMap(specialization, out typeMap)) + return false; + + var typePrinterContext = new TypePrinterContext { Type = type }; + var mappedTo = typeMap.CSharpSignatureType(typePrinterContext); + mappedTo = mappedTo.Desugar(); + mappedTo = (mappedTo.GetFinalPointee() ?? mappedTo).Desugar(); + return (mappedTo.IsPrimitiveType() || + mappedTo.IsPointerToPrimitiveType() || mappedTo.IsEnum()); + } } public static class Operators diff --git a/src/Generator/Passes/TrimSpecializationsPass.cs b/src/Generator/Passes/TrimSpecializationsPass.cs index 51948749..e61313b5 100644 --- a/src/Generator/Passes/TrimSpecializationsPass.cs +++ b/src/Generator/Passes/TrimSpecializationsPass.cs @@ -168,17 +168,26 @@ namespace CppSharp.Passes private void CheckForInternalSpecialization(Declaration container, AST.Type type) { ASTUtils.CheckTypeForSpecialization(type, container, - s => + specialization => { - if (!specializations.Contains(s)) + if (!specializations.Contains(specialization)) { - internalSpecializations.Add(s); - foreach (var f in s.Fields) - f.Visit(this); + internalSpecializations.Add(specialization); + CheckLayoutFields(specialization); } }, Context.TypeMaps, true); } + private void CheckLayoutFields(Class @class) + { + foreach (var field in @class.Fields) + field.Visit(this); + foreach (var @base in from @base in @class.Bases + where @base.IsClass + select @base.Class) + CheckLayoutFields(@base); + } + private HashSet specializations = new HashSet(); private HashSet internalSpecializations = new HashSet(); private HashSet templates = new HashSet();