 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
59.6% |
180 / 302 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
83.4% |
252 / 302 |
| |
|
Line Coverage: |
74.9% |
388 / 518 |
| |
 |
|
 |
1 : /* c-index-test.c */
2 :
3 : #include "clang-c/Index.h"
4 : #include <stdlib.h>
5 : #include <stdio.h>
6 : #include <string.h>
7 : #include <assert.h>
8 :
9 : /******************************************************************************/
10 : /* Utility functions. */
11 : /******************************************************************************/
12 :
13 : #ifdef _MSC_VER
14 : char *basename(const char* path)
15 : {
16 : char* base1 = (char*)strrchr(path, '/');
17 : char* base2 = (char*)strrchr(path, '\\');
18 : if (base1 && base2)
19 : return((base1 > base2) ? base1 + 1 : base2 + 1);
20 : else if (base1)
21 : return(base1 + 1);
22 : else if (base2)
23 : return(base2 + 1);
24 :
25 : return((char*)path);
26 : }
27 : #else
28 : extern char *basename(const char *);
29 : #endif
30 :
31 : static void PrintDiagnosticCallback(CXDiagnostic Diagnostic,
32 : CXClientData ClientData);
33 :
34 : static unsigned CreateTranslationUnit(CXIndex Idx, const char *file,
35 8: CXTranslationUnit *TU) {
36 :
37 8: *TU = clang_createTranslationUnit(Idx, file, PrintDiagnosticCallback, 0);
0: branch 0 not taken
8: branch 1 taken
38 8: if (!TU) {
39 0: fprintf(stderr, "Unable to load translation unit from '%s'!\n", file);
40 0: return 0;
41 : }
42 8: return 1;
43 : }
44 :
45 : void free_remapped_files(struct CXUnsavedFile *unsaved_files,
46 60: int num_unsaved_files) {
47 : int i;
5: branch 0 taken
60: branch 1 taken
48 65: for (i = 0; i != num_unsaved_files; ++i) {
49 5: free((char *)unsaved_files[i].Filename);
50 5: free((char *)unsaved_files[i].Contents);
51 : }
52 60: }
53 :
54 : int parse_remapped_files(int argc, const char **argv, int start_arg,
55 : struct CXUnsavedFile **unsaved_files,
56 61: int *num_unsaved_files) {
57 : int i;
58 : int arg;
59 61: int prefix_len = strlen("-remap-file=");
60 61: *unsaved_files = 0;
61 61: *num_unsaved_files = 0;
62 :
63 : /* Count the number of remapped files. */
66: branch 0 taken
0: branch 1 not taken
64 66: for (arg = start_arg; arg < argc; ++arg) {
61: branch 1 taken
5: branch 2 taken
65 66: if (strncmp(argv[arg], "-remap-file=", prefix_len))
66 61: break;
67 :
68 5: ++*num_unsaved_files;
69 : }
70 :
56: branch 0 taken
5: branch 1 taken
71 61: if (*num_unsaved_files == 0)
72 56: return 0;
73 :
74 5: *unsaved_files
75 : = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
76 : *num_unsaved_files);
5: branch 0 taken
5: branch 1 taken
77 10: for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) {
78 5: struct CXUnsavedFile *unsaved = *unsaved_files + i;
79 5: const char *arg_string = argv[arg] + prefix_len;
80 : int filename_len;
81 : char *filename;
82 : char *contents;
83 : FILE *to_file;
84 5: const char *semi = strchr(arg_string, ';');
0: branch 0 not taken
5: branch 1 taken
85 5: if (!semi) {
86 0: fprintf(stderr,
87 : "error: -remap-file=from;to argument is missing semicolon\n");
88 0: free_remapped_files(*unsaved_files, i);
89 0: *unsaved_files = 0;
90 0: *num_unsaved_files = 0;
91 0: return -1;
92 : }
93 :
94 : /* Open the file that we're remapping to. */
95 5: to_file = fopen(semi + 1, "r");
0: branch 0 not taken
5: branch 1 taken
96 5: if (!to_file) {
97 0: fprintf(stderr, "error: cannot open file %s that we are remapping to\n",
98 : semi + 1);
99 0: free_remapped_files(*unsaved_files, i);
100 0: *unsaved_files = 0;
101 0: *num_unsaved_files = 0;
102 0: return -1;
103 : }
104 :
105 : /* Determine the length of the file we're remapping to. */
106 5: fseek(to_file, 0, SEEK_END);
107 5: unsaved->Length = ftell(to_file);
108 5: fseek(to_file, 0, SEEK_SET);
109 :
110 : /* Read the contents of the file we're remapping to. */
111 5: contents = (char *)malloc(unsaved->Length + 1);
0: branch 1 not taken
5: branch 2 taken
112 5: if (fread(contents, 1, unsaved->Length, to_file) != unsaved->Length) {
0: branch 1 not taken
0: branch 2 not taken
113 0: fprintf(stderr, "error: unexpected %s reading 'to' file %s\n",
114 : (feof(to_file) ? "EOF" : "error"), semi + 1);
115 0: fclose(to_file);
116 0: free_remapped_files(*unsaved_files, i);
117 0: *unsaved_files = 0;
118 0: *num_unsaved_files = 0;
119 0: return -1;
120 : }
121 5: contents[unsaved->Length] = 0;
122 5: unsaved->Contents = contents;
123 :
124 : /* Close the file. */
125 5: fclose(to_file);
126 :
127 : /* Copy the file name that we're remapping from. */
128 5: filename_len = semi - arg_string;
129 5: filename = (char *)malloc(filename_len + 1);
130 5: memcpy(filename, arg_string, filename_len);
131 5: filename[filename_len] = 0;
132 5: unsaved->Filename = filename;
133 : }
134 :
135 5: return 0;
136 : }
137 :
138 : /******************************************************************************/
139 : /* Pretty-printing. */
140 : /******************************************************************************/
141 :
142 375: static void PrintCursor(CXCursor Cursor) {
16: branch 1 taken
359: branch 2 taken
143 375: if (clang_isInvalid(Cursor.kind))
144 16: printf("Invalid Cursor => %s", clang_getCursorKindSpelling(Cursor.kind));
145 : else {
146 : CXString string;
147 : CXCursor Referenced;
148 : unsigned line, column;
149 359: string = clang_getCursorSpelling(Cursor);
150 359: printf("%s=%s", clang_getCursorKindSpelling(Cursor.kind),
151 : clang_getCString(string));
152 359: clang_disposeString(string);
153 :
154 359: Referenced = clang_getCursorReferenced(Cursor);
295: branch 2 taken
64: branch 3 taken
155 359: if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
156 295: CXSourceLocation Loc = clang_getCursorLocation(Referenced);
157 295: clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
158 295: printf(":%d:%d", line, column);
159 : }
160 :
124: branch 1 taken
235: branch 2 taken
161 359: if (clang_isCursorDefinition(Cursor))
162 124: printf(" (Definition)");
163 : }
164 375: }
165 :
166 237: static const char* GetCursorSource(CXCursor Cursor) {
167 237: CXSourceLocation Loc = clang_getCursorLocation(Cursor);
168 : const char *source;
169 : CXFile file;
170 237: clang_getInstantiationLocation(Loc, &file, 0, 0, 0);
171 237: source = clang_getFileName(file);
53: branch 0 taken
184: branch 1 taken
172 237: if (!source)
173 53: return "<invalid loc>";
174 184: return basename(source);
175 : }
176 :
177 : /******************************************************************************/
178 : /* Callbacks. */
179 : /******************************************************************************/
180 :
181 : typedef void (*PostVisitTU)(CXTranslationUnit);
182 :
183 : static void PrintDiagnosticCallback(CXDiagnostic Diagnostic,
184 55: CXClientData ClientData) {
185 55: FILE *out = (FILE *)ClientData;
186 : CXFile file;
187 : unsigned line, column;
188 : CXString text;
189 55: enum CXDiagnosticSeverity severity = clang_getDiagnosticSeverity(Diagnostic);
190 :
191 : /* Ignore diagnostics that should be ignored. */
0: branch 0 not taken
55: branch 1 taken
192 55: if (severity == CXDiagnostic_Ignored)
193 0: return;
194 :
195 : /* Print file:line:column. */
196 55: clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic),
197 : &file, &line, &column, 0);
55: branch 0 taken
0: branch 1 not taken
198 55: if (file) {
199 : unsigned i, n;
200 55: unsigned printed_any_ranges = 0;
201 :
202 55: fprintf(out, "%s:%d:%d:", clang_getFileName(file), line, column);
203 :
204 55: n = clang_getDiagnosticNumRanges(Diagnostic);
11: branch 0 taken
55: branch 1 taken
205 66: for (i = 0; i != n; ++i) {
206 : CXFile start_file, end_file;
207 11: CXSourceRange range = clang_getDiagnosticRange(Diagnostic, i);
208 :
209 : unsigned start_line, start_column, end_line, end_column;
210 11: clang_getInstantiationLocation(clang_getRangeStart(range),
211 : &start_file, &start_line, &start_column,0);
212 11: clang_getInstantiationLocation(clang_getRangeEnd(range),
213 : &end_file, &end_line, &end_column, 0);
214 :
11: branch 0 taken
0: branch 1 not taken
11: branch 2 taken
0: branch 3 not taken
215 11: if (start_file != end_file || start_file != file)
216 : continue;
217 :
218 11: fprintf(out, "{%d:%d-%d:%d}", start_line, start_column, end_line,
219 : end_column+1);
220 11: printed_any_ranges = 1;
221 : }
10: branch 0 taken
45: branch 1 taken
222 55: if (printed_any_ranges)
223 10: fprintf(out, ":");
224 :
225 55: fprintf(out, " ");
226 : }
227 :
228 : /* Print warning/error/etc. */
0: branch 0 not taken
3: branch 1 taken
44: branch 2 taken
6: branch 3 taken
2: branch 4 taken
0: branch 5 not taken
229 55: switch (severity) {
230 0: case CXDiagnostic_Ignored: assert(0 && "impossible"); break;
231 3: case CXDiagnostic_Note: fprintf(out, "note: "); break;
232 44: case CXDiagnostic_Warning: fprintf(out, "warning: "); break;
233 6: case CXDiagnostic_Error: fprintf(out, "error: "); break;
234 2: case CXDiagnostic_Fatal: fprintf(out, "fatal error: "); break;
235 : }
236 :
237 55: text = clang_getDiagnosticSpelling(Diagnostic);
55: branch 1 taken
0: branch 2 not taken
238 55: if (clang_getCString(text))
239 55: fprintf(out, "%s\n", clang_getCString(text));
240 : else
241 0: fprintf(out, "<no diagnostic text>\n");
242 55: clang_disposeString(text);
243 :
55: branch 0 taken
0: branch 1 not taken
244 55: if (file) {
245 55: unsigned i, num_fixits = clang_getDiagnosticNumFixIts(Diagnostic);
3: branch 0 taken
55: branch 1 taken
246 58: for (i = 0; i != num_fixits; ++i) {
1: branch 1 taken
1: branch 2 taken
1: branch 3 taken
0: branch 4 not taken
247 3: switch (clang_getDiagnosticFixItKind(Diagnostic, i)) {
248 : case CXFixIt_Insertion: {
249 : CXSourceLocation insertion_loc;
250 : CXFile insertion_file;
251 : unsigned insertion_line, insertion_column;
252 1: text = clang_getDiagnosticFixItInsertion(Diagnostic, i, &insertion_loc);
253 1: clang_getInstantiationLocation(insertion_loc, &insertion_file,
254 : &insertion_line, &insertion_column, 0);
1: branch 0 taken
0: branch 1 not taken
255 1: if (insertion_file == file)
256 1: fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n",
257 : clang_getCString(text), insertion_line, insertion_column);
258 1: clang_disposeString(text);
259 1: break;
260 : }
261 :
262 : case CXFixIt_Removal: {
263 : CXFile start_file, end_file;
264 : unsigned start_line, start_column, end_line, end_column;
265 : CXSourceRange remove_range
266 1: = clang_getDiagnosticFixItRemoval(Diagnostic, i);
267 1: clang_getInstantiationLocation(clang_getRangeStart(remove_range),
268 : &start_file, &start_line, &start_column,
269 : 0);
270 1: clang_getInstantiationLocation(clang_getRangeEnd(remove_range),
271 : &end_file, &end_line, &end_column, 0);
1: branch 0 taken
0: branch 1 not taken
1: branch 2 taken
0: branch 3 not taken
272 1: if (start_file == file && end_file == file)
273 1: fprintf(out, "FIX-IT: Remove %d:%d-%d:%d\n",
274 : start_line, start_column, end_line, end_column+1);
275 1: break;
276 : }
277 :
278 : case CXFixIt_Replacement: {
279 : CXFile start_file, end_file;
280 : unsigned start_line, start_column, end_line, end_column;
281 : CXSourceRange remove_range;
282 1: text = clang_getDiagnosticFixItReplacement(Diagnostic, i,&remove_range);
283 1: clang_getInstantiationLocation(clang_getRangeStart(remove_range),
284 : &start_file, &start_line, &start_column,
285 : 0);
286 1: clang_getInstantiationLocation(clang_getRangeEnd(remove_range),
287 : &end_file, &end_line, &end_column, 0);
1: branch 0 taken
0: branch 1 not taken
288 1: if (start_file == end_file)
289 1: fprintf(out, "FIX-IT: Replace %d:%d-%d:%d with \"%s\"\n",
290 : start_line, start_column, end_line, end_column+1,
291 : clang_getCString(text));
292 1: clang_disposeString(text);
293 : break;
294 : }
295 : }
296 : }
297 : }
298 : }
299 :
300 : /******************************************************************************/
301 : /* Logic for testing traversal. */
302 : /******************************************************************************/
303 :
304 : static const char *FileCheckPrefix = "CHECK";
305 :
306 237: static void PrintCursorExtent(CXCursor C) {
307 237: CXSourceRange extent = clang_getCursorExtent(C);
308 : CXFile begin_file, end_file;
309 : unsigned begin_line, begin_column, end_line, end_column;
310 :
311 237: clang_getInstantiationLocation(clang_getRangeStart(extent),
312 : &begin_file, &begin_line, &begin_column, 0);
313 237: clang_getInstantiationLocation(clang_getRangeEnd(extent),
314 : &end_file, &end_line, &end_column, 0);
184: branch 0 taken
53: branch 1 taken
0: branch 2 not taken
184: branch 3 taken
315 237: if (!begin_file || !end_file)
316 53: return;
317 :
318 184: printf(" [Extent=%d:%d:%d:%d]", begin_line, begin_column,
319 : end_line, end_column);
320 : }
321 :
322 : /* Data used by all of the visitors. */
323 : typedef struct {
324 : CXTranslationUnit TU;
325 : enum CXCursorKind *Filter;
326 : } VisitorData;
327 :
328 :
329 : enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor,
330 : CXCursor Parent,
331 237: CXClientData ClientData) {
332 237: VisitorData *Data = (VisitorData *)ClientData;
0: branch 0 not taken
237: branch 1 taken
237: branch 2 taken
237: branch 3 taken
333 237: if (!Data->Filter || (Cursor.kind == *(enum CXCursorKind *)Data->Filter)) {
334 237: CXSourceLocation Loc = clang_getCursorLocation(Cursor);
335 : unsigned line, column;
336 237: clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
337 237: printf("// %s: %s:%d:%d: ", FileCheckPrefix,
338 : GetCursorSource(Cursor), line, column);
339 237: PrintCursor(Cursor);
340 237: PrintCursorExtent(Cursor);
341 237: printf("\n");
342 237: return CXChildVisit_Recurse;
343 : }
344 :
345 0: return CXChildVisit_Continue;
346 : }
347 :
348 : static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
349 : CXCursor Parent,
350 0: CXClientData ClientData) {
351 : const char *startBuf, *endBuf;
352 : unsigned startLine, startColumn, endLine, endColumn, curLine, curColumn;
353 : CXCursor Ref;
354 0: VisitorData *Data = (VisitorData *)ClientData;
355 :
0: branch 0 not taken
0: branch 1 not taken
0: branch 3 not taken
0: branch 4 not taken
356 0: if (Cursor.kind != CXCursor_FunctionDecl ||
357 : !clang_isCursorDefinition(Cursor))
358 0: return CXChildVisit_Continue;
359 :
360 0: clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,
361 : &startLine, &startColumn,
362 : &endLine, &endColumn);
363 : /* Probe the entire body, looking for both decls and refs. */
364 0: curLine = startLine;
365 0: curColumn = startColumn;
366 :
0: branch 0 not taken
0: branch 1 not taken
367 0: while (startBuf < endBuf) {
368 : CXSourceLocation Loc;
369 : CXFile file;
370 0: const char *source = 0;
371 :
0: branch 0 not taken
0: branch 1 not taken
372 0: if (*startBuf == '\n') {
373 0: startBuf++;
374 0: curLine++;
375 0: curColumn = 1;
0: branch 0 not taken
0: branch 1 not taken
376 0: } else if (*startBuf != '\t')
377 0: curColumn++;
378 :
379 0: Loc = clang_getCursorLocation(Cursor);
380 0: clang_getInstantiationLocation(Loc, &file, 0, 0, 0);
381 0: source = clang_getFileName(file);
0: branch 0 not taken
0: branch 1 not taken
382 0: if (source) {
383 : CXSourceLocation RefLoc
384 0: = clang_getLocation(Data->TU, file, curLine, curColumn);
385 0: Ref = clang_getCursor(Data->TU, RefLoc);
0: branch 0 not taken
0: branch 1 not taken
386 0: if (Ref.kind == CXCursor_NoDeclFound) {
387 : /* Nothing found here; that's fine. */
0: branch 0 not taken
0: branch 1 not taken
388 0: } else if (Ref.kind != CXCursor_FunctionDecl) {
389 0: printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
390 : curLine, curColumn);
391 0: PrintCursor(Ref);
392 0: printf("\n");
393 : }
394 : }
395 0: startBuf++;
396 : }
397 :
398 0: return CXChildVisit_Continue;
399 : }
400 :
401 : /******************************************************************************/
402 : /* USR testing. */
403 : /******************************************************************************/
404 :
405 : enum CXChildVisitResult USRVisitor(CXCursor C, CXCursor parent,
406 0: CXClientData ClientData) {
407 0: VisitorData *Data = (VisitorData *)ClientData;
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
408 0: if (!Data->Filter || (C.kind == *(enum CXCursorKind *)Data->Filter)) {
409 0: CXString USR = clang_getCursorUSR(C);
0: branch 0 not taken
0: branch 1 not taken
410 0: if (!USR.Spelling) {
411 0: clang_disposeString(USR);
412 0: return CXChildVisit_Continue;
413 : }
414 0: printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C), USR.Spelling);
415 0: PrintCursorExtent(C);
416 0: printf("\n");
417 0: clang_disposeString(USR);
418 :
419 0: return CXChildVisit_Recurse;
420 : }
421 :
422 0: return CXChildVisit_Continue;
423 : }
424 :
425 : /******************************************************************************/
426 : /* Inclusion stack testing. */
427 : /******************************************************************************/
428 :
429 : void InclusionVisitor(CXFile includedFile, CXSourceLocation *includeStack,
430 3: unsigned includeStackLen, CXClientData data) {
431 :
432 : unsigned i;
433 3: printf("file: %s\nincluded by:\n", clang_getFileName(includedFile));
3: branch 0 taken
3: branch 1 taken
434 6: for (i = 0; i < includeStackLen; ++i) {
435 : CXFile includingFile;
436 : unsigned line, column;
437 3: clang_getInstantiationLocation(includeStack[i], &includingFile, &line,
438 : &column, 0);
439 3: printf(" %s:%d:%d\n", clang_getFileName(includingFile), line, column);
440 : }
441 3: printf("\n");
442 3: }
443 :
444 1: void PrintInclusionStack(CXTranslationUnit TU) {
445 1: clang_getInclusions(TU, InclusionVisitor, NULL);
446 1: }
447 :
448 : /******************************************************************************/
449 : /* Loading ASTs/source. */
450 : /******************************************************************************/
451 :
452 : static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
453 : const char *filter, const char *prefix,
454 : CXCursorVisitor Visitor,
455 11: PostVisitTU PV) {
456 :
0: branch 0 not taken
11: branch 1 taken
457 11: if (prefix)
458 0: FileCheckPrefix = prefix;
459 :
10: branch 0 taken
1: branch 1 taken
460 11: if (Visitor) {
461 10: enum CXCursorKind K = CXCursor_NotImplemented;
462 10: enum CXCursorKind *ck = &K;
463 : VisitorData Data;
464 :
465 : /* Perform some simple filtering. */
4: branch 1 taken
6: branch 2 taken
4: branch 4 taken
0: branch 5 not taken
466 10: if (!strcmp(filter, "all") || !strcmp(filter, "local")) ck = NULL;
0: branch 1 not taken
0: branch 2 not taken
467 0: else if (!strcmp(filter, "category")) K = CXCursor_ObjCCategoryDecl;
0: branch 1 not taken
0: branch 2 not taken
468 0: else if (!strcmp(filter, "interface")) K = CXCursor_ObjCInterfaceDecl;
0: branch 1 not taken
0: branch 2 not taken
469 0: else if (!strcmp(filter, "protocol")) K = CXCursor_ObjCProtocolDecl;
0: branch 1 not taken
0: branch 2 not taken
470 0: else if (!strcmp(filter, "function")) K = CXCursor_FunctionDecl;
0: branch 1 not taken
0: branch 2 not taken
471 0: else if (!strcmp(filter, "typedef")) K = CXCursor_TypedefDecl;
0: branch 1 not taken
0: branch 2 not taken
472 0: else if (!strcmp(filter, "scan-function")) Visitor = FunctionScanVisitor;
473 : else {
474 0: fprintf(stderr, "Unknown filter for -test-load-tu: %s\n", filter);
475 0: return 1;
476 : }
477 :
478 10: Data.TU = TU;
479 10: Data.Filter = ck;
480 10: clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
481 : }
482 :
1: branch 0 taken
10: branch 1 taken
483 11: if (PV)
484 1: PV(TU);
485 :
486 11: clang_disposeTranslationUnit(TU);
487 11: return 0;
488 : }
489 :
490 : int perform_test_load_tu(const char *file, const char *filter,
491 : const char *prefix, CXCursorVisitor Visitor,
492 5: PostVisitTU PV) {
493 : CXIndex Idx;
494 : CXTranslationUnit TU;
495 5: Idx = clang_createIndex(/* excludeDeclsFromPCH */
496 : !strcmp(filter, "local") ? 1 : 0);
497 :
0: branch 1 not taken
5: branch 2 taken
498 5: if (!CreateTranslationUnit(Idx, file, &TU))
499 0: return 1;
500 :
501 5: return perform_test_load(Idx, TU, filter, prefix, Visitor, PV);
502 : }
503 :
504 : int perform_test_load_source(int argc, const char **argv,
505 : const char *filter, CXCursorVisitor Visitor,
506 7: PostVisitTU PV) {
507 : const char *UseExternalASTs =
508 7: getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION");
509 : CXIndex Idx;
510 : CXTranslationUnit TU;
511 7: struct CXUnsavedFile *unsaved_files = 0;
512 7: int num_unsaved_files = 0;
513 : int result;
514 :
515 7: Idx = clang_createIndex(/* excludeDeclsFromPCH */
516 : !strcmp(filter, "local") ? 1 : 0);
517 :
1: branch 0 taken
6: branch 1 taken
1: branch 2 taken
0: branch 3 not taken
518 7: if (UseExternalASTs && strlen(UseExternalASTs))
519 1: clang_setUseExternalASTGeneration(Idx, 1);
520 :
0: branch 1 not taken
7: branch 2 taken
521 7: if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files))
522 0: return -1;
523 :
524 7: TU = clang_createTranslationUnitFromSourceFile(Idx, 0,
525 : argc - num_unsaved_files,
526 : argv + num_unsaved_files,
527 : num_unsaved_files,
528 : unsaved_files,
529 : PrintDiagnosticCallback,
530 : stderr);
1: branch 0 taken
6: branch 1 taken
531 7: if (!TU) {
532 1: fprintf(stderr, "Unable to load translation unit!\n");
533 1: return 1;
534 : }
535 :
536 6: result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
537 6: free_remapped_files(unsaved_files, num_unsaved_files);
538 6: return result;
539 : }
540 :
541 : /******************************************************************************/
542 : /* Logic for testing clang_getCursor(). */
543 : /******************************************************************************/
544 :
545 : static void print_cursor_file_scan(CXCursor cursor,
546 : unsigned start_line, unsigned start_col,
547 : unsigned end_line, unsigned end_col,
548 122: const char *prefix) {
549 122: printf("// %s: ", FileCheckPrefix);
0: branch 0 not taken
122: branch 1 taken
550 122: if (prefix)
551 0: printf("-%s", prefix);
552 122: printf("{start_line=%d start_col=%d end_line=%d end_col=%d} ",
553 : start_line, start_col, end_line, end_col);
554 122: PrintCursor(cursor);
555 122: printf("\n");
556 122: }
557 :
558 : static int perform_file_scan(const char *ast_file, const char *source_file,
559 3: const char *prefix) {
560 : CXIndex Idx;
561 : CXTranslationUnit TU;
562 : FILE *fp;
563 : unsigned line;
564 : CXCursor prevCursor;
565 : CXFile file;
566 : unsigned printed;
567 : unsigned start_line, start_col, last_line, last_col;
568 : size_t i;
569 :
0: branch 1 not taken
3: branch 2 taken
570 3: if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1))) {
571 0: fprintf(stderr, "Could not create Index\n");
572 0: return 1;
573 : }
574 :
0: branch 1 not taken
3: branch 2 taken
575 3: if (!CreateTranslationUnit(Idx, ast_file, &TU))
576 0: return 1;
577 :
0: branch 1 not taken
3: branch 2 taken
578 3: if ((fp = fopen(source_file, "r")) == NULL) {
579 0: fprintf(stderr, "Could not open '%s'\n", source_file);
580 0: return 1;
581 : }
582 :
583 3: line = 0;
584 3: prevCursor = clang_getNullCursor();
585 3: printed = 0;
586 3: start_line = last_line = 1;
587 3: start_col = last_col = 1;
588 :
589 3: file = clang_getFile(TU, source_file);
230: branch 1 taken
3: branch 2 taken
590 236: while (!feof(fp)) {
591 230: size_t len = 0;
592 : int c;
593 :
12821: branch 1 taken
3: branch 2 taken
594 13054: while ((c = fgetc(fp)) != EOF) {
595 12821: len++;
227: branch 0 taken
12594: branch 1 taken
596 12821: if (c == '\n')
597 227: break;
598 : }
599 :
600 230: ++line;
601 :
12821: branch 0 taken
230: branch 1 taken
602 13051: for (i = 0; i < len ; ++i) {
603 : CXCursor cursor;
604 12821: cursor = clang_getCursor(TU, clang_getLocation(TU, file, line, i+1));
605 :
122: branch 1 taken
12699: branch 2 taken
119: branch 3 taken
3: branch 4 taken
606 12940: if (!clang_equalCursors(cursor, prevCursor) &&
607 : prevCursor.kind != CXCursor_InvalidFile) {
608 119: print_cursor_file_scan(prevCursor, start_line, start_col,
609 : last_line, last_col, prefix);
610 119: printed = 1;
611 119: start_line = line;
612 119: start_col = (unsigned) i+1;
613 : }
614 : else {
615 12702: printed = 0;
616 : }
617 :
618 12821: prevCursor = cursor;
619 12821: last_line = line;
620 12821: last_col = (unsigned) i+1;
621 : }
622 : }
623 :
3: branch 0 taken
0: branch 1 not taken
3: branch 2 taken
0: branch 3 not taken
624 3: if (!printed && prevCursor.kind != CXCursor_InvalidFile) {
625 3: print_cursor_file_scan(prevCursor, start_line, start_col,
626 : last_line, last_col, prefix);
627 : }
628 :
629 3: fclose(fp);
630 3: return 0;
631 : }
632 :
633 : /******************************************************************************/
634 : /* Logic for testing clang_codeComplete(). */
635 : /******************************************************************************/
636 :
637 : /* Parse file:line:column from the input string. Returns 0 on success, non-zero
638 : on failure. If successful, the pointer *filename will contain newly-allocated
639 : memory (that will be owned by the caller) to store the file name. */
640 : int parse_file_line_column(const char *input, char **filename, unsigned *line,
641 : unsigned *column, unsigned *second_line,
642 56: unsigned *second_column) {
643 : /* Find the second colon. */
644 56: const char *last_colon = strrchr(input, ':');
645 : unsigned values[4], i;
1: branch 0 taken
55: branch 1 taken
1: branch 2 taken
0: branch 3 not taken
646 56: unsigned num_values = (second_line && second_column)? 4 : 2;
647 :
648 56: char *endptr = 0;
56: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
56: branch 3 taken
649 56: if (!last_colon || last_colon == input) {
0: branch 0 not taken
0: branch 1 not taken
650 0: if (num_values == 4)
651 0: fprintf(stderr, "could not parse filename:line:column:line:column in "
652 : "'%s'\n", input);
653 : else
654 0: fprintf(stderr, "could not parse filename:line:column in '%s'\n", input);
655 0: return 1;
656 : }
657 :
114: branch 0 taken
0: branch 1 not taken
658 114: for (i = 0; i != num_values; ++i) {
659 : const char *prev_colon;
660 :
661 : /* Parse the next line or column. */
662 114: values[num_values - i - 1] = strtol(last_colon + 1, &endptr, 10);
58: branch 0 taken
56: branch 1 taken
0: branch 2 not taken
58: branch 3 taken
663 114: if (*endptr != 0 && *endptr != ':') {
0: branch 0 not taken
0: branch 1 not taken
664 0: fprintf(stderr, "could not parse %s in '%s'\n",
665 : (i % 2 ? "column" : "line"), input);
666 0: return 1;
667 : }
668 :
56: branch 0 taken
58: branch 1 taken
669 114: if (i + 1 == num_values)
670 56: break;
671 :
672 : /* Find the previous colon. */
673 58: prev_colon = last_colon - 1;
151: branch 0 taken
0: branch 1 not taken
93: branch 2 taken
58: branch 3 taken
674 209: while (prev_colon != input && *prev_colon != ':')
675 93: --prev_colon;
0: branch 0 not taken
58: branch 1 taken
676 58: if (prev_colon == input) {
0: branch 0 not taken
0: branch 1 not taken
677 0: fprintf(stderr, "could not parse %s in '%s'\n",
678 : (i % 2 == 0? "column" : "line"), input);
679 0: return 1;
680 : }
681 :
682 58: last_colon = prev_colon;
683 : }
684 :
685 56: *line = values[0];
686 56: *column = values[1];
687 :
1: branch 0 taken
55: branch 1 taken
1: branch 2 taken
0: branch 3 not taken
688 56: if (second_line && second_column) {
689 1: *second_line = values[2];
690 1: *second_column = values[3];
691 : }
692 :
693 : /* Copy the file name. */
694 56: *filename = (char*)malloc(last_colon - input + 1);
695 56: memcpy(*filename, input, last_colon - input);
696 56: (*filename)[last_colon - input] = 0;
697 56: return 0;
698 : }
699 :
700 : const char *
701 2262: clang_getCompletionChunkKindSpelling(enum CXCompletionChunkKind Kind) {
0: branch 0 not taken
1728: branch 1 taken
42: branch 2 taken
136: branch 3 taken
20: branch 4 taken
3: branch 5 taken
57: branch 6 taken
57: branch 7 taken
0: branch 8 not taken
0: branch 9 not taken
23: branch 10 taken
23: branch 11 taken
0: branch 12 not taken
0: branch 13 not taken
4: branch 14 taken
90: branch 15 taken
0: branch 16 not taken
22: branch 17 taken
0: branch 18 not taken
42: branch 19 taken
15: branch 20 taken
0: branch 21 not taken
702 2262: switch (Kind) {
703 0: case CXCompletionChunk_Optional: return "Optional";
704 1728: case CXCompletionChunk_TypedText: return "TypedText";
705 42: case CXCompletionChunk_Text: return "Text";
706 136: case CXCompletionChunk_Placeholder: return "Placeholder";
707 20: case CXCompletionChunk_Informative: return "Informative";
708 3: case CXCompletionChunk_CurrentParameter: return "CurrentParameter";
709 57: case CXCompletionChunk_LeftParen: return "LeftParen";
710 57: case CXCompletionChunk_RightParen: return "RightParen";
711 0: case CXCompletionChunk_LeftBracket: return "LeftBracket";
712 0: case CXCompletionChunk_RightBracket: return "RightBracket";
713 23: case CXCompletionChunk_LeftBrace: return "LeftBrace";
714 23: case CXCompletionChunk_RightBrace: return "RightBrace";
715 0: case CXCompletionChunk_LeftAngle: return "LeftAngle";
716 0: case CXCompletionChunk_RightAngle: return "RightAngle";
717 4: case CXCompletionChunk_Comma: return "Comma";
718 90: case CXCompletionChunk_ResultType: return "ResultType";
719 0: case CXCompletionChunk_Colon: return "Colon";
720 22: case CXCompletionChunk_SemiColon: return "SemiColon";
721 0: case CXCompletionChunk_Equal: return "Equal";
722 42: case CXCompletionChunk_HorizontalSpace: return "HorizontalSpace";
723 15: case CXCompletionChunk_VerticalSpace: return "VerticalSpace";
724 : }
725 :
726 0: return "Unknown";
727 : }
728 :
729 1732: void print_completion_string(CXCompletionString completion_string, FILE *file) {
730 : int I, N;
731 :
732 1732: N = clang_getNumCompletionChunks(completion_string);
2263: branch 0 taken
1732: branch 1 taken
733 3995: for (I = 0; I != N; ++I) {
734 2263: const char *text = 0;
735 : enum CXCompletionChunkKind Kind
736 2263: = clang_getCompletionChunkKind(completion_string, I);
737 :
1: branch 0 taken
2262: branch 1 taken
738 2263: if (Kind == CXCompletionChunk_Optional) {
739 1: fprintf(file, "{Optional ");
740 1: print_completion_string(
741 : clang_getCompletionChunkCompletionString(completion_string, I),
742 : file);
743 1: fprintf(file, "}");
744 1: continue;
745 : }
746 :
747 2262: text = clang_getCompletionChunkText(completion_string, I);
2262: branch 0 taken
0: branch 1 not taken
748 2262: fprintf(file, "{%s %s}",
749 : clang_getCompletionChunkKindSpelling(Kind),
750 : text? text : "");
751 : }
752 1732: }
753 :
754 : void print_completion_result(CXCompletionResult *completion_result,
755 1731: CXClientData client_data) {
756 1731: FILE *file = (FILE *)client_data;
757 1731: fprintf(file, "%s:",
758 : clang_getCursorKindSpelling(completion_result->CursorKind));
759 1731: print_completion_string(completion_result->CompletionString, file);
760 1731: fprintf(file, "\n");
761 1731: }
762 :
763 51: int perform_code_completion(int argc, const char **argv) {
764 51: const char *input = argv[1];
765 51: char *filename = 0;
766 : unsigned line;
767 : unsigned column;
768 : CXIndex CIdx;
769 : int errorCode;
770 51: struct CXUnsavedFile *unsaved_files = 0;
771 51: int num_unsaved_files = 0;
772 51: CXCodeCompleteResults *results = 0;
773 :
774 51: input += strlen("-code-completion-at=");
0: branch 1 not taken
51: branch 2 taken
775 51: if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
776 : 0, 0)))
777 0: return errorCode;
778 :
0: branch 1 not taken
51: branch 2 taken
779 51: if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
780 0: return -1;
781 :
782 51: CIdx = clang_createIndex(0);
783 51: results = clang_codeComplete(CIdx,
784 : argv[argc - 1], argc - num_unsaved_files - 3,
785 : argv + num_unsaved_files + 2,
786 : num_unsaved_files, unsaved_files,
787 : filename, line, column,
788 : PrintDiagnosticCallback, stderr);
789 :
51: branch 0 taken
0: branch 1 not taken
790 51: if (results) {
791 51: unsigned i, n = results->NumResults;
1731: branch 0 taken
51: branch 1 taken
792 1782: for (i = 0; i != n; ++i)
793 1731: print_completion_result(results->Results + i, stdout);
794 51: clang_disposeCodeCompleteResults(results);
795 : }
796 :
797 51: clang_disposeIndex(CIdx);
798 51: free(filename);
799 :
800 51: free_remapped_files(unsaved_files, num_unsaved_files);
801 :
802 51: return 0;
803 : }
804 :
805 : typedef struct {
806 : char *filename;
807 : unsigned line;
808 : unsigned column;
809 : } CursorSourceLocation;
810 :
811 2: int inspect_cursor_at(int argc, const char **argv) {
812 : CXIndex CIdx;
813 : int errorCode;
814 2: struct CXUnsavedFile *unsaved_files = 0;
815 2: int num_unsaved_files = 0;
816 : CXTranslationUnit TU;
817 : CXCursor Cursor;
818 2: CursorSourceLocation *Locations = 0;
819 2: unsigned NumLocations = 0, Loc;
820 :
821 : /* Count the number of locations. */
4: branch 1 taken
2: branch 2 taken
822 8: while (strstr(argv[NumLocations+1], "-cursor-at=") == argv[NumLocations+1])
823 4: ++NumLocations;
824 :
825 : /* Parse the locations. */
0: branch 0 not taken
2: branch 1 taken
826 2: assert(NumLocations > 0 && "Unable to count locations?");
827 2: Locations = (CursorSourceLocation *)malloc(
828 : NumLocations * sizeof(CursorSourceLocation));
4: branch 0 taken
2: branch 1 taken
829 6: for (Loc = 0; Loc < NumLocations; ++Loc) {
830 4: const char *input = argv[Loc + 1] + strlen("-cursor-at=");
0: branch 1 not taken
4: branch 2 taken
831 4: if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename,
832 : &Locations[Loc].line,
833 : &Locations[Loc].column, 0, 0)))
834 0: return errorCode;
835 : }
836 :
0: branch 1 not taken
2: branch 2 taken
837 2: if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files,
838 : &num_unsaved_files))
839 0: return -1;
840 :
841 2: CIdx = clang_createIndex(0);
842 2: TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
843 : argc - num_unsaved_files - 2 - NumLocations,
844 : argv + num_unsaved_files + 1 + NumLocations,
845 : num_unsaved_files,
846 : unsaved_files,
847 : PrintDiagnosticCallback,
848 : stderr);
0: branch 0 not taken
2: branch 1 taken
849 2: if (!TU) {
850 0: fprintf(stderr, "unable to parse input\n");
851 0: return -1;
852 : }
853 :
4: branch 0 taken
2: branch 1 taken
854 6: for (Loc = 0; Loc < NumLocations; ++Loc) {
855 4: CXFile file = clang_getFile(TU, Locations[Loc].filename);
0: branch 0 not taken
4: branch 1 taken
856 4: if (!file)
857 0: continue;
858 :
859 4: Cursor = clang_getCursor(TU,
860 : clang_getLocation(TU, file, Locations[Loc].line,
861 : Locations[Loc].column));
862 4: PrintCursor(Cursor);
863 4: printf("\n");
864 4: free(Locations[Loc].filename);
865 : }
866 :
867 2: clang_disposeTranslationUnit(TU);
868 2: clang_disposeIndex(CIdx);
869 2: free(Locations);
870 2: free_remapped_files(unsaved_files, num_unsaved_files);
871 2: return 0;
872 : }
873 :
874 1: int perform_token_annotation(int argc, const char **argv) {
875 1: const char *input = argv[1];
876 1: char *filename = 0;
877 : unsigned line, second_line;
878 : unsigned column, second_column;
879 : CXIndex CIdx;
880 1: CXTranslationUnit TU = 0;
881 : int errorCode;
882 1: struct CXUnsavedFile *unsaved_files = 0;
883 1: int num_unsaved_files = 0;
884 : CXToken *tokens;
885 : unsigned num_tokens;
886 : CXSourceRange range;
887 : CXSourceLocation startLoc, endLoc;
888 1: CXFile file = 0;
889 1: CXCursor *cursors = 0;
890 : unsigned i;
891 :
892 1: input += strlen("-test-annotate-tokens=");
0: branch 1 not taken
1: branch 2 taken
893 1: if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
894 : &second_line, &second_column)))
895 0: return errorCode;
896 :
0: branch 1 not taken
1: branch 2 taken
897 1: if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
898 0: return -1;
899 :
900 1: CIdx = clang_createIndex(0);
901 1: TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
902 : argc - num_unsaved_files - 3,
903 : argv + num_unsaved_files + 2,
904 : num_unsaved_files,
905 : unsaved_files,
906 : PrintDiagnosticCallback,
907 : stderr);
0: branch 0 not taken
1: branch 1 taken
908 1: if (!TU) {
909 0: fprintf(stderr, "unable to parse input\n");
910 0: clang_disposeIndex(CIdx);
911 0: free(filename);
912 0: free_remapped_files(unsaved_files, num_unsaved_files);
913 0: return -1;
914 : }
915 1: errorCode = 0;
916 :
917 1: file = clang_getFile(TU, filename);
0: branch 0 not taken
1: branch 1 taken
918 1: if (!file) {
919 0: fprintf(stderr, "file %s is not in this translation unit\n", filename);
920 0: errorCode = -1;
921 0: goto teardown;
922 : }
923 :
924 1: startLoc = clang_getLocation(TU, file, line, column);
0: branch 2 not taken
1: branch 3 taken
925 1: if (clang_equalLocations(clang_getNullLocation(), startLoc)) {
926 0: fprintf(stderr, "invalid source location %s:%d:%d\n", filename, line,
927 : column);
928 0: errorCode = -1;
929 0: goto teardown;
930 : }
931 :
932 1: endLoc = clang_getLocation(TU, file, second_line, second_column);
0: branch 2 not taken
1: branch 3 taken
933 1: if (clang_equalLocations(clang_getNullLocation(), endLoc)) {
934 0: fprintf(stderr, "invalid source location %s:%d:%d\n", filename,
935 : second_line, second_column);
936 0: errorCode = -1;
937 0: goto teardown;
938 : }
939 :
940 1: range = clang_getRange(startLoc, endLoc);
941 1: clang_tokenize(TU, range, &tokens, &num_tokens);
942 1: cursors = (CXCursor *)malloc(num_tokens * sizeof(CXCursor));
943 1: clang_annotateTokens(TU, tokens, num_tokens, cursors);
51: branch 0 taken
1: branch 1 taken
944 52: for (i = 0; i != num_tokens; ++i) {
945 51: const char *kind = "<unknown>";
946 51: CXString spelling = clang_getTokenSpelling(TU, tokens[i]);
947 51: CXSourceRange extent = clang_getTokenExtent(TU, tokens[i]);
948 : unsigned start_line, start_column, end_line, end_column;
949 :
28: branch 1 taken
7: branch 2 taken
12: branch 3 taken
3: branch 4 taken
1: branch 5 taken
0: branch 6 not taken
950 51: switch (clang_getTokenKind(tokens[i])) {
951 28: case CXToken_Punctuation: kind = "Punctuation"; break;
952 7: case CXToken_Keyword: kind = "Keyword"; break;
953 12: case CXToken_Identifier: kind = "Identifier"; break;
954 3: case CXToken_Literal: kind = "Literal"; break;
955 1: case CXToken_Comment: kind = "Comment"; break;
956 : }
957 51: clang_getInstantiationLocation(clang_getRangeStart(extent),
958 : 0, &start_line, &start_column, 0);
959 51: clang_getInstantiationLocation(clang_getRangeEnd(extent),
960 : 0, &end_line, &end_column, 0);
961 51: printf("%s: \"%s\" [%d:%d - %d:%d]", kind, clang_getCString(spelling),
962 : start_line, start_column, end_line, end_column);
12: branch 1 taken
39: branch 2 taken
963 51: if (!clang_isInvalid(cursors[i].kind)) {
964 12: printf(" ");
965 12: PrintCursor(cursors[i]);
966 : }
967 51: printf("\n");
968 : }
969 1: free(cursors);
970 :
971 1: teardown:
972 1: clang_disposeTranslationUnit(TU);
973 1: clang_disposeIndex(CIdx);
974 1: free(filename);
975 1: free_remapped_files(unsaved_files, num_unsaved_files);
976 1: return errorCode;
977 : }
978 :
979 : /******************************************************************************/
980 : /* Command line processing. */
981 : /******************************************************************************/
982 :
983 11: static CXCursorVisitor GetVisitor(const char *s) {
11: branch 0 taken
0: branch 1 not taken
984 11: if (s[0] == '\0')
985 11: return FilteredPrintingVisitor;
0: branch 1 not taken
0: branch 2 not taken
986 0: if (strcmp(s, "-usrs") == 0)
987 0: return USRVisitor;
988 0: return NULL;
989 : }
990 :
991 0: static void print_usage(void) {
992 0: fprintf(stderr,
993 : "usage: c-index-test -code-completion-at=<site> <compiler arguments>\n"
994 : " c-index-test -cursor-at=<site> <compiler arguments>\n"
995 : " c-index-test -test-file-scan <AST file> <source file> "
996 : "[FileCheck prefix]\n"
997 : " c-index-test -test-load-tu <AST file> <symbol filter> "
998 : "[FileCheck prefix]\n"
999 : " c-index-test -test-load-tu-usrs <AST file> <symbol filter> "
1000 : "[FileCheck prefix]\n"
1001 : " c-index-test -test-load-source <symbol filter> {<args>}*\n"
1002 : " c-index-test -test-load-source-usrs <symbol filter> {<args>}*\n");
1003 0: fprintf(stderr,
1004 : " c-index-test -test-annotate-tokens=<range> {<args>}*\n"
1005 : " c-index-test -test-inclusion-stack-source {<args>}*\n"
1006 : " c-index-test -test-inclusion-stack-tu <AST file>\n\n"
1007 : " <symbol filter> values:\n%s",
1008 : " all - load all symbols, including those from PCH\n"
1009 : " local - load all symbols except those in PCH\n"
1010 : " category - only load ObjC categories (non-PCH)\n"
1011 : " interface - only load ObjC interfaces (non-PCH)\n"
1012 : " protocol - only load ObjC protocols (non-PCH)\n"
1013 : " function - only load functions (non-PCH)\n"
1014 : " typedef - only load typdefs (non-PCH)\n"
1015 : " scan-function - scan function bodies (non-PCH)\n\n");
1016 0: }
1017 :
1018 69: int main(int argc, const char **argv) {
69: branch 0 taken
0: branch 1 not taken
51: branch 3 taken
18: branch 4 taken
1019 69: if (argc > 2 && strstr(argv[1], "-code-completion-at=") == argv[1])
1020 51: return perform_code_completion(argc, argv);
18: branch 0 taken
0: branch 1 not taken
2: branch 3 taken
16: branch 4 taken
1021 18: if (argc > 2 && strstr(argv[1], "-cursor-at=") == argv[1])
1022 2: return inspect_cursor_at(argc, argv);
14: branch 0 taken
2: branch 1 taken
5: branch 3 taken
9: branch 4 taken
1023 16: else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) {
1024 5: CXCursorVisitor I = GetVisitor(argv[1] + 13);
5: branch 0 taken
0: branch 1 not taken
1025 5: if (I)
0: branch 0 not taken
5: branch 1 taken
1026 5: return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I,
1027 : NULL);
1028 : }
9: branch 0 taken
2: branch 1 taken
6: branch 3 taken
3: branch 4 taken
1029 11: else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) {
1030 6: CXCursorVisitor I = GetVisitor(argv[1] + 17);
6: branch 0 taken
0: branch 1 not taken
1031 6: if (I)
1032 6: return perform_test_load_source(argc - 3, argv + 3, argv[2], I, NULL);
1033 : }
3: branch 0 taken
2: branch 1 taken
3: branch 3 taken
0: branch 4 not taken
1034 5: else if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0)
0: branch 0 not taken
3: branch 1 taken
1035 3: return perform_file_scan(argv[2], argv[3],
1036 : argc >= 5 ? argv[4] : 0);
2: branch 0 taken
0: branch 1 not taken
1: branch 3 taken
1: branch 4 taken
1037 2: else if (argc > 2 && strstr(argv[1], "-test-annotate-tokens=") == argv[1])
1038 1: return perform_token_annotation(argc, argv);
1: branch 0 taken
0: branch 1 not taken
1: branch 3 taken
0: branch 4 not taken
1039 1: else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-source") == 0)
1040 1: return perform_test_load_source(argc - 2, argv + 2, "all", NULL,
1041 : PrintInclusionStack);
0: branch 0 not taken
0: branch 1 not taken
0: branch 3 not taken
0: branch 4 not taken
1042 0: else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-tu") == 0)
1043 0: return perform_test_load_tu(argv[2], "all", NULL, NULL,
1044 : PrintInclusionStack);
1045 :
1046 0: print_usage();
1047 0: return 1;
1048 : }
Generated: 2010-02-10 01:31 by zcov