Skip to content

Commit c84a6c6

Browse files
committed
Generate valid C# for independent external specializations
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent 3b0eb18 commit c84a6c6

File tree

7 files changed

+43
-26
lines changed

7 files changed

+43
-26
lines changed

src/AST/ClassExtensions.cs

+13-2
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,19 @@ public static bool HasDependentValueFieldInLayout(this Class @class)
252252
if (@class.Fields.Any(f => IsValueDependent(f.Type)))
253253
return true;
254254

255-
return @class.Bases.Where(b => b.IsClass).Select(
256-
b => b.Class).Any(HasDependentValueFieldInLayout);
255+
if (@class.Bases.Where(b => b.IsClass).Select(
256+
b => b.Class).Any(HasDependentValueFieldInLayout))
257+
return true;
258+
259+
// HACK: Clang can't always resolve complex templates such as the base of std::atomic in msvc
260+
if (@class.IsTemplate && @class.Specializations.Any(
261+
s => s.Layout.Fields.Any(
262+
f => f.QualifiedType.Type.TryGetDeclaration(
263+
out ClassTemplateSpecialization specialization) &&
264+
specialization.TemplatedDecl.TemplatedClass.HasDependentValueFieldInLayout())))
265+
return true;
266+
267+
return false;
257268
}
258269

259270
public static IEnumerable<Property> GetConstCharFieldProperties(this Class @class) =>

src/Generator/Generators/CodeGenerator.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1322,11 +1322,7 @@ public static string GetSuffixForInternal(Class @class)
13221322
return "_Ptr";
13231323
return GetSuffixFor(specialization);
13241324
}
1325-
// HACK: Clang can't always resolve complex templates such as the base of std::atomic in msvc
1326-
return (from @base in @class.Bases
1327-
let suffix = GetSuffixForInternal(@base.Class)
1328-
where suffix.Length > 0
1329-
select suffix).DefaultIfEmpty(string.Empty).First();
1325+
return string.Empty;
13301326
}
13311327

13321328
public static string GetSuffixFor(Declaration decl)

src/Generator/Passes/TrimSpecializationsPass.cs

+2-5
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ private void CleanSpecializations(Class template)
138138
template.Specializations.All(s => s.Ignore))
139139
template.ExplicitlyIgnore();
140140

141-
TryMoveExternalSpecializations(template);
141+
if (template.Specializations.Any() && template.HasDependentValueFieldInLayout())
142+
TryMoveExternalSpecializations(template);
142143
}
143144

144145
/// <summary>
@@ -174,17 +175,13 @@ private static Module GetExternalModule(ClassTemplateSpecialization specializati
174175
{
175176
Module module = arg.Type.Type.GetModule();
176177
if (module != null)
177-
{
178178
modules.Add(module);
179-
}
180179
}
181180
if (arg.Type.Type.TryGetDeclaration(out ClassTemplateSpecialization nestedSpecialization))
182181
{
183182
Module module = GetExternalModule(nestedSpecialization);
184183
if (module != null)
185-
{
186184
modules.Add(module);
187-
}
188185
}
189186
}
190187
return modules.TopologicalSort(m => m.Dependencies).LastOrDefault();

tests/NamespacesBase/NamespacesBase.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ void TemplateClass<T>::setField(const T& value)
7171
}
7272

7373
template <typename T>
74-
class TemplateWithIndependentFields
74+
class IndependentFields
75+
{
76+
};
77+
78+
template <typename T>
79+
class DependentFields
7580
{
7681
public:
7782
class Nested
@@ -85,13 +90,13 @@ class TemplateWithIndependentFields
8590
};
8691

8792
template <typename T>
88-
const T& TemplateWithIndependentFields<T>::constField() const
93+
const T& DependentFields<T>::constField() const
8994
{
9095
return *t;
9196
}
9297

