Browse Source

Trim specializations only used in ignored types

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1641/head
Dimitar Dobrev 4 years ago
parent
commit
12f456e4c4
  1. 7
      src/Generator/AST/Utils.cs
  2. 1
      src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs
  3. 8
      src/Generator/Passes/CheckIgnoredDecls.cs
  4. 10
      src/Generator/Passes/GenerateSymbolsPass.cs
  5. 22
      src/Generator/Passes/IgnoreSystemDeclarationsPass.cs
  6. 4
      src/Generator/Passes/TrimSpecializationsPass.cs
  7. 5
      tests/NamespacesDerived/NamespacesDerived.Gen.cs
  8. 22
      tests/NamespacesDerived/NamespacesDerived.h

7
src/Generator/AST/Utils.cs

@ -147,8 +147,8 @@ namespace CppSharp.AST
}); });
} }
private static bool UnsupportedTemplateArgument( public static bool UnsupportedTemplateArgument(this ClassTemplateSpecialization specialization,
ClassTemplateSpecialization specialization, TemplateArgument a, ITypeMapDatabase typeMaps) TemplateArgument a, ITypeMapDatabase typeMaps)
{ {
if (a.Type.Type == null || if (a.Type.Type == null ||
IsTypeExternal( IsTypeExternal(
@ -168,8 +168,7 @@ namespace CppSharp.AST
return (!internalOnly && (((specialization.Ignore || return (!internalOnly && (((specialization.Ignore ||
specialization.TemplatedDecl.TemplatedClass.Ignore) && typeMap == null) || specialization.TemplatedDecl.TemplatedClass.Ignore) && typeMap == null) ||
specialization.Arguments.Any(a => UnsupportedTemplateArgument( specialization.Arguments.Any(a => specialization.UnsupportedTemplateArgument(a, typeMaps)) ||
specialization, a, typeMaps)) ||
container.Namespace == specialization)) || container.Namespace == specialization)) ||
(!internalOnly && specialization.TemplatedDecl.TemplatedClass.IsIncomplete) || (!internalOnly && specialization.TemplatedDecl.TemplatedClass.IsIncomplete) ||
specialization is ClassTemplatePartialSpecialization; specialization is ClassTemplatePartialSpecialization;

1
src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs

@ -41,6 +41,7 @@ namespace CppSharp.Generators.CSharp
static bool allPointers(TemplateArgument a) => a.Type.Type?.Desugar().IsAddress() == true; static bool allPointers(TemplateArgument a) => a.Type.Type?.Desugar().IsAddress() == true;
var groups = (from @class in specializations var groups = (from @class in specializations
let spec = @class.GetParentSpecialization() let spec = @class.GetParentSpecialization()
orderby spec.IsGenerated descending
group @class by spec.Arguments.All(allPointers) group @class by spec.Arguments.All(allPointers)
into @group into @group
select @group).ToList(); select @group).ToList();

8
src/Generator/Passes/CheckIgnoredDecls.cs

@ -52,7 +52,9 @@ namespace CppSharp.Passes
return false; return false;
TypeMap typeMap; TypeMap typeMap;
if (!Options.GenerateClassTemplates && !specialization.IsExplicitlyGenerated && if (!Options.GenerateClassTemplates &&
!specialization.IsExplicitlyGenerated &&
specialization.GenerationKind != GenerationKind.Internal &&
!Context.TypeMaps.FindTypeMap(specialization, out typeMap)) !Context.TypeMaps.FindTypeMap(specialization, out typeMap))
{ {
specialization.ExplicitlyIgnore(); specialization.ExplicitlyIgnore();
@ -578,7 +580,7 @@ namespace CppSharp.Passes
private void IgnoreUnsupportedTemplates(Class @class) private void IgnoreUnsupportedTemplates(Class @class)
{ {
if (@class.TemplateParameters.Any(param => param is NonTypeTemplateParameter)) if (@class.TemplateParameters.Any(param => param is NonTypeTemplateParameter))
foreach (var specialization in @class.Specializations) foreach (var specialization in @class.Specializations.Where(s => s.IsGenerated))
specialization.ExplicitlyIgnore(); specialization.ExplicitlyIgnore();
if (!Options.IsCLIGenerator && !@class.TranslationUnit.IsSystemHeader && if (!Options.IsCLIGenerator && !@class.TranslationUnit.IsSystemHeader &&
@ -589,7 +591,7 @@ namespace CppSharp.Passes
foreach (var specialization in @class.Specializations) foreach (var specialization in @class.Specializations)
if (specialization.IsExplicitlyGenerated) if (specialization.IsExplicitlyGenerated)
hasExplicitlyGeneratedSpecializations = true; hasExplicitlyGeneratedSpecializations = true;
else else if (specialization.GenerationKind != GenerationKind.Internal)
specialization.ExplicitlyIgnore(); specialization.ExplicitlyIgnore();
if (!hasExplicitlyGeneratedSpecializations) if (!hasExplicitlyGeneratedSpecializations)

10
src/Generator/Passes/GenerateSymbolsPass.cs

@ -83,6 +83,16 @@ namespace CppSharp.Passes
} }
} }
public override bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization)
{
if (!specialization.IsGenerated ||
specialization.Arguments.Any(
a => specialization.UnsupportedTemplateArgument(a, Context.TypeMaps)))
return false;
return base.VisitClassTemplateSpecializationDecl(specialization);
}
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
if (!base.VisitClassDecl(@class)) if (!base.VisitClassDecl(@class))

22
src/Generator/Passes/IgnoreSystemDeclarationsPass.cs

@ -35,7 +35,7 @@ namespace CppSharp.Passes
if (!@class.IsDependent || @class.Specializations.Count == 0) if (!@class.IsDependent || @class.Specializations.Count == 0)
return false; return false;
foreach (var specialization in @class.Specializations) foreach (var specialization in @class.Specializations.Where(s => s.IsGenerated))
specialization.ExplicitlyIgnore(); specialization.ExplicitlyIgnore();
// we only need a few members for marshalling so strip the rest // we only need a few members for marshalling so strip the rest
@ -46,11 +46,14 @@ namespace CppSharp.Passes
case "char_traits": case "char_traits":
@class.GenerationKind = GenerationKind.Generate; @class.GenerationKind = GenerationKind.Generate;
foreach (var specialization in from s in @class.Specializations foreach (var specialization in from s in @class.Specializations
where !s.Arguments.Any(a =>
s.UnsupportedTemplateArgument(a, Context.TypeMaps))
let arg = s.Arguments[0].Type.Type.Desugar() let arg = s.Arguments[0].Type.Type.Desugar()
where arg.IsPrimitiveType(PrimitiveType.Char) where arg.IsPrimitiveType(PrimitiveType.Char)
select s) select s)
{ {
specialization.GenerationKind = GenerationKind.Generate; specialization.GenerationKind = GenerationKind.Generate;
InternalizeSpecializationsInFields(specialization);
} }
break; break;
} }
@ -100,5 +103,22 @@ namespace CppSharp.Passes
return true; return true;
} }
private void InternalizeSpecializationsInFields(ClassTemplateSpecialization specialization)
{
foreach (Field field in specialization.Fields)
{
ASTUtils.CheckTypeForSpecialization(field.Type, specialization,
specialization =>
{
if (!specialization.IsExplicitlyGenerated &&
specialization.GenerationKind != GenerationKind.Internal)
{
specialization.GenerationKind = GenerationKind.Internal;
InternalizeSpecializationsInFields(specialization);
}
}, Context.TypeMaps, true);
}
}
} }
} }

