From aab63d0aa338563e96ee98e2ee617236130faa68 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Tue, 21 Dec 2021 01:32:38 +0200 Subject: [PATCH] Generate valid C# for unresolvable base templates Signed-off-by: Dimitar Dobrev --- .../Generators/CSharp/CSharpSources.cs | 6 ++-- src/Generator/Generators/CodeGenerator.cs | 33 ++++++++++--------- tests/CSharp/CSharp.h | 3 ++ 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index b35b84498e..351d113b29 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -274,7 +274,7 @@ public virtual void GenerateNamespaceFunctionsAndVariables(DeclarationContext co WriteOpenBraceAndIndent(); PushBlock(BlockKind.InternalsClass); - GenerateClassInternalHead(); + GenerateClassInternalHead(new Class { Name = parentName }); WriteOpenBraceAndIndent(); // Generate all the internal function declarations. @@ -704,7 +704,7 @@ private IEnumerable GatherInternalParams(Function function, out TypePrin return @params; } - private void GenerateClassInternalHead(Class @class = null) + private void GenerateClassInternalHead(Class @class) { Write("public "); @@ -3143,7 +3143,7 @@ public void GenerateFunctionCall(string functionName, Function function, if (operatorParam == null) { WriteLine($@"fixed ({Helpers.InternalStruct}{ - Helpers.GetSuffixForInternal(originalFunction.Namespace)}* __instancePtr = &{ + Helpers.GetSuffixForInternal((Class) originalFunction.Namespace)}* __instancePtr = &{ Helpers.InstanceField})"); WriteOpenBraceAndIndent(); } diff --git a/src/Generator/Generators/CodeGenerator.cs b/src/Generator/Generators/CodeGenerator.cs index 1178f18093..b96b428b1b 100644 --- a/src/Generator/Generators/CodeGenerator.cs +++ b/src/Generator/Generators/CodeGenerator.cs @@ -1303,29 +1303,30 @@ public static class Helpers public static readonly string CreateInstanceIdentifier = Generator.GeneratedIdentifier("CreateInstance"); public static readonly string GetOrCreateInstanceIdentifier = Generator.GeneratedIdentifier("GetOrCreateInstance"); - public static string GetSuffixForInternal(DeclarationContext @class) + public static string GetSuffixForInternal(Class @class) { - if (@class == null) - return string.Empty; - - Class template = null; var specialization = @class as ClassTemplateSpecialization ?? @class.Namespace as ClassTemplateSpecialization; - if (specialization != null) - { - template = specialization.TemplatedDecl.TemplatedClass; - if (@class != specialization) - template = template.Classes.FirstOrDefault(c => c.Name == @class.Name); - } - if (template == null || !template.HasDependentValueFieldInLayout()) + if (specialization == null) return string.Empty; - if (specialization.Arguments.All( - a => a.Type.Type?.IsAddress() == true)) - return "_Ptr"; + Class template = specialization.TemplatedDecl.TemplatedClass; + if (@class != specialization) + template = template.Classes.FirstOrDefault(c => c.Name == @class.Name); - return GetSuffixFor(specialization); + if (template.HasDependentValueFieldInLayout()) + { + if (specialization.Arguments.All( + a => a.Type.Type?.IsAddress() == true)) + return "_Ptr"; + return GetSuffixFor(specialization); + } + // HACK: Clang can't always resolve complex templates such as the base of std::atomic in msvc + return (from @base in @class.Bases + let suffix = GetSuffixForInternal(@base.Class) + where suffix.Length > 0 + select suffix).DefaultIfEmpty(string.Empty).First(); } public static string GetSuffixFor(Declaration decl) diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 31552a7737..4ad3b45336 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -1,6 +1,7 @@ #pragma once #include "../Tests.h" +#include #include #include #include @@ -224,6 +225,8 @@ class DLL_API Proprietor : public AbstractProprietor private: Bar::Items _items; Bar::Items _itemsByValue; + std::atomic atomicPrimitive; + std::atomic atomicCustom; }; class DLL_API ComplexType