9398
template <typename T>
94-
typename TemplateWithIndependentFields<T>::Nested TemplateWithIndependentFields<T>::useDependentPointer(const T* t)
99+
typename DependentFields<T>::Nested DependentFields<T>::useDependentPointer(const T* t)
95100
{
96101
return Nested();
97102
}

tests/NamespacesDerived/Independent.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
class Derived;
2-
template<typename T> class TemplateWithIndependentFields;
3-
typedef TemplateWithIndependentFields<Derived*> ForwardedInIndependentHeader;
2+
template<typename T> class DependentFields;
3+
typedef DependentFields<Derived*> ForwardedInIndependentHeader;

tests/NamespacesDerived/NamespacesDerived.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ TemplateClass<int> Derived2::getTemplate()
6262
return t;
6363
}
6464

65+
IndependentFields<int> Derived2::getIndependentSpecialization()
66+
{
67+
return independentSpecialization;
68+
}
69+
6570
Derived2::LocalTypedefSpecialization Derived2::getLocalTypedefSpecialization()
6671
{
6772
return LocalTypedefSpecialization();
@@ -73,13 +78,13 @@ Abstract* Derived2::getAbstract()
7378
}
7479

7580
DerivedFromExternalSpecialization::DerivedFromExternalSpecialization(int i,
76-
TemplateWithIndependentFields<HasVirtualInDependency> defaultExternalSpecialization)
81+
DependentFields<HasVirtualInDependency> defaultExternalSpecialization)
7782
{
7883
}
7984

80-
TemplateWithIndependentFields<Base3> DerivedFromExternalSpecialization::returnExternalSpecialization()
85+
DependentFields<Base3> DerivedFromExternalSpecialization::returnExternalSpecialization()
8186
{
82-
return TemplateWithIndependentFields<Base3>();
87+
return DependentFields<Base3>();
8388
}
8489

8590
int HasVirtualInDependency::callManagedOverride()

tests/NamespacesDerived/NamespacesDerived.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,16 @@ class DLL_API Derived2 : public Base3
6060
void defaultEnumValueFromDependency(OverlappingNamespace::ColorsEnum c = OverlappingNamespace::ColorsEnum::black);
6161

6262
TemplateClass<int> getTemplate();
63-
typedef TemplateWithIndependentFields<int> LocalTypedefSpecialization;
63+
IndependentFields<int> getIndependentSpecialization();
64+
typedef DependentFields<int> LocalTypedefSpecialization;
6465
LocalTypedefSpecialization getLocalTypedefSpecialization();
6566
Abstract* getAbstract();
6667
private:
6768
TemplateClass<int> t;
6869
TemplateClass<Derived> d;
69-
TemplateClass<TemplateWithIndependentFields<Derived>> nestedSpecialization;
70+
TemplateClass<DependentFields<Derived>> nestedSpecialization;
71+
IndependentFields<int> independentSpecialization;
72+
IndependentFields<Derived> independentExternalSpecialization;
7073
};
7174

7275
class DLL_API HasVirtualInDependency : public HasVirtualInCore
@@ -76,13 +79,13 @@ class DLL_API HasVirtualInDependency : public HasVirtualInCore
7679
int callManagedOverride();
7780
};
7881

79-
class DLL_API DerivedFromExternalSpecialization : public TemplateWithIndependentFields<Derived>
82+
class DLL_API DerivedFromExternalSpecialization : public DependentFields<Derived>
8083
{
8184
public:
8285
DerivedFromExternalSpecialization(int i,
83-
TemplateWithIndependentFields<HasVirtualInDependency> defaultExternalSpecialization =
84-
TemplateWithIndependentFields<HasVirtualInDependency>());
85-
TemplateWithIndependentFields<Base3> returnExternalSpecialization();
86+
DependentFields<HasVirtualInDependency> defaultExternalSpecialization =
87+
DependentFields<HasVirtualInDependency>());
88+
DependentFields<Base3> returnExternalSpecialization();
8689
};
8790

8891
class DLL_API DerivedFromSecondaryBaseInDependency : public Derived, public SecondaryBase

0 commit comments

Comments
 (0)