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); } var parents = new List <CXCursor> { parent }; VisitInternal(cursor, parent, parents.ShallowCopy()); return(CXChildVisitResult.CXChildVisit_Continue); }
public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data) { if (cursor.IsInSystemHeader()) { return(CXChildVisitResult.CXChildVisit_Continue); } if (clang.equalCursors(cursor, this.beginningCursor) != 0) { this.beginningCursorReached = true; return(CXChildVisitResult.CXChildVisit_Continue); } if (this.beginningCursorReached) { this.ForwardDeclarationCursor = cursor; return(CXChildVisitResult.CXChildVisit_Break); } return(CXChildVisitResult.CXChildVisit_Recurse); }
public unsafe CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, void *client_data) { if (!this.skipSystemHeaderCheck && cursor.IsInSystemHeader()) { return(CXChildVisitResult.CXChildVisit_Continue); } if (cursor.Equals(this.beginningCXCursor)) { this.beginningCXCursorReached = true; return(CXChildVisitResult.CXChildVisit_Continue); } if (this.beginningCXCursorReached) { this.ForwardDeclarationCXCursor = cursor; return(CXChildVisitResult.CXChildVisit_Break); } return(CXChildVisitResult.CXChildVisit_Recurse); }
private CXChildVisitResult VisitCApi(CXCursor cursor, CXCursor parent, IntPtr data) { if (cursor.IsInSystemHeader()) { return(CXChildVisitResult.CXChildVisit_Continue); } var kind = clang.getCursorKind(cursor); switch (kind) { case CXCursorKind.CXCursor_EnumDecl: var enumName = GetTypeAsString(clang.getCursorType(cursor)); var baseType = clang.getEnumDeclIntegerType(cursor).kind.ToPrimitiveCsType() ?? "int"; var enums = new List <KeyValuePair <string, long> >(); clang.visitChildren(cursor, (cxCursor, parent1, clientData) => { var valName = clang.getCursorSpelling(cxCursor).ToString(); var valValue = clang.getEnumConstantDeclValue(cxCursor); enums.Add(new KeyValuePair <string, long>(valName, valValue)); return(CXChildVisitResult.CXChildVisit_Continue); }, new CXClientData(IntPtr.Zero)); WriteLine(); var enumcs = GetCSharpName(enumName); WriteLine("public enum " + enumcs + (baseType != "int" ? " : " + baseType : string.Empty)); WriteOpenBlock(); foreach (var enumItem in enums) { WriteLine(enumItem.Key + " = " + enumItem.Value + ","); } WriteCloseBlock(); return(CXChildVisitResult.CXChildVisit_Continue); case CXCursorKind.CXCursor_StructDecl: case CXCursorKind.CXCursor_UnionDecl: { AddOpaqueStruct(cursor); // TODO: Check that a struct is either an opaque pointer (used only through a pointer) // or a real struct that we should generate fields for. return(CXChildVisitResult.CXChildVisit_Continue); } case CXCursorKind.CXCursor_TypedefDecl: { var canonicalType = clang.getCanonicalType(clang.getTypedefDeclUnderlyingType(cursor)); bool hasPointer = false; while (canonicalType.kind == CXTypeKind.CXType_Pointer) { canonicalType = clang.getPointeeType(canonicalType); hasPointer = true; } if (canonicalType.kind == CXTypeKind.CXType_Record || hasPointer) { AddOpaqueStruct(cursor); // TODO: Check that a struct is either an opaque pointer (used only through a pointer) // or a real struct that we should generate fields for. } return(CXChildVisitResult.CXChildVisit_Continue); } case CXCursorKind.CXCursor_FunctionDecl: _writer = _writerBody; var functionName = clang.getCursorSpelling(cursor).ToString(); var functionType = clang.getCursorType(cursor); WriteLine(); WriteFunction(functionType, cursor, functionName); return(CXChildVisitResult.CXChildVisit_Continue); } return(CXChildVisitResult.CXChildVisit_Recurse); }
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_TypedefDecl) { var spelling = clang.getCursorSpelling(cursor).ToString(); if (this.visitedTypeDefs.Contains(spelling)) { return(CXChildVisitResult.CXChildVisit_Continue); } this.visitedTypeDefs.Add(spelling); CXType 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) { this.tw.WriteLine(" public partial struct " + spelling); this.tw.WriteLine(" {"); this.tw.WriteLine(" public " + spelling + "(IntPtr pointer)"); this.tw.WriteLine(" {"); this.tw.WriteLine(" this.Pointer = pointer;"); this.tw.WriteLine(" }"); this.tw.WriteLine(); this.tw.WriteLine(" public IntPtr Pointer;"); this.tw.WriteLine(" }"); this.tw.WriteLine(); return(CXChildVisitResult.CXChildVisit_Continue); } if (pointee.kind == CXTypeKind.CXType_FunctionProto) { this.tw.WriteLine(" [UnmanagedFunctionPointer(" + pointee.CallingConventionSpelling() + ")]"); this.tw.Write(" public delegate "); Extensions.ReturnTypeHelper(clang.getResultType(pointee), tw); this.tw.Write(" "); this.tw.Write(spelling); this.tw.Write("("); uint argumentCounter = 0; clang.visitChildren(cursor, delegate(CXCursor cxCursor, CXCursor parent1, IntPtr ptr) { if (cxCursor.kind == CXCursorKind.CXCursor_ParmDecl) { Extensions.ArgumentHelper(pointee, cxCursor, tw, argumentCounter++); } return(CXChildVisitResult.CXChildVisit_Continue); }, new CXClientData(IntPtr.Zero)); this.tw.WriteLine(");"); this.tw.WriteLine(); return(CXChildVisitResult.CXChildVisit_Continue); } } if (clang.isPODType(type) != 0) { var podType = type.ToPlainTypeString(); this.tw.WriteLine(" public partial struct " + spelling); this.tw.WriteLine(" {"); this.tw.WriteLine(" public " + spelling + "(" + podType + " value)"); this.tw.WriteLine(" {"); this.tw.WriteLine(" this.Value = value;"); this.tw.WriteLine(" }"); this.tw.WriteLine(); this.tw.WriteLine(" public " + type.ToPlainTypeString() + " Value;"); this.tw.WriteLine(" }"); this.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); } CXCursorKind curKind = clang.getCursorKind(cursor); if (curKind == CXCursorKind.CXCursor_EnumDecl) { string inheritedEnumType; CXTypeKind kind = clang.getEnumDeclIntegerType(cursor).kind; 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 (this.printedEnums.Contains(enumName)) { return(CXChildVisitResult.CXChildVisit_Continue); } this.printedEnums.Add(enumName); this.tw.WriteLine(" public enum " + enumName + " : " + inheritedEnumType); this.tw.WriteLine(" {"); // visit all the enum values clang.visitChildren(cursor, (cxCursor, _, __) => { this.tw.WriteLine(" @" + clang.getCursorSpelling(cxCursor).ToString() + " = " + clang.getEnumConstantDeclValue(cxCursor) + ","); return(CXChildVisitResult.CXChildVisit_Continue); }, new CXClientData(IntPtr.Zero)); this.tw.WriteLine(" }"); this.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); } CXCursorKind curKind = clang.getCursorKind(cursor); bool isUnion = (curKind == CXCursorKind.CXCursor_UnionDecl); bool isStruct = (curKind == CXCursorKind.CXCursor_StructDecl); if (isUnion || isStruct) { 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)) { if (isUnion) { this.IndentedWriteLine("[StructLayout(LayoutKind.Explicit)]"); } 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++; bool isUnionField = (clang.getCursorKind(parent) == CXCursorKind.CXCursor_UnionDecl); if (isUnionField) { this.IndentedWriteLine("[FieldOffset(0)]"); } if (fieldName == "padding") { System.Diagnostics.Debugger.Break(); } 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); } CXCursorKind curKind = clang.getCursorKind(cursor); if (curKind == CXCursorKind.CXCursor_EnumDecl) { string inheritedEnumType; CXTypeKind kind = clang.getEnumDeclIntegerType(cursor).kind; 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; } // Cross-plat hack: // For whatever reason, libclang detects untyped enums (i.e. your average 'enum X { A, B }') // as uints on Linux and ints on Windows. // Since we want to have the same generated code everywhere, we try to force 'int' // if it doesn't change semantics, i.e. if all enum values are in the right range. // Remember that 2's complement ints use the same binary representation as uints for positive numbers. if (inheritedEnumType == "uint") { bool hasOneValue = false; long minValue = long.MaxValue; long maxValue = long.MinValue; clang.visitChildren(cursor, (cxCursor, _, __) => { hasOneValue = true; long value = clang.getEnumConstantDeclValue(cxCursor); minValue = Math.Min(minValue, value); maxValue = Math.Max(maxValue, value); return(CXChildVisitResult.CXChildVisit_Continue); }, new CXClientData(IntPtr.Zero)); if (hasOneValue && minValue >= 0 && maxValue <= int.MaxValue) { inheritedEnumType = "int"; } } 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 (this.printedEnums.Contains(enumName)) { return(CXChildVisitResult.CXChildVisit_Continue); } this.printedEnums.Add(enumName); this.tw.WriteLine(" public enum " + enumName + " : " + inheritedEnumType); this.tw.WriteLine(" {"); // visit all the enum values clang.visitChildren(cursor, (cxCursor, _, __) => { this.tw.WriteLine(" @" + clang.getCursorSpelling(cxCursor).ToString() + " = " + clang.getEnumConstantDeclValue(cxCursor) + ","); return(CXChildVisitResult.CXChildVisit_Continue); }, new CXClientData(IntPtr.Zero)); this.tw.WriteLine(" }"); this.tw.WriteLine(); } return(CXChildVisitResult.CXChildVisit_Recurse); }