Example #1
0
        public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (cursor.IsInSystemHeader())
            {
                return CXChildVisitResult.CXChildVisit_Continue;
            }

            var cursorKind = cursor.kind;
            if (cursorKind == CXCursorKind.CXCursor_MacroDefinition)
            {
                var macroName = clang.getCursorSpelling(cursor).ToString();

                if (m_visitedMacros.Contains(macroName))
                {
                    return CXChildVisitResult.CXChildVisit_Continue;
                }

                m_visitedMacros.Add(macroName);

                var expression = getMacroExpression(cursor);
                if (string.IsNullOrWhiteSpace(expression))
                {
                    return CXChildVisitResult.CXChildVisit_Continue;
                }

                m_tw.WriteLine(@"public const int {0} = {1};", macroName, expression);
            }

            return CXChildVisitResult.CXChildVisit_Continue;
        }
        public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (cursor.IsInSystemHeader())
            {
                return CXChildVisitResult.CXChildVisit_Continue;
            }

            CXCursorKind curKind = clang.getCursorKind(cursor);

            // look only at function decls
            if (curKind == CXCursorKind.CXCursor_FunctionDecl)
            {
                var functionName = clang.getCursorSpelling(cursor).ToString();

                if (this.visitedFunctions.Contains(functionName))
                {
                    return CXChildVisitResult.CXChildVisit_Continue;
                }

                this.visitedFunctions.Add(functionName);

                Extensions.WriteFunctionInfoHelper(cursor, this.tw, this.prefixStrip);

                return CXChildVisitResult.CXChildVisit_Continue;
            }

            return CXChildVisitResult.CXChildVisit_Recurse;
        }
