Browse Source

Move the GenerateInclude logic to GetTypeReference (#1319)

Improve generation of forward references and includes in C++/CLI.

Move the GenerateInclude logic to GetTypeReference so that an include is also generated for visited types of an ASTRecord that are forward declared, and come from typedef of ignored class template.

Co-authored-by: Build Agent <admin@sage.com>
pull/1322/head
Ali Alamiri 5 years ago committed by GitHub
parent
commit
344656c787
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      build/Tests.lua
  2. 69
      src/Generator/Generators/CLI/CLITypeReferences.cs
  3. 13
      src/Generator/Types/Std/Stdlib.cs
  4. 9
      tests/CLI/CLI.Tests.cs
  5. 54
      tests/CLI/CLI.cs
  6. 3
      tests/CLI/CLI.h
  7. 6
      tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.cpp
  8. 10
      tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.h
  9. 4
      tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeForwardDecl.h
  10. 13
      tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.cpp
  11. 13
      tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.h
  12. 13
      tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/IgnoredClassTemplateForEmployee.h
  13. 2
      tests/CLI/premake4.lua

4
build/Tests.lua

@ -31,10 +31,10 @@ function SetupTestCSharp(name) @@ -31,10 +31,10 @@ function SetupTestCSharp(name)
SetupTestProjectsCSharp(name)
end
function SetupTestCLI(name)
function SetupTestCLI(name, extraFiles, suffix)
SetupTestGeneratorProject(name)
SetupTestNativeProject(name)
SetupTestProjectsCLI(name)
SetupTestProjectsCLI(name, extraFiles, suffix)
end
function SetupManagedTestProject()

69
src/Generator/Generators/CLI/CLITypeReferences.cs

@ -48,10 +48,25 @@ namespace CppSharp.Generators.CLI @@ -48,10 +48,25 @@ namespace CppSharp.Generators.CLI
if (typeReferences.ContainsKey(decl))
return typeReferences[decl];
var @ref = new CLITypeReference { Declaration = decl };
typeReferences.Add(decl, @ref);
var translationUnit = decl.Namespace.TranslationUnit;
if (ShouldIncludeTranslationUnit(translationUnit) && decl.IsGenerated && !IsBuiltinTypedef(decl))
{
var @ref = new CLITypeReference { Declaration = decl };
@ref.Include = new CInclude
{
File = GetIncludePath(translationUnit),
TranslationUnit = translationUnit,
Kind = translationUnit.IsGenerated ? CInclude.IncludeKind.Quoted : CInclude.IncludeKind.Angled
};
return @ref;
typeReferences.Add(decl, @ref);
return @ref;
}
return null;
}
static Namespace GetEffectiveNamespace(Declaration decl)
@ -104,39 +119,27 @@ namespace CppSharp.Generators.CLI @@ -104,39 +119,27 @@ namespace CppSharp.Generators.CLI
if (decl.Namespace == null)
return;
var typedefType = record.Value as TypedefNameDecl;
// Find a type map for the declaration and use it if it exists.
TypeMap typeMap;
if (TypeMapDatabase.FindTypeMap(record.Value, out typeMap))
if (TypeMapDatabase.FindTypeMap(record.Value, out typeMap)
|| (typedefType != null && TypeMapDatabase.FindTypeMap(typedefType.Type.Desugar(), out typeMap)))
{
typeMap.CLITypeReference(this, record);
return;
}
var translationUnit = decl.Namespace.TranslationUnit;
if (translationUnit.IsSystemHeader || !translationUnit.IsValid)
return;
if (!decl.IsGenerated)
return;
if (IsBuiltinTypedef(decl))
return;
var typeRef = GetTypeReference(decl);
if (typeRef.Include.TranslationUnit == null)
if(typeRef != null)
{
typeRef.Include = new CInclude
{
File = GetIncludePath(translationUnit),
TranslationUnit = translationUnit,
Kind = translationUnit.IsGenerated
? CInclude.IncludeKind.Quoted
: CInclude.IncludeKind.Angled,
};
typeRef.Include.InHeader |= IsIncludeInHeader(record);
}
}
typeRef.Include.InHeader |= IsIncludeInHeader(record);
private bool ShouldIncludeTranslationUnit(TranslationUnit unit)
{
return !unit.IsSystemHeader && unit.IsValid && !unit.Ignore;
}
private string GetIncludePath(TranslationUnit translationUnit)
@ -168,7 +171,7 @@ namespace CppSharp.Generators.CLI @@ -168,7 +171,7 @@ namespace CppSharp.Generators.CLI
return typedefType.Declaration.Type is BuiltinType;
}
private bool IsIncludeInHeader(ASTRecord<Declaration> record)
public bool IsIncludeInHeader(ASTRecord<Declaration> record)
{
if (TranslationUnit == record.Value.Namespace.TranslationUnit)
return false;
@ -198,7 +201,12 @@ namespace CppSharp.Generators.CLI @@ -198,7 +201,12 @@ namespace CppSharp.Generators.CLI
var @ref = $"{keywords} {@class.Name};";
GetTypeReference(@class).FowardReference = @ref;
var typeRef = GetTypeReference(@class);
if (typeRef != null)
{
typeRef.FowardReference = @ref;
}
return false;
}
@ -217,7 +225,12 @@ namespace CppSharp.Generators.CLI @@ -217,7 +225,12 @@ namespace CppSharp.Generators.CLI
var @ref = $"{enumKind} {@enum.Name}{@base};";
GetTypeReference(@enum).FowardReference = @ref;
var typeRef = GetTypeReference(@enum);
if (typeRef != null)
{
typeRef.FowardReference = @ref;
}
return false;
}

