Skip to content

Commit 12f456e

Browse files
committed
Trim specializations only used in ignored types
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent 4be3808 commit 12f456e

File tree

8 files changed

+69
-10
lines changed

8 files changed

+69
-10
lines changed

Diff for: src/Generator/AST/Utils.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ private static bool UsesAdditionalTypeParam(Method method)
147147
});
148148
}
149149

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

169169
return (!internalOnly && (((specialization.Ignore ||
170170
specialization.TemplatedDecl.TemplatedClass.Ignore) && typeMap == null) ||
171-
specialization.Arguments.Any(a => UnsupportedTemplateArgument(
172-
specialization, a, typeMaps)) ||
171+
specialization.Arguments.Any(a => specialization.UnsupportedTemplateArgument(a, typeMaps)) ||
173172
container.Namespace == specialization)) ||
174173
(!internalOnly && specialization.TemplatedDecl.TemplatedClass.IsIncomplete) ||
175174
specialization is ClassTemplatePartialSpecialization;

Diff for: src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public static IEnumerable<Class> KeepSingleAllPointersSpecialization(
4141
static bool allPointers(TemplateArgument a) => a.Type.Type?.Desugar().IsAddress() == true;
4242
var groups = (from @class in specializations
4343
let spec = @class.GetParentSpecialization()
44+
orderby spec.IsGenerated descending
4445
group @class by spec.Arguments.All(allPointers)
4546
into @group
4647
select @group).ToList();

Diff for: src/Generator/Passes/CheckIgnoredDecls.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ public override bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializ
5252
return false;
5353

5454
TypeMap typeMap;
55-
if (!Options.GenerateClassTemplates && !specialization.IsExplicitlyGenerated &&
55+
if (!Options.GenerateClassTemplates &&
56+
!specialization.IsExplicitlyGenerated &&
57+
specialization.GenerationKind != GenerationKind.Internal &&
5658
!Context.TypeMaps.FindTypeMap(specialization, out typeMap))
5759
{
5860
specialization.ExplicitlyIgnore();
@@ -578,7 +580,7 @@ private bool IsDeclIgnored(Declaration decl)
578580
private void IgnoreUnsupportedTemplates(Class @class)
579581
{
580582
if (@class.TemplateParameters.Any(param => param is NonTypeTemplateParameter))
581-
foreach (var specialization in @class.Specializations)
583+
foreach (var specialization in @class.Specializations.Where(s => s.IsGenerated))
582584
specialization.ExplicitlyIgnore();
583585

584586
if (!Options.IsCLIGenerator && !@class.TranslationUnit.IsSystemHeader &&
@@ -589,7 +591,7 @@ private void IgnoreUnsupportedTemplates(Class @class)
589591
foreach (var specialization in @class.Specializations)
590592
if (specialization.IsExplicitlyGenerated)
591593
hasExplicitlyGeneratedSpecializations = true;
592-
else
594+
else if (specialization.GenerationKind != GenerationKind.Internal)
593595
specialization.ExplicitlyIgnore();
594596

595597
if (!hasExplicitlyGeneratedSpecializations)

Diff for: src/Generator/Passes/GenerateSymbolsPass.cs

+10
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ private void GenerateSymbols()
8383
}
8484
}
8585

86+
public override bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization)
87+
{
88+
if (!specialization.IsGenerated ||
89+
specialization.Arguments.Any(
90+
a => specialization.UnsupportedTemplateArgument(a, Context.TypeMaps)))
91+
return false;
92+
93+
return base.VisitClassTemplateSpecializationDecl(specialization);
94+
}
95+
8696
public override bool VisitClassDecl(Class @class)
8797
{
8898
if (!base.VisitClassDecl(@class))

Diff for: src/Generator/Passes/IgnoreSystemDeclarationsPass.cs

+21-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public override bool VisitClassDecl(Class @class)
3535
if (!@class.IsDependent || @class.Specializations.Count == 0)
3636
return false;
3737

38-
foreach (var specialization in @class.Specializations)
38+
foreach (var specialization in @class.Specializations.Where(s => s.IsGenerated))
3939
specialization.ExplicitlyIgnore();
4040

4141
// we only need a few members for marshalling so strip the rest
@@ -46,11 +46,14 @@ public override bool VisitClassDecl(Class @class)
4646
case "char_traits":
4747
@class.GenerationKind = GenerationKind.Generate;
4848
foreach (var specialization in from s in @class.Specializations
49+
where !s.Arguments.Any(a =>
50+
s.UnsupportedTemplateArgument(a, Context.TypeMaps))
4951
let arg = s.Arguments[0].Type.Type.Desugar()
5052
where arg.IsPrimitiveType(PrimitiveType.Char)
5153
select s)
5254
{
5355
specialization.GenerationKind = GenerationKind.Generate;
56+
InternalizeSpecializationsInFields(specialization);
5457
}
5558
break;
5659
}
@@ -100,5 +103,22 @@ public override bool VisitVariableDecl(Variable variable)
100103

101104
return true;
102105
}
106+
107+
private void InternalizeSpecializationsInFields(ClassTemplateSpecialization specialization)
108+
{
109+
foreach (Field field in specialization.Fields)
110+
{
111+
ASTUtils.CheckTypeForSpecialization(field.Type, specialization,
112+
specialization =>
113+
{
114+
if (!specialization.IsExplicitlyGenerated &&
115+
specialization.GenerationKind != GenerationKind.Internal)
116+
{
117+
specialization.GenerationKind = GenerationKind.Internal;
118+
InternalizeSpecializationsInFields(specialization);
119+
}
120+
}, Context.TypeMaps, true);
121+
}
122+
}
103123
}
104124
}

