public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr clientData) { if (cursor.IsInSystemHeader()) { return CXChildVisitResult.CXChildVisit_Continue; } var cursorKind = clang.getCursorKind(cursor); if (cursorKind == CXCursorKind.CXCursor_StructDecl || cursorKind == CXCursorKind.CXCursor_UnionDecl) { if (m_writingStruct) { Action defferedVisit = () => Visit(cursor, parent, clientData); m_defferedVisits.Push(defferedVisit); return CXChildVisitResult.CXChildVisit_Continue; } m_writingStruct = true; var structName = clang.getCursorSpelling(cursor).ToString(); // struct names can be empty, and so we visit its sibling to find the name if (string.IsNullOrEmpty(structName)) { var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor); clang.visitChildren(clang.getCursorSemanticParent(cursor), forwardDeclaringVisitor.Visit, new CXClientData(IntPtr.Zero)); structName = clang.getCursorSpelling(forwardDeclaringVisitor.ForwardDeclarationCursor).ToString(); if (string.IsNullOrEmpty(structName)) { structName = @"_"; } } if (!m_visitedStructs.Contains(structName)) { //m_tw.WriteLine(@"[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]"); m_tw.WriteLine(@"public unsafe partial struct " + structName); m_tw.WriteLine(@"{"); m_hasChildren = false; m_tw.Indent++; clang.visitChildren(cursor, Visit, new CXClientData(IntPtr.Zero)); m_tw.Indent--; m_tw.WriteLine(@"}"); m_tw.WriteLine(); if (m_hasChildren) { m_visitedStructs.Add(structName); } } m_writingStruct = false; while (m_defferedVisits.Count > 0) { var defferedVisit = m_defferedVisits.Pop(); defferedVisit(); } //var fieldPosition = 0; return CXChildVisitResult.CXChildVisit_Continue; } if (cursorKind == CXCursorKind.CXCursor_FieldDecl) { m_hasChildren = true; var fieldName = clang.getCursorSpelling(cursor).ToString(); if (string.IsNullOrEmpty(fieldName)) { throw new NotSupportedException(); //fieldName = @"field" + fieldPosition; // what if they have fields called field*? :) } //fieldPosition++; m_tw.WriteLine(ToMarshalString(cursor, fieldName)); return CXChildVisitResult.CXChildVisit_Continue; } return CXChildVisitResult.CXChildVisit_Recurse; }
public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data) { if (cursor.IsInSystemHeader()) { return CXChildVisitResult.CXChildVisit_Continue; } var curKind = clang.getCursorKind(cursor); if (curKind == CXCursorKind.CXCursor_EnumDecl) { var kind = clang.getEnumDeclIntegerType(cursor).kind; string inheritedEnumType; switch (kind) { case CXTypeKind.CXType_Int: inheritedEnumType = @"int"; break; case CXTypeKind.CXType_UInt: inheritedEnumType = @"uint"; break; case CXTypeKind.CXType_Short: inheritedEnumType = @"short"; break; case CXTypeKind.CXType_UShort: inheritedEnumType = @"ushort"; break; case CXTypeKind.CXType_LongLong: inheritedEnumType = @"long"; break; case CXTypeKind.CXType_ULongLong: inheritedEnumType = @"ulong"; break; default: inheritedEnumType = @"int"; break; } var enumName = clang.getCursorSpelling(cursor).ToString(); // enumName can be empty because of typedef enum { .. } enumName; // so we have to find the sibling, and this is the only way I've found // to do with libclang, maybe there is a better way? if (string.IsNullOrEmpty(enumName)) { var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor); clang.visitChildren(clang.getCursorLexicalParent(cursor), forwardDeclaringVisitor.Visit, new CXClientData(IntPtr.Zero)); enumName = clang.getCursorSpelling(forwardDeclaringVisitor.ForwardDeclarationCursor).ToString(); if (string.IsNullOrEmpty(enumName)) { enumName = @"_"; } } // if we've printed these previously, skip them if (m_visitedEnums.Contains(enumName)) { return CXChildVisitResult.CXChildVisit_Continue; } m_visitedEnums.Add(enumName); m_tw.WriteLine(@"public enum " + enumName + @" : " + inheritedEnumType); m_tw.WriteLine(@"{"); m_tw.Indent ++; // visit all the enum values clang.visitChildren(cursor, (cxCursor, _, __) => { m_tw.WriteLine(@"@" + clang.getCursorSpelling(cxCursor).ToString() + @" = " + clang.getEnumConstantDeclValue(cxCursor) + ","); return CXChildVisitResult.CXChildVisit_Continue; }, new CXClientData(IntPtr.Zero)); m_tw.Indent--; m_tw.WriteLine(@"}"); m_tw.WriteLine(); } return CXChildVisitResult.CXChildVisit_Recurse; }
public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr clientData) { if (cursor.IsInSystemHeader()) { return(CXChildVisitResult.CXChildVisit_Continue); } var cursorKind = clang.getCursorKind(cursor); if (cursorKind == CXCursorKind.CXCursor_StructDecl || cursorKind == CXCursorKind.CXCursor_UnionDecl) { if (m_writingStruct) { Action defferedVisit = () => Visit(cursor, parent, clientData); m_defferedVisits.Push(defferedVisit); return(CXChildVisitResult.CXChildVisit_Continue); } m_writingStruct = true; var structName = clang.getCursorSpelling(cursor).ToString(); // struct names can be empty, and so we visit its sibling to find the name if (string.IsNullOrEmpty(structName)) { var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor); clang.visitChildren(clang.getCursorSemanticParent(cursor), forwardDeclaringVisitor.Visit, new CXClientData(IntPtr.Zero)); structName = clang.getCursorSpelling(forwardDeclaringVisitor.ForwardDeclarationCursor).ToString(); if (string.IsNullOrEmpty(structName)) { structName = @"_"; } } if (!m_visitedStructs.Contains(structName)) { //m_tw.WriteLine(@"[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]"); m_tw.WriteLine(@"public unsafe partial struct " + structName); m_tw.WriteLine(@"{"); m_hasChildren = false; m_tw.Indent++; clang.visitChildren(cursor, Visit, new CXClientData(IntPtr.Zero)); m_tw.Indent--; m_tw.WriteLine(@"}"); m_tw.WriteLine(); if (m_hasChildren) { m_visitedStructs.Add(structName); } } m_writingStruct = false; while (m_defferedVisits.Count > 0) { var defferedVisit = m_defferedVisits.Pop(); defferedVisit(); } //var fieldPosition = 0; return(CXChildVisitResult.CXChildVisit_Continue); } if (cursorKind == CXCursorKind.CXCursor_FieldDecl) { m_hasChildren = true; var fieldName = clang.getCursorSpelling(cursor).ToString(); if (string.IsNullOrEmpty(fieldName)) { throw new NotSupportedException(); //fieldName = @"field" + fieldPosition; // what if they have fields called field*? :) } //fieldPosition++; m_tw.WriteLine(ToMarshalString(cursor, fieldName)); return(CXChildVisitResult.CXChildVisit_Continue); } return(CXChildVisitResult.CXChildVisit_Recurse); }
public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data) { if (cursor.IsInSystemHeader()) { return(CXChildVisitResult.CXChildVisit_Continue); } var curKind = clang.getCursorKind(cursor); if (curKind == CXCursorKind.CXCursor_EnumDecl) { var kind = clang.getEnumDeclIntegerType(cursor).kind; string inheritedEnumType; switch (kind) { case CXTypeKind.CXType_Int: inheritedEnumType = @"int"; break; case CXTypeKind.CXType_UInt: inheritedEnumType = @"uint"; break; case CXTypeKind.CXType_Short: inheritedEnumType = @"short"; break; case CXTypeKind.CXType_UShort: inheritedEnumType = @"ushort"; break; case CXTypeKind.CXType_LongLong: inheritedEnumType = @"long"; break; case CXTypeKind.CXType_ULongLong: inheritedEnumType = @"ulong"; break; default: inheritedEnumType = @"int"; break; } var enumName = clang.getCursorSpelling(cursor).ToString(); // enumName can be empty because of typedef enum { .. } enumName; // so we have to find the sibling, and this is the only way I've found // to do with libclang, maybe there is a better way? if (string.IsNullOrEmpty(enumName)) { var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor); clang.visitChildren(clang.getCursorLexicalParent(cursor), forwardDeclaringVisitor.Visit, new CXClientData(IntPtr.Zero)); enumName = clang.getCursorSpelling(forwardDeclaringVisitor.ForwardDeclarationCursor).ToString(); if (string.IsNullOrEmpty(enumName)) { enumName = @"_"; } } // if we've printed these previously, skip them if (m_visitedEnums.Contains(enumName)) { return(CXChildVisitResult.CXChildVisit_Continue); } m_visitedEnums.Add(enumName); m_tw.WriteLine(@"public enum " + enumName + @" : " + inheritedEnumType); m_tw.WriteLine(@"{"); m_tw.Indent++; // visit all the enum values clang.visitChildren(cursor, (cxCursor, _, __) => { m_tw.WriteLine(@"@" + clang.getCursorSpelling(cxCursor).ToString() + @" = " + clang.getEnumConstantDeclValue(cxCursor) + ","); return(CXChildVisitResult.CXChildVisit_Continue); }, new CXClientData(IntPtr.Zero)); m_tw.Indent--; m_tw.WriteLine(@"}"); m_tw.WriteLine(); } return(CXChildVisitResult.CXChildVisit_Recurse); }