Beispiel #1
0
    string GetDefaultParameter(CXCursor handle)
    {
        string result = null;

        handle.VisitChildren((cursor, parent, client_data) =>
        {
            if (cursor.kind == CXCursorKind.CXCursor_CXXBoolLiteralExpr ||
                cursor.kind == CXCursorKind.CXCursor_IntegerLiteral ||
                cursor.kind == CXCursorKind.CXCursor_FloatingLiteral ||
                cursor.kind == CXCursorKind.CXCursor_CompoundLiteralExpr ||
                cursor.kind == CXCursorKind.CXCursor_FirstExpr ||
                cursor.kind == CXCursorKind.CXCursor_BinaryOperator)
            {
                CXSourceRange range = clang.getCursorExtent(cursor);
                CXToken *tokens     = null;
                uint numTokens      = 0;
                clang.tokenize(cursor.TranslationUnit, range, &tokens, &numTokens);

                for (int i = 0; i < numTokens; ++i)
                {
                    result += clang.getTokenSpelling(cursor.TranslationUnit, tokens[i]).ToString();
                }

                clang.disposeTokens(cursor.TranslationUnit, tokens, numTokens);
                return(CXChildVisitResult.CXChildVisit_Break);
            }
            return(CXChildVisitResult.CXChildVisit_Continue);
        }, new CXClientData());

        return(result);
    }
Beispiel #2
0
        public static void VisitChildren(this CXCursor cursor, VisitChildCursorAction visitAction)
        {
            var handle     = GCHandle.Alloc(visitAction);
            var clientData = new CXClientData((IntPtr)handle);

            cursor.VisitChildren(Visit, clientData);

            handle.Free();
        }
Beispiel #3
0
        protected CXChildVisitResult Handle(CXCursorVisitor visitor, CXCursor cursor, CXCursor parent, CXClientData data)
        {
            if (BeginHandle(cursor, parent))
            {
                cursor.VisitChildren(visitor, data);
            }
            EndHandle(cursor, parent);

            return(CXChildVisitResult.CXChildVisit_Continue);
        }
Beispiel #4
0
        public static unsafe void VisitChildren(this CXCursor cursor, VisitChildAction visitAction)
        {
            var clientData = new CXClientData(IntPtr.Zero);

            cursor.VisitChildren(Visitor, clientData);

            CXChildVisitResult Visitor(CXCursor childCursor, CXCursor childParent, void *data)
            {
                visitAction(childCursor);
                return(CXChildVisitResult.CXChildVisit_Continue);
            }
        }
Beispiel #5
0
        public static ImmutableArray <CXCursor> ChildrenOfKind(this CXCursor cursor, CXCursorKind kind)
        {
            var childrenBuilder = ImmutableArray.CreateBuilder <CXCursor>();

            cursor.VisitChildren(child =>
            {
                if (child.kind == kind)
                {
                    childrenBuilder.Add(child);
                }
            });
            return(childrenBuilder.ToImmutable());
        }
Beispiel #6
0
    void VisitClassOrStructDecl(CXCursor handle, ClassInfo parentClass = null)
    {
        if (IsForwardDeclaration(handle))
        {
            return;
        }

        ClassInfo top = new ClassInfo(handle);

        var annotations = GetAnnotations(handle);

        if (annotations.Contains("NOEXPORT"))
        {
            top.Export = ExportSetting.Ignore;
        }

        _allClasses[handle] = top;
        _classMap[top.FullyQualifiedName] = top;

        if (parentClass == null)
        {
            parentClass = _root;
        }

        parentClass.ChildClasses.Add(top);

        handle.VisitChildren((cursor, parent, clientData) =>
        {
            if (cursor.Kind == CXCursorKind.CXCursor_StructDecl || cursor.Kind == CXCursorKind.CXCursor_ClassDecl)
            {
                VisitClassOrStructDecl(cursor, top);
            }
            else if (cursor.kind == CXCursorKind.CXCursor_CXXBaseSpecifier)
            {
                if (cursor.Definition.kind == CXCursorKind.CXCursor_ClassDecl || cursor.Definition.kind == CXCursorKind.CXCursor_StructDecl)
                {
                    if (0 < cursor.Type.NumTemplateArguments)
                    {
                        top.Base = _classMap[GetFullyQualifiedName(cursor.Type.Declaration)];
                    }
                    else
                    {
                        top.Base = _allClasses[cursor.Definition];
                    }
                }
            }
            return(CXChildVisitResult.CXChildVisit_Continue);
        }, clientData: new CXClientData());
    }
