Browse Source

Fix printing of function pointers in C++

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1284/head
Dimitar Dobrev 6 years ago committed by João Matos
parent
commit
e4ac492560
  1. 49
      src/Generator/Generators/C/CppTypePrinter.cs
  2. 2
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 4
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  4. 20
      src/Generator/Generators/TypePrinter.cs
  5. 13
      src/Generator/Passes/SymbolsCodeGenerator.cs

49
src/Generator/Generators/C/CppTypePrinter.cs

@ -69,31 +69,14 @@ namespace CppSharp.Generators.C @@ -69,31 +69,14 @@ namespace CppSharp.Generators.C
public override TypePrinterResult VisitPointerType(PointerType pointer, TypeQualifiers quals)
{
var pointee = pointer.Pointee;
var function = pointee as FunctionType;
if (function != null)
{
var arguments = function.Parameters;
var returnType = function.ReturnType;
var args = string.Empty;
if (arguments.Count > 0)
args = VisitParameters(function.Parameters, hasNames: false);
var callingConvention = string.Empty;
if (function.CallingConvention != CallingConvention.Default &&
function.CallingConvention != CallingConvention.C)
{
string conventionString = function.CallingConvention.ToString();
callingConvention = $"__{conventionString.ToLowerInvariant()} ";
}
return $"{returnType.Visit(this)} ({callingConvention}*)({args})";
}
var qual = GetStringQuals(quals, false);
var pointeeType = pointee.Visit(this, pointer.QualifiedPointee.Qualifiers);
var pointeeType = pointer.Pointee.Visit(this, pointer.QualifiedPointee.Qualifiers);
var mod = PrintTypeModifiers ? ConvertModifierToString(pointer.Modifier) : string.Empty;
if (pointeeType.Type.Contains("{0}"))
{
pointeeType.NameSuffix = pointeeType.NameSuffix + mod + qual;
return pointeeType;
}
return $"{pointeeType}{mod}{(string.IsNullOrEmpty(qual) ? string.Empty : " ")}{qual}";
}
@ -181,7 +164,10 @@ namespace CppSharp.Generators.C @@ -181,7 +164,10 @@ namespace CppSharp.Generators.C
FunctionType func;
var qual = GetStringQuals(quals);
if (ResolveTypedefs && !typedef.Declaration.Type.IsPointerTo(out func))
return $"{qual}{typedef.Declaration.QualifiedType.Visit(this)}";
{
TypePrinterResult type = typedef.Declaration.QualifiedType.Visit(this);
return new TypePrinterResult { Type = $"{qual}{type.Type}", NameSuffix = type.NameSuffix };
}
return $"{qual}{typedef.Declaration.Visit(this)}";
}
@ -310,7 +296,14 @@ namespace CppSharp.Generators.C @@ -310,7 +296,14 @@ namespace CppSharp.Generators.C
if (arguments.Count > 0)
args = VisitParameters(function.Parameters, hasNames: false);
return string.Format("{0} ({1})", returnType.Visit(this), args);
var callingConvention = string.Empty;
if (function.CallingConvention != CallingConvention.Default &&
function.CallingConvention != CallingConvention.C)
{
string conventionString = function.CallingConvention.ToString();
callingConvention = $"__{conventionString.ToLowerInvariant()} ";
}
return $"{returnType.Visit(this)} ({callingConvention}{{0}})({args})";
}
public override TypePrinterResult VisitParameters(IEnumerable<Parameter> @params,
@ -329,9 +322,9 @@ namespace CppSharp.Generators.C @@ -329,9 +322,9 @@ namespace CppSharp.Generators.C
public override TypePrinterResult VisitParameter(Parameter arg, bool hasName = true)
{
var type = arg.Type.Visit(this, arg.QualifiedType.Qualifiers).Type;
var name = arg.Name;
var printName = hasName && !string.IsNullOrEmpty(name);
string type = arg.Type.Visit(this, arg.QualifiedType.Qualifiers);
string name = arg.Name;
bool printName = hasName && !string.IsNullOrEmpty(name);
if (PrintFlavorKind == CppTypePrintFlavorKind.ObjC)
return printName ? string.Format(":({0}){1}", type, name)

2
src/Generator/Generators/CSharp/CSharpSources.cs

@ -764,7 +764,7 @@ namespace CppSharp.Generators.CSharp @@ -764,7 +764,7 @@ namespace CppSharp.Generators.CSharp
if (!Options.GenerateSequentialLayout || @class.IsUnion)
WriteLine($"[FieldOffset({field.Offset})]");
Write($"internal {retType}{retType.NameSuffix}");
Write($"internal {retType}");
if (field.Expression != null)
{
var fieldValuePrinted = field.Expression.CSharpValue(ExpressionPrinter);

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

@ -104,7 +104,7 @@ namespace CppSharp.Generators.CSharp @@ -104,7 +104,7 @@ namespace CppSharp.Generators.CSharp
};
}
var arrayElemType = array.QualifiedType.Visit(this).ToString();
TypePrinterResult arrayElemType = array.QualifiedType.Visit(this);
// C# does not support fixed arrays of machine pointer type (void* or IntPtr).
// In that case, replace it by a pointer to an integer type of the same size.
@ -115,7 +115,7 @@ namespace CppSharp.Generators.CSharp @@ -115,7 +115,7 @@ namespace CppSharp.Generators.CSharp
var fixedKeyword = arrayType is ArrayType ? string.Empty : "fixed ";
return new TypePrinterResult
{
Type = $"{fixedKeyword}{arrayElemType}",
Type = $"{fixedKeyword}{arrayElemType.Type}",
NameSuffix = $"[{array.Size}]"
};
}