4
src/Generator/Passes/TrimSpecializationsPass.cs

@ -22,7 +22,7 @@ namespace CppSharp.Passes
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
if (!base.VisitClassDecl(@class)) if (!@class.Ignore && !base.VisitClassDecl(@class))
return false; return false;
if (@class.IsTemplate) if (@class.IsTemplate)
@ -124,7 +124,7 @@ namespace CppSharp.Passes
specialization.ExplicitlyIgnore(); specialization.ExplicitlyIgnore();
foreach (var specialization in template.Specializations.Where( foreach (var specialization in template.Specializations.Where(
s => !s.IsExplicitlyGenerated && internalSpecializations.Contains(s))) s => !s.IsExplicitlyGenerated && !s.Ignore && internalSpecializations.Contains(s)))
specialization.GenerationKind = GenerationKind.Internal; specialization.GenerationKind = GenerationKind.Internal;
for (int i = template.Specializations.Count - 1; i >= 0; i--) for (int i = template.Specializations.Count - 1; i >= 0; i--)

5
tests/NamespacesDerived/NamespacesDerived.Gen.cs

@ -27,6 +27,11 @@ namespace CppSharp.Tests
module.Libraries.Add($"{@base}.Native"); module.Libraries.Add($"{@base}.Native");
driver.Options.Modules[1].Dependencies.Add(module); driver.Options.Modules[1].Dependencies.Add(module);
} }
public override void Preprocess(Driver driver, AST.ASTContext ctx)
{
ctx.IgnoreClassWithName("Ignored");
}
} }
public static class NamespacesDerived public static class NamespacesDerived

22
tests/NamespacesDerived/NamespacesDerived.h

@ -1,6 +1,7 @@
#include "../Tests.h" #include "../Tests.h"
#include "../NamespacesBase/NamespacesBase.h" #include "../NamespacesBase/NamespacesBase.h"
#include "Independent.h" #include "Independent.h"
#include <string>
// Namespace clashes with NamespacesBase.OverlappingNamespace // Namespace clashes with NamespacesBase.OverlappingNamespace
// Test whether qualified names turn out right. // Test whether qualified names turn out right.
@ -86,6 +87,27 @@ class DLL_API DerivedFromSecondaryBaseInDependency : public Derived, public Seco
{ {
}; };
template<typename T>
class CustomAllocator
{
public:
typedef T value_type;
T* allocate(size_t cnt, const void* = 0)
{
return 0;
}
void deallocate(T* p, size_t cnt)
{
}
};
class DLL_API Ignored
{
private:
std::basic_string<char, std::char_traits<char>, CustomAllocator<char>> f;
};
DLL_API bool operator<<(const Base& b, const char* str); DLL_API bool operator<<(const Base& b, const char* str);
namespace NamespacesBase namespace NamespacesBase

Loading…
Cancel
Save