Beispiel #7
0
    string[] GetAnnotations(CXCursor handle)
    {
        List <string> result = new List <string>();

        handle.VisitChildren((cursor, parent, clientData) =>
        {
            if (cursor.kind == CXCursorKind.CXCursor_AnnotateAttr)
            {
                result.Add(cursor.ToString());
            }
            return(CXChildVisitResult.CXChildVisit_Continue);
        }, clientData: new CXClientData());

        return(result.ToArray());
    }
Beispiel #8
0
    static bool IsMethodStatic(CXCursor functionHandle)
    {
        bool result = false;

        functionHandle.VisitChildren((cursor, parent, clientData) =>
        {
            if (cursor.kind == CXCursorKind.CXCursor_AnnotateAttr && cursor.ToString() == "STATIC")
            {
                result = true;
                return(CXChildVisitResult.CXChildVisit_Break);
            }
            return(CXChildVisitResult.CXChildVisit_Continue);
        }, clientData: new CXClientData());

        return(result);
    }
Beispiel #9
0
    void WriteEnum(CodeBuilder code, CXCursor handle)
    {
        string name = handle.Spelling.ToString();

        code.Append("[Flags]");
        code.Append("public enum " + name);
        code.BeginScope();

        handle.VisitChildren((cursor, parent, client_data) =>
        {
            if (cursor.Kind == CXCursorKind.CXCursor_EnumConstantDecl)
            {
                code.Append("{0} = {1},", cursor.Spelling.ToString(), clang.getEnumConstantDeclValue(cursor).ToString());
            }
            return(CXChildVisitResult.CXChildVisit_Continue);
        }, new CXClientData());

        code.EndScope();
    }
Beispiel #10
0
        public MethodDeclarationSyntax CreateExternMethod(CXCursor function)
        {
            // TODO: Other calling conventions
            var clangCallingConvention = function.Type.FunctionTypeCallingConv;
            CallingConvention cSharpCallingConvention;

            switch (clangCallingConvention)
            {
            case CXCallingConv.CXCallingConv_C:
                cSharpCallingConvention = CallingConvention.Cdecl;
                break;

            default:
                throw new NotImplementedException();
            }

            var typeClang     = function.ResultType;
            var baseTypeClang = GetClangBaseType(typeClang);
            var returnType    = GetTypeSyntax(typeClang, baseTypeClang);
            var method        = MethodDeclaration(returnType, function.Spelling.CString)
                                .WithDllImportAttribute(cSharpCallingConvention)
                                .WithModifiers(TokenList(
                                                   Token(SyntaxKind.PublicKeyword),
                                                   Token(SyntaxKind.StaticKeyword),
                                                   Token(SyntaxKind.ExternKeyword)))
                                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

            var parametersC = new List <CXCursor>();

            function.VisitChildren(child =>
            {
                if (child.kind == CXCursorKind.CXCursor_ParmDecl)
                {
                    parametersC.Add(child);
                }
            });
            var parameters = CreateMethodParameters(parametersC);

            method = method
                     .AddParameterListParameters(parameters.ToArray());

            return(method);
        }
Beispiel #11
0
        public unsafe static CodeTypeDelegate ToDelegate(this CXType type, string nativeName, CXCursor cursor, ModuleGenerator generator)
        {
            if (type.kind != CXTypeKind.CXType_FunctionProto &&
                type.kind != CXTypeKind.CXType_Unexposed)
            {
                throw new InvalidOperationException();
            }

            var clrName = NameConversions.ToClrName(nativeName, NameConversion.Type);

            CodeTypeDelegate delegateType = new CodeTypeDelegate();

            delegateType.CustomAttributes.Add(
                new CodeAttributeDeclaration(
                    new CodeTypeReference(typeof(UnmanagedFunctionPointerAttribute)),
                    new CodeAttributeArgument(
                        new CodePropertyReferenceExpression(
                            new CodeTypeReferenceExpression(typeof(CallingConvention)),
                            type.GetCallingConvention().ToString()))));

            delegateType.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            delegateType.Name       = clrName;
            delegateType.ReturnType = new CodeTypeReference(type.ResultType.ToClrType());

            uint argumentCounter = 0;

            var cursorVisitor = new DelegatingCXCursorVisitor(
                delegate(CXCursor c, CXCursor parent1)
            {
                if (c.Kind == CXCursorKind.CXCursor_ParmDecl)
                {
                    delegateType.Parameters.Add(Argument.GenerateArgument(generator, type, c, argumentCounter++, FunctionType.Delegate));
                }

                return(CXChildVisitResult.CXChildVisit_Continue);
            });

            cursor.VisitChildren(cursorVisitor.Visit, new CXClientData());

            return(delegateType);
        }