20
src/Generator/Generators/TypePrinter.cs

@ -6,20 +6,18 @@ namespace CppSharp.Generators @@ -6,20 +6,18 @@ namespace CppSharp.Generators
{
public class TypePrinterResult
{
public string Type;
public string NameSuffix;
public string Type { get; set; }
public string NameSuffix { get; set; } = string.Empty;
public static implicit operator TypePrinterResult(string type)
{
return new TypePrinterResult { Type = type };
}
public static implicit operator TypePrinterResult(string type) =>
new TypePrinterResult { Type = type };
public static implicit operator string(TypePrinterResult result)
{
return result.Type;
}
public static implicit operator string(TypePrinterResult result) =>
result.ToString();
public override string ToString() => Type;
public override string ToString() =>
NameSuffix.Length > 0 ? Type.Contains("{0}") ?
string.Format(Type, NameSuffix) : Type + NameSuffix : Type;
}
public class TypePrinter : ITypePrinter<TypePrinterResult>,

13
src/Generator/Passes/SymbolsCodeGenerator.cs

@ -197,7 +197,6 @@ namespace CppSharp.Passes @@ -197,7 +197,6 @@ namespace CppSharp.Passes
private void TakeFunctionAddress(Function function)
{
//function = function.OriginalFunction ?? function;
string wrapper = GetWrapper(function);
string @namespace = function.OriginalNamespace.Visit(cppTypePrinter);
if (function.Access == AccessSpecifier.Protected)
@ -205,7 +204,7 @@ namespace CppSharp.Passes @@ -205,7 +204,7 @@ namespace CppSharp.Passes
Write($"class {wrapper}{function.Namespace.Name} : public {@namespace} {{ public: ");
Write("static constexpr ");
}
string returnType = function.OriginalReturnType.Visit(cppTypePrinter);
TypePrinterResult returnType = function.OriginalReturnType.Visit(cppTypePrinter);
string signature = GetSignature(function);
string functionName = GetFunctionName(function, @namespace);
@ -216,8 +215,14 @@ namespace CppSharp.Passes @@ -216,8 +215,14 @@ namespace CppSharp.Passes
if (function.Namespace.Access == AccessSpecifier.Protected)
Write($@"class {wrapper}{function.Namespace.Name} : public {
function.Namespace.Namespace.Visit(cppTypePrinter)} {{ ");
Write($@"{returnType} ({(method != null && !method.IsStatic ?
(@namespace + "::") : string.Empty)}*{wrapper}){signature}");
string variable = $@"({(method?.IsStatic == false ?
(@namespace + "::") : string.Empty)}*{wrapper}){signature}";
if (!string.IsNullOrEmpty(returnType.NameSuffix))
Write(returnType.Type, $"{returnType.NameSuffix} {variable}");
else
Write($"{returnType} {variable}");
if (function.Access == AccessSpecifier.Protected)
{
Write($" = &{wrapper}{function.Namespace.Name}::{functionName};");

Loading…
Cancel
Save