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;
        }
Exemple #3
0
        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);
        }