Beispiel #12
0
        public unsafe CXChildVisitResult Visit(CXCursor cursor, CXCursor parent)
        {
            if (!cursor.Location.IsFromMainFile)
            {
                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            CXCursorKind curKind = cursor.Kind;

            if (curKind == CXCursorKind.CXCursor_EnumDecl)
            {
                var nativeName  = cursor.Spelling.CString;
                var type        = cursor.EnumDecl_IntegerType.ToClrType();
                var enumComment = this.GetComment(cursor, forType: true);

                // 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(nativeName))
                {
                    var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor, skipSystemHeaderCheck: true);
                    cursor.LexicalParent.VisitChildren(forwardDeclaringVisitor.Visit, new CXClientData());
                    nativeName = forwardDeclaringVisitor.ForwardDeclarationCXCursor.Spelling.CString;

                    if (string.IsNullOrEmpty(nativeName))
                    {
                        nativeName = "_";
                    }
                }

                var clrName = NameConversions.ToClrName(nativeName, NameConversion.Type);

                // if we've printed these previously, skip them
                if (this.generator.NameMapping.ContainsKey(nativeName))
                {
                    return(CXChildVisitResult.CXChildVisit_Continue);
                }

                CodeTypeDeclaration enumDeclaration = new CodeTypeDeclaration();
                enumDeclaration.Attributes = MemberAttributes.Public;
                enumDeclaration.IsEnum     = true;
                enumDeclaration.Name       = clrName;
                enumDeclaration.BaseTypes.Add(type);

                if (enumComment != null)
                {
                    enumDeclaration.Comments.Add(enumComment);
                }

                // visit all the enum values
                DelegatingCXCursorVisitor visitor = new DelegatingCXCursorVisitor(
                    (c, vistor) =>
                {
                    var field =
                        new CodeMemberField()
                    {
                        Name           = NameConversions.ToClrName(c.Spelling.CString, NameConversion.Field),
                        InitExpression = new CodePrimitiveExpression(c.EnumConstantDeclValue)
                    };

                    var fieldComment = this.GetComment(c, forType: true);
                    if (fieldComment != null)
                    {
                        field.Comments.Add(fieldComment);
                    }

                    enumDeclaration.Members.Add(field);
                    return(CXChildVisitResult.CXChildVisit_Continue);
                });
                cursor.VisitChildren(visitor.Visit, new CXClientData());

                this.generator.AddType(nativeName, new CodeDomGeneratedType(enumDeclaration));
            }

            return(CXChildVisitResult.CXChildVisit_Recurse);
        }
Beispiel #13
0
        public unsafe CXChildVisitResult Visit(CXCursor cursor, CXCursor parent)
        {
            if (!cursor.Location.IsFromMainFile)
            {
                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            CXCursorKind curKind = cursor.Kind;

            if (curKind == CXCursorKind.CXCursor_StructDecl)
            {
                this.fieldPosition = 0;
                var nativeName = cursor.Spelling.CString;

                // struct names can be empty, and so we visit its sibling to find the name
                if (string.IsNullOrEmpty(nativeName))
                {
                    var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor, skipSystemHeaderCheck: true);
                    cursor.SemanticParent.VisitChildren(forwardDeclaringVisitor.Visit, new CXClientData());
                    nativeName = forwardDeclaringVisitor.ForwardDeclarationCXCursor.Spelling.CString;

                    if (string.IsNullOrEmpty(nativeName))
                    {
                        nativeName = "_";
                    }
                }

                var clrName = NameConversions.ToClrName(nativeName, NameConversion.Type);

                if (!this.generator.NameMapping.ContainsKey(nativeName))
                {
                    this.current            = new CodeTypeDeclaration(clrName);
                    this.current.IsStruct   = true;
                    this.current.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                    this.generator.AddType(nativeName, new CodeDomGeneratedType(this.current));

                    var layoutAttribute =
                        new CodeAttributeDeclaration(
                            new CodeTypeReference(typeof(StructLayoutAttribute)),
                            new CodeAttributeArgument(
                                new CodePropertyReferenceExpression(
                                    new CodeTypeReferenceExpression(typeof(LayoutKind)),
                                    nameof(LayoutKind.Sequential))));

                    this.current.CustomAttributes.Add(layoutAttribute);

                    var visitor = new DelegatingCXCursorVisitor(this.Visit);
                    cursor.VisitChildren(visitor.Visit, new CXClientData());
                }

                return(CXChildVisitResult.CXChildVisit_Continue);
            }

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

                this.fieldPosition++;

                foreach (var member in cursor.ToCodeTypeMember(fieldName, this.generator))
                {
                    this.current.Members.Add(member);
                }

                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            return(CXChildVisitResult.CXChildVisit_Recurse);
        }