Browse Source

Generate valid C# for unresolvable base templates

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
update-llvm
Dimitar Dobrev 3 years ago
parent
commit
aab63d0aa3
  1. 6
      src/Generator/Generators/CSharp/CSharpSources.cs
  2. 33
      src/Generator/Generators/CodeGenerator.cs
  3. 3
      tests/CSharp/CSharp.h

6
src/Generator/Generators/CSharp/CSharpSources.cs

@ -274,7 +274,7 @@ namespace CppSharp.Generators.CSharp @@ -274,7 +274,7 @@ namespace CppSharp.Generators.CSharp
WriteOpenBraceAndIndent();
PushBlock(BlockKind.InternalsClass);
GenerateClassInternalHead();
GenerateClassInternalHead(new Class { Name = parentName });
WriteOpenBraceAndIndent();
// Generate all the internal function declarations.
@ -704,7 +704,7 @@ namespace CppSharp.Generators.CSharp @@ -704,7 +704,7 @@ namespace CppSharp.Generators.CSharp
return @params;
}
private void GenerateClassInternalHead(Class @class = null)
private void GenerateClassInternalHead(Class @class)
{
Write("public ");
@ -3143,7 +3143,7 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty @@ -3143,7 +3143,7 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty
if (operatorParam == null)
{
WriteLine($@"fixed ({Helpers.InternalStruct}{
Helpers.GetSuffixForInternal(originalFunction.Namespace)}* __instancePtr = &{
Helpers.GetSuffixForInternal((Class) originalFunction.Namespace)}* __instancePtr = &{
Helpers.InstanceField})");
WriteOpenBraceAndIndent();
}

33
src/Generator/Generators/CodeGenerator.cs

@ -1303,29 +1303,30 @@ namespace CppSharp.Generators @@ -1303,29 +1303,30 @@ namespace CppSharp.Generators
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)

3
tests/CSharp/CSharp.h

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
#pragma once
#include "../Tests.h"
#include <atomic>
#include <cstdint>
#include <vector>
#include <limits>
@ -224,6 +225,8 @@ public: @@ -224,6 +225,8 @@ public:
private:
Bar::Items _items;
Bar::Items _itemsByValue;
std::atomic<int> atomicPrimitive;
std::atomic<SmallPOD> atomicCustom;
};
class DLL_API ComplexType

Loading…
Cancel
Save