This repository was archived by the owner on Jul 10, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathEnumVisitor.cs
99 lines (84 loc) · 3.68 KB
/
EnumVisitor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
namespace ClangSharpPInvokeGenerator
{
using System;
using System.Collections.Generic;
using System.IO;
using ClangSharp;
internal sealed class EnumVisitor : ICXCursorVisitor
{
private readonly ISet<string> printedEnums = new HashSet<string>();
private readonly TextWriter tw;
public EnumVisitor(TextWriter sw)
{
this.tw = sw;
}
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;
}
}
}