1 /**
2    libclang utility code
3  */
4 module dpp.clang;
5 
6 
7 import dpp.from;
8 
9 
10 from!"clang".Cursor namespace(in from!"clang".Cursor cursor) @safe {
11     import clang: Cursor;
12 
13     auto ret = Cursor(cursor.cx);
14 
15     while(!ret.isInvalid && ret.kind != Cursor.Kind.Namespace)
16         ret = ret.semanticParent;
17 
18     return ret;
19 }
20 
21 
22 /**
23    Returns the type name without namespaces.
24  */
25 string typeNameNoNs(in from!"clang".Cursor cursor) @safe {
26     import clang: Cursor;
27     import std.array: join;
28     import std.algorithm: reverse;
29 
30     string[] parts;
31 
32     auto c = Cursor(cursor.cx);
33 
34     bool isWanted(in Cursor c) {
35         return
36             !c.isInvalid
37             && c.kind != Cursor.Kind.Namespace
38             && c.kind != Cursor.Kind.TranslationUnit
39             ;
40     }
41 
42     while(isWanted(c.semanticParent)) {
43         c = c.semanticParent;
44         parts ~= c.spelling;
45     }
46 
47     parts = parts.reverse ~ cursor.spelling;
48 
49     return parts.join("::");
50 }
51 
52 
53 /**
54    If the cursor is a virtual function that overrides
55    another virtual function.
56  */
57 bool isOverride(in from!"clang".Cursor cursor) @safe {
58     import clang: Cursor;
59     import std.algorithm: any;
60 
61     return cursor
62         .children
63         .any!(a => a.kind == Cursor.Kind.CXXOverrideAttr)
64         ;
65 }