Example #3
0
        public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (cursor.IsInSystemHeader())
            {
                return CXChildVisitResult.CXChildVisit_Continue;
            }

            CXCursorKind curKind = clang.getCursorKind(cursor);
            if (curKind == CXCursorKind.CXCursor_StructDecl)
            {
                this.fieldPosition = 0;
                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 (!this.visitedStructs.Contains(structName))
                {
                    this.IndentedWriteLine("public partial struct " + structName);
                    this.IndentedWriteLine("{");

                    this.indentLevel++;
                    clang.visitChildren(cursor, this.Visit, new CXClientData(IntPtr.Zero));
                    this.indentLevel--;

                    this.IndentedWriteLine("}");
                    this.tw.WriteLine();

                    this.visitedStructs.Add(structName);
                }

                return CXChildVisitResult.CXChildVisit_Continue;
            }

            if (curKind == CXCursorKind.CXCursor_FieldDecl)
            {
                var fieldName = clang.getCursorSpelling(cursor).ToString();
                if (string.IsNullOrEmpty(fieldName))
                {
                    fieldName = "field" + this.fieldPosition; // what if they have fields called field*? :)
                }

                this.fieldPosition++;
                this.IndentedWriteLine(cursor.ToMarshalString(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 cursorKind = clang.getCursorKind(cursor);

            // look only at function decls
            if (cursorKind == CXCursorKind.CXCursor_FunctionDecl)
            {
                var functionName = clang.getCursorSpelling(cursor).ToString();
                
                if (m_visitedFunctions.Contains(functionName))
                {
                    return CXChildVisitResult.CXChildVisit_Continue;
                }

                string libraryName;
                if (m_exportMap.TryGetValue(functionName, out libraryName))
                {
                    if (!string.Equals(libraryName, m_libraryName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        string message = string.Format(@"Warning: Function {0} belongs to {1}. Skipping generation for {2}.",
                            functionName, libraryName, m_libraryName);
                        Console.WriteLine(message);
                        return CXChildVisitResult.CXChildVisit_Continue;
                    }
                }
                else
                {
                    m_visitedFunctions.Add(functionName);

                    string message = string.Format(@"Info: Unknow function export {0}. Skipping generation for {1}.",
                           functionName, m_libraryName);
                    Console.WriteLine(message);
                    return CXChildVisitResult.CXChildVisit_Continue;
                }

                m_visitedFunctions.Add(functionName);

                WriteFunction(cursor, m_prefixStrip);

                return CXChildVisitResult.CXChildVisit_Continue;
            }

            return CXChildVisitResult.CXChildVisit_Recurse;
        }
        public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (cursor.IsInSystemHeader())
            {
                return CXChildVisitResult.CXChildVisit_Continue;
            }

            if (clang.equalCursors(cursor, m_beginningCursor) != 0)
            {
                m_beginningCursorReached = true;
                return CXChildVisitResult.CXChildVisit_Continue;
            }

            if (m_beginningCursorReached)
            {
                ForwardDeclarationCursor = cursor;
                return CXChildVisitResult.CXChildVisit_Break;
            }

            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 cursorKind = clang.getCursorKind(cursor);
            if (cursorKind == CXCursorKind.CXCursor_TypedefDecl)
            {
                var spelling = clang.getCursorSpelling(cursor).ToString();

                if (m_visitedTypeDefs.Contains(spelling))
                {
                    return CXChildVisitResult.CXChildVisit_Continue;
                }

                m_visitedTypeDefs.Add(spelling);

                var type = clang.getCanonicalType(clang.getTypedefDeclUnderlyingType(cursor));

                // we handle enums and records in struct and enum visitors with forward declarations also
                if (type.kind == CXTypeKind.CXType_Record || type.kind == CXTypeKind.CXType_Enum)
                {
                    return CXChildVisitResult.CXChildVisit_Continue;
                }

                // no idea what this is? -- template stuff?
                if (type.kind == CXTypeKind.CXType_Unexposed)
                {
                    var canonical = clang.getCanonicalType(type);
                    if (canonical.kind == CXTypeKind.CXType_Unexposed)
                    {
                        return CXChildVisitResult.CXChildVisit_Continue;
                    }
                }

                if (type.kind == CXTypeKind.CXType_Pointer)
                {
                    var pointee = clang.getPointeeType(type);
                    if (pointee.kind == CXTypeKind.CXType_Record || pointee.kind == CXTypeKind.CXType_Void)
                    {
                        m_tw.WriteLine(@"public partial struct " + spelling);
                        m_tw.WriteLine(@"{");
                        m_tw.WriteLine(@"    public " + spelling + @"(IntPtr pointer)");
                        m_tw.WriteLine(@"    {");
                        m_tw.WriteLine(@"        this.Pointer = pointer;");
                        m_tw.WriteLine(@"    }");
                        m_tw.WriteLine();
                        m_tw.WriteLine(@"    public IntPtr Pointer;");
                        m_tw.WriteLine(@"}");
                        m_tw.WriteLine();

                        return CXChildVisitResult.CXChildVisit_Continue;
                    }

                    if (pointee.kind == CXTypeKind.CXType_FunctionProto)
                    {
                        m_tw.WriteLine(@"[UnmanagedFunctionPointer(" + pointee.CallingConventionSpelling() + ")]");
                        m_tw.Write(@"public unsafe delegate ");
                        FunctionHelper.WriteReturnType(clang.getResultType(pointee), m_tw);
                        m_tw.Write(@" ");
                        m_tw.Write(spelling);
                        m_tw.Write(@"(");

                        uint argumentCounter = 0;

                        clang.visitChildren(cursor, delegate(CXCursor cxCursor, CXCursor parent1, IntPtr ptr)
                        {
                            if (cxCursor.kind == CXCursorKind.CXCursor_ParmDecl)
                            {
                                FunctionHelper.WriteArgument(pointee, cxCursor, m_tw, argumentCounter++);
                            }

                            return CXChildVisitResult.CXChildVisit_Continue;
                        }, new CXClientData(IntPtr.Zero));

                        m_tw.WriteLine(@");");
                        m_tw.WriteLine();

                        return CXChildVisitResult.CXChildVisit_Continue;
                    }
                }

                if (clang.isPODType(type) != 0)
                {
                    var podType = type.ToPlainTypeString();
                    m_tw.WriteLine(@"public partial struct " + spelling);
                    m_tw.WriteLine(@"{");
                    m_tw.WriteLine(@"    public " + spelling + @"(" + podType + @" value)");
                    m_tw.WriteLine(@"    {");
                    m_tw.WriteLine(@"        this.Value = value;");
                    m_tw.WriteLine(@"    }");
                    m_tw.WriteLine();
                    m_tw.WriteLine(@"    public " + type.ToPlainTypeString() + @" Value;");
                    m_tw.WriteLine(@"}");
                    m_tw.WriteLine();
                }

                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;
        }