1 /** 2 * Copyright: Copyright (c) 2016 Wojciech Szęszoł. All rights reserved. 3 * Authors: Wojciech Szęszoł 4 * Version: Initial created: May 26, 2016 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 6 */ 7 module dstep.translator.TypedefIndex; 8 9 import clang.c.Index; 10 import clang.Cursor; 11 import clang.TranslationUnit; 12 13 14 class TypedefIndex 15 { 16 import std.typecons: Flag, No; 17 18 private Cursor[Cursor] typedefs; 19 20 this(TranslationUnit translUnit) 21 { 22 this(translUnit, (ref const(Cursor)) => false); 23 } 24 25 this(TranslationUnit translUnit, bool function(ref const(Cursor)) isWantedCursor) 26 { 27 import std.functional: toDelegate; 28 this(translUnit, isWantedCursor.toDelegate); 29 } 30 31 this(TranslationUnit translUnit, bool delegate(ref const(Cursor)) isWantedCursor) 32 { 33 bool[Cursor] visited; 34 35 auto file = translUnit.file; 36 37 foreach (cursor; translUnit.cursor.all) 38 { 39 if (cursor.file == file || (isWantedCursor !is null && isWantedCursor(cursor))) 40 { 41 visited[cursor] = true; 42 inspect(cursor, visited); 43 } 44 } 45 } 46 47 private void inspect(Cursor cursor, bool[Cursor] visited) 48 { 49 if (cursor.kind == CXCursorKind.typedefDecl) 50 { 51 foreach (child; cursor.all) 52 { 53 if (child.kind == CXCursorKind.typeRef 54 || child.isDeclaration) 55 { 56 if (child.referenced !in typedefs) 57 { 58 typedefs[child.referenced] = cursor; 59 typedefs[child.referenced.canonical] = cursor; 60 } 61 } 62 } 63 } 64 else if ((cursor in visited) is null) 65 { 66 foreach (child; cursor.all) 67 { 68 visited[cursor] = true; 69 inspect(cursor, visited); 70 } 71 } 72 } 73 74 Cursor typedefParent(in Cursor cursor) 75 { 76 auto result = cursor in typedefs; 77 78 if (result is null) 79 return cursor.empty; 80 else 81 return *result; 82 } 83 }