Skip to content

Commit

Permalink
Fixed the generated C# when a template is used with different type ar…
Browse files Browse the repository at this point in the history
…guments.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
  • Loading branch information
ddobrev committed Aug 6, 2017
1 parent cd54805 commit 38ed4ab
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
14 changes: 10 additions & 4 deletions src/Generator/Generators/CSharp/CSharpSources.cs
Expand Up @@ -641,10 +641,16 @@ public override void GenerateClassSpecifier(Class @class)

if (@class.NeedsBase)
{
bases.AddRange(
from @base in @class.Bases
where @base.IsClass
select @base.Class.Visit(TypePrinter).Type);
foreach (var @base in @class.Bases.Where(b => b.IsClass))
{
var typeMaps = new List<System.Type>();
var keys = new List<string>();
this.DisableTypeMap(@base.Class, typeMaps, keys);
var printedBase = @base.Type.Desugar().Visit(TypePrinter);
bases.Add(printedBase.Type);
for (int i = 0; i < typeMaps.Count; i++)
Context.TypeMaps.TypeMaps.Add(keys[i], typeMaps[i]);
}
}

if (@class.IsGenerated)
Expand Down
16 changes: 14 additions & 2 deletions src/Generator/Generators/CSharp/CSharpTypePrinter.cs
Expand Up @@ -342,7 +342,8 @@ public static bool IsConstCharString(QualifiedType qualType)
if (!TypeMapDatabase.FindTypeMap(template, out typeMap))
{
if (ContextKind == TypePrinterContextKind.Managed &&
decl == template.Template.TemplatedDecl)
decl == template.Template.TemplatedDecl &&
template.Arguments.All(IsValid))
return $@"{VisitDeclaration(decl)}<{string.Join(", ",
template.Arguments.Select(VisitTemplateArgument))}>";
return decl.Visit(this);
Expand Down Expand Up @@ -395,7 +396,9 @@ public static bool IsConstCharString(QualifiedType qualType)
public override TypePrinterResult VisitInjectedClassNameType(
InjectedClassNameType injected, TypeQualifiers quals)
{
return injected.Class.Visit(this);
return injected.InjectedSpecializationType.Type != null ?
injected.InjectedSpecializationType.Visit(this) :
injected.Class.Visit(this);
}

public override TypePrinterResult VisitDependentNameType(DependentNameType dependent,
Expand Down Expand Up @@ -776,6 +779,15 @@ public TypePrinterResult PrintNative(QualifiedType type)
return typePrinterResult;
}

private static bool IsValid(TemplateArgument a)
{
if (a.Type.Type == null)
return true;
var templateParam = a.Type.Type.Desugar() as TemplateParameterType;
// HACK: TemplateParameterType.Parameter is null in some corner cases, see the parser
return templateParam == null || templateParam.Parameter != null;
}

private CSharpExpressionPrinter expressionPrinter => new CSharpExpressionPrinter(this);
}
}
8 changes: 7 additions & 1 deletion tests/CSharp/CSharpTemplates.h
Expand Up @@ -92,6 +92,11 @@ int IndependentFields<T>::getIndependent()
return independent;
}

template <typename X>
class DerivedChangesTypeName : public IndependentFields<X>
{
};

template <typename T>
class DLL_API DependentValueFields
{
Expand Down Expand Up @@ -302,7 +307,7 @@ struct MapResultType<InputSequence<T>, MapFunctor>
void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool> _2,
IndependentFields<T1> _3, IndependentFields<std::string> _4,
VirtualTemplate<int> _5, VirtualTemplate<bool> _6,
HasDefaultTemplateArgument<int, int> _7, std::string s);
HasDefaultTemplateArgument<int, int> _7, DerivedChangesTypeName<T1> _8, std::string s);

// force the symbols for the template instantiations because we do not have the auto-compilation for the generated C++ source
template class DLL_API IndependentFields<int>;
Expand All @@ -312,3 +317,4 @@ template class DLL_API IndependentFields<std::string>;
template class DLL_API VirtualTemplate<int>;
template class DLL_API VirtualTemplate<bool>;
template class DLL_API HasDefaultTemplateArgument<int, int>;
template class DLL_API DerivedChangesTypeName<T1>;

0 comments on commit 38ed4ab

Please sign in to comment.