Browse Source

Generate valid C# for independent external specializations

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
update-llvm
Dimitar Dobrev 4 years ago
parent
commit
c84a6c606e
  1. 15
      src/AST/ClassExtensions.cs
  2. 6
      src/Generator/Generators/CodeGenerator.cs
  3. 7
      src/Generator/Passes/TrimSpecializationsPass.cs
  4. 11
      tests/NamespacesBase/NamespacesBase.h
  5. 4
      tests/NamespacesDerived/Independent.h
  6. 11
      tests/NamespacesDerived/NamespacesDerived.cpp
  7. 15
      tests/NamespacesDerived/NamespacesDerived.h

15
src/AST/ClassExtensions.cs

@ -252,8 +252,19 @@ namespace CppSharp.AST @@ -252,8 +252,19 @@ namespace CppSharp.AST
if (@class.Fields.Any(f => IsValueDependent(f.Type)))
return true;
return @class.Bases.Where(b => b.IsClass).Select(
b => b.Class).Any(HasDependentValueFieldInLayout);
if (@class.Bases.Where(b => b.IsClass).Select(
b => b.Class).Any(HasDependentValueFieldInLayout))
return true;
// HACK: Clang can't always resolve complex templates such as the base of std::atomic in msvc
if (@class.IsTemplate && @class.Specializations.Any(
s => s.Layout.Fields.Any(
f => f.QualifiedType.Type.TryGetDeclaration(
out ClassTemplateSpecialization specialization) &&
specialization.TemplatedDecl.TemplatedClass.HasDependentValueFieldInLayout())))
return true;
return false;
}
public static IEnumerable<Property> GetConstCharFieldProperties(this Class @class) =>

6
src/Generator/Generators/CodeGenerator.cs

@ -1322,11 +1322,7 @@ namespace CppSharp.Generators @@ -1322,11 +1322,7 @@ namespace CppSharp.Generators
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();
return string.Empty;
}
public static string GetSuffixFor(Declaration decl)

7
src/Generator/Passes/TrimSpecializationsPass.cs

@ -138,7 +138,8 @@ namespace CppSharp.Passes @@ -138,7 +138,8 @@ namespace CppSharp.Passes
template.Specializations.All(s => s.Ignore))
template.ExplicitlyIgnore();
TryMoveExternalSpecializations(template);
if (template.Specializations.Any() && template.HasDependentValueFieldInLayout())
TryMoveExternalSpecializations(template);
}
/// <summary>
@ -174,17 +175,13 @@ namespace CppSharp.Passes @@ -174,17 +175,13 @@ namespace CppSharp.Passes
{
Module module = arg.Type.Type.GetModule();
if (module != null)
{
modules.Add(module);
}
}
if (arg.Type.Type.TryGetDeclaration(out ClassTemplateSpecialization nestedSpecialization))
{
Module module = GetExternalModule(nestedSpecialization);
if (module != null)
{
modules.Add(module);
}
}
}
return modules.TopologicalSort(m => m.Dependencies).LastOrDefault();

11
tests/NamespacesBase/NamespacesBase.h

@ -71,7 +71,12 @@ void TemplateClass<T>::setField(const T& value) @@ -71,7 +71,12 @@ void TemplateClass<T>::setField(const T& value)
}
template <typename T>
class TemplateWithIndependentFields
class IndependentFields
{
};
template <typename T>
class DependentFields
{
public:
class Nested
@ -85,13 +90,13 @@ private: @@ -85,13 +90,13 @@ private:
};
template <typename T>
const T& TemplateWithIndependentFields<T>::constField() const
const T& DependentFields<T>::constField() const
{
return *t;
}
template <typename T>
typename TemplateWithIndependentFields<T>::Nested TemplateWithIndependentFields<T>::useDependentPointer(const T* t)
typename DependentFields<T>::Nested DependentFields<T>::useDependentPointer(const T* t)
{
return Nested();
}

4
tests/NamespacesDerived/Independent.h

@ -1,3 +1,3 @@ @@ -1,3 +1,3 @@
class Derived;
template<typename T> class TemplateWithIndependentFields;
typedef TemplateWithIndependentFields<Derived*> ForwardedInIndependentHeader;
template<typename T> class DependentFields;
typedef DependentFields<Derived*> ForwardedInIndependentHeader;

11
tests/NamespacesDerived/NamespacesDerived.cpp

@ -62,6 +62,11 @@ TemplateClass<int> Derived2::getTemplate() @@ -62,6 +62,11 @@ TemplateClass<int> Derived2::getTemplate()
return t;
}
IndependentFields<int> Derived2::getIndependentSpecialization()
{
return independentSpecialization;
}
Derived2::LocalTypedefSpecialization Derived2::getLocalTypedefSpecialization()
{
return LocalTypedefSpecialization();
@ -73,13 +78,13 @@ Abstract* Derived2::getAbstract() @@ -73,13 +78,13 @@ Abstract* Derived2::getAbstract()
}
DerivedFromExternalSpecialization::DerivedFromExternalSpecialization(int i,
TemplateWithIndependentFields<HasVirtualInDependency> defaultExternalSpecialization)
DependentFields<HasVirtualInDependency> defaultExternalSpecialization)
{
}
TemplateWithIndependentFields<Base3> DerivedFromExternalSpecialization::returnExternalSpecialization()
DependentFields<Base3> DerivedFromExternalSpecialization::returnExternalSpecialization()
{
return TemplateWithIndependentFields<Base3>();
return DependentFields<Base3>();
}
int HasVirtualInDependency::callManagedOverride()

15
tests/NamespacesDerived/NamespacesDerived.h

@ -60,13 +60,16 @@ public: @@ -60,13 +60,16 @@ public:
void defaultEnumValueFromDependency(OverlappingNamespace::ColorsEnum c = OverlappingNamespace::ColorsEnum::black);
TemplateClass<int> getTemplate();
typedef TemplateWithIndependentFields<int> LocalTypedefSpecialization;
IndependentFields<int> getIndependentSpecialization();
typedef DependentFields<int> LocalTypedefSpecialization;
LocalTypedefSpecialization getLocalTypedefSpecialization();
Abstract* getAbstract();
private:
TemplateClass<int> t;
TemplateClass<Derived> d;
TemplateClass<TemplateWithIndependentFields<Derived>> nestedSpecialization;
TemplateClass<DependentFields<Derived>> nestedSpecialization;
IndependentFields<int> independentSpecialization;
IndependentFields<Derived> independentExternalSpecialization;
};
class DLL_API HasVirtualInDependency : public HasVirtualInCore
@ -76,13 +79,13 @@ public: @@ -76,13 +79,13 @@ public:
int callManagedOverride();
};
class DLL_API DerivedFromExternalSpecialization : public TemplateWithIndependentFields<Derived>
class DLL_API DerivedFromExternalSpecialization : public DependentFields<Derived>
{
public:
DerivedFromExternalSpecialization(int i,
TemplateWithIndependentFields<HasVirtualInDependency> defaultExternalSpecialization =
TemplateWithIndependentFields<HasVirtualInDependency>());
TemplateWithIndependentFields<Base3> returnExternalSpecialization();
DependentFields<HasVirtualInDependency> defaultExternalSpecialization =
DependentFields<HasVirtualInDependency>());
DependentFields<Base3> returnExternalSpecialization();
};
class DLL_API DerivedFromSecondaryBaseInDependency : public Derived, public SecondaryBase

Loading…
Cancel
Save