From 853e82f095f478a32b879e2af4c9d7995b519953 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Tue, 28 Nov 2017 15:34:36 +0200 Subject: [PATCH] Fixed the generated C# for specialisations only used as type arguments. Signed-off-by: Dimitar Dobrev --- src/CppParser/Parser.cpp | 11 +++++------ src/Generator/Generators/CSharp/CSharpSources.cs | 5 ++--- src/Generator/Generators/CSharp/CSharpTypePrinter.cs | 3 +++ src/Generator/Passes/TrimSpecializationsPass.cs | 4 ++-- src/Generator/Types/TypeIgnoreChecker.cs | 5 +---- tests/CSharp/CSharpTemplates.cpp | 3 ++- tests/CSharp/CSharpTemplates.h | 8 +++++++- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 13ff4dd2..fec1f63d 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -1437,15 +1437,14 @@ Parser::WalkTemplateArgument(const clang::TemplateArgument& TA, clang::TemplateA case clang::TemplateArgument::Type: { Arg.kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::Type; + clang::TypeLoc ArgTL; if (ArgLoc && ArgLoc->getTypeSourceInfo()) { - auto ArgTL = ArgLoc->getTypeSourceInfo()->getTypeLoc(); - Arg.type = GetQualifiedType(TA.getAsType(), &ArgTL); - } - else - { - Arg.type = GetQualifiedType(TA.getAsType()); + ArgTL = ArgLoc->getTypeSourceInfo()->getTypeLoc(); } + auto Type = TA.getAsType(); + CompleteIfSpecializationType(Type); + Arg.type = GetQualifiedType(Type, &ArgTL); break; } case clang::TemplateArgument::Declaration: diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 7dde37aa..ca4d892c 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -295,9 +295,8 @@ namespace CppSharp.Generators.CSharp private IEnumerable GetGenerated( IList specializations) { - var specialization = specializations.FirstOrDefault(s => !s.Ignore); - if (specialization == null) - specialization = specializations[0]; + var specialization = specializations.FirstOrDefault(s => s.IsGenerated) ?? + specializations[0]; Class classTemplate = specialization.TemplatedDecl.TemplatedClass; if (classTemplate.HasDependentValueFieldInLayout()) diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index f07827d6..919b0665 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -179,6 +179,9 @@ namespace CppSharp.Generators.CSharp public static bool IsConstCharString(PointerType pointer) { + if (pointer.IsReference) + return false; + var pointee = pointer.Pointee.Desugar(); return (pointee.IsPrimitiveType(PrimitiveType.Char) || diff --git a/src/Generator/Passes/TrimSpecializationsPass.cs b/src/Generator/Passes/TrimSpecializationsPass.cs index 9ff80c84..2c1586e9 100644 --- a/src/Generator/Passes/TrimSpecializationsPass.cs +++ b/src/Generator/Passes/TrimSpecializationsPass.cs @@ -66,8 +66,7 @@ namespace CppSharp.Passes Action add = s => { - if (internalSpecializations.Contains(s)) - internalSpecializations.Remove(s); + internalSpecializations.Remove(s); specializations.Add(s); }; ASTUtils.CheckTypeForSpecialization(function.OriginalReturnType.Type, @@ -189,6 +188,7 @@ namespace CppSharp.Passes var specialization = @base.Class as ClassTemplateSpecialization; if (specialization != null) { + internalSpecializations.Remove(specialization); specializations.Add(specialization); foreach (var field in specialization.Fields) field.Visit(this); diff --git a/src/Generator/Types/TypeIgnoreChecker.cs b/src/Generator/Types/TypeIgnoreChecker.cs index 8dcae3e0..015fcdf3 100644 --- a/src/Generator/Types/TypeIgnoreChecker.cs +++ b/src/Generator/Types/TypeIgnoreChecker.cs @@ -126,10 +126,7 @@ namespace CppSharp return false; } - var result = base.VisitTemplateSpecializationType(template, quals); - if (!result) - Ignore(); - return result; + return IsIgnored = !base.VisitTemplateSpecializationType(template, quals); } public override bool VisitArrayType(ArrayType array, TypeQualifiers quals) diff --git a/tests/CSharp/CSharpTemplates.cpp b/tests/CSharp/CSharpTemplates.cpp index 514e23b7..fc7bfcce 100644 --- a/tests/CSharp/CSharpTemplates.cpp +++ b/tests/CSharp/CSharpTemplates.cpp @@ -126,7 +126,8 @@ void forceUseSpecializations(IndependentFields _1, IndependentFields VirtualTemplate _6, VirtualTemplate _7, HasDefaultTemplateArgument _8, DerivedChangesTypeName _9, TemplateWithIndexer _10, TemplateWithIndexer _11, - TemplateWithIndexer _12, TemplateDerivedFromRegularDynamic _13, std::string s) + TemplateWithIndexer _12, TemplateDerivedFromRegularDynamic _13, + IndependentFields > _14, std::string s) { } diff --git a/tests/CSharp/CSharpTemplates.h b/tests/CSharp/CSharpTemplates.h index 6fc307bd..1f9a7f99 100644 --- a/tests/CSharp/CSharpTemplates.h +++ b/tests/CSharp/CSharpTemplates.h @@ -492,6 +492,11 @@ TemplateDerivedFromRegularDynamic::~TemplateDerivedFromRegularDynamic() { } +template +class OnlySpecialisedInTypeArg +{ +}; + // we optimise specialisations so that only actually used ones are wrapped void forceUseSpecializations(IndependentFields _1, IndependentFields _2, IndependentFields _3, IndependentFields _4, @@ -499,7 +504,8 @@ void forceUseSpecializations(IndependentFields _1, IndependentFields VirtualTemplate _6, VirtualTemplate _7, HasDefaultTemplateArgument _8, DerivedChangesTypeName _9, TemplateWithIndexer _10, TemplateWithIndexer _11, - TemplateWithIndexer _12, TemplateDerivedFromRegularDynamic _13, std::string s); + TemplateWithIndexer _12, TemplateDerivedFromRegularDynamic _13, + IndependentFields> _14, std::string s); DLL_API DependentValueFields specialiseReturnOnly();