Skip to content

Commit

Permalink
Trim specializations only used in ignored types
Browse files Browse the repository at this point in the history
Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
  • Loading branch information
ddobrev committed Oct 27, 2021
1 parent 4be3808 commit 12f456e
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 10 deletions.
7 changes: 3 additions & 4 deletions src/Generator/AST/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ private static bool UsesAdditionalTypeParam(Method method)
});
}

private static bool UnsupportedTemplateArgument(
ClassTemplateSpecialization specialization, TemplateArgument a, ITypeMapDatabase typeMaps)
public static bool UnsupportedTemplateArgument(this ClassTemplateSpecialization specialization,
TemplateArgument a, ITypeMapDatabase typeMaps)
{
if (a.Type.Type == null ||
IsTypeExternal(
Expand All @@ -168,8 +168,7 @@ private static bool IsSpecializationNeeded(Declaration container,

return (!internalOnly && (((specialization.Ignore ||
specialization.TemplatedDecl.TemplatedClass.Ignore) && typeMap == null) ||
specialization.Arguments.Any(a => UnsupportedTemplateArgument(
specialization, a, typeMaps)) ||
specialization.Arguments.Any(a => specialization.UnsupportedTemplateArgument(a, typeMaps)) ||
container.Namespace == specialization)) ||
(!internalOnly && specialization.TemplatedDecl.TemplatedClass.IsIncomplete) ||
specialization is ClassTemplatePartialSpecialization;
Expand Down
1 change: 1 addition & 0 deletions src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public static IEnumerable<Class> KeepSingleAllPointersSpecialization(
static bool allPointers(TemplateArgument a) => a.Type.Type?.Desugar().IsAddress() == true;
var groups = (from @class in specializations
let spec = @class.GetParentSpecialization()
orderby spec.IsGenerated descending
group @class by spec.Arguments.All(allPointers)
into @group
select @group).ToList();
Expand Down
8 changes: 5 additions & 3 deletions src/Generator/Passes/CheckIgnoredDecls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public override bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializ
return false;

TypeMap typeMap;
if (!Options.GenerateClassTemplates && !specialization.IsExplicitlyGenerated &&
if (!Options.GenerateClassTemplates &&
!specialization.IsExplicitlyGenerated &&
specialization.GenerationKind != GenerationKind.Internal &&
!Context.TypeMaps.FindTypeMap(specialization, out typeMap))
{
specialization.ExplicitlyIgnore();
Expand Down Expand Up @@ -578,7 +580,7 @@ private bool IsDeclIgnored(Declaration decl)
private void IgnoreUnsupportedTemplates(Class @class)
{
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();

if (!Options.IsCLIGenerator && !@class.TranslationUnit.IsSystemHeader &&
Expand All @@ -589,7 +591,7 @@ private void IgnoreUnsupportedTemplates(Class @class)
foreach (var specialization in @class.Specializations)
if (specialization.IsExplicitlyGenerated)
hasExplicitlyGeneratedSpecializations = true;
else
else if (specialization.GenerationKind != GenerationKind.Internal)
specialization.ExplicitlyIgnore();

if (!hasExplicitlyGeneratedSpecializations)
Expand Down
10 changes: 10 additions & 0 deletions src/Generator/Passes/GenerateSymbolsPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ private void GenerateSymbols()
}
}

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)
{
if (!base.VisitClassDecl(@class))
Expand Down
22 changes: 21 additions & 1 deletion src/Generator/Passes/IgnoreSystemDeclarationsPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public override bool VisitClassDecl(Class @class)
if (!@class.IsDependent || @class.Specializations.Count == 0)
return false;

foreach (var specialization in @class.Specializations)
foreach (var specialization in @class.Specializations.Where(s => s.IsGenerated))
specialization.ExplicitlyIgnore();

// we only need a few members for marshalling so strip the rest
Expand All @@ -46,11 +46,14 @@ public override bool VisitClassDecl(Class @class)
case "char_traits":
@class.GenerationKind = GenerationKind.Generate;
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()
where arg.IsPrimitiveType(PrimitiveType.Char)
select s)
{
specialization.GenerationKind = GenerationKind.Generate;
InternalizeSpecializationsInFields(specialization);
}
break;
}
Expand Down Expand Up @@ -100,5 +103,22 @@ public override bool VisitVariableDecl(Variable variable)

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 changes: 2 additions & 2 deletions src/Generator/Passes/TrimSpecializationsPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public override bool VisitASTContext(ASTContext context)

public override bool VisitClassDecl(Class @class)
{
if (!base.VisitClassDecl(@class))
if (!@class.Ignore && !base.VisitClassDecl(@class))
return false;

if (@class.IsTemplate)
Expand Down Expand Up @@ -124,7 +124,7 @@ private void CleanSpecializations(Class template)
specialization.ExplicitlyIgnore();

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;

for (int i = template.Specializations.Count - 1; i >= 0; i--)
Expand Down
5 changes: 5 additions & 0 deletions tests/NamespacesDerived/NamespacesDerived.Gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public override void Setup(Driver driver)
module.Libraries.Add($"{@base}.Native");
driver.Options.Modules[1].Dependencies.Add(module);
}

public override void Preprocess(Driver driver, AST.ASTContext ctx)
{
ctx.IgnoreClassWithName("Ignored");
}
}

public static class NamespacesDerived
Expand Down
22 changes: 22 additions & 0 deletions tests/NamespacesDerived/NamespacesDerived.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "../Tests.h"
#include "../NamespacesBase/NamespacesBase.h"
#include "Independent.h"
#include <string>

// Namespace clashes with NamespacesBase.OverlappingNamespace
// Test whether qualified names turn out right.
Expand Down Expand Up @@ -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);

namespace NamespacesBase
Expand Down

0 comments on commit 12f456e

Please sign in to comment.