1 /**
2    From clang's cursors to dpp's nodes.
3  */
4 module dpp2.transform;
5 
6 
7 import dpp.from;
8 
9 
10 from!"dpp2.sea.node".Node toNode(in from!"clang".Cursor cursor) @safe {
11     import dpp2.sea.node;
12     import dpp2.sea.type;
13     import dpp.runtime.context: Context;
14     import dpp.translation.translation: debugCursor;
15     import clang: Cursor;
16     import std.algorithm: map, filter;
17     import std.array: array;
18 
19     return Node(
20         Struct(
21             cursor.spelling,
22             cursor
23                 .children
24                 .filter!(c => c.kind == Cursor.Kind.FieldDecl)
25                 .map!(c => Field(toType(c.type), c.spelling))
26                 .array,
27             cursor
28                 .children
29                 .filter!(c => c.kind == Cursor.Kind.StructDecl)
30             // FIXME
31             .map!(cursor => Struct(cursor.spelling,
32                                    cursor
33                                        .children
34                                        .filter!(c => c.kind == Cursor.Kind.FieldDecl)
35                                        .map!(c => Field(toType(c.type), c.spelling))
36                                        .array,
37                       ))
38                 .array
39         )
40     );
41 }
42 
43 
44 from!"dpp2.sea.type".Type toType(in from!"clang".Type clangType) @safe pure {
45     import dpp2.sea.type;
46     import std.conv: text;
47 
48     alias Kind = clangType.Kind;
49 
50     switch(clangType.kind) {
51 
52         default:
53             throw new Exception(text("Unknown type kind: ", clangType));
54 
55         case Kind.Void: return Type(Void());
56         case Kind.NullPtr: return Type(NullPointerT());
57         case Kind.Bool: return Type(Bool());
58 
59         case Kind.WChar: return Type(Wchar());
60         case Kind.SChar: return Type(SignedChar());
61         case Kind.Char16: return Type(Char16());
62         case Kind.Char32: return Type(Char32());
63         case Kind.UChar: return Type(UnsignedChar());
64         case Kind.Char_U: return Type(UnsignedChar());
65         case Kind.Char_S: return Type(SignedChar());
66 
67         case Kind.UShort: return Type(UnsignedShort());
68         case Kind.Short: return Type(Short());
69         case Kind.Int: return Type(Int());
70         case Kind.UInt: return Type(UnsignedInt());
71         case Kind.Long: return Type(Long());
72         case Kind.ULong: return Type(UnsignedLong());
73         case Kind.LongLong: return Type(LongLong());
74         case Kind.ULongLong: return Type(UnsignedLongLong());
75         case Kind.Int128: return Type(Int128());
76         case Kind.UInt128: return Type(UnsignedInt128());
77 
78         case Kind.Half: return Type(Half());
79         case Kind.Float: return Type(Float());
80         case Kind.Double: return Type(Double());
81         case Kind.LongDouble: return Type(LongDouble());
82         case Kind.Float128: return Type(LongDouble());
83 
84         case Kind.Record:
85         case Kind.Elaborated:
86             return Type(UserDefinedType(clangType.spelling.unelaborate));
87     }
88 }
89 
90 
91 private string unelaborate(in string spelling) @safe pure {
92     import std.array: replace;
93     return spelling
94         .replace("struct ", "")
95         .replace("union ", "")
96         .replace("enum ", "")
97         ;
98 }