Permalink
Browse files

Added support for class templates which do not specialise types exter…

…nal to them.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
  • Loading branch information...
ddobrev committed Jun 8, 2017
1 parent 225cd5c commit cd548059e941685916acd6128e4a40d716cb3e5a
@@ -184,7 +184,12 @@ public virtual bool VisitDecayedType(DecayedType decayed, TypeQualifiers quals)
}
if (template.IsDependent && template.Template != null)
{
var @class = template.Template.TemplatedDecl as Class;
if (@class != null)
return @class.Specializations.Any(s => s.Visit(this));
return template.Template.Visit(this);
}
var specialization = template.GetClassTemplateSpecialization();
return specialization != null && specialization.Visit(this);
@@ -732,7 +732,7 @@ private void MarshalRefClass(Class @class)
}
string param = Context.Parameter.Name;
Type type = Context.Parameter.Type.Desugar();
Type type = Context.Parameter.Type.Desugar(false);
string paramInstance;
Class @interface;
var finalType = type.GetFinalPointee() ?? type;
@@ -39,9 +39,18 @@ public override bool VisitClassDecl(Class @class)
if (!@class.IsDependent)
return false;
// templates are not supported yet
foreach (var specialization in @class.Specializations.Where(s => !s.IsExplicitlyGenerated))
specialization.ExplicitlyIgnore();
if (Options.IsCLIGenerator || @class.TranslationUnit.IsSystemHeader ||
@class.Specializations.Count == 0)
{
bool hasExplicitlyGeneratedSpecializations = false;
foreach (var specialization in @class.Specializations)
if (specialization.IsExplicitlyGenerated)
hasExplicitlyGeneratedSpecializations = true;
else
specialization.ExplicitlyIgnore();
if (!hasExplicitlyGeneratedSpecializations)
@class.ExplicitlyIgnore();
}
return true;
}
@@ -62,14 +71,6 @@ public override bool VisitDeclaration(Declaration decl)
return true;
}
if (decl.IsDependent && !decl.IsExplicitlyGenerated)
{
decl.GenerationKind = decl is Field ? GenerationKind.Internal : GenerationKind.None;
Diagnostics.Debug("Decl '{0}' was ignored due to dependent context",
decl.Name);
return true;
}
return true;
}
@@ -107,6 +108,14 @@ public override bool VisitFunctionDecl(Function function)
|| function.IsExplicitlyGenerated)
return false;
if (function.IsDependent && !(function.Namespace is Class))
{
function.GenerationKind = GenerationKind.None;
Diagnostics.Debug("Function '{0}' was ignored due to dependent context",
function.Name);
return false;
}
var ret = function.OriginalReturnType;
string msg;
@@ -231,7 +240,8 @@ public override bool VisitTypedefDecl(TypedefDecl typedef)
return false;
string msg;
if (HasInvalidType(typedef.Type, typedef.TranslationUnit.Module, out msg))
if (HasInvalidType(typedef.Type, typedef.TranslationUnit.Module, out msg) &&
!(typedef.Type.Desugar() is MemberPointerType))
{
typedef.ExplicitlyIgnore();
Diagnostics.Debug("Typedef '{0}' was ignored due to {1} type",
@@ -78,7 +78,7 @@ public override bool VisitClassDecl(Class @class)
if (@class.IsDependent)
foreach (var specialization in @class.Specializations.Where(
s => s.IsExplicitlyGenerated))
Add(specialization);
specialization.Visit(this);
else
foreach (var @base in @class.Bases.Where(b => b.IsClass))
{
@@ -203,7 +203,6 @@ private void Add(ClassTemplateSpecialization specialization)
specs = specializations[specialization.TranslationUnit.Module];
else specs = specializations[specialization.TranslationUnit.Module] =
new HashSet<ClassTemplateSpecialization>();
GetSymbolsCodeGenerator(specialization.TranslationUnit.Module);
specs.Add(specialization);
}
@@ -21,6 +21,7 @@ public override bool VisitClassTemplateDecl(ClassTemplate template)
if (!base.VisitClassTemplateDecl(template))
return false;
bool complete = !template.TemplatedDecl.IsIncomplete;
EnsureCompleteDeclaration(template.TemplatedDecl);
template.TemplatedDecl = template.TemplatedDecl.CompleteDeclaration ?? template.TemplatedDecl;
@@ -29,8 +30,11 @@ public override bool VisitClassTemplateDecl(ClassTemplate template)
s => !s.IsIncomplete && !template.TemplatedClass.Specializations.Contains(s)))
template.TemplatedClass.Specializations.Add(specialization);
if (template.TemplatedClass.TemplateParameters.Count == 0)
if (template.TemplatedClass.TemplateParameters.Count == 0 || complete)
{
template.TemplatedClass.TemplateParameters.Clear();
template.TemplatedClass.TemplateParameters.AddRange(template.Parameters);
}
return true;
}
@@ -123,10 +123,10 @@ public override bool VisitParameterDecl(Parameter parameter)
return false;
}
var specialization = template.GetClassTemplateSpecialization();
if (specialization == null || specialization.Ignore)
var result = base.VisitTemplateSpecializationType(template, quals);
if (!result)
Ignore();
return base.VisitTemplateSpecializationType(template, quals);
return result;
}
public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
@@ -656,6 +656,89 @@ public void TestStackOverflowOnVirtualCall()
}
}
[Test]
public void TestTemplateWithPointerToTypeParameter()
{
int staticT = 5;
Assert.That(IndependentFieldsExtensions.StaticDependent(ref staticT), Is.EqualTo(5));
}
[Test]
public void TestTemplateCopyConstructor()
{
using (var original = new IndependentFields<int>(5))
{
using (var copy = new IndependentFields<int>(original))
{
Assert.That(copy.Independent, Is.EqualTo(original.Independent));
}
}
}
[Test]
public void TestTemplateWithIndependentFields()
{
using (var independentFields = new IndependentFields<int>())
{
var t = 5;
Assert.That(independentFields.GetDependent(ref t), Is.EqualTo(5));
Assert.That(independentFields.Independent, Is.EqualTo(1));
}
using (var independentFields = new IndependentFields<bool>())
{
var t = true;
Assert.That(independentFields.GetDependent(ref t), Is.EqualTo(true));
Assert.That(independentFields.Independent, Is.EqualTo(1));
}
}
[Test]
public void TestVirtualTemplate()
{
using (var virtualTemplate = new VirtualTemplate<int>())
{
Assert.That(virtualTemplate.Function, Is.EqualTo(5));
}
}
[Test]
public void TestOverrideOfTemplate()
{
using (var hasVirtualTemplate = new HasVirtualTemplate())
{
using (var overrideVirtualTemplate = new OverrideVirtualTemplate())
{
hasVirtualTemplate.SetV(overrideVirtualTemplate);
Assert.That(hasVirtualTemplate.Function, Is.EqualTo(10));
}
}
}
[Test]
public void TestDefaultTemplateArgument()
{
using (var hasDefaultTemplateArgument = new HasDefaultTemplateArgument<int, int>())
{
hasDefaultTemplateArgument.Property = 10;
Assert.That(hasDefaultTemplateArgument.Property, Is.EqualTo(10));
}
}
[Test]
public void TestTemplateStaticProperty()
{
HasDefaultTemplateArgument<int, int>.StaticProperty = 5;
Assert.That(HasDefaultTemplateArgument<int, int>.StaticProperty, Is.EqualTo(5));
}
[Test]
public void TestIndependentConstInIndependentTemplate()
{
Assert.That(IndependentFields<int>.IndependentConst, Is.EqualTo(15));
Assert.That(IndependentFields<bool>.IndependentConst, Is.EqualTo(15));
Assert.That(IndependentFields<T1>.IndependentConst, Is.EqualTo(15));
}
[Test]
public void TestAbstractImplementatonsInPrimaryAndSecondaryBases()
{
@@ -862,4 +945,12 @@ public void TestFuncWithTypedefedFuncPtrAsParam()
TypedefedFuncPtr function = (a, b) => 5;
Assert.That(CSharp.CSharp.FuncWithTypedefedFuncPtrAsParam(function), Is.EqualTo(5));
}
private class OverrideVirtualTemplate : VirtualTemplate<int>
{
public override int Function
{
get { return 10; }
}
}
}
@@ -700,12 +700,12 @@ void HasOverridesWithIncreasedAccess::privateOverride(int i)
{
}
IgnoredType<int> PropertyWithIgnoredType::ignoredType()
IgnoredType PropertyWithIgnoredType::ignoredType()
{
return _ignoredType;
}
void PropertyWithIgnoredType::setIgnoredType(const IgnoredType<int> &value)
void PropertyWithIgnoredType::setIgnoredType(const IgnoredType& value)
{
_ignoredType = value;
}
@@ -131,9 +131,14 @@ private static Type GetEnumType(Type mappedType)
ClassTemplateSpecialization classTemplateSpecialization;
var templateSpecializationType = type as TemplateSpecializationType;
if (templateSpecializationType != null)
{
classTemplateSpecialization = templateSpecializationType.GetClassTemplateSpecialization();
else
classTemplateSpecialization = (ClassTemplateSpecialization)((TagType)type).Declaration;
return classTemplateSpecialization.Arguments[0].Type.Type;
}
var declaration = ((TagType) type).Declaration;
if (declaration.IsDependent)
return new TagType(((Class) declaration).TemplateParameters[0]);
classTemplateSpecialization = (ClassTemplateSpecialization) declaration;
return classTemplateSpecialization.Arguments[0].Type.Type;
}
}
@@ -185,8 +190,14 @@ public override bool IsIgnored
public override string CSharpSignature(TypePrinterContext ctx)
{
if (ctx.Kind == TypePrinterContextKind.Native)
return string.Format("QList.{0}{1}", Helpers.InternalStruct,
{
var type = (TemplateSpecializationType) ctx.Type.Desugar();
var specialization = type.GetClassTemplateSpecialization();
var typePrinter = new CSharpTypePrinter(null);
typePrinter.PushContext(TypePrinterContextKind.Native);
return string.Format($"{specialization.Visit(typePrinter)}{(Type.IsAddress() ? "*" : string.Empty)}", specialization.Visit(typePrinter),
Type.IsAddress() ? "*" : string.Empty);
}
return string.Format("System.Collections.Generic.{0}<{1}>",
ctx.MarshalKind == MarshalKind.DefaultExpression ? "List" : "IList",
@@ -196,7 +207,11 @@ public override string CSharpSignature(TypePrinterContext ctx)
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{
// pointless, put just so that the generated code compiles
ctx.Return.Write("new QList.{0}()", Helpers.InternalStruct);
var type = (TemplateSpecializationType) ctx.Parameter.Type.Desugar();
var specialization = type.GetClassTemplateSpecialization();
var typePrinter = new CSharpTypePrinter(null);
typePrinter.PushContext(TypePrinterContextKind.Native);
ctx.Return.Write("new {0}()", specialization.Visit(typePrinter));
}
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
@@ -481,7 +481,6 @@ class DLL_API AbstractWithProperty
virtual int property() = 0;
};
template <typename T>
class DLL_API IgnoredType
{
};
@@ -493,10 +492,10 @@ class DLL_API IgnoredTypeInheritingNonIgnoredWithNoEmptyCtor : public P
class DLL_API PropertyWithIgnoredType
{
public:
IgnoredType<int> ignoredType();
void setIgnoredType(const IgnoredType<int>& value);
IgnoredType ignoredType();
void setIgnoredType(const IgnoredType& value);
private:
IgnoredType<int> _ignoredType;
IgnoredType _ignoredType;
};
// --- Multiple inheritance
Oops, something went wrong.

0 comments on commit cd54805

Please sign in to comment.