1 /**
2 Copyright: Copyright (c) 2011-2016 Jacob Carlborg. All rights reserved.
3 Authors: Jacob Carlborg, Joakim Brännström (joakim.brannstrom dottli gmx.com)
4 Version: 1.1+
5 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6 
7 History:
8   1.0 initial release. 2011$(BR)
9     Jacob Carlborg
10   1.1+ additional documentation
11     Joakim Brännström
12 */
13 module clang.Index;
14 
15 import logger = std.experimental.logger;
16 
17 import my.gc.refc;
18 import my.set;
19 
20 import clang.c.Index;
21 
22 /** An "index" that consists of a set of translation units that would typically
23  * be linked together into an executable or library.
24  *
25  * Provides a shared context for creating translation units.
26  *
27  * It provides two options:
28  *
29  * - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
30  * declarations (when loading any new translation units). A "local" declaration
31  * is one that belongs in the translation unit itself and not in a precompiled
32  * header that was used by the translation unit. If zero, all declarations
33  * will be enumerated.
34  *
35  * Here is an example:
36  *
37  * Example:
38  * ---
39  *   // excludeDeclsFromPCH = 1, displayDiagnostics=1
40  *   Idx = clang_createIndex(1, 1);
41  *
42  *   // IndexTest.pch was produced with the following command:
43  *   // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
44  *   TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
45  *
46  *   // This will load all the symbols from 'IndexTest.pch'
47  *   clang_visitChildren(clang_getTranslationUnitCursor(TU),
48  *                       TranslationUnitVisitor, 0);
49  *   clang_disposeTranslationUnit(TU);
50  *
51  *   // This will load all the symbols from 'IndexTest.c', excluding symbols
52  *   // from 'IndexTest.pch'.
53  *   char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
54  *   TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
55  *                                                  0, 0);
56  *   clang_visitChildren(clang_getTranslationUnitCursor(TU),
57  *                       TranslationUnitVisitor, 0);
58  *   clang_disposeTranslationUnit(TU);
59  * ---
60  *
61  * This process of creating the 'pch', loading it separately, and using it (via
62  * -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
63  * (which gives the indexer the same performance benefit as the compiler).
64  */
65 struct Index {
66     import clang.Util;
67 
68     static private struct ContainIndex {
69         mixin CX!("Index");
70         CXTranslationUnit[] tunits;
71 
72         void put(CXTranslationUnit t) @safe pure nothrow {
73             tunits ~= t;
74         }
75 
76         ~this() @trusted {
77             if (cx is null)
78                 return;
79 
80             foreach (a; tunits)
81                 clang_disposeTranslationUnit(a);
82             dispose();
83         }
84     }
85 
86     RefCounted!ContainIndex cx;
87     alias cx this;
88 
89     this(bool excludeDeclarationsFromPCH, bool displayDiagnostics) @trusted {
90         cx = ContainIndex(clang_createIndex(excludeDeclarationsFromPCH ? 1 : 0,
91                 displayDiagnostics ? 1 : 0));
92     }
93 }