protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> Parents) { if (cursor.Kind == CXCursorKind.CXCursor_EnumDecl) { var enumSpelling = string.IsNullOrWhiteSpace(cursor.Spelling) ? Parents.ToNamespace() : cursor.Spelling; if (config.NativeEnums.Any(i => i.Name == enumSpelling) && !info.Enums.Any(e => e.Name == enumSpelling)) { var enumType = cursor.EnumType; if (enumType == typeof(IntPtr)) { enumType = typeof(int); } var enumDecl = new IDescribeEnum { Name = enumSpelling, Type = enumType }; cursor.VisitChildren((valueCursor) => { if (valueCursor.Kind != CXCursorKind.CXCursor_EnumConstantDecl && valueCursor.Kind != CXCursorKind.CXCursor_EnumDecl) { return; } var enumValue = new IDescribeEnumValue { Name = valueCursor.Spelling, Value = valueCursor.EnumValue }; enumDecl.Values.Add(enumValue); }); info.Enums.Add(enumDecl); } } }
protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> parents) { if (cursor.Kind == CXCursorKind.CXCursor_ClassDecl && config.NativeInterfaces.Any(i => i.Name == cursor.Spelling) && !cursor.IsForwardDeclaration) { cursor.VisitChildren((childCursor) => { if (childCursor.Kind == CXCursorKind.CXCursor_CXXBaseSpecifier) { var definitionSpelling = childCursor.CursorDefinition.Spelling; if (!config.NativeInterfaces.Any(i => i.Name == definitionSpelling)) { config.NativeInterfaces.Add(new NativeInterface { Name = definitionSpelling, }); } } }); } }
protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> parents) { if (cursor.Kind == CXCursorKind.CXCursor_TypedefDecl) { if (config.NativeDelegates.Any(i => i.Name == cursor.Spelling) && !info.Delegates.Any(i => i.Name == cursor.Spelling)) { CXType type = clang.getCanonicalType(clang.getTypedefDeclUnderlyingType(cursor.Cursor)); var pointee = clang.getPointeeType(type); if (pointee.kind == CXTypeKind.CXType_FunctionProto) { var callingConv = clang.getFunctionTypeCallingConv(pointee); var returnType = clang.getResultType(pointee); var name = cursor.Spelling; var delegateDecl = new IDescribeMethod { Name = cursor.Spelling, Returns = new List <IDescribeReturn> { new IDescribeReturn { Type = returnType.ToPlainType() } }, }; CodeAttributeArgument arg; switch (callingConv) { case CXCallingConv.CXCallingConv_X86StdCall: case CXCallingConv.CXCallingConv_X86_64Win64: arg = new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(CallingConvention)), "StdCall")); break; default: arg = new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(CallingConvention)), "Cdecl")); break; } uint parmCounter = 0; cursor.VisitChildren((childCursor) => { if (childCursor.Kind == CXCursorKind.CXCursor_ParmDecl) { var paramType = clang.getArgType(pointee, parmCounter); var paramSpelling = childCursor.Spelling; if (string.IsNullOrEmpty(paramSpelling)) { paramSpelling = "param" + parmCounter; } delegateDecl.Arguments.Add(new IDescribeArgument { Name = paramSpelling, Type = paramType.ToPlainType() }); parmCounter++; } }); if (delegateDecl.Arguments.Any(a => a.Type == typeof(string)) || delegateDecl.Returns.Any(a => a.Type == typeof(string))) { delegateDecl.Attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(UnmanagedFunctionPointerAttribute)), arg, new CodeAttributeArgument(nameof(UnmanagedFunctionPointerAttribute.CharSet), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(CharSet)), nameof(CharSet.Ansi))))); } else { delegateDecl.Attributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(UnmanagedFunctionPointerAttribute)), arg)); } info.Delegates.Add(delegateDecl); } } } }
protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> parents) { if (cursor.Kind == CXCursorKind.CXCursor_StructDecl) { this.fieldPosition = 0; if (config.NativeStructs.Any(s => s.Name == cursor.Spelling) && !this.info.Structs.Any((s) => { return(s.Name == cursor.Spelling); }) && !cursor.IsForwardDeclaration) { var structDecl = new IDescribeStruct { Name = cursor.Spelling }; cursor.VisitChildren((childCursor) => { if (childCursor.Kind == CXCursorKind.CXCursor_FieldDecl) { var fieldName = childCursor.Spelling; if (string.IsNullOrEmpty(fieldName)) { fieldName = "field" + this.fieldPosition; // what if they have fields called field*? :) } var fieldDecl = new IDescribeField { Name = fieldName }; var canonical = childCursor.CanonicalType; switch (childCursor.CanonicalType.kind) { case CXTypeKind.CXType_ConstantArray: long arraySize = clang.getArraySize(canonical); var elementType = clang.getCanonicalType(clang.getArrayElementType(canonical)); fieldDecl.Type = elementType.ToPlainType().MakeArrayType(); fieldDecl.Attributes.Add(new CodeAttributeDeclaration( new CodeTypeReference(typeof(MarshalAsAttribute)), new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(UnmanagedType)), "ByValArray")), new CodeAttributeArgument("SizeConst", new CodePrimitiveExpression(arraySize)))); break; case CXTypeKind.CXType_Pointer: var pointeeType = clang.getCanonicalType(clang.getPointeeType(canonical)); switch (pointeeType.kind) { case CXTypeKind.CXType_Char_S: fieldDecl.Type = typeof(string); fieldDecl.Attributes.Add(new CodeAttributeDeclaration( new CodeTypeReference(typeof(MarshalAsAttribute)), new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(UnmanagedType)), "LPTStr")))); break; case CXTypeKind.CXType_WChar: fieldDecl.Type = typeof(string); fieldDecl.Attributes.Add(new CodeAttributeDeclaration( new CodeTypeReference(typeof(MarshalAsAttribute)), new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(UnmanagedType)), "LPWStr")))); break; default: fieldDecl.Type = typeof(IntPtr); break; } break; case CXTypeKind.CXType_Record: case CXTypeKind.CXType_Enum: Console.WriteLine("Struct field type dunno: " + canonical.ToString()); fieldDecl.Type = typeof(IntPtr); break; default: fieldDecl.Type = canonical.ToPlainType(); break; } structDecl.Fields.Add(fieldDecl); } }); info.Structs.Add(structDecl); } } }
protected override void VisitChild(VisitorCursor cursor, List <VisitorCursor> parents) { if (cursor.Kind == CXCursorKind.CXCursor_ClassDecl) { if (!config.NativeInterfaces.Any(i => i.Name == cursor.Spelling) || cursor.IsForwardDeclaration) { return; } var classInfo = new IDescribeInterface { Name = cursor.Spelling }; cursor.VisitChildren((methodCursor) => { if (methodCursor.Kind == CXCursorKind.CXCursor_CXXMethod || methodCursor.Kind == CXCursorKind.CXCursor_Destructor || methodCursor.Kind == CXCursorKind.CXCursor_Constructor) { var methodName = methodCursor.Spelling; if (methodCursor.Kind == CXCursorKind.CXCursor_Constructor) { methodName = "ctor" + methodName; } if (methodCursor.Kind == CXCursorKind.CXCursor_Destructor) { methodName = "dtor" + (methodName.Replace("~", "")); } if (methodCursor.IsVirtual) { var methodInfo = new IDescribeMethod { Name = methodName, Returns = { new IDescribeReturn { Type = methodCursor.ReturnTypeCSharp } } }; for (uint index = 0; index < methodCursor.NumArgs; ++index) { var paramSpelling = methodCursor.GetArgSpelling(index); if (string.IsNullOrEmpty(paramSpelling)) { paramSpelling = "param" + index; } var info = new IDescribeArgument { Type = methodCursor.GetArgType(index), Name = paramSpelling }; var tokens = methodCursor.GetArgCursor(index).GetTokens(); var foundEquals = false; for (int i = 0; i < tokens.Length - 1; i++) { var token = tokens[i]; if (token.Kind == CXTokenKind.CXToken_Punctuation && token.Spelling == "=") { foundEquals = true; continue; } if (foundEquals && token.Kind == CXTokenKind.CXToken_Identifier) { info.Default = ""; break; } //probably an enum dont support this(yet(maybe)) if (foundEquals) { info.Default += token.Spelling; } } methodInfo.Arguments.Add(info); } classInfo.Methods.Add(methodInfo); } } if (methodCursor.Kind == CXCursorKind.CXCursor_CXXBaseSpecifier) { var definitionSpelling = methodCursor.CursorDefinition.Spelling; classInfo.Parents.Add(definitionSpelling); } }); this.info.Interfaces.Add(classInfo); } }