Browse Source

Reduced the wrapped specialisations to ones used in public members.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/859/head
Dimitar Dobrev 8 years ago
parent
commit
d487088f53
  1. 111
      src/Generator/AST/Utils.cs
  2. 15
      src/Generator/Passes/CheckIgnoredDecls.cs
  3. 64
      src/Generator/Passes/GenerateSymbolsPass.cs
  4. 123
      src/Generator/Passes/TrimSpecializationsPass.cs

111
src/Generator/AST/Utils.cs

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@

using System;
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST.Extensions;
using CppSharp.Types;
namespace CppSharp.AST
{
@ -20,6 +22,9 @@ namespace CppSharp.AST @@ -20,6 +22,9 @@ namespace CppSharp.AST
{
if (!method.IsGenerated) return true;
if (method.IsDependent && UsesAdditionalTypeParam(method))
return true;
var isEmptyCtor = method.IsConstructor && method.Parameters.Count == 0;
var @class = method.Namespace as Class;
@ -48,9 +53,10 @@ namespace CppSharp.AST @@ -48,9 +53,10 @@ namespace CppSharp.AST
if (!baseClass.IsInterface)
{
var copyConstructor = baseClass.Methods.FirstOrDefault(m => m.IsCopyConstructor);
if (copyConstructor == null
|| copyConstructor.Access == AccessSpecifier.Private
|| !copyConstructor.IsDeclared)
if (copyConstructor == null ||
copyConstructor.Access == AccessSpecifier.Private ||
(!copyConstructor.IsDeclared &&
!copyConstructor.TranslationUnit.IsSystemHeader))
return true;
}
}
@ -61,7 +67,7 @@ namespace CppSharp.AST @@ -61,7 +67,7 @@ namespace CppSharp.AST
public static bool CheckIgnoreField(Field field, bool useInternals = false)
{
if (field.Access == AccessSpecifier.Private && !useInternals)
if (field.Access == AccessSpecifier.Private && !useInternals)
return true;
if (field.Class.IsValueType && field.IsDeclared)
@ -80,6 +86,99 @@ namespace CppSharp.AST @@ -80,6 +86,99 @@ namespace CppSharp.AST
return !prop.IsGenerated;
}
public static void CheckTypeForSpecialization(Type type, Declaration container,
Action<ClassTemplateSpecialization> addSpecialization,
ITypeMapDatabase typeMaps, bool internalOnly = false)
{
type = type.Desugar();
type = type.GetFinalPointee() ?? type;
ClassTemplateSpecialization specialization;
if (!type.TryGetDeclaration(out specialization) ||
specialization.IsExplicitlyGenerated)
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 ||
specialization.TemplatedDecl.TemplatedClass.IsIncomplete ||
specialization is ClassTemplatePartialSpecialization ||
container.Namespace == specialization)
return;
while (container.Namespace != null)
{
if (container.Namespace == specialization)
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())
return;
}
addSpecialization(specialization);
}
public static bool IsTypeExternal(Module module, Type type)
{
Declaration declaration;
if (!(type.GetFinalPointee() ?? type).TryGetDeclaration(out declaration))
return false;
declaration = declaration.CompleteDeclaration ?? declaration;
if (declaration.Namespace == null || declaration.TranslationUnit.Module == null)
return false;
return declaration.TranslationUnit.Module.Dependencies.Contains(module);
}
private static bool UsesAdditionalTypeParam(Method method)
{
var specialization = method.Namespace as ClassTemplateSpecialization;
Class template;
if (specialization != null)
template = specialization.TemplatedDecl.TemplatedClass;
else
{
template = (Class) method.Namespace;
if (!template.IsDependent)
return false;
}
var typeParams = template.TemplateParameters.Select(t => t.Name).ToList();
return method.Parameters.Any(p =>
{
if (!p.IsDependent)
return false;
var desugared = p.Type.Desugar();
var finalType = (desugared.GetFinalPointee() ?? desugared).Desugar()
as TemplateParameterType;
return finalType != null && !typeParams.Contains(finalType.Parameter.Name);
});
}
private static bool UnsupportedTemplateArgument(
ClassTemplateSpecialization specialization, TemplateArgument a, ITypeMapDatabase typeMaps)
{
if (a.Type.Type == null ||
IsTypeExternal(specialization.TranslationUnit.Module, a.Type.Type))
return true;
var typeIgnoreChecker = new TypeIgnoreChecker(typeMaps);
a.Type.Type.Visit(typeIgnoreChecker);
return typeIgnoreChecker.IsIgnored;
}
}
public static class Operators

15
src/Generator/Passes/CheckIgnoredDecls.cs

