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