protected override CXChildVisitResult VisitChildren(CXCursor childHandle, CXCursor handle, CXClientData clientData) { ValidateVisit(ref handle); switch (childHandle.Kind) { case CXCursorKind.CXCursor_UnionDecl: { return(GetOrAddChild <UnionDecl>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_ClassDecl: { return(GetOrAddChild <ClassDecl>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_EnumDecl: { return(GetOrAddChild <EnumDecl>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_FieldDecl: { return(GetOrAddChild <FieldDecl>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_VarDecl: { return(GetOrAddChild <VarDecl>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_TypedefDecl: { return(GetOrAddChild <TypedefDecl>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_CXXMethod: { return(GetOrAddChild <CXXMethod>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_Constructor: { return(GetOrAddChild <Constructor>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_Destructor: { return(GetOrAddChild <Destructor>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_ConversionFunction: { return(GetOrAddChild <ConversionFunction>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_FunctionTemplate: { return(GetOrAddChild <FunctionTemplate>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_ClassTemplate: { return(GetOrAddChild <ClassTemplate>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_TypeAliasDecl: { return(GetOrAddChild <TypeAliasDecl>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_CXXAccessSpecifier: { return(GetOrAddChild <CXXAccessSpecifier>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_CXXBaseSpecifier: { return(GetOrAddChild <CXXBaseSpecifier>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_UnexposedAttr: { return(GetOrAddChild <UnexposedAttr>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_DLLExport: { return(GetOrAddChild <DLLExport>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_DLLImport: { return(GetOrAddChild <DLLImport>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_StaticAssert: { return(GetOrAddChild <StaticAssert>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_FriendDecl: { return(GetOrAddChild <FriendDecl>(childHandle).Visit(clientData)); } default: { return(base.VisitChildren(childHandle, handle, clientData)); } } }
internal static extern CXComment clang_Cursor_getParsedComment(CXCursor c);
internal static extern UInt64 clang_getEnumConstantDeclUnsignedValue(CXCursor c);
internal static extern CXType clang_getEnumDeclIntegerType(CXCursor C);
internal static extern CXCursor clang_getSpecializedCursorTemplate(CXCursor c);
internal static extern CXType clang_getCursorResultType(CXCursor c);
internal static extern uint clang_isVirtualBase(CXCursor c);
public Function(CProject proj, CXCursor cursor) : base(proj, cursor) { }
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); }
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); }
private CodeCommentStatement GetComment(CXCursor cursor) { // Standard hierarchy: // - Full Comment // - Paragraph Comment or ParamCommand comment // - Text Comment var fullComment = clang.Cursor_getParsedComment(cursor); var fullCommentKind = clang.Comment_getKind(fullComment); var fullCommentChildren = clang.Comment_getNumChildren(fullComment); if (fullCommentKind != CXCommentKind.CXComment_FullComment || fullCommentChildren < 1) { return(null); } StringBuilder summary = new StringBuilder(); StringBuilder parameters = new StringBuilder(); StringBuilder remarks = new StringBuilder(); StringBuilder returnValue = new StringBuilder(); bool hasComment = false; bool hasParameter = false; for (int i = 0; i < fullCommentChildren; i++) { var childComment = clang.Comment_getChild(fullComment, (uint)i); var childCommentKind = clang.Comment_getKind(childComment); if (childCommentKind != CXCommentKind.CXComment_Paragraph && childCommentKind != CXCommentKind.CXComment_ParamCommand && childCommentKind != CXCommentKind.CXComment_BlockCommand) { continue; } StringBuilder textBuilder = new StringBuilder(); this.GetCommentInnerText(childComment, textBuilder); string text = textBuilder.ToString(); if (string.IsNullOrWhiteSpace(text)) { continue; } if (childCommentKind == CXCommentKind.CXComment_Paragraph) { summary.Append(text); hasComment = true; } else if (childCommentKind == CXCommentKind.CXComment_ParamCommand) { // Get the parameter name var paramName = clang.ParamCommandComment_getParamName(childComment).ToString(); if (hasParameter) { parameters.AppendLine(); } parameters.AppendLine($" <param name=\"{paramName}\">"); parameters.Append(text); parameters.Append(" </param>"); hasComment = true; hasParameter = true; } else if (childCommentKind == CXCommentKind.CXComment_BlockCommand) { var name = clang.BlockCommandComment_getCommandName(childComment).ToString(); if (name == "note") { remarks.Append(text); } else if (name == "return") { returnValue.Append(text); } } } if (!hasComment) { return(null); } StringBuilder comment = new StringBuilder(); if (summary.Length > 0) { comment.AppendLine("<summary>"); comment.Append(summary.ToString()); comment.Append(" </summary>"); } if (parameters.Length > 0) { comment.AppendLine(); comment.Append(parameters.ToString()); } if (returnValue.Length > 0) { comment.AppendLine(); comment.AppendLine(" <returns>"); comment.Append(returnValue.ToString()); comment.Append(" </returns>"); } if (remarks.Length > 0) { comment.AppendLine(); comment.AppendLine(" <remarks>"); comment.Append(remarks.ToString()); comment.Append(" </remarks>"); } return(new CodeCommentStatement(comment.ToString(), docComment: true)); }
public Macro(CProject proj, CXCursor cursor) : base(proj, cursor) { }
protected override CXChildVisitResult VisitChildren(CXCursor childHandle, CXCursor handle, CXClientData clientData) { ValidateVisit(ref handle); Expr expr; switch (childHandle.Kind) { case CXCursorKind.CXCursor_UnexposedExpr: { expr = GetOrAddChild <UnexposedExpr>(childHandle); break; } case CXCursorKind.CXCursor_DeclRefExpr: { expr = GetOrAddChild <DeclRefExpr>(childHandle); break; } case CXCursorKind.CXCursor_MemberRefExpr: { expr = GetOrAddChild <MemberRefExpr>(childHandle); break; } case CXCursorKind.CXCursor_CallExpr: { expr = GetOrAddChild <CallExpr>(childHandle); break; } case CXCursorKind.CXCursor_IntegerLiteral: { expr = GetOrAddChild <IntegerLiteral>(childHandle); break; } case CXCursorKind.CXCursor_FloatingLiteral: { expr = GetOrAddChild <FloatingLiteral>(childHandle); break; } case CXCursorKind.CXCursor_ParenExpr: { expr = GetOrAddChild <ParenExpr>(childHandle); break; } case CXCursorKind.CXCursor_UnaryOperator: { expr = GetOrAddChild <UnaryOperator>(childHandle); break; } case CXCursorKind.CXCursor_ArraySubscriptExpr: { expr = GetOrAddChild <ArraySubscriptExpr>(childHandle); break; } case CXCursorKind.CXCursor_BinaryOperator: { expr = GetOrAddChild <BinaryOperator>(childHandle); break; } case CXCursorKind.CXCursor_CStyleCastExpr: { expr = GetOrAddChild <CStyleCastExpr>(childHandle); break; } case CXCursorKind.CXCursor_CXXStaticCastExpr: { expr = GetOrAddChild <CXXStaticCastExpr>(childHandle); break; } case CXCursorKind.CXCursor_CXXBoolLiteralExpr: { expr = GetOrAddChild <CXXBoolLiteralExpr>(childHandle); break; } case CXCursorKind.CXCursor_UnaryExpr: { expr = GetOrAddChild <UnaryExpr>(childHandle); break; } case CXCursorKind.CXCursor_SizeOfPackExpr: { expr = GetOrAddChild <SizeOfPackExpr>(childHandle); break; } default: { return(base.VisitChildren(childHandle, handle, clientData)); } } Debug.Assert(expr != null); if (LhsExpr is null) { LhsExpr = expr; } else { RhsExpr = expr; } return(expr.Visit(clientData)); }
public ClassDecl(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.Kind == CXCursorKind.CXCursor_ClassDecl); }
internal static extern uint clang_hashCursor(CXCursor c);
public BreakStmt(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.Kind == CXCursorKind.CXCursor_BreakStmt); }
internal static extern int clang_Cursor_getNumArguments(CXCursor c);
protected Ref(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.IsReference); _type = new Lazy <Type>(() => TranslationUnit.GetOrCreateType(Handle.Type, () => Type.Create(Handle.Type, TranslationUnit))); }
internal static unsafe extern void clang_getOverriddenCursors(CXCursor c, CXCursor** overridden, uint* num_overridden);
public CXXAccessSpecifier(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.Kind == CXCursorKind.CXCursor_CXXAccessSpecifier); }
internal static extern uint clang_CXXMethod_isStatic(CXCursor C);
/// <summary> /// Determines whether the specified cursor is a declaration or reference by its kind. /// </summary> /// <returns><c>true</c> if cursor is reference or declaration; otherwise, <c>false</c>.</returns> /// <param name="cursor">Cursor.</param> bool IsReferenceOrDeclaration(CXCursor cursor) { return(clang.isReference(cursor.kind) != 0 || clang.isDeclaration(cursor.kind) != 0); }
internal static extern uint clang_Cursor_isVariadic(CXCursor C);
public DecodedLocation(CXCursor c, Kind kind = Kind.Presumed) : this(clang.getCursorLocation(c), kind) { }
internal static extern uint clang_getNumOverloadedDecls(CXCursor cursor);
Entity EntityOf(CXCursor cursor) { switch (cursor.kind) { case CXCursorKind.CXCursor_TypedefDecl: case CXCursorKind.CXCursor_StructDecl: case CXCursorKind.CXCursor_UnionDecl: case CXCursorKind.CXCursor_EnumDecl: case CXCursorKind.CXCursor_ClassDecl: case CXCursorKind.CXCursor_ClassTemplate: case CXCursorKind.CXCursor_ClassTemplatePartialSpecialization: // 型など宣言 return(EntityOf <Type>(cursor, () => new Type(this))); case CXCursorKind.CXCursor_FunctionDecl: case CXCursorKind.CXCursor_FunctionTemplate: case CXCursorKind.CXCursor_Constructor: case CXCursorKind.CXCursor_Destructor: case CXCursorKind.CXCursor_CXXMethod: case CXCursorKind.CXCursor_ConversionFunction: // 関数、メソッドなど宣言 return(EntityOf <Function>(cursor, () => new Function(this))); case CXCursorKind.CXCursor_VarDecl: case CXCursorKind.CXCursor_FieldDecl: // 変数など宣言 return(EntityOf <Variable>(cursor, () => new Variable(this))); case CXCursorKind.CXCursor_ParmDecl: // 引数宣言 return(EntityOf <Param>(cursor, () => new Param(this))); case CXCursorKind.CXCursor_Namespace: // ネームスペース return(EntityOf <Namespace>(cursor, () => new Namespace(this))); case CXCursorKind.CXCursor_CallExpr: // 関数呼び出し return(EntityOf <FunctionCall>(cursor, () => new FunctionCall(this))); case CXCursorKind.CXCursor_DeclRefExpr: case CXCursorKind.CXCursor_MemberRef: case CXCursorKind.CXCursor_MemberRefExpr: // 参照 return(EntityOf <VariableRef>(cursor, () => new VariableRef(this))); //case CXCursorKind.CXCursor_BinaryOperator: // break; // TODO: ↓の種類を処理する必要がありそう //case CXCursorKind.CXCursor_EnumConstantDecl: // break; //case CXCursorKind.CXCursor_NullStmt: // break; //case CXCursorKind.CXCursor_MemberRefExpr: // //ShowCode(cursor); // break; //case CXCursorKind.CXCursor_PackExpansionExpr: // //ShowCode(cursor); // break; //case CXCursorKind.CXCursor_UnaryExpr: // //ShowCode(cursor); // break; //case CXCursorKind.CXCursor_TemplateTypeParameter: // ShowCode(cursor); // break; //case CXCursorKind.CXCursor_NonTypeTemplateParameter: // ShowCode(cursor); // break; //case CXCursorKind.CXCursor_TemplateTemplateParameter: // ShowCode(cursor); // break; default: return(null); } }
internal static extern CXType clang_getTypedefDeclUnderlyingType(CXCursor c);
public CursorKey(CXCursor c) { this.Cursor = c; }
internal static extern CXResult clang_findReferencesInFile(CXCursor c, CXFile f, CXCursorAndRangeVisitor visitor);
public T Entity <T>(CXCursor cursor, Func <T> creator) where T : Entity { var c = cursor; uint offset1, offset2; var list = new List <LocationItem>(); File leafFile = null; string leafName = null; do { var loc = clang.getCursorLocation(c); CXFile f1, f2; Position position1 = new Position(), position2 = new Position(); clang.getSpellingLocation(loc, out f1, out position1.Line, out position1.Column, out offset1); if (position1.Line == 0) { return(null); } clang.getExpansionLocation(loc, out f2, out position2.Line, out position2.Column, out offset2); var file = File(clang.getFileName(f1).ToString()); if (leafFile == null) { leafFile = file; } var name = clang.getCursorDisplayName(c).ToString(); list.Add(new LocationItem(file, position1, name, c.kind)); if (leafName == null) { leafName = name; } c = clang.getCursorSemanticParent(c); } while (offset1 != offset2 && clang.isInvalid(c.kind) == 0 && c.kind != CXCursorKind.CXCursor_TranslationUnit); list.Reverse(); var locationPath = new LocationPath(list.ToArray()); Entity e; if (leafFile.Entities.TryGetValue(locationPath, out e)) { var t = e as T; if (t == null) { throw new ApplicationException(string.Concat("\"", e.FullName, "\" class mismatch: ", e.GetType().Name, " vs ", typeof(T).Name)); } return(t); } else { if (creator == null) { return(null); } var t = creator(); t.Name = leafName; t.Cursors.Add(new CursorKey(cursor)); t.LocationPath = locationPath; leafFile.Entities.Add(locationPath, t); return(t); } }
internal static extern uint clang_equalCursors(CXCursor c1, CXCursor c2);
public LightEntity(CXCursor cursor, int depth) { this.Cursor = cursor; this.Depth = depth; }
internal static extern CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor c);
public FloatingLiteral(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.Kind == CXCursorKind.CXCursor_FloatingLiteral); }
internal static extern CXCursor clang_Cursor_getArgument(CXCursor C, uint i);
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); }
internal static extern CXString clang_getCursorDisplayName(CXCursor c);
public static bool IsInSystemHeader(this CXCursor cursor) { return(clang.Location_isInSystemHeader(clang.getCursorLocation(cursor)) != 0); }
internal static unsafe extern void clang_disposeOverriddenCursors(CXCursor* overridden);
public CXXFinalAttr(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.Kind == CXCursorKind.CXCursor_CXXFinalAttr); }
internal static extern uint clang_CXXMethod_isPureVirtual(CXCursor c);
private CXChildVisitResult Visitor(CXCursor cursor, CXCursor parent, IntPtr data) { // prepare client data GCHandle classHandle = (GCHandle)data; NativeClass thisClass = classHandle.Target as NativeClass; CXCursorKind kind = clang.getCursorKind(cursor); switch (kind) { case CXCursorKind.CXCursor_FieldDecl: ProcessField(thisClass, cursor, parent); break; case CXCursorKind.CXCursor_VarDecl: ProcessField(thisClass, cursor, parent, true); break; case CXCursorKind.CXCursor_CXXMethod: ProcessMethod(thisClass, cursor, parent); break; case CXCursorKind.CXCursor_CXXBaseSpecifier: ProcessBaseClass(thisClass, cursor, parent); break; case CXCursorKind.CXCursor_CXXFinalAttr: thisClass.IsFinal = true; break; case CXCursorKind.CXCursor_StructDecl: case CXCursorKind.CXCursor_ClassDecl: // recursive visit child ClassVisitor subClassVisitor = new ClassVisitor(AST_, thisClass); subClassVisitor.DoVisit(cursor, parent); break; case CXCursorKind.CXCursor_TypedefDecl: case CXCursorKind.CXCursor_TypeAliasDecl: ProcessTypeExport(thisClass, cursor, parent); break; //case CXCursorKind.CXCursor_ClassTemplate: //case CXCursorKind.CXCursor_ClassTemplatePartialSpecialization: // break; //case CXCursorKind.CXCursor_FunctionTemplate: // break; case CXCursorKind.CXCursor_Constructor: ProcessConstructor(thisClass, cursor, parent); break; case CXCursorKind.CXCursor_EnumDecl: EnumVisitor subEnumVisitor = new EnumVisitor(AST_, thisClass); subEnumVisitor.DoVisit(cursor, parent); break; default: break; } return(CXChildVisitResult.CXChildVisit_Continue); }
internal static extern uint clang_CXXMethod_isVirtual(CXCursor C);
/// <summary> /// Initializes a new instance of the <see cref="Cursor"/> class. /// </summary> /// <param name="cursor">The cursor<see cref="CXCursor"/></param> internal Cursor(CXCursor cursor) { this.m_value = cursor; }
internal static extern int clang_Cursor_isDynamicCall(CXCursor C); //returns int not uint
public void given_a_class_cursor_in_a_file() { FilePath = Path.Combine(TestProjectPath, "ClangWrapperShould.h"); ClangWrapper = ClangWrapper.For(FilePath); ClassCursor = ClangWrapper.RetrieveClassCursors().Single(); }
internal static extern uint clang_Cursor_isBitField(CXCursor C);
public ForwardDeclarationVisitor(CXCursor beginningCursor) { this.beginningCursor = beginningCursor; }
internal static extern CursorKind clang_getTemplateCursorKind(CXCursor c);
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); }
internal static extern CXCursor clang_getOverloadedDecl(CXCursor cursor, uint index);
protected override CXChildVisitResult VisitChildren(CXCursor childHandle, CXCursor handle, CXClientData clientData) { ValidateVisit(ref handle); switch (childHandle.Kind) { case CXCursorKind.CXCursor_DeclRefExpr: { return(GetOrAddChild <DeclRefExpr>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_CallExpr: { return(GetOrAddChild <CallExpr>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_IntegerLiteral: { return(GetOrAddChild <IntegerLiteral>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_FloatingLiteral: { return(GetOrAddChild <FloatingLiteral>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_StringLiteral: { return(GetOrAddChild <StringLiteral>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_CharacterLiteral: { return(GetOrAddChild <CharacterLiteral>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_ParenExpr: { return(GetOrAddChild <ParenExpr>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_UnaryOperator: { return(GetOrAddChild <UnaryOperator>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_ArraySubscriptExpr: { return(GetOrAddChild <ArraySubscriptExpr>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_BinaryOperator: { return(GetOrAddChild <BinaryOperator>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_ConditionalOperator: { return(GetOrAddChild <ConditionalOperator>(childHandle).Visit(clientData)); } case CXCursorKind.CXCursor_CStyleCastExpr: { return(GetOrAddChild <CStyleCastExpr>(childHandle).Visit(clientData)); } default: { return(base.VisitChildren(childHandle, handle, clientData)); } } }
internal static extern CXSourceRange clang_getCursorReferenceNameRange(CXCursor c, uint flags, uint pieceIndex);
public ParenExpr(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.Kind == CXCursorKind.CXCursor_ParenExpr); }
internal static extern Int64 clang_getEnumConstantDeclValue(CXCursor c);
public ArraySubscriptExpr(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.Kind == CXCursorKind.CXCursor_ArraySubscriptExpr); }
internal static extern int clang_getFieldDeclBitWidth(CXCursor c);
internal static extern CXCursor clang_getCanonicalCursor(CXCursor c);
internal static extern CXFile clang_getIncludedFile(CXCursor c);
public UnexposedAttr(CXCursor handle, Cursor parent) : base(handle, parent) { Debug.Assert(handle.Kind == CXCursorKind.CXCursor_UnexposedAttr); }