1 /** 2 From clang's cursors to dpp's nodes. 3 */ 4 module dpp2.transform; 5 6 7 import dpp.from; 8 9 10 /** 11 Transforms a clang `Cursor` (or a mock) into a dpp `Node` 12 */ 13 from!"dpp2.sea.node".Node[] toNode(C)(in C cursor) @trusted { 14 15 import std.traits: isPointer; 16 import std.conv: text; 17 18 static if(isPointer!C) 19 const cursorText = text(*cursor, " def? ", cursor.isDefinition); 20 else 21 const cursorText = text( cursor, " def? ", cursor.isDefinition); 22 23 version(unittest) { 24 import unit_threaded; 25 () @trusted { writelnUt("toNode cursor: ", cursorText); }(); 26 } 27 28 auto transform = cursor.kind in transformations!C; 29 30 if(transform is null) 31 throw new Exception("Unknown cursor kind: " ~ cursorText); 32 33 return (*transform)(cursor); 34 } 35 36 auto transformations(C)() { 37 import clang: Cursor; 38 with(Cursor.Kind) { 39 return [ 40 TranslationUnit: &fromTranslationUnit!C, 41 StructDecl: &fromStruct!C, 42 FieldDecl: &fromField!C, 43 TypedefDecl: &fromTypedef!C, 44 ]; 45 } 46 } 47 48 from!"dpp2.sea.node".Node[] fromTranslationUnit(C)(in C cursor) @trusted 49 in(cursor.kind == from!"clang".Cursor.Kind.TranslationUnit) 50 do 51 { 52 import std.algorithm: filter, map; 53 import std.array: join; 54 55 auto cursors = cursor.children 56 .filter!(a => a.isDefinition) 57 ; 58 59 return cursors.map!(c => toNode(c)).join; 60 } 61 62 63 from!"dpp2.sea.node".Node[] fromStruct(C)(in C cursor) @trusted 64 in(cursor.kind == from!"clang".Cursor.Kind.StructDecl) 65 do 66 { 67 import dpp2.sea.node: Node, Struct; 68 import std.algorithm: map; 69 import std.array: join; 70 71 return [ 72 Node( 73 Struct(cursor.spelling, 74 cursor.children.map!(c => toNode(c)).join, 75 cursor.type.spelling), 76 ) 77 ]; 78 } 79 80 81 82 from!"dpp2.sea.node".Node[] fromField(C)(in C cursor) @trusted 83 in(cursor.kind == from!"clang".Cursor.Kind.FieldDecl) 84 do 85 { 86 import dpp2.sea.node: Node, Field; 87 return [Node(Field(toType(cursor.type), cursor.spelling))]; 88 } 89 90 91 from!"dpp2.sea.node".Node[] fromTypedef(C)(in C cursor) @trusted 92 in(cursor.kind == from!"clang".Cursor.Kind.TypedefDecl) 93 do 94 { 95 import dpp2.sea.node: Node, Typedef; 96 return [Node(Typedef(cursor.spelling, cursor.underlyingType.toType))]; 97 } 98 99 100 from!"dpp2.sea.type".Type toType(T)(in T clangType) @safe { 101 import dpp2.sea.type; 102 import std.conv: text; 103 104 alias Kind = clangType.Kind; 105 106 switch(clangType.kind) { 107 108 default: 109 throw new Exception(text("Unknown type kind: ", clangType)); 110 111 case Kind.Void: return Type(Void()); 112 case Kind.NullPtr: return Type(NullPointerT()); 113 case Kind.Bool: return Type(Bool()); 114 115 case Kind.WChar: return Type(Wchar()); 116 case Kind.SChar: return Type(SignedChar()); 117 case Kind.Char16: return Type(Char16()); 118 case Kind.Char32: return Type(Char32()); 119 case Kind.UChar: return Type(UnsignedChar()); 120 case Kind.Char_U: return Type(UnsignedChar()); 121 case Kind.Char_S: return Type(SignedChar()); 122 123 case Kind.UShort: return Type(UnsignedShort()); 124 case Kind.Short: return Type(Short()); 125 case Kind.Int: return Type(Int()); 126 case Kind.UInt: return Type(UnsignedInt()); 127 case Kind.Long: return Type(Long()); 128 case Kind.ULong: return Type(UnsignedLong()); 129 case Kind.LongLong: return Type(LongLong()); 130 case Kind.ULongLong: return Type(UnsignedLongLong()); 131 case Kind.Int128: return Type(Int128()); 132 case Kind.UInt128: return Type(UnsignedInt128()); 133 134 case Kind.Half: return Type(Half()); 135 case Kind.Float: return Type(Float()); 136 case Kind.Double: return Type(Double()); 137 case Kind.LongDouble: return Type(LongDouble()); 138 case Kind.Float128: return Type(LongDouble()); 139 140 case Kind.Record: 141 case Kind.Elaborated: // FIXME (could be enum or union) 142 return Type(UserDefinedType(clangType.spelling.unelaborate)); 143 } 144 } 145 146 147 private string unelaborate(in string spelling) @safe pure { 148 import std.array: replace; 149 return spelling 150 .replace("struct ", "") 151 .replace("union ", "") 152 .replace("enum ", "") 153 ; 154 }