public ChildVisitResult Visit(Cursor cursor, Cursor parent) { if (!cursor.GetLocation().IsFromMainFile()) { return(ChildVisitResult.Continue); } CursorKind curKind = cursor.Kind; if (curKind == CursorKind.EnumDecl) { var nativeName = cursor.GetSpelling(); var type = cursor.GetEnumDeclIntegerType().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); forwardDeclaringVisitor.VisitChildren(cursor.GetLexicalParent()); nativeName = forwardDeclaringVisitor.ForwardDeclarationCursor.GetSpelling(); 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(ChildVisitResult.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 DelegatingCursorVisitor visitor = new DelegatingCursorVisitor( (c, vistor) => { var field = new CodeMemberField() { Name = NameConversions.ToClrName(c.GetSpelling(), NameConversion.Field), InitExpression = new CodePrimitiveExpression(c.GetEnumConstantDeclValue()) }; var fieldComment = this.GetComment(c, forType: true); if (fieldComment != null) { field.Comments.Add(fieldComment); } enumDeclaration.Members.Add(field); return(ChildVisitResult.Continue); }); visitor.VisitChildren(cursor); this.generator.AddType(nativeName, new CodeDomGeneratedType(enumDeclaration)); } return(ChildVisitResult.Recurse); }
public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data) { if (clang.Location_isFromMainFile(clang.getCursorLocation(cursor)) == 0) { return(CXChildVisitResult.CXChildVisit_Continue); } CXCursorKind curKind = clang.getCursorKind(cursor); if (curKind == CXCursorKind.CXCursor_StructDecl) { this.fieldPosition = 0; var nativeName = clang.getCursorSpelling(cursor).ToString(); // struct names can be empty, and so we visit its sibling to find the name if (string.IsNullOrEmpty(nativeName)) { var forwardDeclaringVisitor = new ForwardDeclarationVisitor(cursor); clang.visitChildren(clang.getCursorSemanticParent(cursor), forwardDeclaringVisitor.Visit, new CXClientData(IntPtr.Zero)); nativeName = clang.getCursorSpelling(forwardDeclaringVisitor.ForwardDeclarationCursor).ToString(); 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, 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); clang.visitChildren(cursor, this.Visit, new CXClientData(IntPtr.Zero)); } 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++; foreach (var member in cursor.ToCodeTypeMember(fieldName, this.generator)) { this.current.Members.Add(member); } return(CXChildVisitResult.CXChildVisit_Continue); } return(CXChildVisitResult.CXChildVisit_Recurse); }
public ChildVisitResult Visit(Cursor cursor, Cursor parent) { if (!cursor.GetLocation().IsFromMainFile()) { return(ChildVisitResult.Continue); } CursorKind curKind = cursor.Kind; if (curKind == CursorKind.StructDecl) { this.fieldPosition = 0; var nativeName = cursor.GetSpelling(); // 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); forwardDeclaringVisitor.VisitChildren(cursor.GetSemanticParent()); nativeName = forwardDeclaringVisitor.ForwardDeclarationCursor.GetSpelling(); 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, 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 DelegatingCursorVisitor(this.Visit); visitor.VisitChildren(cursor); } return(ChildVisitResult.Continue); } if (curKind == CursorKind.FieldDecl) { var fieldName = cursor.GetSpelling(); 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(ChildVisitResult.Continue); } return(ChildVisitResult.Recurse); }
public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data) { if (clang.Location_isFromMainFile(clang.getCursorLocation(cursor)) == 0) { return(CXChildVisitResult.CXChildVisit_Continue); } CXCursorKind curKind = clang.getCursorKind(cursor); if (curKind == CXCursorKind.CXCursor_EnumDecl) { var nativeName = clang.getCursorSpelling(cursor).ToString(); var type = clang.getEnumDeclIntegerType(cursor).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); clang.visitChildren(clang.getCursorLexicalParent(cursor), forwardDeclaringVisitor.Visit, new CXClientData(IntPtr.Zero)); nativeName = clang.getCursorSpelling(forwardDeclaringVisitor.ForwardDeclarationCursor).ToString(); 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 clang.visitChildren( cursor, (cxCursor, vistor, clientData) => { var field = new CodeMemberField() { Name = NameConversions.ToClrName(clang.getCursorSpelling(cxCursor).ToString(), NameConversion.Field), InitExpression = new CodePrimitiveExpression(clang.getEnumConstantDeclValue(cxCursor)) }; var fieldComment = this.GetComment(cxCursor, forType: false); if (fieldComment != null) { field.Comments.Add(fieldComment); } enumDeclaration.Members.Add(field); return(CXChildVisitResult.CXChildVisit_Continue); }, new CXClientData(IntPtr.Zero)); this.generator.AddType(nativeName, enumDeclaration); } return(CXChildVisitResult.CXChildVisit_Recurse); }