string CreateFunctionPointerDelegateName(ClangType type) { var x = delegates.FirstOrDefault (e => e.Type == type); if (x != null) return x.TypeNameForReference; var pt = type.PointeeType; string ret = ToTypeName (pt.ResultType); bool hasArgs = pt.ArgumentTypeCount > 0; string args = ""; string f = "delegate" + delegates.Count.ToString (System.Globalization.CultureInfo.InvariantCulture); for (int i = 0; i < pt.ArgumentTypeCount; i++) { var tn = ToTypeName (pt.GetArgumentType (i)); if (i > 0) args += ", "; args += $"{tn} p{i}"; if (tn == "va_list") { Console.Error.WriteLine ($"Cannot bind {type.Spelling} because its arguments contain va_list."); // give up and return void* return "System.IntPtr"; } } // FIXME: we need to acquire location (impossible with current code structure) delegates.Add (new FunctionPointerDelegate { Type = type, ReturnType = ret, Arguments = args, TypeNameForDeclaration = f, TypeNameForReference = "Delegates." + f, }); return f; }
string GetTypeDetails(ClangType type) { if (type.Kind == TypeKind.Pointer) return "[CTypeDetails (\"Pointer<" + ToTypeName (type.PointeeType) + ">\")]"; if (type.Kind == TypeKind.ConstantArray) return "[CTypeDetails (\"ConstArrayOf<" + ToTypeName (type.ElementType) + ">\")] "; return null; }
string ToTypeName(ClangType type, bool strip = true) { var ret = ToManagedTypeName_ (type, strip); if (!InsideUsingDeclaration) return ret; var alias = usings.FirstOrDefault (u => u.Alias == ret)?.Managed; if (alias != null) return alias; return ToNonKeywordTypeName (ret); }
private static bool IsBuiltInType(ClangType cursor) { var result = false; if (cursor != null && cursor.Kind >= TypeKind.FirstBuiltin && cursor.Kind <= TypeKind.LastBuiltin) { return(true); } return(result); }
string GetTypeDetails(ClangType type) { if (type.Kind == TypeKind.Pointer) { return("[CTypeDetails (\"Pointer<" + ToTypeName(type.PointeeType) + ">\")]"); } if (type.Kind == TypeKind.ConstantArray) { return("[CTypeDetails (\"ConstArrayOf<" + ToTypeName(type.ElementType) + ">\")] "); } return(null); }
string ToTypeName(ClangType type, bool strip = true) { var ret = ToTypeName_(type, strip); if (!InsideUsingDeclaration) { return(ret); } var alias = usings.FirstOrDefault(u => u.Alias == ret).Actual; if (alias != null) { return(alias); } return(ToNonKeywordTypeName(ret)); }
string ToManagedTypeName_(ClangType type, bool strip = true) { if (type.IsPODType) { switch (type.Kind) { case TypeKind.Int: return("int"); // FIXME: this should be actually platform dependent case TypeKind.UInt: return("uint"); // FIXME: this should be actually platform dependent case TypeKind.Float: return("float"); case TypeKind.Double: case TypeKind.LongDouble: // FIXME: this should be actually platform dependent return("double"); case TypeKind.UChar: case TypeKind.CharU: case TypeKind.CharS: return("byte"); // The sign most unlikely matters. case TypeKind.SChar: return("sbyte"); case TypeKind.Short: return("short"); case TypeKind.UShort: return("ushort"); case TypeKind.Long: return("long"); // FIXME: this should be actually platform dependent case TypeKind.ULong: return("ulong"); // FIXME: this should be actually platform dependent case TypeKind.LongLong: return("long"); // FIXME: this should be actually platform dependent case TypeKind.ULongLong: return("ulong"); // FIXME: this should be actually platform dependent } // for aliased types to POD they still have IsPODType = true, so we need to ignore them. } if (type.Kind == TypeKind.ConstantArray) { return(ToTypeName(type.ElementType) + "[]"); } if (type.Kind == TypeKind.IncompleteArray) { return("ArrayOf<" + ToTypeName(type.ElementType) + ">"); } if (type.Kind == TypeKind.Pointer) { if (type.PointeeType != null && type.PointeeType.ArgumentTypeCount >= 0) { // function pointer return(CreateFunctionPointerDelegateName(type)); } else { var pointee = ToTypeName(type.PointeeType); switch (pointee) { case "byte": if (PreferStringOverByteArray) { return("string"); } goto default; case "void": return("System.IntPtr"); // mere pointer case "void *": return("System.IntPtr"); // pointer to pointer default: return("System.IntPtr"); // complex pointer, yet P/Invoke does not accept generic types... //return "Pointer<" + ToTypeName (type.PointeeType) + ">"; } } } if (strip && type.IsConstQualifiedType) { return(ToTypeName(type, false).Substring(6)); // "const " } else { return(type.Spelling.Replace("struct ", "").Replace("union ", "").Replace("enum ", "")); } }
private static bool IsBuiltInType(ClangType cursor) { var result = false; if (cursor != null && cursor.Kind >= TypeKind.FirstBuiltin && cursor.Kind <= TypeKind.LastBuiltin) { return true; } return result; }
string ToTypeName_(ClangType type, bool strip = true) { if (type.IsPODType) { switch (type.Spelling) { case "unsigned char": return("byte"); case "char": return("byte"); // we most likely don't need sbyte case "signed char": return("sbyte"); // probably explicit signed specification means something case "short": return("short"); case "unsigned short": return("ushort"); case "long": return("long"); // FIXME: this should be actually platform dependent case "unsigned long": return("ulong"); // FIXME: this should be actually platform dependent case "unsigned long long": return("ulong"); // FIXME: this should be actually platform dependent case "int": return("int"); // FIXME: this should be actually platform dependent case "unsigned int": return("uint"); // FIXME: this should be actually platform dependent case "float": return("float"); case "double": return("double"); } // for aliased types to POD they still have IsPODType = true, so we need to ignore them. } if (type.Kind == TypeKind.ConstantArray) { return("ConstArrayOf<" + ToTypeName(type.ElementType) + ">"); } if (type.Kind == TypeKind.IncompleteArray) { return("ArrayOf<" + ToTypeName(type.ElementType) + ">"); } if (type.Kind == TypeKind.Pointer) { if (type.PointeeType != null && type.PointeeType.ArgumentTypeCount >= 0) { // function pointer var pt = type.PointeeType; string ret = ToTypeName(pt.ResultType); string f = ret == "void" ? "System.Action<" : "System.Func<"; for (int i = 0; i < pt.ArgumentTypeCount; i++) { f += (i > 0 ? ", " : string.Empty) + ToTypeName(pt.GetArgumentType(i)); } if (ret != "void") { f += (pt.ArgumentTypeCount > 0 ? ", " : string.Empty) + ret; } f += ">"; return(f); } else { var t = ToTypeName(type.PointeeType); return(t == "void" ? "System.IntPtr" : "Pointer<" + t + ">"); } } if (strip && type.IsConstQualifiedType) { return(ToTypeName(type, false).Substring(6)); // "const " } else { return(type.Spelling.Replace("struct ", "").Replace("union", "").Replace("enum", "")); } }