Browse Source

Collected template parameters of class templates.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/769/head
Dimitar Dobrev 9 years ago
parent
commit
c7203ad8e7
  1. 20
      src/AST/Class.cs
  2. 9
      src/AST/ITypePrinter.cs
  3. 3
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  4. 6
      src/Generator/Passes/RenamePass.cs
  5. 3
      src/Generator/Passes/ResolveIncompleteDeclsPass.cs
  6. 30
      src/Generator/Types/Std/Stdlib.cs

20
src/AST/Class.cs

@ -127,6 +127,7 @@ namespace CppSharp.AST
IsPOD = false; IsPOD = false;
Type = ClassType.RefType; Type = ClassType.RefType;
Layout = new ClassLayout(); Layout = new ClassLayout();
templateParameters = new List<Declaration>();
specializations = new List<ClassTemplateSpecialization>(); specializations = new List<ClassTemplateSpecialization>();
} }
@ -218,6 +219,24 @@ namespace CppSharp.AST
} }
} }
/// <summary>
/// If this class is a template, this list contains all of its template parameters.
/// <para>
/// <see cref="ClassTemplate"/> cannot be relied upon to contain all of them because
/// ClassTemplateDecl in Clang is not a complete declaration, it only serves to forward template classes.
/// </para>
/// </summary>
public List<Declaration> TemplateParameters
{
get
{
if (!IsDependent)
throw new InvalidOperationException(
"Only dependent classes have template parameters.");
return templateParameters;
}
}
/// <summary> /// <summary>
/// If this class is a template, this list contains all of its specializations. /// If this class is a template, this list contains all of its specializations.
/// <see cref="ClassTemplate"/> cannot be relied upon to contain all of them because /// <see cref="ClassTemplate"/> cannot be relied upon to contain all of them because
@ -274,6 +293,7 @@ namespace CppSharp.AST
return visitor.VisitClassDecl(this); return visitor.VisitClassDecl(this);
} }
private List<Declaration> templateParameters;
private List<ClassTemplateSpecialization> specializations; private List<ClassTemplateSpecialization> specializations;
} }
} }

9
src/AST/ITypePrinter.cs

@ -38,7 +38,14 @@ namespace CppSharp.AST
if (templateSpecializationType != null) if (templateSpecializationType != null)
templateArgs = templateSpecializationType.Arguments; templateArgs = templateSpecializationType.Arguments;
else else
templateArgs = ((ClassTemplateSpecialization) ((TagType) type).Declaration).Arguments; {
var declaration = ((TagType) type).Declaration;
var specialization = declaration as ClassTemplateSpecialization;
if (specialization == null)
return string.Join(", ",
((Class) declaration).TemplateParameters.Select(t => t.Name));
templateArgs = ((ClassTemplateSpecialization) declaration).Arguments;
}
var paramsList = new List<string>(); var paramsList = new List<string>();
foreach (var arg in templateArgs.Where(a => a.Kind == TemplateArgument.ArgumentKind.Type)) foreach (var arg in templateArgs.Where(a => a.Kind == TemplateArgument.ArgumentKind.Type))

3
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -579,7 +579,8 @@ namespace CppSharp.Generators.CSharp
if (ContextKind == TypePrinterContextKind.Native) if (ContextKind == TypePrinterContextKind.Native)
return $"{GetName(@class.OriginalClass ?? @class)}.{Helpers.InternalStruct}"; return $"{GetName(@class.OriginalClass ?? @class)}.{Helpers.InternalStruct}";
return GetName(@class); return $@"{GetName(@class)}{(@class.IsDependent ? $@"<{
string.Join(", ", @class.TemplateParameters.Select(p => p.Name))}>" : string.Empty)}";
} }
public override TypePrinterResult VisitClassTemplateSpecializationDecl( public override TypePrinterResult VisitClassTemplateSpecializationDecl(

6
src/Generator/Passes/RenamePass.cs

@ -146,12 +146,16 @@ namespace CppSharp.Passes
if (specialization != null) if (specialization != null)
declarations.RemoveAll(d => specialization.TemplatedDecl.TemplatedDecl == d); declarations.RemoveAll(d => specialization.TemplatedDecl.TemplatedDecl == d);
var @class = decl.Namespace as Class;
if (@class != null && @class.IsDependent)
declarations.AddRange(@class.TemplateParameters);
var result = declarations.Any(d => d != decl && d.Name == newName); var result = declarations.Any(d => d != decl && d.Name == newName);
if (result) if (result)
return true; return true;
if (decl is Method && decl.IsGenerated) if (decl is Method && decl.IsGenerated)
return ((Class) decl.Namespace).GetPropertyByName(newName) != null; return @class.GetPropertyByName(newName) != null;
var property = decl as Property; var property = decl as Property;
if (property != null && property.Field != null) if (property != null && property.Field != null)

3
src/Generator/Passes/ResolveIncompleteDeclsPass.cs

@ -28,6 +28,9 @@ namespace CppSharp.Passes
s => !s.IsIncomplete && !template.TemplatedClass.Specializations.Contains(s))) s => !s.IsIncomplete && !template.TemplatedClass.Specializations.Contains(s)))
template.TemplatedClass.Specializations.Add(specialization); template.TemplatedClass.Specializations.Add(specialization);
if (template.TemplatedClass.TemplateParameters.Count == 0)
template.TemplatedClass.TemplateParameters.AddRange(template.Parameters);
return true; return true;
} }

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