@ -368,7 +368,7 @@ namespace CppSharp.Passes @@ -368,7 +368,7 @@ namespace CppSharp.Passes
}
if (Options.DoAllModulesHaveLibraries() &&
module != Options.SystemModule && IsTypeExternal(module, type))
module != Options.SystemModule && ASTUtils.IsTypeExternal(module, type))
{
msg = "external";
return true;
@ -433,19 +433,6 @@ namespace CppSharp.Passes @@ -433,19 +433,6 @@ namespace CppSharp.Passes
return !decl.IsIncomplete || decl.CompleteDeclaration != null;
}
public static bool IsTypeExternal(Module module, Type type)
{
Declaration declaration;
if (!(type.GetFinalPointee() ?? type).TryGetDeclaration(out declaration))
return false;
declaration = declaration.CompleteDeclaration ?? declaration;
if (declaration.Namespace == null || declaration.TranslationUnit.Module == null)
return false;
return declaration.TranslationUnit.Module.Dependencies.Contains(module);
}
private bool IsTypeIgnored(Type type)
{
var checker = new TypeIgnoreChecker(TypeMaps);

64
src/Generator/Passes/GenerateSymbolsPass.cs

@ -83,9 +83,21 @@ namespace CppSharp.Passes @@ -83,9 +83,21 @@ namespace CppSharp.Passes
if (function.IsGenerated)
{
CheckTypeForSpecialization(function.OriginalReturnType.Type);
Action<ClassTemplateSpecialization> add =
s =>
{
ICollection<ClassTemplateSpecialization> specs;
if (specializations.ContainsKey(s.TranslationUnit.Module))
specs = specializations[s.TranslationUnit.Module];
else specs = specializations[s.TranslationUnit.Module] =
new HashSet<ClassTemplateSpecialization>();
specs.Add(s);
};
ASTUtils.CheckTypeForSpecialization(function.OriginalReturnType.Type,
function, add, Context.TypeMaps);
foreach (var parameter in function.Parameters)
CheckTypeForSpecialization(parameter.Type);
ASTUtils.CheckTypeForSpecialization(parameter.Type, function,
add, Context.TypeMaps);
}
if (!NeedsSymbol(function))
@ -95,54 +107,6 @@ namespace CppSharp.Passes @@ -95,54 +107,6 @@ namespace CppSharp.Passes
return function.Visit(symbolsCodeGenerator);
}
private void CheckTypeForSpecialization(AST.Type type)
{
type = type.Desugar();
ClassTemplateSpecialization specialization;
type = type.GetFinalPointee() ?? type;
if (!type.TryGetDeclaration(out specialization))
return;
if (specialization.Ignore ||
specialization.TemplatedDecl.TemplatedClass.Ignore ||
specialization.IsIncomplete ||
specialization.TemplatedDecl.TemplatedClass.IsIncomplete ||
specialization is ClassTemplatePartialSpecialization ||
specialization.Arguments.Any(a => UnsupportedTemplateArgument(specialization, a)))
return;
TypeMap typeMap;
if (Context.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())
return;
}
HashSet<ClassTemplateSpecialization> list;
if (specializations.ContainsKey(specialization.TranslationUnit.Module))
list = specializations[specialization.TranslationUnit.Module];
else
specializations[specialization.TranslationUnit.Module] =
list = new HashSet<ClassTemplateSpecialization>();
list.Add(specialization);
}
private bool UnsupportedTemplateArgument(ClassTemplateSpecialization specialization, TemplateArgument a)
{
if (a.Type.Type == null ||
CheckIgnoredDeclsPass.IsTypeExternal(
specialization.TranslationUnit.Module, a.Type.Type))
return true;
var typeIgnoreChecker = new TypeIgnoreChecker(Context.TypeMaps);
a.Type.Type.Visit(typeIgnoreChecker);
return typeIgnoreChecker.IsIgnored;
}
public class SymbolsCodeEventArgs : EventArgs
{
public SymbolsCodeEventArgs(Module module)

123
src/Generator/Passes/TrimSpecializationsPass.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
@ -7,38 +8,124 @@ namespace CppSharp.Passes @@ -7,38 +8,124 @@ namespace CppSharp.Passes
{
public class TrimSpecializationsPass : TranslationUnitPass
{
public override bool VisitASTContext(ASTContext context)
{
var result = base.VisitASTContext(context);
foreach (var template in templates)
CleanSpecializations(template);
return result;
}
public override bool VisitClassDecl(Class @class)
{
if (!base.VisitClassDecl(@class) || @class.IsIncomplete || !@class.IsDependent)
if (!base.VisitClassDecl(@class))
return false;
@class.Specializations.RemoveAll(
s => s.Fields.Any(f => f.Type.IsPrimitiveType(PrimitiveType.Void)));
if (@class.IsDependent)
templates.Add(@class);
else
foreach (var @base in @class.Bases.Where(b => b.IsClass))
{
var specialization = @base.Class as ClassTemplateSpecialization;
if (specialization != null)
specializations.Add(specialization);
}
foreach (var specialization in @class.Specializations.Where(s => s.Arguments.Any(
a => a.Type.Type != null &&
CheckIgnoredDeclsPass.IsTypeExternal(@class.TranslationUnit.Module, a.Type.Type)) ||
@class is ClassTemplatePartialSpecialization))
specialization.ExplicitlyIgnore();
return true;
}
if (@class.Specializations.Count == 0)
public override bool VisitFunctionDecl(Function function)
{
if (!base.VisitFunctionDecl(function))
return false;
Func<TemplateArgument, bool> allPointers = a => a.Type.Type != null && a.Type.Type.IsAddress();
var groups = (from specialization in @class.Specializations
group specialization by specialization.Arguments.All(allPointers) into @group
if (function.IsGenerated)
{
Action<ClassTemplateSpecialization> add =
s =>
{
if (internalSpecializations.Contains(s))
internalSpecializations.Remove(s);
specializations.Add(s);
};
ASTUtils.CheckTypeForSpecialization(function.OriginalReturnType.Type,
function, add, Context.TypeMaps);
foreach (var parameter in function.Parameters)
ASTUtils.CheckTypeForSpecialization(parameter.Type, function,
add, Context.TypeMaps);
}
return true;
}
public override bool VisitFieldDecl(Field field)
{
if (!base.VisitDeclaration(field))
return false;
ASTUtils.CheckTypeForSpecialization(field.Type, field,
s =>
{
if (!specializations.Contains(s))
internalSpecializations.Add(s);
}, Context.TypeMaps, true);
return true;
}
private void CleanSpecializations(Class template)
{
template.Specializations.RemoveAll(s => !s.IsExplicitlyGenerated &&
!specializations.Contains(s) && !internalSpecializations.Contains(s));
foreach (var specialization in template.Specializations.Where(
s => !s.IsExplicitlyGenerated &&
(s.Arguments.Any(a =>
{
if (a.Kind != TemplateArgument.ArgumentKind.Declaration &&
a.Kind != TemplateArgument.ArgumentKind.Template &&
a.Kind != TemplateArgument.ArgumentKind.Type)
return true;
var type = a.Type.Type.Desugar();
if (ASTUtils.IsTypeExternal(template.TranslationUnit.Module, type) ||
type.IsPrimitiveType(PrimitiveType.Void))
return true;
var typeIgnoreChecker = new TypeIgnoreChecker(TypeMaps);
type.Visit(typeIgnoreChecker);
return typeIgnoreChecker.IsIgnored;
}) ||
s.SpecializationKind == TemplateSpecializationKind.ExplicitSpecialization ||
s is ClassTemplatePartialSpecialization ||
internalSpecializations.Contains(s))))
specialization.ExplicitlyIgnore();
Func<TemplateArgument, bool> allPointers =
a => a.Type.Type != null && a.Type.Type.IsAddress();
var groups = (from specialization in template.Specializations
group specialization by specialization.Arguments.All(allPointers)
into @group
select @group).ToList();
foreach (var group in groups.Where(g => g.Key))
foreach (var specialization in group.Skip(1))
@class.Specializations.Remove(specialization);
template.Specializations.Remove(specialization);
for (int i = @class.Specializations.Count - 1; i >= 0; i--)
if (@class.Specializations[i] is ClassTemplatePartialSpecialization &&
!@class.Specializations[i].Arguments.All(allPointers))
@class.Specializations.RemoveAt(i);
for (int i = template.Specializations.Count - 1; i >= 0; i--)
{
var specialization = template.Specializations[i];
if (specialization is ClassTemplatePartialSpecialization &&
!specialization.Arguments.All(allPointers))
template.Specializations.RemoveAt(i);
}
return true;
if (!template.IsExplicitlyGenerated &&
template.Specializations.All(s => s.Ignore))
template.ExplicitlyIgnore();
}
private HashSet<ClassTemplateSpecialization> specializations = new HashSet<ClassTemplateSpecialization>();
private HashSet<ClassTemplateSpecialization> internalSpecializations = new HashSet<ClassTemplateSpecialization>();
private HashSet<Class> templates = new HashSet<Class>();
}
}

Loading…
Cancel
Save