forked from exclipy/clang_indexer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clic_add.cpp
133 lines (114 loc) · 4.35 KB
/
clic_add.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "clic_printer.hpp"
#include "types.hpp"
extern "C" {
#include <clang-c/Index.h>
}
#include "ClicDb.hpp"
#include <boost/foreach.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <cassert>
#include <fstream>
#include <string>
#include <sstream>
// This code intentionally leaks memory like a sieve because the program is shortlived.
class IVisitor {
public:
virtual enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent) = 0;
};
class EverythingIndexer : public IVisitor {
public:
EverythingIndexer(const char* translationUnitFilename)
: translationUnitFilename(translationUnitFilename) {}
virtual enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
CXFile file;
unsigned int line, column, offset;
clang_getInstantiationLocation(
clang_getCursorLocation(cursor),
&file, &line, &column, &offset);
CXCursorKind kind = clang_getCursorKind(cursor);
const char* cursorFilename = clang_getCString(clang_getFileName(file));
if (!clang_getFileName(file).data || strcmp(cursorFilename, translationUnitFilename) != 0) {
return CXChildVisit_Continue;
}
CXCursor refCursor = clang_getCursorReferenced(cursor);
if (!clang_equalCursors(refCursor, clang_getNullCursor())) {
CXFile refFile;
unsigned int refLine, refColumn, refOffset;
clang_getInstantiationLocation(
clang_getCursorLocation(refCursor),
&refFile, &refLine, &refColumn, &refOffset);
if (clang_getFileName(refFile).data) {
std::string referencedUsr(clang_getCString(clang_getCursorUSR(refCursor)));
if (!referencedUsr.empty()) {
std::stringstream ss;
ss << cursorFilename
<< ":" << line << ":" << column << ":" << kind;
std::string location(ss.str());
usrToReferences[referencedUsr].insert(location);
}
}
}
return CXChildVisit_Recurse;
}
const char* translationUnitFilename;
ClicIndex usrToReferences;
};
enum CXChildVisitResult visitorFunction(
CXCursor cursor,
CXCursor parent,
CXClientData clientData)
{
IVisitor* visitor = (IVisitor*)clientData;
return visitor->visit(cursor, parent);
}
int main(int argc, const char* argv[]) {
if (argc < 4) {
std::cerr << "Usage:\n"
<< " " << argv[0] << " <dbFilename> <indexFilename> [<options>] <sourceFilename>\n";
return 1;
}
const char* dbFilename = argv[1];
const char* indexFilename = argv[2];
const char* sourceFilename = argv[argc-1];
// Set up the clang translation unit
CXIndex cxindex = clang_createIndex(0, 0);
CXTranslationUnit tu = clang_parseTranslationUnit(
cxindex, 0,
argv + 3, argc - 3, // Skip over dbFilename and indexFilename
0, 0,
CXTranslationUnit_None);
// Print any errors or warnings
int n = clang_getNumDiagnostics(tu);
if (n > 0) {
int nErrors = 0;
for (unsigned i = 0; i != n; ++i) {
CXDiagnostic diag = clang_getDiagnostic(tu, i);
CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());
fprintf(stderr, "%s\n", clang_getCString(string));
if (clang_getDiagnosticSeverity(diag) == CXDiagnostic_Error
|| clang_getDiagnosticSeverity(diag) == CXDiagnostic_Fatal)
nErrors++;
}
}
// Create the index
EverythingIndexer visitor(sourceFilename);
clang_visitChildren(
clang_getTranslationUnitCursor(tu),
&visitorFunction,
&visitor);
ClicIndex& index = visitor.usrToReferences;
// OK, now write the index to a compressed file
std::ofstream fout(indexFilename);
boost::iostreams::filtering_stream<boost::iostreams::output> zout;
zout.push(boost::iostreams::gzip_compressor());
zout.push(fout);
printIndex(zout, index);
// Now open the database and add the index to it
ClicDb db(dbFilename);
BOOST_FOREACH(const ClicIndex::value_type& it, index) {
const std::string& usr = it.first;
db.addMultiple(usr, it.second);
}
return 0;
}