13
src/Generator/Types/Std/Stdlib.cs

@ -690,13 +690,16 @@ namespace CppSharp.Types.Std @@ -690,13 +690,16 @@ namespace CppSharp.Types.Std
{
var typeRef = collector.GetTypeReference(loc.Value);
var include = new CInclude
if (typeRef != null)
{
File = "cstddef",
Kind = CInclude.IncludeKind.Angled,
};
var include = new CInclude
{
File = "cstddef",
Kind = CInclude.IncludeKind.Angled,
};
typeRef.Include = include;
typeRef.Include = include;
}
}
}

9
tests/CLI/CLI.Tests.cs

@ -26,4 +26,13 @@ public class CLITests : GeneratorTestFixture @@ -26,4 +26,13 @@ public class CLITests : GeneratorTestFixture
Assert.AreEqual(EnumParam.E1, byRefEnumParam.GetPassedEnumParam(EnumParam.E1));
}
}
[Test]
public void GetEmployeeNameFromOrgTest()
{
using (EmployeeOrg org = new EmployeeOrg())
{
Assert.AreEqual("Employee", org.Employee.Name);
}
}
}

54
tests/CLI/CLI.cs

@ -1,9 +1,58 @@ @@ -1,9 +1,58 @@
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Passes;
using CppSharp.Types;
using CppSharp.Utils;
namespace CppSharp.Tests
{
[TypeMap("IgnoredClassTemplateForEmployee")]
public class IgnoredClassTemplateForEmployeeMap : TypeMap
{
public override Type CLISignatureType(TypePrinterContext ctx)
{
return new CustomType("CLI::Employee^");
}
public override void CLIMarshalToManaged(MarshalContext ctx)
{
ctx.Return.Write($"gcnew CLI::Employee({ctx.ReturnVarName}.m_employee)");
}
}
public class CompleteIgnoredClassTemplateForEmployeeTypedefPass : TranslationUnitPass
{
public override bool VisitTypedefDecl(TypedefDecl typedef)
{
var templateType = GetDesugaredFinalPointeeElseType(typedef?.Type?.Desugar()) as TemplateSpecializationType;
bool isTemplateTypedef = IsTemplateTypedef(templateType?.Template?.OriginalName);
if (isTemplateTypedef)
{
Class @class;
if (templateType.TryGetClass(out @class))
{
@class.IsIncomplete = false;
return true;
}
}
return base.VisitTypedefDecl(typedef);
}
private bool IsTemplateTypedef(string templateName)
{
return !string.IsNullOrEmpty(templateName) && "IgnoredClassTemplateForEmployee" == templateName;
}
public Type GetDesugaredFinalPointeeElseType(Type t)
{
Type finalPointee = t.GetFinalPointee();
return finalPointee != null ? finalPointee.Desugar() : t;
}
}
public class CLITestsGenerator : GeneratorTest
{
public CLITestsGenerator(GeneratorKind kind)
@ -22,6 +71,11 @@ namespace CppSharp.Tests @@ -22,6 +71,11 @@ namespace CppSharp.Tests
{
}
public override void SetupPasses(Driver driver)
{
driver.AddTranslationUnitPass(new CompleteIgnoredClassTemplateForEmployeeTypedefPass());
}
public static void Main(string[] args)
{
ConsoleDriver.Run(new CLITestsGenerator(GeneratorKind.CLI));

3
tests/CLI/CLI.h

@ -1,5 +1,8 @@ @@ -1,5 +1,8 @@
#include "../Tests.h"
#include "UseTemplateTypeFromIgnoredClassTemplate/Employee.h"
#include "UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.h"
#include <ostream>
// Tests for C++ types

6
tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.cpp

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
#include "Employee.h"
std::string Employee::GetName()
{
return "Employee";
}

10
tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.h

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
#pragma once
#include "../../Tests.h"
#include <string>
class DLL_API Employee
{
public:
virtual std::string GetName();
};

4
tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeForwardDecl.h

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
#include "IgnoredClassTemplateForEmployee.h"
class Employee;
typedef IgnoredClassTemplateForEmployee<Employee> EmployeeTypedef;

13
tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.cpp

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
#include "EmployeeOrg.h"
#include "Employee.h"
EmployeeTypedef EmployeeOrg::GetEmployee()
{
return IgnoredClassTemplateForEmployee<Employee>(new Employee());
}
void EmployeeOrg::DoSomething()
{
}

13
tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.h

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
#pragma once
#include "../../Tests.h"
#include "EmployeeForwardDecl.h"
class DLL_API EmployeeOrg
{
public:
void DoSomething();
EmployeeTypedef GetEmployee();
};

13
tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/IgnoredClassTemplateForEmployee.h

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
#pragma once
template<typename EmployeeT>
class IgnoredClassTemplateForEmployee
{
public:
IgnoredClassTemplateForEmployee<EmployeeT>(EmployeeT* employee)
: m_employee(employee)
{
}
EmployeeT* m_employee;
};

2
tests/CLI/premake4.lua

@ -1,2 +1,2 @@ @@ -1,2 +1,2 @@
group "Tests/CLI"
SetupTestCLI("CLI")
SetupTestCLI("CLI", { "Employee", "EmployeeOrg" })
Loading…
Cancel
Save