@ -64,29 +64,29 @@ namespace CppSharp.Types.Std
var typePrinter = new CSharpTypePrinter(ctx.Context); var typePrinter = new CSharpTypePrinter(ctx.Context);
typePrinter.PushContext(TypePrinterContextKind.Native); typePrinter.PushContext(TypePrinterContextKind.Native);
if (!ctx.Parameter.Type.Desugar().IsAddress()) if (!ctx.Parameter.Type.Desugar().IsAddress())
ctx.Return.Write("*({0}*) ", basicString.Visit(typePrinter)); ctx.Return.Write($"*({basicString.Visit(typePrinter)}*) ");
typePrinter.PopContext(); typePrinter.PopContext();
var allocator = ctx.Context.ASTContext.FindClass("allocator", false, true).First( var allocator = ctx.Context.ASTContext.FindClass("allocator", false, true).First(
a => a.IsDependent && a.TranslationUnit.IsSystemHeader); a => a.IsDependent && a.TranslationUnit.IsSystemHeader);
var allocatorChar = allocator.Specializations.First(s => !s.Ignore);
if (type.IsPointer() || (type.IsReference() && ctx.Declaration is Field)) if (type.IsPointer() || (type.IsReference() && ctx.Declaration is Field))
{ {
ctx.Return.Write("new {0}({1}, new {2}()).{3}", ctx.Return.Write($@"new {basicString.Visit(typePrinter)}({
basicString.Visit(typePrinter), ctx.Parameter.Name, ctx.Parameter.Name}, new {allocatorChar.Visit(typePrinter)}()).{
allocator.Visit(typePrinter), Helpers.InstanceIdentifier); Helpers.InstanceIdentifier}");
} }
else else
{ {
string varAllocator = "__allocator" + ctx.ParameterIndex; var varAllocator = $"__allocator{ctx.ParameterIndex}";
string varBasicString = "__basicString" + ctx.ParameterIndex; var varBasicString = $"__basicString{ctx.ParameterIndex}";
ctx.SupportBefore.WriteLine("var {0} = new {1}();", ctx.SupportBefore.WriteLine($@"var {varAllocator} = new {
varAllocator, allocator.Visit(typePrinter)); allocatorChar.Visit(typePrinter)}();");
ctx.SupportBefore.WriteLine("var {0} = new {1}({2}, {3});", ctx.SupportBefore.WriteLine($@"var {varBasicString} = new {
varBasicString, basicString.Visit(typePrinter), basicString.Visit(typePrinter)}({ctx.Parameter.Name}, {varAllocator});");
ctx.Parameter.Name, varAllocator); ctx.Return.Write($"{varBasicString}.{Helpers.InstanceIdentifier}");
ctx.Return.Write("{0}.{1}", varBasicString, Helpers.InstanceIdentifier); ctx.Cleanup.WriteLine($@"{varBasicString}.Dispose({
ctx.Cleanup.WriteLine("{0}.Dispose({1});", varBasicString, (type.IsPointer() ? "true" : "false")});");
type.IsPointer() ? "true" : "false"); ctx.Cleanup.WriteLine($"{varAllocator}.Dispose();");
ctx.Cleanup.WriteLine("{0}.Dispose();", varAllocator);
} }
} }

Loading…
Cancel
Save