Skip to content

Commit

Permalink
Restored explicit specialisations but added exceptions for their meth…
Browse files Browse the repository at this point in the history
…ods.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
  • Loading branch information
ddobrev committed Aug 13, 2017
1 parent 1c81a92 commit f818005
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 20 deletions.
55 changes: 39 additions & 16 deletions src/Generator/Generators/CSharp/CSharpSources.cs
Expand Up @@ -799,7 +799,15 @@ private void GenerateClassField(Field field, bool @public = false)

private void GenerateFunctionSetter(Class @class, Property property)
{
property = GetActualProperty(property, @class);
var actualProperty = GetActualProperty(property, @class);
if (actualProperty == null)
{
WriteLine($@"throw new MissingMethodException(""Method {
property.Name} missing from explicit specialization {
@class.Visit(TypePrinter)}."");");
return;
}
property = actualProperty;
var param = new Parameter
{
Name = "value",
Expand Down Expand Up @@ -1070,7 +1078,15 @@ private void GenerateIndexerSetter(Function function)

private void GenerateFunctionGetter(Class @class, Property property)
{
property = GetActualProperty(property, @class);
var actualProperty = GetActualProperty(property, @class);
if (actualProperty == null)
{
WriteLine($@"throw new MissingMethodException(""Method {
property.Name} missing from explicit specialization {
@class.Visit(TypePrinter)}."");");
return;
}
property = actualProperty;
if (property.GetMethod.SynthKind == FunctionSynthKind.AbstractImplCall)
GenerateVirtualPropertyCall(property.GetMethod, @class.BaseClass, property);
else if (property.GetMethod.IsVirtual)
Expand All @@ -1083,11 +1099,8 @@ private static Property GetActualProperty(Property property, Class c)
{
if (!(c is ClassTemplateSpecialization))
return property;
if (property.GetMethod != null
&& property.GetMethod.OperatorKind == CXXOperatorKind.Subscript)
return c.Properties.Single(p => p.GetMethod != null
&& p.GetMethod.InstantiatedFrom == property.GetMethod);
return c.Properties.Single(p => p.Name == property.Name);
return c.Properties.SingleOrDefault(p => p.GetMethod != null &&
p.GetMethod.InstantiatedFrom == property.GetMethod);
}

private void GenerateFieldGetter(Field field, Class @class)
Expand Down Expand Up @@ -1956,9 +1969,7 @@ private void GenerateDisposeMethods(Class @class)
c is ClassTemplateSpecialization ?
c.Methods.First(m => m.InstantiatedFrom == dtor) : dtor), true);
else
this.GenerateMember(@class, c => GenerateInternalFunctionCall(
c is ClassTemplateSpecialization ?
c.Methods.First(m => m.InstantiatedFrom == dtor) : dtor), true);
this.GenerateMember(@class, c => GenerateMethodBody(c, dtor), true);
if (@class.IsDependent || dtor.IsVirtual)
WriteCloseBraceIndent();
else
Expand Down Expand Up @@ -2265,16 +2276,14 @@ public void GenerateMethod(Method method, Class @class)
if (method.SynthKind == FunctionSynthKind.DefaultValueOverload ||
method.SynthKind == FunctionSynthKind.ComplementOperator)
{
GenerateMethodBody(method);
GenerateMethodBody(@class, method);
}
else
{
var isVoid = method.OriginalReturnType.Type.Desugar().IsPrimitiveType(PrimitiveType.Void) ||
method.IsConstructor;
this.GenerateMember(@class, c => GenerateMethodBody(
c is ClassTemplateSpecialization ?
c.Methods.First(m => m.InstantiatedFrom == method) : method,
method.OriginalReturnType), isVoid);
c, method, method.OriginalReturnType), isVoid);
}

SkipImpl:
Expand All @@ -2289,10 +2298,24 @@ public void GenerateMethod(Method method, Class @class)
PopBlock(NewLineKind.BeforeNextBlock);
}

private void GenerateMethodBody(Method method,
private void GenerateMethodBody(Class @class, Method method,
QualifiedType returnType = default(QualifiedType))
{
var @class = (Class) method.Namespace;
var specialization = @class as ClassTemplateSpecialization;
if (specialization != null)
{
var specializedMethod = @class.Methods.FirstOrDefault(
m => m.InstantiatedFrom == method);
if (specializedMethod != null)
method = specializedMethod;
else
{
WriteLine($@"throw new MissingMethodException(""Method {
method.Name} missing from explicit specialization {
@class.Visit(TypePrinter)}."");");
return;
}
}
if (@class.IsRefType)
{
if (method.IsConstructor)
Expand Down
7 changes: 3 additions & 4 deletions src/Generator/Passes/TrimSpecializationsPass.cs
Expand Up @@ -95,10 +95,9 @@ private void CleanSpecializations(Class template)
!specializations.Contains(s) && !internalSpecializations.Contains(s));

foreach (var specialization in template.Specializations.Where(
s => !s.IsExplicitlyGenerated
&& (s.SpecializationKind == TemplateSpecializationKind.ExplicitSpecialization
|| s is ClassTemplatePartialSpecialization
|| internalSpecializations.Contains(s))))
s => !s.IsExplicitlyGenerated &&
(s is ClassTemplatePartialSpecialization ||
internalSpecializations.Contains(s))))
specialization.ExplicitlyIgnore();

Func<TemplateArgument, bool> allPointers =
Expand Down
8 changes: 8 additions & 0 deletions tests/CSharp/CSharpTemplates.cpp
Expand Up @@ -56,6 +56,14 @@ void HasDefaultTemplateArgument<bool, bool>::setStaticProperty(const bool& t)

bool HasDefaultTemplateArgument<bool, bool>::staticField;

DerivesFromExplicitSpecialization::DerivesFromExplicitSpecialization()
{
}

DerivesFromExplicitSpecialization::~DerivesFromExplicitSpecialization()
{
}

HasVirtualTemplate::HasVirtualTemplate()
{
}
Expand Down
25 changes: 25 additions & 0 deletions tests/CSharp/CSharpTemplates.h
Expand Up @@ -275,6 +275,31 @@ DependentValueFields<D> HasDefaultTemplateArgument<T, D>::returnTemplateWithRena
template <typename T, typename D>
T HasDefaultTemplateArgument<T, D>::staticField;

template <typename T, typename D>
class DerivesFromTemplateWithExplicitSpecialization : public HasDefaultTemplateArgument<T, D>
{
public:
DerivesFromTemplateWithExplicitSpecialization();
~DerivesFromTemplateWithExplicitSpecialization();
};

template <typename T, typename D>
DerivesFromTemplateWithExplicitSpecialization<T, D>::DerivesFromTemplateWithExplicitSpecialization()
{
}

template <typename T, typename D>
DerivesFromTemplateWithExplicitSpecialization<T, D>::~DerivesFromTemplateWithExplicitSpecialization()
{
}

class DerivesFromExplicitSpecialization : public DerivesFromTemplateWithExplicitSpecialization<bool, bool>
{
public:
DerivesFromExplicitSpecialization();
~DerivesFromExplicitSpecialization();
};

template <typename T>
class TemplateWithIndexer
{
Expand Down

0 comments on commit f818005

Please sign in to comment.