Diff for: src/Generator/Passes/TrimSpecializationsPass.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public override bool VisitASTContext(ASTContext context)
2222

2323
public override bool VisitClassDecl(Class @class)
2424
{
25-
if (!base.VisitClassDecl(@class))
25+
if (!@class.Ignore && !base.VisitClassDecl(@class))
2626
return false;
2727

2828
if (@class.IsTemplate)
@@ -124,7 +124,7 @@ private void CleanSpecializations(Class template)
124124
specialization.ExplicitlyIgnore();
125125

126126
foreach (var specialization in template.Specializations.Where(
127-
s => !s.IsExplicitlyGenerated && internalSpecializations.Contains(s)))
127+
s => !s.IsExplicitlyGenerated && !s.Ignore && internalSpecializations.Contains(s)))
128128
specialization.GenerationKind = GenerationKind.Internal;
129129

130130
for (int i = template.Specializations.Count - 1; i >= 0; i--)

Diff for: tests/NamespacesDerived/NamespacesDerived.Gen.cs

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public override void Setup(Driver driver)
2727
module.Libraries.Add($"{@base}.Native");
2828
driver.Options.Modules[1].Dependencies.Add(module);
2929
}
30+
31+
public override void Preprocess(Driver driver, AST.ASTContext ctx)
32+
{
33+
ctx.IgnoreClassWithName("Ignored");
34+
}
3035
}
3136

3237
public static class NamespacesDerived

Diff for: tests/NamespacesDerived/NamespacesDerived.h

+22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "../Tests.h"
22
#include "../NamespacesBase/NamespacesBase.h"
33
#include "Independent.h"
4+
#include <string>
45

56
// Namespace clashes with NamespacesBase.OverlappingNamespace
67
// Test whether qualified names turn out right.
@@ -86,6 +87,27 @@ class DLL_API DerivedFromSecondaryBaseInDependency : public Derived, public Seco
8687
{
8788
};
8889

90+
template<typename T>
91+
class CustomAllocator
92+
{
93+
public:
94+
typedef T value_type;
95+
96+
T* allocate(size_t cnt, const void* = 0)
97+
{
98+
return 0;
99+
}
100+
void deallocate(T* p, size_t cnt)
101+
{
102+
}
103+
};
104+
105+
class DLL_API Ignored
106+
{
107+
private:
108+
std::basic_string<char, std::char_traits<char>, CustomAllocator<char>> f;
109+
};
110+
89111
DLL_API bool operator<<(const Base& b, const char* str);
90112

91113
namespace NamespacesBase

0 commit comments

Comments
 (0)