public bool TryResolveType(CppType cppType, out TypeInfo typeInfo, bool lookForward = true) { if (TryGetType(cppType.GetDisplayName(), out typeInfo)) { return(true); } if (cppType is CppQualifiedType qualified) { return(TryResolveType(qualified.ElementType, out typeInfo, lookForward)); } if (cppType is CppPointerType pointer) { if (TryResolveType(pointer.ElementType, out var innerTypeInfo, lookForward)) { typeInfo = new TypeInfo(cppType.GetDisplayName(), cppType, PointerType(innerTypeInfo.TypeSyntax)); _nativeMap.Add(typeInfo.Name, typeInfo); return(true); } } if (lookForward) { _buildType(cppType).GetAwaiter().GetResult(); return(TryResolveType(cppType, out typeInfo, false)); } return(false); }
internal string MapToManagedApiType(CppType nativeType) { string type = nativeType.GetDisplayName(); if (IsKnownNativeType(nativeType)) { return(RenameForApi(CleanType(type), false)); } type = NativeToPinvokeType(nativeType); if (type.Contains("/*usize_t*/")) { return(nameof(UInt64)); } if (type.Contains("/*size_t*/")) { return(nameof(Int64)); } if (type.Contains("/*bool*/")) { return(nameof(Boolean)); } return(type); }
internal string NativeToPinvokeType(CppType nativeType) { string type = nativeType.GetDisplayName(); bool isPtr = type.Trim().EndsWith("*"); type = CleanType(type); if (_mappings.TryGetValue(type, out string managedType)) { return(managedType + (isPtr ? "*" : "")); } if (isPtr && _mappings.TryGetValue(type + "*", out string managedTypePtr)) { return(managedTypePtr); } if (_registeredTypes.Contains(type)) { return("IntPtr"); } Logger.LogWarning($"No C# equivalent for {type}"); return(type + (isPtr ? "*" : "")); }
protected TypeDesc GetTypeDesc(CppType type) { var t = new TypeDesc(type.GetDisplayName(), type); if (type is CppPointerType pointerType) { t.FunctionTypeRef = pointerType.ElementType as CppFunctionType; } return(t); }
internal bool IsKnownNativeType(CppType nativeTtype) { var type = nativeTtype.GetDisplayName(); if (_registeredTypes.Any(rt => rt == CleanType(type))) { return(true); } return(false); }
/// <summary> /// If a type defined under another type, then print the full name, e.g. Class1::Class2 /// </summary> public static string GetFullTypeName(this CppType cppType) { string name = cppType.GetDisplayName(); while (cppType.Parent is CppType parentType) { name = parentType.GetDisplayName() + "::" + name; cppType = parentType; } return(name); }
private static string GetCppType(CppType type) { var typeName = type.GetDisplayName(); // remove the const typeName = typeName.Replace("const ", ""); // replace the [] with a * int start; while ((start = typeName.IndexOf("[")) != -1) { var end = typeName.IndexOf("]"); typeName = typeName.Substring(0, start) + "*" + typeName.Substring(end + 1); } return(typeName); }
public static bool IsVoid(this CppType type) => type.GetDisplayName() == "void";
public static string GetVType(CppType cppType) { // unwrap any const vars if (cppType.TypeKind == CppTypeKind.Qualified && cppType is CppQualifiedType cppQualType) { if (cppQualType.Qualifier == CppTypeQualifier.Const) { return(GetVType(cppQualType.ElementType)); } } if (cppType is CppClass cppClass && cppClass.ClassKind == CppClassKind.Union) { Console.WriteLine($"Found union we can't handle! [{cppType.Span}]"); return("voidptr"); } if (cppType.TypeKind == CppTypeKind.Enum || cppType.TypeKind == CppTypeKind.Primitive) { return(GetVType(cppType.GetDisplayName())); } if (cppType.TypeKind == CppTypeKind.Typedef && cppType is CppTypedef typeDefType) { if (typeDefType.IsPrimitiveType()) { return(typeDefType.ElementTypeAsPrimitive().GetVType()); } else { return(GetVType(typeDefType.ElementType)); } } if (cppType.TypeKind == CppTypeKind.Pointer) { var cppPtrType = cppType as CppPointerType; // special V types if (cppPtrType.GetDisplayName() == "const char*" || cppPtrType.GetDisplayName() == "char*") { return("byteptr"); } if (cppPtrType.GetDisplayName() == "const void*" || cppPtrType.GetDisplayName() == "void*") { return("voidptr"); } // double pointer check if (cppPtrType.ElementType.TypeKind == CppTypeKind.Pointer) { if (cppPtrType.ElementType.TypeKind == CppTypeKind.Pointer) { return($"&voidptr /* {cppPtrType.GetDisplayName()} */"); } return($"&{GetVType(cppPtrType.ElementType)} /* {cppPtrType.GetDisplayName()} */"); } // unwrap any const vars if (cppPtrType.ElementType.TypeKind == CppTypeKind.Qualified && cppPtrType.ElementType is CppQualifiedType qualType) { if (qualType.Qualifier == CppTypeQualifier.Const) { if (qualType.ElementType is CppPrimitiveType qualPrimType && qualPrimType.Kind == CppPrimitiveKind.Void) { return($"voidptr"); } return("&" + GetVType(qualType.ElementType)); } } // function pointers if (cppPtrType.ElementType.TypeKind == CppTypeKind.Function) { var funcType = cppPtrType.ElementType as CppFunctionType; if (funcType.Parameters.Count == 1 && funcType.Parameters[0].Type is CppPointerType cppPtrPtrType && cppPtrPtrType.ElementType.TypeKind == CppTypeKind.Function) { funcType = cppPtrPtrType.ElementType as CppFunctionType; } // HACK: for some reason, there can occassionally be function pointer args inside a function pointer argument // for some reason. We just peel away the top function pointer and use that as the full type to fix the issue. foreach (var p in funcType.Parameters) { if (p.Type is CppPointerType pType && pType.ElementType.TypeKind == CppTypeKind.Function) { funcType = pType.ElementType as CppFunctionType; } } string GetReturnType() { // void return if (funcType.ReturnType is CppPrimitiveType cppPrimType && cppPrimType.Kind == CppPrimitiveKind.Void) { return(null); } return(GetVType(funcType.ReturnType)); }; // easy case: no parameters if (funcType.Parameters.Count == 0) { return($"fn() {GetReturnType()}".TrimEnd()); } var sb = new StringBuilder(); sb.Append("fn("); foreach (var p in funcType.Parameters) { var paramType = GetVType(p.Type); if (paramType.Contains("fn")) { // TODO: typedef the function param var typeDef = $"pub type Fn{V.ToPascalCase(p.Name)} {paramType}"; } sb.Append(paramType); if (funcType.Parameters.Last() != p) { sb.Append(", "); } } sb.Append(")"); var ret = GetReturnType(); if (ret != null) { sb.Append($" {ret}"); } // check for a function pointer that has a function as a param. This is currently invalid in V. var definition = sb.ToString(); if (definition.LastIndexOf("fn") > 2) { return($"voidptr /* {definition} */"); } return(sb.ToString()); } else if (cppPtrType.ElementType.TypeKind == CppTypeKind.Typedef) { // functions dont get passed with '&' so we have to see if this Typedef has a function in its lineage if (cppPtrType.ElementType is CppTypedef td && td.IsFunctionType()) { return(GetVType(cppPtrType.ElementType)); } return("&" + GetVType(cppPtrType.ElementType)); } return("&" + GetVType(cppPtrType.ElementType.GetDisplayName())); } // end Pointer if (cppType.TypeKind == CppTypeKind.Array) { var arrType = cppType as CppArrayType; if (arrType.ElementType is CppClass arrParamClass) { if (arrParamClass.Name.Contains("va_")) { Console.WriteLine($"Found unhandled vararg param! [{cppType}]"); return("voidptr /* ...voidptr */"); } } var eleType = GetVType(arrType.ElementType); if (arrType.Size > 0) { return($"[{arrType.Size}]{eleType}"); } return($"[]{eleType}"); } return(GetVType(cppType.GetDisplayName())); }
public static bool IsBool(this CppType type) => type.GetDisplayName() == "bool";