private void MarshalArray(ArrayType array) { Type arrayType = array.Type.Desugar(); if (arrayType.IsPrimitiveType() || arrayType.IsPointerToPrimitiveType() || Context.MarshalKind != MarshalKind.GenericDelegate) { Context.Return.Write(Context.ReturnVarName); return; } var intermediateArray = Generator.GeneratedIdentifier(Context.ReturnVarName); var intermediateArrayType = arrayType.Visit(typePrinter); Context.Before.WriteLine($"{intermediateArrayType}[] {intermediateArray};"); Context.Before.WriteLine($"if ({Context.ReturnVarName} is null)"); Context.Before.WriteLineIndent($"{intermediateArray} = null;"); Context.Before.WriteLine("else"); Context.Before.WriteOpenBraceAndIndent(); Context.Before.WriteLine($@"{intermediateArray} = new { intermediateArrayType}[{Context.ReturnVarName}.Length];"); Context.Before.WriteLine($"for (int i = 0; i < {intermediateArray}.Length; i++)"); if (arrayType.IsAddress()) { Context.Before.WriteOpenBraceAndIndent(); string element = Generator.GeneratedIdentifier("element"); Context.Before.WriteLine($"var {element} = {Context.ReturnVarName}[i];"); var intPtrZero = $"{typePrinter.IntPtrType}.Zero"; Context.Before.WriteLine($@"{intermediateArray}[i] = {element} == { intPtrZero} ? null : {intermediateArrayType}.{ Helpers.CreateInstanceIdentifier}({element});"); Context.Before.UnindentAndWriteCloseBrace(); } else { Context.Before.WriteLineIndent($@"{intermediateArray}[i] = { intermediateArrayType}.{Helpers.CreateInstanceIdentifier}({ Context.ReturnVarName}[i]);"); } Context.Before.UnindentAndWriteCloseBrace(); Context.Return.Write(intermediateArray); }
public override TypePrinterResult VisitPointerType(PointerType pointer, TypeQualifiers quals) { Type pointee = pointer.GetFinalPointee(); if (pointee != null) { if ((pointee is BuiltinType) && pointer.IsPointer()) { if ((pointee as BuiltinType).Type == PrimitiveType.Void) { return(NodeV8IsTypedBuffer); } } TypePrinterResult pointeeType = pointee.Visit(this); return(pointeeType); } throw new NotSupportedException(); }
public bool FindTypeMap(Type type, out TypeMap typeMap) { typeMap = null; while (true) { var typePrinter = new CppTypePrinter(this); var output = type.Visit(typePrinter); if (FindTypeMap(output, out typeMap)) { return(true); } // Try to strip the global scope resolution operator. if (output.StartsWith("::")) { output = output.Substring(2); } if (FindTypeMap(output, out typeMap)) { return(true); } var desugaredType = type.Desugar(); if (desugaredType == type) { return(false); } type = desugaredType; } return(true); }
public string ToString(Type type) { return(type.Visit(this)); }
public override string ToString(Type type) { return(type.Visit(this).Type); }
protected override string TypePrinterDelegate(CppSharp.AST.Type type) { return(type.Visit(TypePrinter).ToString()); }
private string TypePrinterDelegate(CppSharp.AST.Type type) { return(type.Visit(new CSharpTypePrinter(Driver.Context)).Type); }
public T Visit <T>(ITypeVisitor <T> visitor) { return(Type.Visit(visitor, Qualifiers)); }
public override TypePrinterResult VisitArrayType(ArrayType array, TypeQualifiers quals) { Type arrayType = array.Type.Desugar(); if ((MarshalKind == MarshalKind.NativeField || (ContextKind == TypePrinterContextKind.Native && MarshalKind == MarshalKind.ReturnVariableArray)) && array.SizeType == ArrayType.ArraySize.Constant) { if (array.Size == 0) { var pointer = new PointerType(array.QualifiedType); return(pointer.Visit(this)); } PrimitiveType primitiveType; if ((arrayType.IsPointerToPrimitiveType(out primitiveType) && !(arrayType is FunctionType)) || (arrayType.IsPrimitiveType() && MarshalKind != MarshalKind.NativeField)) { if (primitiveType == PrimitiveType.Void) { return("void*"); } return(array.QualifiedType.Visit(this)); } if (Parameter != null) { return(IntPtrType); } Enumeration @enum; if (arrayType.TryGetEnum(out @enum)) { return(new TypePrinterResult { Type = $"fixed {@enum.BuiltinType}", NameSuffix = $"[{array.Size}]" }); } Class @class; if (arrayType.TryGetClass(out @class)) { return(new TypePrinterResult { Type = "fixed byte", NameSuffix = $"[{array.Size * @class.Layout.Size}]" }); } var arrayElemType = array.QualifiedType.Visit(this).ToString(); // 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. if (arrayElemType == IntPtrType) { arrayElemType = Context.TargetInfo.PointerWidth == 64 ? "long" : "int"; } // Do not write the fixed keyword multiple times for nested array types var fixedKeyword = arrayType is ArrayType ? string.Empty : "fixed "; return(new TypePrinterResult { Type = $"{fixedKeyword}{arrayElemType}", NameSuffix = $"[{array.Size}]" }); } // const char* and const char[] are the same so we can use a string if (array.SizeType == ArrayType.ArraySize.Incomplete && arrayType.IsPrimitiveType(PrimitiveType.Char) && array.QualifiedType.Qualifiers.IsConst) { return("string"); } if (arrayType.IsPointerToPrimitiveType(PrimitiveType.Char)) { var prefix = ContextKind == TypePrinterContextKind.Managed ? string.Empty : "[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] "; return($"{prefix}string[]"); } var arraySuffix = array.SizeType != ArrayType.ArraySize.Constant && MarshalKind == MarshalKind.ReturnVariableArray ? (ContextKind == TypePrinterContextKind.Managed && arrayType.IsPrimitiveType() ? "*" : string.Empty) : "[]"; return($"{arrayType.Visit(this)}{arraySuffix}"); }
public string ToString(CppSharp.AST.Type type) { return(type.Visit(this)); }
public bool FindTypeMap(Type type, out TypeMap typeMap) { if (typeMaps.ContainsKey(type)) { typeMap = typeMaps[type]; return(typeMap.IsEnabled); } var template = type as TemplateSpecializationType; if (template != null) { var specialization = template.GetClassTemplateSpecialization(); if (specialization != null && FindTypeMap(specialization, out typeMap)) { return(true); } if (template.Template.TemplatedDecl != null) { if (FindTypeMap(template.Template.TemplatedDecl, out typeMap)) { typeMap.Type = type; return(true); } return(false); } } Type desugared = type.Desugar(); desugared = (desugared.GetFinalPointee() ?? desugared).Desugar(); bool printExtra = desugared.IsPrimitiveType() || (desugared.GetFinalPointee() ?? desugared).Desugar().IsPrimitiveType(); var typePrinter = new CppTypePrinter { PrintTypeQualifiers = printExtra, PrintTypeModifiers = printExtra, PrintLogicalNames = true }; foreach (var resolveTypeDefs in new[] { true, false }) { foreach (var typePrintScopeKind in new[] { TypePrintScopeKind.Local, TypePrintScopeKind.Qualified }) { typePrinter.ResolveTypedefs = resolveTypeDefs; typePrinter.ScopeKind = typePrintScopeKind; if (FindTypeMap(type.Visit(typePrinter), out typeMap)) { typeMap.Type = type; typeMaps[type] = typeMap; return(true); } } } typeMap = null; var typedef = type as TypedefType; return(typedef != null && FindTypeMap(typedef.Declaration.Type, out typeMap)); }
public override bool VisitClassDecl(Class @class) { var originalClass = @class.OriginalClass ?? @class; Type returnType = Context.ReturnType.Type.Desugar(); // if the class is an abstract impl, use the original for the object map var qualifiedClass = originalClass.Visit(typePrinter); var finalType = (returnType.GetFinalPointee() ?? returnType).Desugar(); Class returnedClass; if (finalType.TryGetClass(out returnedClass) && returnedClass.IsDependent) { Context.Return.Write($"({returnType.Visit(typePrinter)}) (object) "); } // these two aren't the same for members of templates if (Context.Function?.OriginalReturnType.Type.Desugar().IsAddress() == true || returnType.IsAddress()) { Context.Return.Write(HandleReturnedPointer(@class, qualifiedClass)); } else { if (Context.MarshalKind == MarshalKind.NativeField || Context.MarshalKind == MarshalKind.Variable || Context.MarshalKind == MarshalKind.ReturnVariableArray || !originalClass.HasNonTrivialDestructor) { Context.Return.Write($"{qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName})"); } else { Context.Before.WriteLine($@"var __{Context.ReturnVarName} = { qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName});"); Method dtor = originalClass.Destructors.First(); if (dtor.IsVirtual) { var i = VTables.GetVTableIndex(dtor); int vtableIndex = 0; if (Context.Context.ParserOptions.IsMicrosoftAbi) { vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.First( v => v.Layout.Components.Any(c => c.Method == dtor))); } string instance = $"new {typePrinter.IntPtrType}(&{Context.ReturnVarName})"; Context.Before.WriteLine($@"var __vtables = new IntPtr[] {{ { string.Join(", ", originalClass.Layout.VTablePointers.Select( x => $"*({typePrinter.IntPtrType}*) ({instance} + {x.Offset})"))} }};"); Context.Before.WriteLine($@"var __slot = *({typePrinter.IntPtrType}*) (__vtables[{ vtableIndex}] + {i} * sizeof({typePrinter.IntPtrType}));"); Context.Before.Write($"Marshal.GetDelegateForFunctionPointer<{dtor.FunctionType}>(__slot)({instance}"); if (dtor.GatherInternalParams(Context.Context.ParserOptions.IsItaniumLikeAbi).Count > 1) { Context.Before.Write(", 0"); } Context.Before.WriteLine(");"); } else { string suffix = string.Empty; var specialization = @class as ClassTemplateSpecialization; if (specialization != null) { suffix = Helpers.GetSuffixFor(specialization); } Context.Before.WriteLine($@"{typePrinter.PrintNative(originalClass)}.dtor{ suffix}(new {typePrinter.IntPtrType}(&{Context.ReturnVarName}));"); } Context.Return.Write($"__{Context.ReturnVarName}"); } } return(true); }
public bool FindTypeMap(Type type, out TypeMap typeMap) { var typePrinter = new CppTypePrinter(this); var template = type as TemplateSpecializationType; if (template != null) return FindTypeMap(template.Template.TemplatedDecl, type, out typeMap); if (FindTypeMap(type.Visit(typePrinter), out typeMap)) { typeMap.Type = type; return true; } typePrinter.PrintKind = CppTypePrintKind.Qualified; if (FindTypeMap(type.Visit(typePrinter), out typeMap)) { typeMap.Type = type; return true; } return false; }
public bool FindTypeMap(Type type, out TypeMap typeMap) { // Looks up the type in the cache map. if (typeMaps.ContainsKey(type)) { typeMap = typeMaps[type]; typeMap.Type = type; return(typeMap.IsEnabled); } var template = type as TemplateSpecializationType; if (template != null) { var specialization = template.GetClassTemplateSpecialization(); if (specialization != null && FindTypeMap(specialization, out typeMap)) { return(true); } if (template.Template.TemplatedDecl != null) { if (FindTypeMap(template.Template.TemplatedDecl, out typeMap)) { typeMap.Type = type; return(true); } return(false); } } Type desugared = type.Desugar(); desugared = (desugared.GetFinalPointee() ?? desugared).Desugar(); bool printExtra = desugared.IsPrimitiveType() || (desugared.GetFinalPointee() ?? desugared).Desugar().IsPrimitiveType(); var typePrinter = new CppTypePrinter(Context) { ResolveTypeMaps = false, PrintTypeQualifiers = printExtra, PrintTypeModifiers = printExtra, PrintLogicalNames = true }; typePrinter.PushContext(TypePrinterContextKind.Native); foreach (var resolveTypeDefs in new[] { false, true }) { foreach (var typePrintScopeKind in new[] { TypePrintScopeKind.Local, TypePrintScopeKind.Qualified }) { typePrinter.ResolveTypedefs = resolveTypeDefs; typePrinter.PushScope(typePrintScopeKind); var typeName = type.Visit(typePrinter); typePrinter.PopScope(); if (FindTypeMap(typeName, out typeMap)) { typeMap.Type = type; typeMaps[type] = typeMap; return(true); } } } typeMap = null; return(false); }
public bool FindTypeMap(Type type, out TypeMap typeMap) { var typePrinter = new CppTypePrinter { PrintTypeQualifiers = false, PrintTypeModifiers = false, PrintLogicalNames = true }; var template = type as TemplateSpecializationType; if (template != null) { var specialization = template.GetClassTemplateSpecialization(); if (specialization != null && FindTypeMap(specialization, type, out typeMap)) return true; if (template.Template.TemplatedDecl != null) return FindTypeMap(template.Template.TemplatedDecl, type, out typeMap); } if (FindTypeMap(type.Visit(typePrinter), out typeMap)) { typeMap.Type = type; return true; } if (FindTypeMap(type.Visit(typePrinter), out typeMap)) { typeMap.Type = type; return true; } typePrinter.PrintScopeKind = CppTypePrintScopeKind.Qualified; if (FindTypeMap(type.Visit(typePrinter), out typeMap)) { typeMap.Type = type; return true; } var typedef = type as TypedefType; return typedef != null && FindTypeMap(typedef.Declaration, type, out typeMap); }