public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals) { if (!VisitType(pointer, quals)) { return(false); } var param = Context.Parameter; var isRefParam = param != null && (param.IsInOut || param.IsOut); var pointee = pointer.Pointee.Desugar(); if (pointee.IsConstCharString()) { if (param.IsOut) { MarshalString(pointee); Context.Return.Write($"{typePrinter.IntPtrType}.Zero"); Context.ArgumentPrefix.Write("&"); return(true); } if (param.IsInOut) { MarshalString(pointee); pointer.QualifiedPointee.Visit(this); Context.ArgumentPrefix.Write("&"); return(true); } if (pointer.IsReference) { Context.Return.Write($@"({typePrinter.PrintNative( pointee.GetQualifiedPointee())}*) "); pointer.QualifiedPointee.Visit(this); Context.ArgumentPrefix.Write("&"); return(true); } } var finalPointee = (pointee.GetFinalPointee() ?? pointee).Desugar(); if (finalPointee.IsPrimitiveType(out PrimitiveType primitive) || finalPointee.IsEnumType()) { if (isRefParam) { var local = Generator.GeneratedIdentifier($@"{ param.Name}{Context.ParameterIndex}"); Context.Before.WriteLine($@"fixed ({ pointer.Visit(typePrinter)} {local} = &{param.Name})"); Context.HasCodeBlock = true; Context.Before.WriteOpenBraceAndIndent(); Context.Return.Write(local); return(true); } bool isConst = quals.IsConst || pointer.QualifiedPointee.Qualifiers.IsConst || pointer.GetFinalQualifiedPointee().Qualifiers.IsConst; if (Context.Context.Options.MarshalCharAsManagedChar && primitive == PrimitiveType.Char) { Context.Return.Write($"({typePrinter.PrintNative(pointer)})"); if (isConst) { Context.Return.Write("&"); } Context.Return.Write(param.Name); return(true); } pointer.QualifiedPointee.Visit(this); if (Context.Parameter.IsIndirect) { Context.ArgumentPrefix.Write("&"); } bool isVoid = primitive == PrimitiveType.Void && pointer.IsReference() && isConst; if (pointer.Pointee.Desugar(false) is TemplateParameterSubstitutionType || isVoid) { var local = Generator.GeneratedIdentifier($@"{ param.Name}{Context.ParameterIndex}"); string cast = isVoid ? $@"({pointee.Visit( new CppTypePrinter(Context.Context) { PrintTypeQualifiers = false })}) " : string.Empty; Context.Before.WriteLine($"var {local} = {cast}{Context.Return};"); Context.Return.StringBuilder.Clear(); Context.Return.Write(local); } if (new QualifiedType(pointer, quals).IsConstRefToPrimitive()) { Context.Return.StringBuilder.Insert(0, '&'); } return(true); } string arg = Generator.GeneratedIdentifier(Context.ArgName); if (pointee.TryGetClass(out Class @class) && @class.IsValueType) { if (Context.Parameter.Usage == ParameterUsage.Out) { var qualifiedIdentifier = (@class.OriginalClass ?? @class).Visit(typePrinter); Context.Before.WriteLine("var {0} = new {1}.{2}();", arg, qualifiedIdentifier, Helpers.InternalStruct); } else { Context.Before.WriteLine("var {0} = {1}.{2};", arg, Context.Parameter.Name, Helpers.InstanceIdentifier); } Context.Return.Write($"new {typePrinter.IntPtrType}(&{arg})"); return(true); } if (pointee.IsPointerTo(out Type type) && type.Desugar().TryGetClass(out Class c)) { pointer.QualifiedPointee.Visit(this); Context.Before.WriteLine($"var {arg} = {Context.Return};"); Context.Return.StringBuilder.Clear(); Context.Return.Write($"new {typePrinter.IntPtrType}(&{arg})"); return(true); } return(pointer.QualifiedPointee.Visit(this)); }
public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals) { if (!VisitType(pointer, quals)) { return(false); } var pointee = pointer.Pointee.Desugar(); if (pointee.IsPrimitiveType(PrimitiveType.Void)) { Context.Return.Write("::System::IntPtr({0})", Context.ReturnVarName); return(true); } PrimitiveType primitive; var param = Context.Parameter; if (param != null && (param.IsOut || param.IsInOut) && pointee.IsPrimitiveType(out primitive)) { Context.Return.Write(Context.ReturnVarName); return(true); } if (pointee.IsPrimitiveType(out primitive)) { var returnVarName = Context.ReturnVarName; if (pointer.GetFinalQualifiedPointee().Qualifiers.IsConst != Context.ReturnType.Qualifiers.IsConst) { var nativeTypePrinter = new CppTypePrinter(Context.Context) { PrintTypeQualifiers = false }; var returnType = Context.ReturnType.Type.Desugar(); var constlessPointer = new PointerType() { IsDependent = pointer.IsDependent, Modifier = pointer.Modifier, QualifiedPointee = new QualifiedType(returnType.GetPointee()) }; var nativeConstlessTypeName = constlessPointer.Visit(nativeTypePrinter, new TypeQualifiers()); returnVarName = string.Format("const_cast<{0}>({1})", nativeConstlessTypeName, Context.ReturnVarName); } if (pointer.Pointee is TypedefType) { var desugaredPointer = new PointerType() { IsDependent = pointer.IsDependent, Modifier = pointer.Modifier, QualifiedPointee = new QualifiedType(pointee) }; var nativeTypePrinter = new CppTypePrinter(Context.Context); var nativeTypeName = desugaredPointer.Visit(nativeTypePrinter, quals); Context.Return.Write("reinterpret_cast<{0}>({1})", nativeTypeName, returnVarName); } else { Context.Return.Write(returnVarName); } return(true); } TypeMap typeMap = null; Context.Context.TypeMaps.FindTypeMap(pointee, out typeMap); Class @class; if (pointee.TryGetClass(out @class) && typeMap == null) { var instance = (pointer.IsReference) ? "&" + Context.ReturnVarName : Context.ReturnVarName; WriteClassInstance(@class, instance); return(true); } return(pointer.QualifiedPointee.Visit(this)); }
public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals) { if (!VisitType(pointer, quals)) { return(false); } var pointee = pointer.Pointee.Desugar(); if ((pointee.IsPrimitiveType(PrimitiveType.Char) || pointee.IsPrimitiveType(PrimitiveType.WideChar)) && pointer.QualifiedPointee.Qualifiers.IsConst) { Context.SupportBefore.WriteLine( "auto _{0} = clix::marshalString<clix::E_UTF8>({1});", Context.ArgName, Context.Parameter.Name); Context.Return.Write("_{0}.c_str()", Context.ArgName); return(true); } if (pointee is FunctionType) { var function = pointee as FunctionType; var cppTypePrinter = new CppTypePrinter(); var cppTypeName = pointer.Visit(cppTypePrinter, quals); return(VisitDelegateType(function, cppTypeName)); } Enumeration @enum; if (pointee.TryGetEnum(out @enum)) { var isRef = Context.Parameter.Usage == ParameterUsage.Out || Context.Parameter.Usage == ParameterUsage.InOut; ArgumentPrefix.Write("&"); Context.Return.Write("(::{0}){1}{2}", @enum.QualifiedOriginalName, isRef ? string.Empty : "*", Context.Parameter.Name); return(true); } Class @class; if (pointee.TryGetClass(out @class) && @class.IsValueType) { if (Context.Function == null) { Context.Return.Write("&"); } return(pointee.Visit(this, quals)); } var finalPointee = pointer.GetFinalPointee(); if (finalPointee.IsPrimitiveType()) { var cppTypePrinter = new CppTypePrinter(); var cppTypeName = pointer.Visit(cppTypePrinter, pointer.GetFinalQualifiedPointee().Qualifiers); Context.Return.Write("({0})", cppTypeName); Context.Return.Write(Context.Parameter.Name); return(true); } return(pointer.Pointee.Visit(this, quals)); }