Bug Summary

File:tools/clang/tools/c-index-test/c-index-test.c
Warning:line 2997, column 13
Potential leak of memory pointed to by 'Filenames'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name c-index-test.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/tools/c-index-test -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu89 -fconst-strings -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/tools/c-index-test -fdebug-prefix-map=/build/llvm-toolchain-snapshot-7~svn329677=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c
1/* c-index-test.c */
2
3#include "clang/Config/config.h"
4#include "clang-c/Index.h"
5#include "clang-c/CXCompilationDatabase.h"
6#include "clang-c/BuildSystem.h"
7#include "clang-c/Documentation.h"
8#include <ctype.h>
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12#include <assert.h>
13
14#ifdef CLANG_HAVE_LIBXML
15#include <libxml/parser.h>
16#include <libxml/relaxng.h>
17#include <libxml/xmlerror.h>
18#endif
19
20#ifdef _WIN32
21# include <direct.h>
22#else
23# include <unistd.h>
24#endif
25
26extern int indextest_core_main(int argc, const char **argv);
27
28/******************************************************************************/
29/* Utility functions. */
30/******************************************************************************/
31
32#ifdef _MSC_VER
33char *basename(const char* path)
34{
35 char* base1 = (char*)strrchr(path, '/');
36 char* base2 = (char*)strrchr(path, '\\');
37 if (base1 && base2)
38 return((base1 > base2) ? base1 + 1 : base2 + 1);
39 else if (base1)
40 return(base1 + 1);
41 else if (base2)
42 return(base2 + 1);
43
44 return((char*)path);
45}
46char *dirname(char* path)
47{
48 char* base1 = (char*)strrchr(path, '/');
49 char* base2 = (char*)strrchr(path, '\\');
50 if (base1 && base2)
51 if (base1 > base2)
52 *base1 = 0;
53 else
54 *base2 = 0;
55 else if (base1)
56 *base1 = 0;
57 else if (base2)
58 *base2 = 0;
59
60 return path;
61}
62#else
63extern char *basename(const char *);
64extern char *dirname(char *);
65#endif
66
67/** \brief Return the default parsing options. */
68static unsigned getDefaultParsingOptions() {
69 unsigned options = CXTranslationUnit_DetailedPreprocessingRecord;
70
71 if (getenv("CINDEXTEST_EDITING"))
72 options |= clang_defaultEditingTranslationUnitOptions();
73 if (getenv("CINDEXTEST_COMPLETION_CACHING"))
74 options |= CXTranslationUnit_CacheCompletionResults;
75 if (getenv("CINDEXTEST_COMPLETION_NO_CACHING"))
76 options &= ~CXTranslationUnit_CacheCompletionResults;
77 if (getenv("CINDEXTEST_SKIP_FUNCTION_BODIES"))
78 options |= CXTranslationUnit_SkipFunctionBodies;
79 if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
80 options |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
81 if (getenv("CINDEXTEST_CREATE_PREAMBLE_ON_FIRST_PARSE"))
82 options |= CXTranslationUnit_CreatePreambleOnFirstParse;
83 if (getenv("CINDEXTEST_KEEP_GOING"))
84 options |= CXTranslationUnit_KeepGoing;
85
86 return options;
87}
88
89static void ModifyPrintingPolicyAccordingToEnv(CXPrintingPolicy Policy) {
90 struct Mapping {
91 const char *name;
92 enum CXPrintingPolicyProperty property;
93 };
94 struct Mapping mappings[] = {
95 {"CINDEXTEST_PRINTINGPOLICY_INDENTATION", CXPrintingPolicy_Indentation},
96 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSPECIFIERS",
97 CXPrintingPolicy_SuppressSpecifiers},
98 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSTAGKEYWORD",
99 CXPrintingPolicy_SuppressTagKeyword},
100 {"CINDEXTEST_PRINTINGPOLICY_INCLUDETAGDEFINITION",
101 CXPrintingPolicy_IncludeTagDefinition},
102 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSCOPE",
103 CXPrintingPolicy_SuppressScope},
104 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSUNWRITTENSCOPE",
105 CXPrintingPolicy_SuppressUnwrittenScope},
106 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSINITIALIZERS",
107 CXPrintingPolicy_SuppressInitializers},
108 {"CINDEXTEST_PRINTINGPOLICY_CONSTANTARRAYSIZEASWRITTEN",
109 CXPrintingPolicy_ConstantArraySizeAsWritten},
110 {"CINDEXTEST_PRINTINGPOLICY_ANONYMOUSTAGLOCATIONS",
111 CXPrintingPolicy_AnonymousTagLocations},
112 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSTRONGLIFETIME",
113 CXPrintingPolicy_SuppressStrongLifetime},
114 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSLIFETIMEQUALIFIERS",
115 CXPrintingPolicy_SuppressLifetimeQualifiers},
116 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSTEMPLATEARGSINCXXCONSTRUCTORS",
117 CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors},
118 {"CINDEXTEST_PRINTINGPOLICY_BOOL", CXPrintingPolicy_Bool},
119 {"CINDEXTEST_PRINTINGPOLICY_RESTRICT", CXPrintingPolicy_Restrict},
120 {"CINDEXTEST_PRINTINGPOLICY_ALIGNOF", CXPrintingPolicy_Alignof},
121 {"CINDEXTEST_PRINTINGPOLICY_UNDERSCOREALIGNOF",
122 CXPrintingPolicy_UnderscoreAlignof},
123 {"CINDEXTEST_PRINTINGPOLICY_USEVOIDFORZEROPARAMS",
124 CXPrintingPolicy_UseVoidForZeroParams},
125 {"CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT", CXPrintingPolicy_TerseOutput},
126 {"CINDEXTEST_PRINTINGPOLICY_POLISHFORDECLARATION",
127 CXPrintingPolicy_PolishForDeclaration},
128 {"CINDEXTEST_PRINTINGPOLICY_HALF", CXPrintingPolicy_Half},
129 {"CINDEXTEST_PRINTINGPOLICY_MSWCHAR", CXPrintingPolicy_MSWChar},
130 {"CINDEXTEST_PRINTINGPOLICY_INCLUDENEWLINES",
131 CXPrintingPolicy_IncludeNewlines},
132 {"CINDEXTEST_PRINTINGPOLICY_MSVCFORMATTING",
133 CXPrintingPolicy_MSVCFormatting},
134 {"CINDEXTEST_PRINTINGPOLICY_CONSTANTSASWRITTEN",
135 CXPrintingPolicy_ConstantsAsWritten},
136 {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSIMPLICITBASE",
137 CXPrintingPolicy_SuppressImplicitBase},
138 {"CINDEXTEST_PRINTINGPOLICY_FULLYQUALIFIEDNAME",
139 CXPrintingPolicy_FullyQualifiedName},
140 };
141
142 unsigned i;
143 for (i = 0; i < sizeof(mappings) / sizeof(struct Mapping); i++) {
144 char *value = getenv(mappings[i].name);
145 if (value) {
146 clang_PrintingPolicy_setProperty(Policy, mappings[i].property,
147 (unsigned)strtoul(value, 0L, 10));
148 }
149 }
150}
151
152/** \brief Returns 0 in case of success, non-zero in case of a failure. */
153static int checkForErrors(CXTranslationUnit TU);
154
155static void describeLibclangFailure(enum CXErrorCode Err) {
156 switch (Err) {
157 case CXError_Success:
158 fprintf(stderrstderr, "Success\n");
159 return;
160
161 case CXError_Failure:
162 fprintf(stderrstderr, "Failure (no details available)\n");
163 return;
164
165 case CXError_Crashed:
166 fprintf(stderrstderr, "Failure: libclang crashed\n");
167 return;
168
169 case CXError_InvalidArguments:
170 fprintf(stderrstderr, "Failure: invalid arguments passed to a libclang routine\n");
171 return;
172
173 case CXError_ASTReadError:
174 fprintf(stderrstderr, "Failure: AST deserialization error occurred\n");
175 return;
176 }
177}
178
179static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column,
180 unsigned end_line, unsigned end_column) {
181 fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column,
182 end_line, end_column);
183}
184
185static unsigned CreateTranslationUnit(CXIndex Idx, const char *file,
186 CXTranslationUnit *TU) {
187 enum CXErrorCode Err = clang_createTranslationUnit2(Idx, file, TU);
188 if (Err != CXError_Success) {
189 fprintf(stderrstderr, "Unable to load translation unit from '%s'!\n", file);
190 describeLibclangFailure(Err);
191 *TU = 0;
192 return 0;
193 }
194 return 1;
195}
196
197void free_remapped_files(struct CXUnsavedFile *unsaved_files,
198 int num_unsaved_files) {
199 int i;
200 for (i = 0; i != num_unsaved_files; ++i) {
201 free((char *)unsaved_files[i].Filename);
202 free((char *)unsaved_files[i].Contents);
203 }
204 free(unsaved_files);
205}
206
207static int parse_remapped_files_with_opt(const char *opt_name,
208 int argc, const char **argv,
209 int start_arg,
210 struct CXUnsavedFile **unsaved_files,
211 int *num_unsaved_files) {
212 int i;
213 int arg;
214 int prefix_len = strlen(opt_name);
215 int arg_indices[20];
216 *unsaved_files = 0;
217 *num_unsaved_files = 0;
218
219 /* Count the number of remapped files. */
220 for (arg = start_arg; arg < argc; ++arg) {
221 if (strncmp(argv[arg], opt_name, prefix_len))
222 continue;
223
224 assert(*num_unsaved_files < (int)(sizeof(arg_indices)/sizeof(int)))((void) sizeof ((*num_unsaved_files < (int)(sizeof(arg_indices
)/sizeof(int))) ? 1 : 0), __extension__ ({ if (*num_unsaved_files
< (int)(sizeof(arg_indices)/sizeof(int))) ; else __assert_fail
("*num_unsaved_files < (int)(sizeof(arg_indices)/sizeof(int))"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 224, __extension__ __PRETTY_FUNCTION__); }))
;
225 arg_indices[*num_unsaved_files] = arg;
226 ++*num_unsaved_files;
227 }
228
229 if (*num_unsaved_files == 0)
230 return 0;
231
232 *unsaved_files
233 = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
234 *num_unsaved_files);
235 assert(*unsaved_files)((void) sizeof ((*unsaved_files) ? 1 : 0), __extension__ ({ if
(*unsaved_files) ; else __assert_fail ("*unsaved_files", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 235, __extension__ __PRETTY_FUNCTION__); }))
;
236 for (i = 0; i != *num_unsaved_files; ++i) {
237 struct CXUnsavedFile *unsaved = *unsaved_files + i;
238 const char *arg_string = argv[arg_indices[i]] + prefix_len;
239 int filename_len;
240 char *filename;
241 char *contents;
242 FILE *to_file;
243 const char *sep = strchr(arg_string, ',');
244 if (!sep) {
245 fprintf(stderrstderr,
246 "error: %sfrom:to argument is missing comma\n", opt_name);
247 free_remapped_files(*unsaved_files, i);
248 *unsaved_files = 0;
249 *num_unsaved_files = 0;
250 return -1;
251 }
252
253 /* Open the file that we're remapping to. */
254 to_file = fopen(sep + 1, "rb");
255 if (!to_file) {
256 fprintf(stderrstderr, "error: cannot open file %s that we are remapping to\n",
257 sep + 1);
258 free_remapped_files(*unsaved_files, i);
259 *unsaved_files = 0;
260 *num_unsaved_files = 0;
261 return -1;
262 }
263
264 /* Determine the length of the file we're remapping to. */
265 fseek(to_file, 0, SEEK_END2);
266 unsaved->Length = ftell(to_file);
267 fseek(to_file, 0, SEEK_SET0);
268
269 /* Read the contents of the file we're remapping to. */
270 contents = (char *)malloc(unsaved->Length + 1);
271 assert(contents)((void) sizeof ((contents) ? 1 : 0), __extension__ ({ if (contents
) ; else __assert_fail ("contents", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 271, __extension__ __PRETTY_FUNCTION__); }))
;
272 if (fread(contents, 1, unsaved->Length, to_file) != unsaved->Length) {
273 fprintf(stderrstderr, "error: unexpected %s reading 'to' file %s\n",
274 (feof(to_file) ? "EOF" : "error"), sep + 1);
275 fclose(to_file);
276 free_remapped_files(*unsaved_files, i);
277 free(contents);
278 *unsaved_files = 0;
279 *num_unsaved_files = 0;
280 return -1;
281 }
282 contents[unsaved->Length] = 0;
283 unsaved->Contents = contents;
284
285 /* Close the file. */
286 fclose(to_file);
287
288 /* Copy the file name that we're remapping from. */
289 filename_len = sep - arg_string;
290 filename = (char *)malloc(filename_len + 1);
291 assert(filename)((void) sizeof ((filename) ? 1 : 0), __extension__ ({ if (filename
) ; else __assert_fail ("filename", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 291, __extension__ __PRETTY_FUNCTION__); }))
;
292 memcpy(filename, arg_string, filename_len);
293 filename[filename_len] = 0;
294 unsaved->Filename = filename;
295 }
296
297 return 0;
298}
299
300static int parse_remapped_files(int argc, const char **argv, int start_arg,
301 struct CXUnsavedFile **unsaved_files,
302 int *num_unsaved_files) {
303 return parse_remapped_files_with_opt("-remap-file=", argc, argv, start_arg,
304 unsaved_files, num_unsaved_files);
305}
306
307static int parse_remapped_files_with_try(int try_idx,
308 int argc, const char **argv,
309 int start_arg,
310 struct CXUnsavedFile **unsaved_files,
311 int *num_unsaved_files) {
312 struct CXUnsavedFile *unsaved_files_no_try_idx;
313 int num_unsaved_files_no_try_idx;
314 struct CXUnsavedFile *unsaved_files_try_idx;
315 int num_unsaved_files_try_idx;
316 int ret;
317 char opt_name[32];
318
319 ret = parse_remapped_files(argc, argv, start_arg,
320 &unsaved_files_no_try_idx, &num_unsaved_files_no_try_idx);
321 if (ret)
322 return ret;
323
324 sprintf(opt_name, "-remap-file-%d=", try_idx);
325 ret = parse_remapped_files_with_opt(opt_name, argc, argv, start_arg,
326 &unsaved_files_try_idx, &num_unsaved_files_try_idx);
327 if (ret)
328 return ret;
329
330 if (num_unsaved_files_no_try_idx == 0) {
331 *unsaved_files = unsaved_files_try_idx;
332 *num_unsaved_files = num_unsaved_files_try_idx;
333 return 0;
334 }
335 if (num_unsaved_files_try_idx == 0) {
336 *unsaved_files = unsaved_files_no_try_idx;
337 *num_unsaved_files = num_unsaved_files_no_try_idx;
338 return 0;
339 }
340
341 *num_unsaved_files = num_unsaved_files_no_try_idx + num_unsaved_files_try_idx;
342 *unsaved_files
343 = (struct CXUnsavedFile *)realloc(unsaved_files_no_try_idx,
344 sizeof(struct CXUnsavedFile) *
345 *num_unsaved_files);
346 assert(*unsaved_files)((void) sizeof ((*unsaved_files) ? 1 : 0), __extension__ ({ if
(*unsaved_files) ; else __assert_fail ("*unsaved_files", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 346, __extension__ __PRETTY_FUNCTION__); }))
;
347 memcpy(*unsaved_files + num_unsaved_files_no_try_idx,
348 unsaved_files_try_idx, sizeof(struct CXUnsavedFile) *
349 num_unsaved_files_try_idx);
350 free(unsaved_files_try_idx);
351 return 0;
352}
353
354static const char *parse_comments_schema(int argc, const char **argv) {
355 const char *CommentsSchemaArg = "-comments-xml-schema=";
356 const char *CommentSchemaFile = NULL((void*)0);
357
358 if (argc == 0)
359 return CommentSchemaFile;
360
361 if (!strncmp(argv[0], CommentsSchemaArg, strlen(CommentsSchemaArg)))
362 CommentSchemaFile = argv[0] + strlen(CommentsSchemaArg);
363
364 return CommentSchemaFile;
365}
366
367/******************************************************************************/
368/* Pretty-printing. */
369/******************************************************************************/
370
371static const char *FileCheckPrefix = "CHECK";
372
373static void PrintCString(const char *CStr) {
374 if (CStr != NULL((void*)0) && CStr[0] != '\0') {
375 for ( ; *CStr; ++CStr) {
376 const char C = *CStr;
377 switch (C) {
378 case '\n': printf("\\n"); break;
379 case '\r': printf("\\r"); break;
380 case '\t': printf("\\t"); break;
381 case '\v': printf("\\v"); break;
382 case '\f': printf("\\f"); break;
383 default: putchar(C); break;
384 }
385 }
386 }
387}
388
389static void PrintCStringWithPrefix(const char *Prefix, const char *CStr) {
390 printf(" %s=[", Prefix);
391 PrintCString(CStr);
392 printf("]");
393}
394
395static void PrintCXStringAndDispose(CXString Str) {
396 PrintCString(clang_getCString(Str));
397 clang_disposeString(Str);
398}
399
400static void PrintCXStringWithPrefix(const char *Prefix, CXString Str) {
401 PrintCStringWithPrefix(Prefix, clang_getCString(Str));
402}
403
404static void PrintCXStringWithPrefixAndDispose(const char *Prefix,
405 CXString Str) {
406 PrintCStringWithPrefix(Prefix, clang_getCString(Str));
407 clang_disposeString(Str);
408}
409
410static void PrintRange(CXSourceRange R, const char *str) {
411 CXFile begin_file, end_file;
412 unsigned begin_line, begin_column, end_line, end_column;
413
414 clang_getSpellingLocation(clang_getRangeStart(R),
415 &begin_file, &begin_line, &begin_column, 0);
416 clang_getSpellingLocation(clang_getRangeEnd(R),
417 &end_file, &end_line, &end_column, 0);
418 if (!begin_file || !end_file)
419 return;
420
421 if (str)
422 printf(" %s=", str);
423 PrintExtent(stdoutstdout, begin_line, begin_column, end_line, end_column);
424}
425
426static enum DisplayType {
427 DisplayType_Spelling,
428 DisplayType_DisplayName,
429 DisplayType_Pretty
430} wanted_display_type = DisplayType_Spelling;
431
432static void printVersion(const char *Prefix, CXVersion Version) {
433 if (Version.Major < 0)
434 return;
435 printf("%s%d", Prefix, Version.Major);
436
437 if (Version.Minor < 0)
438 return;
439 printf(".%d", Version.Minor);
440
441 if (Version.Subminor < 0)
442 return;
443 printf(".%d", Version.Subminor);
444}
445
446struct CommentASTDumpingContext {
447 int IndentLevel;
448};
449
450static void DumpCXCommentInternal(struct CommentASTDumpingContext *Ctx,
451 CXComment Comment) {
452 unsigned i;
453 unsigned e;
454 enum CXCommentKind Kind = clang_Comment_getKind(Comment);
455
456 Ctx->IndentLevel++;
457 for (i = 0, e = Ctx->IndentLevel; i != e; ++i)
458 printf(" ");
459
460 printf("(");
461 switch (Kind) {
462 case CXComment_Null:
463 printf("CXComment_Null");
464 break;
465 case CXComment_Text:
466 printf("CXComment_Text");
467 PrintCXStringWithPrefixAndDispose("Text",
468 clang_TextComment_getText(Comment));
469 if (clang_Comment_isWhitespace(Comment))
470 printf(" IsWhitespace");
471 if (clang_InlineContentComment_hasTrailingNewline(Comment))
472 printf(" HasTrailingNewline");
473 break;
474 case CXComment_InlineCommand:
475 printf("CXComment_InlineCommand");
476 PrintCXStringWithPrefixAndDispose(
477 "CommandName",
478 clang_InlineCommandComment_getCommandName(Comment));
479 switch (clang_InlineCommandComment_getRenderKind(Comment)) {
480 case CXCommentInlineCommandRenderKind_Normal:
481 printf(" RenderNormal");
482 break;
483 case CXCommentInlineCommandRenderKind_Bold:
484 printf(" RenderBold");
485 break;
486 case CXCommentInlineCommandRenderKind_Monospaced:
487 printf(" RenderMonospaced");
488 break;
489 case CXCommentInlineCommandRenderKind_Emphasized:
490 printf(" RenderEmphasized");
491 break;
492 }
493 for (i = 0, e = clang_InlineCommandComment_getNumArgs(Comment);
494 i != e; ++i) {
495 printf(" Arg[%u]=", i);
496 PrintCXStringAndDispose(
497 clang_InlineCommandComment_getArgText(Comment, i));
498 }
499 if (clang_InlineContentComment_hasTrailingNewline(Comment))
500 printf(" HasTrailingNewline");
501 break;
502 case CXComment_HTMLStartTag: {
503 unsigned NumAttrs;
504 printf("CXComment_HTMLStartTag");
505 PrintCXStringWithPrefixAndDispose(
506 "Name",
507 clang_HTMLTagComment_getTagName(Comment));
508 NumAttrs = clang_HTMLStartTag_getNumAttrs(Comment);
509 if (NumAttrs != 0) {
510 printf(" Attrs:");
511 for (i = 0; i != NumAttrs; ++i) {
512 printf(" ");
513 PrintCXStringAndDispose(clang_HTMLStartTag_getAttrName(Comment, i));
514 printf("=");
515 PrintCXStringAndDispose(clang_HTMLStartTag_getAttrValue(Comment, i));
516 }
517 }
518 if (clang_HTMLStartTagComment_isSelfClosing(Comment))
519 printf(" SelfClosing");
520 if (clang_InlineContentComment_hasTrailingNewline(Comment))
521 printf(" HasTrailingNewline");
522 break;
523 }
524 case CXComment_HTMLEndTag:
525 printf("CXComment_HTMLEndTag");
526 PrintCXStringWithPrefixAndDispose(
527 "Name",
528 clang_HTMLTagComment_getTagName(Comment));
529 if (clang_InlineContentComment_hasTrailingNewline(Comment))
530 printf(" HasTrailingNewline");
531 break;
532 case CXComment_Paragraph:
533 printf("CXComment_Paragraph");
534 if (clang_Comment_isWhitespace(Comment))
535 printf(" IsWhitespace");
536 break;
537 case CXComment_BlockCommand:
538 printf("CXComment_BlockCommand");
539 PrintCXStringWithPrefixAndDispose(
540 "CommandName",
541 clang_BlockCommandComment_getCommandName(Comment));
542 for (i = 0, e = clang_BlockCommandComment_getNumArgs(Comment);
543 i != e; ++i) {
544 printf(" Arg[%u]=", i);
545 PrintCXStringAndDispose(
546 clang_BlockCommandComment_getArgText(Comment, i));
547 }
548 break;
549 case CXComment_ParamCommand:
550 printf("CXComment_ParamCommand");
551 switch (clang_ParamCommandComment_getDirection(Comment)) {
552 case CXCommentParamPassDirection_In:
553 printf(" in");
554 break;
555 case CXCommentParamPassDirection_Out:
556 printf(" out");
557 break;
558 case CXCommentParamPassDirection_InOut:
559 printf(" in,out");
560 break;
561 }
562 if (clang_ParamCommandComment_isDirectionExplicit(Comment))
563 printf(" explicitly");
564 else
565 printf(" implicitly");
566 PrintCXStringWithPrefixAndDispose(
567 "ParamName",
568 clang_ParamCommandComment_getParamName(Comment));
569 if (clang_ParamCommandComment_isParamIndexValid(Comment))
570 printf(" ParamIndex=%u", clang_ParamCommandComment_getParamIndex(Comment));
571 else
572 printf(" ParamIndex=Invalid");
573 break;
574 case CXComment_TParamCommand:
575 printf("CXComment_TParamCommand");
576 PrintCXStringWithPrefixAndDispose(
577 "ParamName",
578 clang_TParamCommandComment_getParamName(Comment));
579 if (clang_TParamCommandComment_isParamPositionValid(Comment)) {
580 printf(" ParamPosition={");
581 for (i = 0, e = clang_TParamCommandComment_getDepth(Comment);
582 i != e; ++i) {
583 printf("%u", clang_TParamCommandComment_getIndex(Comment, i));
584 if (i != e - 1)
585 printf(", ");
586 }
587 printf("}");
588 } else
589 printf(" ParamPosition=Invalid");
590 break;
591 case CXComment_VerbatimBlockCommand:
592 printf("CXComment_VerbatimBlockCommand");
593 PrintCXStringWithPrefixAndDispose(
594 "CommandName",
595 clang_BlockCommandComment_getCommandName(Comment));
596 break;
597 case CXComment_VerbatimBlockLine:
598 printf("CXComment_VerbatimBlockLine");
599 PrintCXStringWithPrefixAndDispose(
600 "Text",
601 clang_VerbatimBlockLineComment_getText(Comment));
602 break;
603 case CXComment_VerbatimLine:
604 printf("CXComment_VerbatimLine");
605 PrintCXStringWithPrefixAndDispose(
606 "Text",
607 clang_VerbatimLineComment_getText(Comment));
608 break;
609 case CXComment_FullComment:
610 printf("CXComment_FullComment");
611 break;
612 }
613 if (Kind != CXComment_Null) {
614 const unsigned NumChildren = clang_Comment_getNumChildren(Comment);
615 unsigned i;
616 for (i = 0; i != NumChildren; ++i) {
617 printf("\n// %s: ", FileCheckPrefix);
618 DumpCXCommentInternal(Ctx, clang_Comment_getChild(Comment, i));
619 }
620 }
621 printf(")");
622 Ctx->IndentLevel--;
623}
624
625static void DumpCXComment(CXComment Comment) {
626 struct CommentASTDumpingContext Ctx;
627 Ctx.IndentLevel = 1;
628 printf("\n// %s: CommentAST=[\n// %s:", FileCheckPrefix, FileCheckPrefix);
629 DumpCXCommentInternal(&Ctx, Comment);
630 printf("]");
631}
632
633static void ValidateCommentXML(const char *Str, const char *CommentSchemaFile) {
634#ifdef CLANG_HAVE_LIBXML
635 xmlRelaxNGParserCtxtPtr RNGParser;
636 xmlRelaxNGPtr Schema;
637 xmlDocPtr Doc;
638 xmlRelaxNGValidCtxtPtr ValidationCtxt;
639 int status;
640
641 if (!CommentSchemaFile)
642 return;
643
644 RNGParser = xmlRelaxNGNewParserCtxt(CommentSchemaFile);
645 if (!RNGParser) {
646 printf(" libXMLError");
647 return;
648 }
649 Schema = xmlRelaxNGParse(RNGParser);
650
651 Doc = xmlParseDoc((const xmlChar *) Str);
652
653 if (!Doc) {
654 xmlErrorPtr Error = xmlGetLastError();
655 printf(" CommentXMLInvalid [not well-formed XML: %s]", Error->message);
656 return;
657 }
658
659 ValidationCtxt = xmlRelaxNGNewValidCtxt(Schema);
660 status = xmlRelaxNGValidateDoc(ValidationCtxt, Doc);
661 if (!status)
662 printf(" CommentXMLValid");
663 else if (status > 0) {
664 xmlErrorPtr Error = xmlGetLastError();
665 printf(" CommentXMLInvalid [not valid XML: %s]", Error->message);
666 } else
667 printf(" libXMLError");
668
669 xmlRelaxNGFreeValidCtxt(ValidationCtxt);
670 xmlFreeDoc(Doc);
671 xmlRelaxNGFree(Schema);
672 xmlRelaxNGFreeParserCtxt(RNGParser);
673#endif
674}
675
676static void PrintCursorComments(CXCursor Cursor,
677 const char *CommentSchemaFile) {
678 {
679 CXString RawComment;
680 const char *RawCommentCString;
681 CXString BriefComment;
682 const char *BriefCommentCString;
683
684 RawComment = clang_Cursor_getRawCommentText(Cursor);
685 RawCommentCString = clang_getCString(RawComment);
686 if (RawCommentCString != NULL((void*)0) && RawCommentCString[0] != '\0') {
687 PrintCStringWithPrefix("RawComment", RawCommentCString);
688 PrintRange(clang_Cursor_getCommentRange(Cursor), "RawCommentRange");
689
690 BriefComment = clang_Cursor_getBriefCommentText(Cursor);
691 BriefCommentCString = clang_getCString(BriefComment);
692 if (BriefCommentCString != NULL((void*)0) && BriefCommentCString[0] != '\0')
693 PrintCStringWithPrefix("BriefComment", BriefCommentCString);
694 clang_disposeString(BriefComment);
695 }
696 clang_disposeString(RawComment);
697 }
698
699 {
700 CXComment Comment = clang_Cursor_getParsedComment(Cursor);
701 if (clang_Comment_getKind(Comment) != CXComment_Null) {
702 PrintCXStringWithPrefixAndDispose("FullCommentAsHTML",
703 clang_FullComment_getAsHTML(Comment));
704 {
705 CXString XML;
706 XML = clang_FullComment_getAsXML(Comment);
707 PrintCXStringWithPrefix("FullCommentAsXML", XML);
708 ValidateCommentXML(clang_getCString(XML), CommentSchemaFile);
709 clang_disposeString(XML);
710 }
711
712 DumpCXComment(Comment);
713 }
714 }
715}
716
717typedef struct {
718 unsigned line;
719 unsigned col;
720} LineCol;
721
722static int lineCol_cmp(const void *p1, const void *p2) {
723 const LineCol *lhs = p1;
724 const LineCol *rhs = p2;
725 if (lhs->line != rhs->line)
726 return (int)lhs->line - (int)rhs->line;
727 return (int)lhs->col - (int)rhs->col;
728}
729
730static CXString CursorToText(CXCursor Cursor) {
731 CXString text;
732 switch (wanted_display_type) {
733 case DisplayType_Spelling:
734 return clang_getCursorSpelling(Cursor);
735 case DisplayType_DisplayName:
736 return clang_getCursorDisplayName(Cursor);
737 case DisplayType_Pretty: {
738 CXPrintingPolicy Policy = clang_getCursorPrintingPolicy(Cursor);
739 ModifyPrintingPolicyAccordingToEnv(Policy);
740 text = clang_getCursorPrettyPrinted(Cursor, Policy);
741 clang_PrintingPolicy_dispose(Policy);
742 return text;
743 }
744 }
745 assert(0 && "unknown display type")((void) sizeof ((0 && "unknown display type") ? 1 : 0
), __extension__ ({ if (0 && "unknown display type") ;
else __assert_fail ("0 && \"unknown display type\"",
"/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 745, __extension__ __PRETTY_FUNCTION__); }))
; /* no llvm_unreachable in C. */
746 /* Set to NULL to prevent uninitialized variable warnings. */
747 text.data = NULL((void*)0);
748 text.private_flags = 0;
749 return text;
750}
751
752static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
753 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
754 if (clang_isInvalid(Cursor.kind)) {
755 CXString ks = clang_getCursorKindSpelling(Cursor.kind);
756 printf("Invalid Cursor => %s", clang_getCString(ks));
757 clang_disposeString(ks);
758 }
759 else {
760 CXString string, ks;
761 CXCursor Referenced;
762 unsigned line, column;
763 CXCursor SpecializationOf;
764 CXCursor *overridden;
765 unsigned num_overridden;
766 unsigned RefNameRangeNr;
767 CXSourceRange CursorExtent;
768 CXSourceRange RefNameRange;
769 int AlwaysUnavailable;
770 int AlwaysDeprecated;
771 CXString UnavailableMessage;
772 CXString DeprecatedMessage;
773 CXPlatformAvailability PlatformAvailability[2];
774 int NumPlatformAvailability;
775 int I;
776
777 ks = clang_getCursorKindSpelling(Cursor.kind);
778 string = CursorToText(Cursor);
779 printf("%s=%s", clang_getCString(ks),
780 clang_getCString(string));
781 clang_disposeString(ks);
782 clang_disposeString(string);
783
784 Referenced = clang_getCursorReferenced(Cursor);
785 if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
786 if (clang_getCursorKind(Referenced) == CXCursor_OverloadedDeclRef) {
787 unsigned I, N = clang_getNumOverloadedDecls(Referenced);
788 printf("[");
789 for (I = 0; I != N; ++I) {
790 CXCursor Ovl = clang_getOverloadedDecl(Referenced, I);
791 CXSourceLocation Loc;
792 if (I)
793 printf(", ");
794
795 Loc = clang_getCursorLocation(Ovl);
796 clang_getSpellingLocation(Loc, 0, &line, &column, 0);
797 printf("%d:%d", line, column);
798 }
799 printf("]");
800 } else {
801 CXSourceLocation Loc = clang_getCursorLocation(Referenced);
802 clang_getSpellingLocation(Loc, 0, &line, &column, 0);
803 printf(":%d:%d", line, column);
804 }
805
806 if (clang_getCursorKind(Referenced) == CXCursor_TypedefDecl) {
807 CXType T = clang_getCursorType(Referenced);
808 if (clang_Type_isTransparentTagTypedef(T)) {
809 CXType Underlying = clang_getTypedefDeclUnderlyingType(Referenced);
810 CXString S = clang_getTypeSpelling(Underlying);
811 printf(" (Transparent: %s)", clang_getCString(S));
812 clang_disposeString(S);
813 }
814 }
815 }
816
817 if (clang_isCursorDefinition(Cursor))
818 printf(" (Definition)");
819
820 switch (clang_getCursorAvailability(Cursor)) {
821 case CXAvailability_Available:
822 break;
823
824 case CXAvailability_Deprecated:
825 printf(" (deprecated)");
826 break;
827
828 case CXAvailability_NotAvailable:
829 printf(" (unavailable)");
830 break;
831
832 case CXAvailability_NotAccessible:
833 printf(" (inaccessible)");
834 break;
835 }
836
837 NumPlatformAvailability
838 = clang_getCursorPlatformAvailability(Cursor,
839 &AlwaysDeprecated,
840 &DeprecatedMessage,
841 &AlwaysUnavailable,
842 &UnavailableMessage,
843 PlatformAvailability, 2);
844 if (AlwaysUnavailable) {
845 printf(" (always unavailable: \"%s\")",
846 clang_getCString(UnavailableMessage));
847 } else if (AlwaysDeprecated) {
848 printf(" (always deprecated: \"%s\")",
849 clang_getCString(DeprecatedMessage));
850 } else {
851 for (I = 0; I != NumPlatformAvailability; ++I) {
852 if (I >= 2)
853 break;
854
855 printf(" (%s", clang_getCString(PlatformAvailability[I].Platform));
856 if (PlatformAvailability[I].Unavailable)
857 printf(", unavailable");
858 else {
859 printVersion(", introduced=", PlatformAvailability[I].Introduced);
860 printVersion(", deprecated=", PlatformAvailability[I].Deprecated);
861 printVersion(", obsoleted=", PlatformAvailability[I].Obsoleted);
862 }
863 if (clang_getCString(PlatformAvailability[I].Message)[0])
864 printf(", message=\"%s\"",
865 clang_getCString(PlatformAvailability[I].Message));
866 printf(")");
867 }
868 }
869 for (I = 0; I != NumPlatformAvailability; ++I) {
870 if (I >= 2)
871 break;
872 clang_disposeCXPlatformAvailability(PlatformAvailability + I);
873 }
874
875 clang_disposeString(DeprecatedMessage);
876 clang_disposeString(UnavailableMessage);
877
878 if (clang_CXXConstructor_isDefaultConstructor(Cursor))
879 printf(" (default constructor)");
880
881 if (clang_CXXConstructor_isMoveConstructor(Cursor))
882 printf(" (move constructor)");
883 if (clang_CXXConstructor_isCopyConstructor(Cursor))
884 printf(" (copy constructor)");
885 if (clang_CXXConstructor_isConvertingConstructor(Cursor))
886 printf(" (converting constructor)");
887 if (clang_CXXField_isMutable(Cursor))
888 printf(" (mutable)");
889 if (clang_CXXMethod_isDefaulted(Cursor))
890 printf(" (defaulted)");
891 if (clang_CXXMethod_isStatic(Cursor))
892 printf(" (static)");
893 if (clang_CXXMethod_isVirtual(Cursor))
894 printf(" (virtual)");
895 if (clang_CXXMethod_isConst(Cursor))
896 printf(" (const)");
897 if (clang_CXXMethod_isPureVirtual(Cursor))
898 printf(" (pure)");
899 if (clang_CXXRecord_isAbstract(Cursor))
900 printf(" (abstract)");
901 if (clang_EnumDecl_isScoped(Cursor))
902 printf(" (scoped)");
903 if (clang_Cursor_isVariadic(Cursor))
904 printf(" (variadic)");
905 if (clang_Cursor_isObjCOptional(Cursor))
906 printf(" (@optional)");
907 if (clang_isInvalidDeclaration(Cursor))
908 printf(" (invalid)");
909
910 switch (clang_getCursorExceptionSpecificationType(Cursor))
911 {
912 case CXCursor_ExceptionSpecificationKind_None:
913 break;
914
915 case CXCursor_ExceptionSpecificationKind_DynamicNone:
916 printf(" (noexcept dynamic none)");
917 break;
918
919 case CXCursor_ExceptionSpecificationKind_Dynamic:
920 printf(" (noexcept dynamic)");
921 break;
922
923 case CXCursor_ExceptionSpecificationKind_MSAny:
924 printf(" (noexcept dynamic any)");
925 break;
926
927 case CXCursor_ExceptionSpecificationKind_BasicNoexcept:
928 printf(" (noexcept)");
929 break;
930
931 case CXCursor_ExceptionSpecificationKind_ComputedNoexcept:
932 printf(" (computed-noexcept)");
933 break;
934
935 case CXCursor_ExceptionSpecificationKind_Unevaluated:
936 case CXCursor_ExceptionSpecificationKind_Uninstantiated:
937 case CXCursor_ExceptionSpecificationKind_Unparsed:
938 break;
939 }
940
941 {
942 CXString language;
943 CXString definedIn;
944 unsigned generated;
945 if (clang_Cursor_isExternalSymbol(Cursor, &language, &definedIn,
946 &generated)) {
947 printf(" (external lang: %s, defined: %s, gen: %d)",
948 clang_getCString(language), clang_getCString(definedIn), generated);
949 clang_disposeString(language);
950 clang_disposeString(definedIn);
951 }
952 }
953
954 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
955 CXType T =
956 clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor));
957 CXString S = clang_getTypeKindSpelling(T.kind);
958 printf(" [IBOutletCollection=%s]", clang_getCString(S));
959 clang_disposeString(S);
960 }
961
962 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
963 enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
964 unsigned isVirtual = clang_isVirtualBase(Cursor);
965 const char *accessStr = 0;
966
967 switch (access) {
968 case CX_CXXInvalidAccessSpecifier:
969 accessStr = "invalid"; break;
970 case CX_CXXPublic:
971 accessStr = "public"; break;
972 case CX_CXXProtected:
973 accessStr = "protected"; break;
974 case CX_CXXPrivate:
975 accessStr = "private"; break;
976 }
977
978 printf(" [access=%s isVirtual=%s]", accessStr,
979 isVirtual ? "true" : "false");
980 }
981
982 SpecializationOf = clang_getSpecializedCursorTemplate(Cursor);
983 if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) {
984 CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf);
985 CXString Name = clang_getCursorSpelling(SpecializationOf);
986 clang_getSpellingLocation(Loc, 0, &line, &column, 0);
987 printf(" [Specialization of %s:%d:%d]",
988 clang_getCString(Name), line, column);
989 clang_disposeString(Name);
990
991 if (Cursor.kind == CXCursor_FunctionDecl) {
992 /* Collect the template parameter kinds from the base template. */
993 int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
994 int I;
995 if (NumTemplateArgs < 0) {
996 printf(" [no template arg info]");
997 }
998 for (I = 0; I < NumTemplateArgs; I++) {
999 enum CXTemplateArgumentKind TAK =
1000 clang_Cursor_getTemplateArgumentKind(Cursor, I);
1001 switch(TAK) {
1002 case CXTemplateArgumentKind_Type:
1003 {
1004 CXType T = clang_Cursor_getTemplateArgumentType(Cursor, I);
1005 CXString S = clang_getTypeSpelling(T);
1006 printf(" [Template arg %d: kind: %d, type: %s]",
1007 I, TAK, clang_getCString(S));
1008 clang_disposeString(S);
1009 }
1010 break;
1011 case CXTemplateArgumentKind_Integral:
1012 printf(" [Template arg %d: kind: %d, intval: %lld]",
1013 I, TAK, clang_Cursor_getTemplateArgumentValue(Cursor, I));
1014 break;
1015 default:
1016 printf(" [Template arg %d: kind: %d]\n", I, TAK);
1017 }
1018 }
1019 }
1020 }
1021
1022 clang_getOverriddenCursors(Cursor, &overridden, &num_overridden);
1023 if (num_overridden) {
1024 unsigned I;
1025 LineCol lineCols[50];
1026 assert(num_overridden <= 50)((void) sizeof ((num_overridden <= 50) ? 1 : 0), __extension__
({ if (num_overridden <= 50) ; else __assert_fail ("num_overridden <= 50"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 1026, __extension__ __PRETTY_FUNCTION__); }))
;
1027 printf(" [Overrides ");
1028 for (I = 0; I != num_overridden; ++I) {
1029 CXSourceLocation Loc = clang_getCursorLocation(overridden[I]);
1030 clang_getSpellingLocation(Loc, 0, &line, &column, 0);
1031 lineCols[I].line = line;
1032 lineCols[I].col = column;
1033 }
1034 /* Make the order of the override list deterministic. */
1035 qsort(lineCols, num_overridden, sizeof(LineCol), lineCol_cmp);
1036 for (I = 0; I != num_overridden; ++I) {
1037 if (I)
1038 printf(", ");
1039 printf("@%d:%d", lineCols[I].line, lineCols[I].col);
1040 }
1041 printf("]");
1042 clang_disposeOverriddenCursors(overridden);
1043 }
1044
1045 if (Cursor.kind == CXCursor_InclusionDirective) {
1046 CXFile File = clang_getIncludedFile(Cursor);
1047 CXString Included = clang_getFileName(File);
1048 printf(" (%s)", clang_getCString(Included));
1049 clang_disposeString(Included);
1050
1051 if (clang_isFileMultipleIncludeGuarded(TU, File))
1052 printf(" [multi-include guarded]");
1053 }
1054
1055 CursorExtent = clang_getCursorExtent(Cursor);
1056 RefNameRange = clang_getCursorReferenceNameRange(Cursor,
1057 CXNameRange_WantQualifier
1058 | CXNameRange_WantSinglePiece
1059 | CXNameRange_WantTemplateArgs,
1060 0);
1061 if (!clang_equalRanges(CursorExtent, RefNameRange))
1062 PrintRange(RefNameRange, "SingleRefName");
1063
1064 for (RefNameRangeNr = 0; 1; RefNameRangeNr++) {
1065 RefNameRange = clang_getCursorReferenceNameRange(Cursor,
1066 CXNameRange_WantQualifier
1067 | CXNameRange_WantTemplateArgs,
1068 RefNameRangeNr);
1069 if (clang_equalRanges(clang_getNullRange(), RefNameRange))
1070 break;
1071 if (!clang_equalRanges(CursorExtent, RefNameRange))
1072 PrintRange(RefNameRange, "RefName");
1073 }
1074
1075 PrintCursorComments(Cursor, CommentSchemaFile);
1076
1077 {
1078 unsigned PropAttrs = clang_Cursor_getObjCPropertyAttributes(Cursor, 0);
1079 if (PropAttrs != CXObjCPropertyAttr_noattr) {
1080 printf(" [");
1081 #define PRINT_PROP_ATTR(A)if (PropAttrs & CXObjCPropertyAttr_A) printf("A" ",") \
1082 if (PropAttrs & CXObjCPropertyAttr_##A) printf(#A ",")
1083 PRINT_PROP_ATTR(readonly)if (PropAttrs & CXObjCPropertyAttr_readonly) printf("readonly"
",")
;
1084 PRINT_PROP_ATTR(getter)if (PropAttrs & CXObjCPropertyAttr_getter) printf("getter"
",")
;
1085 PRINT_PROP_ATTR(assign)if (PropAttrs & CXObjCPropertyAttr_assign) printf("assign"
",")
;
1086 PRINT_PROP_ATTR(readwrite)if (PropAttrs & CXObjCPropertyAttr_readwrite) printf("readwrite"
",")
;
1087 PRINT_PROP_ATTR(retain)if (PropAttrs & CXObjCPropertyAttr_retain) printf("retain"
",")
;
1088 PRINT_PROP_ATTR(copy)if (PropAttrs & CXObjCPropertyAttr_copy) printf("copy" ","
)
;
1089 PRINT_PROP_ATTR(nonatomic)if (PropAttrs & CXObjCPropertyAttr_nonatomic) printf("nonatomic"
",")
;
1090 PRINT_PROP_ATTR(setter)if (PropAttrs & CXObjCPropertyAttr_setter) printf("setter"
",")
;
1091 PRINT_PROP_ATTR(atomic)if (PropAttrs & CXObjCPropertyAttr_atomic) printf("atomic"
",")
;
1092 PRINT_PROP_ATTR(weak)if (PropAttrs & CXObjCPropertyAttr_weak) printf("weak" ","
)
;
1093 PRINT_PROP_ATTR(strong)if (PropAttrs & CXObjCPropertyAttr_strong) printf("strong"
",")
;
1094 PRINT_PROP_ATTR(unsafe_unretained)if (PropAttrs & CXObjCPropertyAttr_unsafe_unretained) printf
("unsafe_unretained" ",")
;
1095 PRINT_PROP_ATTR(class)if (PropAttrs & CXObjCPropertyAttr_class) printf("class" ","
)
;
1096 printf("]");
1097 }
1098 }
1099
1100 {
1101 unsigned QT = clang_Cursor_getObjCDeclQualifiers(Cursor);
1102 if (QT != CXObjCDeclQualifier_None) {
1103 printf(" [");
1104 #define PRINT_OBJC_QUAL(A)if (QT & CXObjCDeclQualifier_A) printf("A" ",") \
1105 if (QT & CXObjCDeclQualifier_##A) printf(#A ",")
1106 PRINT_OBJC_QUAL(In)if (QT & CXObjCDeclQualifier_In) printf("In" ",");
1107 PRINT_OBJC_QUAL(Inout)if (QT & CXObjCDeclQualifier_Inout) printf("Inout" ",");
1108 PRINT_OBJC_QUAL(Out)if (QT & CXObjCDeclQualifier_Out) printf("Out" ",");
1109 PRINT_OBJC_QUAL(Bycopy)if (QT & CXObjCDeclQualifier_Bycopy) printf("Bycopy" ",");
1110 PRINT_OBJC_QUAL(Byref)if (QT & CXObjCDeclQualifier_Byref) printf("Byref" ",");
1111 PRINT_OBJC_QUAL(Oneway)if (QT & CXObjCDeclQualifier_Oneway) printf("Oneway" ",");
1112 printf("]");
1113 }
1114 }
1115 }
1116}
1117
1118static const char* GetCursorSource(CXCursor Cursor) {
1119 CXSourceLocation Loc = clang_getCursorLocation(Cursor);
1120 CXString source;
1121 CXFile file;
1122 clang_getExpansionLocation(Loc, &file, 0, 0, 0);
1123 source = clang_getFileName(file);
1124 if (!clang_getCString(source)) {
1125 clang_disposeString(source);
1126 return "<invalid loc>";
1127 }
1128 else {
1129 const char *b = basename(clang_getCString(source));
1130 clang_disposeString(source);
1131 return b;
1132 }
1133}
1134
1135static CXString createCXString(const char *CS) {
1136 CXString Str;
1137 Str.data = (const void *) CS;
1138 Str.private_flags = 0;
1139 return Str;
1140}
1141
1142/******************************************************************************/
1143/* Callbacks. */
1144/******************************************************************************/
1145
1146typedef void (*PostVisitTU)(CXTranslationUnit);
1147
1148void PrintDiagnostic(CXDiagnostic Diagnostic) {
1149 FILE *out = stderrstderr;
1150 CXFile file;
1151 CXString Msg;
1152 unsigned display_opts = CXDiagnostic_DisplaySourceLocation
1153 | CXDiagnostic_DisplayColumn | CXDiagnostic_DisplaySourceRanges
1154 | CXDiagnostic_DisplayOption;
1155 unsigned i, num_fixits;
1156
1157 if (clang_getDiagnosticSeverity(Diagnostic) == CXDiagnostic_Ignored)
1158 return;
1159
1160 Msg = clang_formatDiagnostic(Diagnostic, display_opts);
1161 fprintf(stderrstderr, "%s\n", clang_getCString(Msg));
1162 clang_disposeString(Msg);
1163
1164 clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
1165 &file, 0, 0, 0);
1166 if (!file)
1167 return;
1168
1169 num_fixits = clang_getDiagnosticNumFixIts(Diagnostic);
1170 fprintf(stderrstderr, "Number FIX-ITs = %d\n", num_fixits);
1171 for (i = 0; i != num_fixits; ++i) {
1172 CXSourceRange range;
1173 CXString insertion_text = clang_getDiagnosticFixIt(Diagnostic, i, &range);
1174 CXSourceLocation start = clang_getRangeStart(range);
1175 CXSourceLocation end = clang_getRangeEnd(range);
1176 unsigned start_line, start_column, end_line, end_column;
1177 CXFile start_file, end_file;
1178 clang_getSpellingLocation(start, &start_file, &start_line,
1179 &start_column, 0);
1180 clang_getSpellingLocation(end, &end_file, &end_line, &end_column, 0);
1181 if (clang_equalLocations(start, end)) {
1182 /* Insertion. */
1183 if (start_file == file)
1184 fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n",
1185 clang_getCString(insertion_text), start_line, start_column);
1186 } else if (strcmp(clang_getCString(insertion_text), "") == 0) {
1187 /* Removal. */
1188 if (start_file == file && end_file == file) {
1189 fprintf(out, "FIX-IT: Remove ");
1190 PrintExtent(out, start_line, start_column, end_line, end_column);
1191 fprintf(out, "\n");
1192 }
1193 } else {
1194 /* Replacement. */
1195 if (start_file == end_file) {
1196 fprintf(out, "FIX-IT: Replace ");
1197 PrintExtent(out, start_line, start_column, end_line, end_column);
1198 fprintf(out, " with \"%s\"\n", clang_getCString(insertion_text));
1199 }
1200 }
1201 clang_disposeString(insertion_text);
1202 }
1203}
1204
1205void PrintDiagnosticSet(CXDiagnosticSet Set) {
1206 int i = 0, n = clang_getNumDiagnosticsInSet(Set);
1207 for ( ; i != n ; ++i) {
1208 CXDiagnostic Diag = clang_getDiagnosticInSet(Set, i);
1209 CXDiagnosticSet ChildDiags = clang_getChildDiagnostics(Diag);
1210 PrintDiagnostic(Diag);
1211 if (ChildDiags)
1212 PrintDiagnosticSet(ChildDiags);
1213 }
1214}
1215
1216void PrintDiagnostics(CXTranslationUnit TU) {
1217 CXDiagnosticSet TUSet = clang_getDiagnosticSetFromTU(TU);
1218 PrintDiagnosticSet(TUSet);
1219 clang_disposeDiagnosticSet(TUSet);
1220}
1221
1222void PrintMemoryUsage(CXTranslationUnit TU) {
1223 unsigned long total = 0;
1224 unsigned i = 0;
1225 CXTUResourceUsage usage = clang_getCXTUResourceUsage(TU);
1226 fprintf(stderrstderr, "Memory usage:\n");
1227 for (i = 0 ; i != usage.numEntries; ++i) {
1228 const char *name = clang_getTUResourceUsageName(usage.entries[i].kind);
1229 unsigned long amount = usage.entries[i].amount;
1230 total += amount;
1231 fprintf(stderrstderr, " %s : %ld bytes (%f MBytes)\n", name, amount,
1232 ((double) amount)/(1024*1024));
1233 }
1234 fprintf(stderrstderr, " TOTAL = %ld bytes (%f MBytes)\n", total,
1235 ((double) total)/(1024*1024));
1236 clang_disposeCXTUResourceUsage(usage);
1237}
1238
1239/******************************************************************************/
1240/* Logic for testing traversal. */
1241/******************************************************************************/
1242
1243static void PrintCursorExtent(CXCursor C) {
1244 CXSourceRange extent = clang_getCursorExtent(C);
1245 PrintRange(extent, "Extent");
1246}
1247
1248/* Data used by the visitors. */
1249typedef struct {
1250 CXTranslationUnit TU;
1251 enum CXCursorKind *Filter;
1252 const char *CommentSchemaFile;
1253} VisitorData;
1254
1255
1256enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor,
1257 CXCursor Parent,
1258 CXClientData ClientData) {
1259 VisitorData *Data = (VisitorData *)ClientData;
1260 if (!Data->Filter || (Cursor.kind == *(enum CXCursorKind *)Data->Filter)) {
1261 CXSourceLocation Loc = clang_getCursorLocation(Cursor);
1262 unsigned line, column;
1263 clang_getSpellingLocation(Loc, 0, &line, &column, 0);
1264 printf("// %s: %s:%d:%d: ", FileCheckPrefix,
1265 GetCursorSource(Cursor), line, column);
1266 PrintCursor(Cursor, Data->CommentSchemaFile);
1267 PrintCursorExtent(Cursor);
1268 if (clang_isDeclaration(Cursor.kind)) {
1269 enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
1270 const char *accessStr = 0;
1271
1272 switch (access) {
1273 case CX_CXXInvalidAccessSpecifier: break;
1274 case CX_CXXPublic:
1275 accessStr = "public"; break;
1276 case CX_CXXProtected:
1277 accessStr = "protected"; break;
1278 case CX_CXXPrivate:
1279 accessStr = "private"; break;
1280 }
1281
1282 if (accessStr)
1283 printf(" [access=%s]", accessStr);
1284 }
1285 printf("\n");
1286 return CXChildVisit_Recurse;
1287 }
1288
1289 return CXChildVisit_Continue;
1290}
1291
1292static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
1293 CXCursor Parent,
1294 CXClientData ClientData) {
1295 const char *startBuf, *endBuf;
1296 unsigned startLine, startColumn, endLine, endColumn, curLine, curColumn;
1297 CXCursor Ref;
1298 VisitorData *Data = (VisitorData *)ClientData;
1299
1300 if (Cursor.kind != CXCursor_FunctionDecl ||
1301 !clang_isCursorDefinition(Cursor))
1302 return CXChildVisit_Continue;
1303
1304 clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,
1305 &startLine, &startColumn,
1306 &endLine, &endColumn);
1307 /* Probe the entire body, looking for both decls and refs. */
1308 curLine = startLine;
1309 curColumn = startColumn;
1310
1311 while (startBuf < endBuf) {
1312 CXSourceLocation Loc;
1313 CXFile file;
1314 CXString source;
1315
1316 if (*startBuf == '\n') {
1317 startBuf++;
1318 curLine++;
1319 curColumn = 1;
1320 } else if (*startBuf != '\t')
1321 curColumn++;
1322
1323 Loc = clang_getCursorLocation(Cursor);
1324 clang_getSpellingLocation(Loc, &file, 0, 0, 0);
1325
1326 source = clang_getFileName(file);
1327 if (clang_getCString(source)) {
1328 CXSourceLocation RefLoc
1329 = clang_getLocation(Data->TU, file, curLine, curColumn);
1330 Ref = clang_getCursor(Data->TU, RefLoc);
1331 if (Ref.kind == CXCursor_NoDeclFound) {
1332 /* Nothing found here; that's fine. */
1333 } else if (Ref.kind != CXCursor_FunctionDecl) {
1334 printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
1335 curLine, curColumn);
1336 PrintCursor(Ref, Data->CommentSchemaFile);
1337 printf("\n");
1338 }
1339 }
1340 clang_disposeString(source);
1341 startBuf++;
1342 }
1343
1344 return CXChildVisit_Continue;
1345}
1346
1347/******************************************************************************/
1348/* USR testing. */
1349/******************************************************************************/
1350
1351enum CXChildVisitResult USRVisitor(CXCursor C, CXCursor parent,
1352 CXClientData ClientData) {
1353 VisitorData *Data = (VisitorData *)ClientData;
1354 if (!Data->Filter || (C.kind == *(enum CXCursorKind *)Data->Filter)) {
1355 CXString USR = clang_getCursorUSR(C);
1356 const char *cstr = clang_getCString(USR);
1357 if (!cstr || cstr[0] == '\0') {
1358 clang_disposeString(USR);
1359 return CXChildVisit_Recurse;
1360 }
1361 printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C), cstr);
1362
1363 PrintCursorExtent(C);
1364 printf("\n");
1365 clang_disposeString(USR);
1366
1367 return CXChildVisit_Recurse;
1368 }
1369
1370 return CXChildVisit_Continue;
1371}
1372
1373/******************************************************************************/
1374/* Inclusion stack testing. */
1375/******************************************************************************/
1376
1377void InclusionVisitor(CXFile includedFile, CXSourceLocation *includeStack,
1378 unsigned includeStackLen, CXClientData data) {
1379
1380 unsigned i;
1381 CXString fname;
1382
1383 fname = clang_getFileName(includedFile);
1384 printf("file: %s\nincluded by:\n", clang_getCString(fname));
1385 clang_disposeString(fname);
1386
1387 for (i = 0; i < includeStackLen; ++i) {
1388 CXFile includingFile;
1389 unsigned line, column;
1390 clang_getSpellingLocation(includeStack[i], &includingFile, &line,
1391 &column, 0);
1392 fname = clang_getFileName(includingFile);
1393 printf(" %s:%d:%d\n", clang_getCString(fname), line, column);
1394 clang_disposeString(fname);
1395 }
1396 printf("\n");
1397}
1398
1399void PrintInclusionStack(CXTranslationUnit TU) {
1400 clang_getInclusions(TU, InclusionVisitor, NULL((void*)0));
1401}
1402
1403/******************************************************************************/
1404/* Linkage testing. */
1405/******************************************************************************/
1406
1407static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
1408 CXClientData d) {
1409 const char *linkage = 0;
1410
1411 if (clang_isInvalid(clang_getCursorKind(cursor)))
1412 return CXChildVisit_Recurse;
1413
1414 switch (clang_getCursorLinkage(cursor)) {
1415 case CXLinkage_Invalid: break;
1416 case CXLinkage_NoLinkage: linkage = "NoLinkage"; break;
1417 case CXLinkage_Internal: linkage = "Internal"; break;
1418 case CXLinkage_UniqueExternal: linkage = "UniqueExternal"; break;
1419 case CXLinkage_External: linkage = "External"; break;
1420 }
1421
1422 if (linkage) {
1423 PrintCursor(cursor, NULL((void*)0));
1424 printf("linkage=%s\n", linkage);
1425 }
1426
1427 return CXChildVisit_Recurse;
1428}
1429
1430/******************************************************************************/
1431/* Visibility testing. */
1432/******************************************************************************/
1433
1434static enum CXChildVisitResult PrintVisibility(CXCursor cursor, CXCursor p,
1435 CXClientData d) {
1436 const char *visibility = 0;
1437
1438 if (clang_isInvalid(clang_getCursorKind(cursor)))
1439 return CXChildVisit_Recurse;
1440
1441 switch (clang_getCursorVisibility(cursor)) {
1442 case CXVisibility_Invalid: break;
1443 case CXVisibility_Hidden: visibility = "Hidden"; break;
1444 case CXVisibility_Protected: visibility = "Protected"; break;
1445 case CXVisibility_Default: visibility = "Default"; break;
1446 }
1447
1448 if (visibility) {
1449 PrintCursor(cursor, NULL((void*)0));
1450 printf("visibility=%s\n", visibility);
1451 }
1452
1453 return CXChildVisit_Recurse;
1454}
1455
1456/******************************************************************************/
1457/* Typekind testing. */
1458/******************************************************************************/
1459
1460static void PrintTypeAndTypeKind(CXType T, const char *Format) {
1461 CXString TypeSpelling, TypeKindSpelling;
1462
1463 TypeSpelling = clang_getTypeSpelling(T);
1464 TypeKindSpelling = clang_getTypeKindSpelling(T.kind);
1465 printf(Format,
1466 clang_getCString(TypeSpelling),
1467 clang_getCString(TypeKindSpelling));
1468 clang_disposeString(TypeSpelling);
1469 clang_disposeString(TypeKindSpelling);
1470}
1471
1472static enum CXVisitorResult FieldVisitor(CXCursor C,
1473 CXClientData client_data) {
1474 (*(int *) client_data)+=1;
1475 return CXVisit_Continue;
1476}
1477
1478static void PrintTypeTemplateArgs(CXType T, const char *Format) {
1479 int NumTArgs = clang_Type_getNumTemplateArguments(T);
1480 if (NumTArgs != -1 && NumTArgs != 0) {
1481 int i;
1482 CXType TArg;
1483 printf(Format, NumTArgs);
1484 for (i = 0; i < NumTArgs; ++i) {
1485 TArg = clang_Type_getTemplateArgumentAsType(T, i);
1486 if (TArg.kind != CXType_Invalid) {
1487 PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]");
1488 }
1489 }
1490 /* Ensure that the returned type is invalid when indexing off-by-one. */
1491 TArg = clang_Type_getTemplateArgumentAsType(T, i);
1492 assert(TArg.kind == CXType_Invalid)((void) sizeof ((TArg.kind == CXType_Invalid) ? 1 : 0), __extension__
({ if (TArg.kind == CXType_Invalid) ; else __assert_fail ("TArg.kind == CXType_Invalid"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 1492, __extension__ __PRETTY_FUNCTION__); }))
;
1493 printf("]");
1494 }
1495}
1496
1497static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
1498 CXClientData d) {
1499 if (!clang_isInvalid(clang_getCursorKind(cursor))) {
1500 CXType T = clang_getCursorType(cursor);
1501 enum CXRefQualifierKind RQ = clang_Type_getCXXRefQualifier(T);
1502 PrintCursor(cursor, NULL((void*)0));
1503 PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
1504 if (clang_isConstQualifiedType(T))
1505 printf(" const");
1506 if (clang_isVolatileQualifiedType(T))
1507 printf(" volatile");
1508 if (clang_isRestrictQualifiedType(T))
1509 printf(" restrict");
1510 if (RQ == CXRefQualifier_LValue)
1511 printf(" lvalue-ref-qualifier");
1512 if (RQ == CXRefQualifier_RValue)
1513 printf(" rvalue-ref-qualifier");
1514 /* Print the template argument types if they exist. */
1515 PrintTypeTemplateArgs(T, " [templateargs/%d=");
1516 /* Print the canonical type if it is different. */
1517 {
1518 CXType CT = clang_getCanonicalType(T);
1519 if (!clang_equalTypes(T, CT)) {
1520 PrintTypeAndTypeKind(CT, " [canonicaltype=%s] [canonicaltypekind=%s]");
1521 PrintTypeTemplateArgs(CT, " [canonicaltemplateargs/%d=");
1522 }
1523 }
1524 /* Print the return type if it exists. */
1525 {
1526 CXType RT = clang_getCursorResultType(cursor);
1527 if (RT.kind != CXType_Invalid) {
1528 PrintTypeAndTypeKind(RT, " [resulttype=%s] [resulttypekind=%s]");
1529 }
1530 }
1531 /* Print the argument types if they exist. */
1532 {
1533 int NumArgs = clang_Cursor_getNumArguments(cursor);
1534 if (NumArgs != -1 && NumArgs != 0) {
1535 int i;
1536 printf(" [args=");
1537 for (i = 0; i < NumArgs; ++i) {
1538 CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
1539 if (T.kind != CXType_Invalid) {
1540 PrintTypeAndTypeKind(T, " [%s] [%s]");
1541 }
1542 }
1543 printf("]");
1544 }
1545 }
1546 /* Print if this is a non-POD type. */
1547 printf(" [isPOD=%d]", clang_isPODType(T));
1548 /* Print the pointee type. */
1549 {
1550 CXType PT = clang_getPointeeType(T);
1551 if (PT.kind != CXType_Invalid) {
1552 PrintTypeAndTypeKind(PT, " [pointeetype=%s] [pointeekind=%s]");
1553 }
1554 }
1555 /* Print the number of fields if they exist. */
1556 {
1557 int numFields = 0;
1558 if (clang_Type_visitFields(T, FieldVisitor, &numFields)){
1559 if (numFields != 0) {
1560 printf(" [nbFields=%d]", numFields);
1561 }
1562 /* Print if it is an anonymous record. */
1563 {
1564 unsigned isAnon = clang_Cursor_isAnonymous(cursor);
1565 if (isAnon != 0) {
1566 printf(" [isAnon=%d]", isAnon);
1567 }
1568 }
1569 }
1570 }
1571
1572 printf("\n");
1573 }
1574 return CXChildVisit_Recurse;
1575}
1576
1577static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
1578 CXClientData d) {
1579 CXType T;
1580 enum CXCursorKind K = clang_getCursorKind(cursor);
1581 if (clang_isInvalid(K))
1582 return CXChildVisit_Recurse;
1583 T = clang_getCursorType(cursor);
1584 PrintCursor(cursor, NULL((void*)0));
1585 PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
1586 /* Print the type sizeof if applicable. */
1587 {
1588 long long Size = clang_Type_getSizeOf(T);
1589 if (Size >= 0 || Size < -1 ) {
1590 printf(" [sizeof=%lld]", Size);
1591 }
1592 }
1593 /* Print the type alignof if applicable. */
1594 {
1595 long long Align = clang_Type_getAlignOf(T);
1596 if (Align >= 0 || Align < -1) {
1597 printf(" [alignof=%lld]", Align);
1598 }
1599 }
1600 /* Print the record field offset if applicable. */
1601 {
1602 CXString FieldSpelling = clang_getCursorSpelling(cursor);
1603 const char *FieldName = clang_getCString(FieldSpelling);
1604 /* recurse to get the first parent record that is not anonymous. */
1605 unsigned RecordIsAnonymous = 0;
1606 if (clang_getCursorKind(cursor) == CXCursor_FieldDecl) {
1607 CXCursor Record;
1608 CXCursor Parent = p;
1609 do {
1610 Record = Parent;
1611 Parent = clang_getCursorSemanticParent(Record);
1612 RecordIsAnonymous = clang_Cursor_isAnonymous(Record);
1613 /* Recurse as long as the parent is a CXType_Record and the Record
1614 is anonymous */
1615 } while ( clang_getCursorType(Parent).kind == CXType_Record &&
1616 RecordIsAnonymous > 0);
1617 {
1618 long long Offset = clang_Type_getOffsetOf(clang_getCursorType(Record),
1619 FieldName);
1620 long long Offset2 = clang_Cursor_getOffsetOfField(cursor);
1621 if (Offset == Offset2){
1622 printf(" [offsetof=%lld]", Offset);
1623 } else {
1624 /* Offsets will be different in anonymous records. */
1625 printf(" [offsetof=%lld/%lld]", Offset, Offset2);
1626 }
1627 }
1628 }
1629 clang_disposeString(FieldSpelling);
1630 }
1631 /* Print if its a bitfield */
1632 {
1633 int IsBitfield = clang_Cursor_isBitField(cursor);
1634 if (IsBitfield)
1635 printf(" [BitFieldSize=%d]", clang_getFieldDeclBitWidth(cursor));
1636 }
1637 printf("\n");
1638 return CXChildVisit_Recurse;
1639}
1640
1641/******************************************************************************/
1642/* Mangling testing. */
1643/******************************************************************************/
1644
1645static enum CXChildVisitResult PrintMangledName(CXCursor cursor, CXCursor p,
1646 CXClientData d) {
1647 CXString MangledName;
1648 if (clang_isUnexposed(clang_getCursorKind(cursor)))
1649 return CXChildVisit_Recurse;
1650 PrintCursor(cursor, NULL((void*)0));
1651 MangledName = clang_Cursor_getMangling(cursor);
1652 printf(" [mangled=%s]\n", clang_getCString(MangledName));
1653 clang_disposeString(MangledName);
1654 return CXChildVisit_Continue;
1655}
1656
1657static enum CXChildVisitResult PrintManglings(CXCursor cursor, CXCursor p,
1658 CXClientData d) {
1659 unsigned I, E;
1660 CXStringSet *Manglings = NULL((void*)0);
1661 if (clang_isUnexposed(clang_getCursorKind(cursor)))
1662 return CXChildVisit_Recurse;
1663 if (!clang_isDeclaration(clang_getCursorKind(cursor)))
1664 return CXChildVisit_Recurse;
1665 if (clang_getCursorKind(cursor) == CXCursor_ParmDecl)
1666 return CXChildVisit_Continue;
1667 PrintCursor(cursor, NULL((void*)0));
1668 Manglings = clang_Cursor_getCXXManglings(cursor);
1669 if (Manglings) {
1670 for (I = 0, E = Manglings->Count; I < E; ++I)
1671 printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I]));
1672 clang_disposeStringSet(Manglings);
1673 printf("\n");
1674 }
1675 Manglings = clang_Cursor_getObjCManglings(cursor);
1676 if (Manglings) {
1677 for (I = 0, E = Manglings->Count; I < E; ++I)
1678 printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I]));
1679 clang_disposeStringSet(Manglings);
1680 printf("\n");
1681 }
1682 return CXChildVisit_Recurse;
1683}
1684
1685/******************************************************************************/
1686/* Bitwidth testing. */
1687/******************************************************************************/
1688
1689static enum CXChildVisitResult PrintBitWidth(CXCursor cursor, CXCursor p,
1690 CXClientData d) {
1691 int Bitwidth;
1692 if (clang_getCursorKind(cursor) != CXCursor_FieldDecl)
1693 return CXChildVisit_Recurse;
1694
1695 Bitwidth = clang_getFieldDeclBitWidth(cursor);
1696 if (Bitwidth >= 0) {
1697 PrintCursor(cursor, NULL((void*)0));
1698 printf(" bitwidth=%d\n", Bitwidth);
1699 }
1700
1701 return CXChildVisit_Recurse;
1702}
1703
1704/******************************************************************************/
1705/* Type declaration testing */
1706/******************************************************************************/
1707
1708static enum CXChildVisitResult PrintTypeDeclaration(CXCursor cursor, CXCursor p,
1709 CXClientData d) {
1710 CXCursor typeDeclaration = clang_getTypeDeclaration(clang_getCursorType(cursor));
1711
1712 if (clang_isDeclaration(typeDeclaration.kind)) {
1713 PrintCursor(cursor, NULL((void*)0));
1714 PrintTypeAndTypeKind(clang_getCursorType(typeDeclaration), " [typedeclaration=%s] [typekind=%s]\n");
1715 }
1716
1717 return CXChildVisit_Recurse;
1718}
1719
1720/******************************************************************************/
1721/* Target information testing. */
1722/******************************************************************************/
1723
1724static int print_target_info(int argc, const char **argv) {
1725 CXIndex Idx;
1726 CXTranslationUnit TU;
1727 CXTargetInfo TargetInfo;
1728 CXString Triple;
1729 const char *FileName;
1730 enum CXErrorCode Err;
1731 int PointerWidth;
1732
1733 if (argc == 0) {
1734 fprintf(stderrstderr, "No filename specified\n");
1735 return 1;
1736 }
1737
1738 FileName = argv[1];
1739
1740 Idx = clang_createIndex(0, 1);
1741 Err = clang_parseTranslationUnit2(Idx, FileName, argv, argc, NULL((void*)0), 0,
1742 getDefaultParsingOptions(), &TU);
1743 if (Err != CXError_Success) {
1744 fprintf(stderrstderr, "Couldn't parse translation unit!\n");
1745 describeLibclangFailure(Err);
1746 clang_disposeIndex(Idx);
1747 return 1;
1748 }
1749
1750 TargetInfo = clang_getTranslationUnitTargetInfo(TU);
1751
1752 Triple = clang_TargetInfo_getTriple(TargetInfo);
1753 printf("TargetTriple: %s\n", clang_getCString(Triple));
1754 clang_disposeString(Triple);
1755
1756 PointerWidth = clang_TargetInfo_getPointerWidth(TargetInfo);
1757 printf("PointerWidth: %d\n", PointerWidth);
1758
1759 clang_TargetInfo_dispose(TargetInfo);
1760 clang_disposeTranslationUnit(TU);
1761 clang_disposeIndex(Idx);
1762 return 0;
1763}
1764
1765/******************************************************************************/
1766/* Loading ASTs/source. */
1767/******************************************************************************/
1768
1769static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
1770 const char *filter, const char *prefix,
1771 CXCursorVisitor Visitor,
1772 PostVisitTU PV,
1773 const char *CommentSchemaFile) {
1774
1775 if (prefix)
1776 FileCheckPrefix = prefix;
1777
1778 if (Visitor) {
1779 enum CXCursorKind K = CXCursor_NotImplemented;
1780 enum CXCursorKind *ck = &K;
1781 VisitorData Data;
1782
1783 /* Perform some simple filtering. */
1784 if (!strcmp(filter, "all") || !strcmp(filter, "local")) ck = NULL((void*)0);
1785 else if (!strcmp(filter, "all-display") ||
1786 !strcmp(filter, "local-display")) {
1787 ck = NULL((void*)0);
1788 wanted_display_type = DisplayType_DisplayName;
1789 }
1790 else if (!strcmp(filter, "all-pretty") ||
1791 !strcmp(filter, "local-pretty")) {
1792 ck = NULL((void*)0);
1793 wanted_display_type = DisplayType_Pretty;
1794 }
1795 else if (!strcmp(filter, "none")) K = (enum CXCursorKind) ~0;
1796 else if (!strcmp(filter, "category")) K = CXCursor_ObjCCategoryDecl;
1797 else if (!strcmp(filter, "interface")) K = CXCursor_ObjCInterfaceDecl;
1798 else if (!strcmp(filter, "protocol")) K = CXCursor_ObjCProtocolDecl;
1799 else if (!strcmp(filter, "function")) K = CXCursor_FunctionDecl;
1800 else if (!strcmp(filter, "typedef")) K = CXCursor_TypedefDecl;
1801 else if (!strcmp(filter, "scan-function")) Visitor = FunctionScanVisitor;
1802 else {
1803 fprintf(stderrstderr, "Unknown filter for -test-load-tu: %s\n", filter);
1804 return 1;
1805 }
1806
1807 Data.TU = TU;
1808 Data.Filter = ck;
1809 Data.CommentSchemaFile = CommentSchemaFile;
1810 clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
1811 }
1812
1813 if (PV)
1814 PV(TU);
1815
1816 PrintDiagnostics(TU);
1817 if (checkForErrors(TU) != 0) {
1818 clang_disposeTranslationUnit(TU);
1819 return -1;
1820 }
1821
1822 clang_disposeTranslationUnit(TU);
1823 return 0;
1824}
1825
1826int perform_test_load_tu(const char *file, const char *filter,
1827 const char *prefix, CXCursorVisitor Visitor,
1828 PostVisitTU PV) {
1829 CXIndex Idx;
1830 CXTranslationUnit TU;
1831 int result;
1832 Idx = clang_createIndex(/* excludeDeclsFromPCH */
1833 !strcmp(filter, "local") ? 1 : 0,
1834 /* displayDiagnostics=*/1);
1835
1836 if (!CreateTranslationUnit(Idx, file, &TU)) {
1837 clang_disposeIndex(Idx);
1838 return 1;
1839 }
1840
1841 result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV, NULL((void*)0));
1842 clang_disposeIndex(Idx);
1843 return result;
1844}
1845
1846int perform_test_load_source(int argc, const char **argv,
1847 const char *filter, CXCursorVisitor Visitor,
1848 PostVisitTU PV) {
1849 CXIndex Idx;
1850 CXTranslationUnit TU;
1851 const char *CommentSchemaFile;
1852 struct CXUnsavedFile *unsaved_files = 0;
1853 int num_unsaved_files = 0;
1854 enum CXErrorCode Err;
1855 int result;
1856 unsigned Repeats = 0;
1857 unsigned I;
1858 const char *InvocationPath;
1859
1860 Idx = clang_createIndex(/* excludeDeclsFromPCH */
1861 (!strcmp(filter, "local") ||
1862 !strcmp(filter, "local-display") ||
1863 !strcmp(filter, "local-pretty"))
1864 ? 1
1865 : 0,
1866 /* displayDiagnostics=*/1);
1867 InvocationPath = getenv("CINDEXTEST_INVOCATION_EMISSION_PATH");
1868 if (InvocationPath)
1869 clang_CXIndex_setInvocationEmissionPathOption(Idx, InvocationPath);
1870
1871 if ((CommentSchemaFile = parse_comments_schema(argc, argv))) {
1872 argc--;
1873 argv++;
1874 }
1875
1876 if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
1877 clang_disposeIndex(Idx);
1878 return -1;
1879 }
1880
1881 if (getenv("CINDEXTEST_EDITING"))
1882 Repeats = 5;
1883
1884 Err = clang_parseTranslationUnit2(Idx, 0,
1885 argv + num_unsaved_files,
1886 argc - num_unsaved_files,
1887 unsaved_files, num_unsaved_files,
1888 getDefaultParsingOptions(), &TU);
1889 if (Err != CXError_Success) {
1890 fprintf(stderrstderr, "Unable to load translation unit!\n");
1891 describeLibclangFailure(Err);
1892 free_remapped_files(unsaved_files, num_unsaved_files);
1893 clang_disposeIndex(Idx);
1894 return 1;
1895 }
1896
1897 for (I = 0; I != Repeats; ++I) {
1898 if (checkForErrors(TU) != 0)
1899 return -1;
1900
1901 if (Repeats > 1) {
1902 clang_suspendTranslationUnit(TU);
1903
1904 Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
1905 clang_defaultReparseOptions(TU));
1906 if (Err != CXError_Success) {
1907 describeLibclangFailure(Err);
1908 free_remapped_files(unsaved_files, num_unsaved_files);
1909 clang_disposeIndex(Idx);
1910 return 1;
1911 }
1912 }
1913 }
1914
1915 result = perform_test_load(Idx, TU, filter, NULL((void*)0), Visitor, PV,
1916 CommentSchemaFile);
1917 free_remapped_files(unsaved_files, num_unsaved_files);
1918 clang_disposeIndex(Idx);
1919 return result;
1920}
1921
1922int perform_test_reparse_source(int argc, const char **argv, int trials,
1923 const char *filter, CXCursorVisitor Visitor,
1924 PostVisitTU PV) {
1925 CXIndex Idx;
1926 CXTranslationUnit TU;
1927 struct CXUnsavedFile *unsaved_files = 0;
1928 int num_unsaved_files = 0;
1929 int compiler_arg_idx = 0;
1930 enum CXErrorCode Err;
1931 int result, i;
1932 int trial;
1933 int remap_after_trial = 0;
1934 char *endptr = 0;
1935
1936 Idx = clang_createIndex(/* excludeDeclsFromPCH */
1937 !strcmp(filter, "local") ? 1 : 0,
1938 /* displayDiagnostics=*/1);
1939
1940 if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
1941 clang_disposeIndex(Idx);
1942 return -1;
1943 }
1944
1945 for (i = 0; i < argc; ++i) {
1946 if (strcmp(argv[i], "--") == 0)
1947 break;
1948 }
1949 if (i < argc)
1950 compiler_arg_idx = i+1;
1951 if (num_unsaved_files > compiler_arg_idx)
1952 compiler_arg_idx = num_unsaved_files;
1953
1954 /* Load the initial translation unit -- we do this without honoring remapped
1955 * files, so that we have a way to test results after changing the source. */
1956 Err = clang_parseTranslationUnit2(Idx, 0,
1957 argv + compiler_arg_idx,
1958 argc - compiler_arg_idx,
1959 0, 0, getDefaultParsingOptions(), &TU);
1960 if (Err != CXError_Success) {
1961 fprintf(stderrstderr, "Unable to load translation unit!\n");
1962 describeLibclangFailure(Err);
1963 free_remapped_files(unsaved_files, num_unsaved_files);
1964 clang_disposeIndex(Idx);
1965 return 1;
1966 }
1967
1968 if (checkForErrors(TU) != 0)
1969 return -1;
1970
1971 if (getenv("CINDEXTEST_REMAP_AFTER_TRIAL")) {
1972 remap_after_trial =
1973 strtol(getenv("CINDEXTEST_REMAP_AFTER_TRIAL"), &endptr, 10);
1974 }
1975
1976 for (trial = 0; trial < trials; ++trial) {
1977 free_remapped_files(unsaved_files, num_unsaved_files);
1978 if (parse_remapped_files_with_try(trial, argc, argv, 0,
1979 &unsaved_files, &num_unsaved_files)) {
1980 clang_disposeTranslationUnit(TU);
1981 clang_disposeIndex(Idx);
1982 return -1;
1983 }
1984
1985 Err = clang_reparseTranslationUnit(
1986 TU,
1987 trial >= remap_after_trial ? num_unsaved_files : 0,
1988 trial >= remap_after_trial ? unsaved_files : 0,
1989 clang_defaultReparseOptions(TU));
1990 if (Err != CXError_Success) {
1991 fprintf(stderrstderr, "Unable to reparse translation unit!\n");
1992 describeLibclangFailure(Err);
1993 clang_disposeTranslationUnit(TU);
1994 free_remapped_files(unsaved_files, num_unsaved_files);
1995 clang_disposeIndex(Idx);
1996 return -1;
1997 }
1998
1999 if (checkForErrors(TU) != 0)
2000 return -1;
2001 }
2002
2003 result = perform_test_load(Idx, TU, filter, NULL((void*)0), Visitor, PV, NULL((void*)0));
2004
2005 free_remapped_files(unsaved_files, num_unsaved_files);
2006 clang_disposeIndex(Idx);
2007 return result;
2008}
2009
2010static int perform_single_file_parse(const char *filename) {
2011 CXIndex Idx;
2012 CXTranslationUnit TU;
2013 enum CXErrorCode Err;
2014 int result;
2015
2016 Idx = clang_createIndex(/* excludeDeclsFromPCH */1,
2017 /* displayDiagnostics=*/1);
2018
2019 Err = clang_parseTranslationUnit2(Idx, filename,
2020 /*command_line_args=*/NULL((void*)0),
2021 /*num_command_line_args=*/0,
2022 /*unsaved_files=*/NULL((void*)0),
2023 /*num_unsaved_files=*/0,
2024 CXTranslationUnit_SingleFileParse, &TU);
2025 if (Err != CXError_Success) {
2026 fprintf(stderrstderr, "Unable to load translation unit!\n");
2027 describeLibclangFailure(Err);
2028 clang_disposeIndex(Idx);
2029 return 1;
2030 }
2031
2032 result = perform_test_load(Idx, TU, /*filter=*/"all", /*prefix=*/NULL((void*)0), FilteredPrintingVisitor, /*PostVisit=*/NULL((void*)0),
2033 /*CommentSchemaFile=*/NULL((void*)0));
2034 clang_disposeIndex(Idx);
2035 return result;
2036}
2037
2038/******************************************************************************/
2039/* Logic for testing clang_getCursor(). */
2040/******************************************************************************/
2041
2042static void print_cursor_file_scan(CXTranslationUnit TU, CXCursor cursor,
2043 unsigned start_line, unsigned start_col,
2044 unsigned end_line, unsigned end_col,
2045 const char *prefix) {
2046 printf("// %s: ", FileCheckPrefix);
2047 if (prefix)
2048 printf("-%s", prefix);
2049 PrintExtent(stdoutstdout, start_line, start_col, end_line, end_col);
2050 printf(" ");
2051 PrintCursor(cursor, NULL((void*)0));
2052 printf("\n");
2053}
2054
2055static int perform_file_scan(const char *ast_file, const char *source_file,
2056 const char *prefix) {
2057 CXIndex Idx;
2058 CXTranslationUnit TU;
2059 FILE *fp;
2060 CXCursor prevCursor = clang_getNullCursor();
2061 CXFile file;
2062 unsigned line = 1, col = 1;
2063 unsigned start_line = 1, start_col = 1;
2064
2065 if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
2066 /* displayDiagnostics=*/1))) {
2067 fprintf(stderrstderr, "Could not create Index\n");
2068 return 1;
2069 }
2070
2071 if (!CreateTranslationUnit(Idx, ast_file, &TU))
2072 return 1;
2073
2074 if ((fp = fopen(source_file, "r")) == NULL((void*)0)) {
2075 fprintf(stderrstderr, "Could not open '%s'\n", source_file);
2076 clang_disposeTranslationUnit(TU);
2077 return 1;
2078 }
2079
2080 file = clang_getFile(TU, source_file);
2081 for (;;) {
2082 CXCursor cursor;
2083 int c = fgetc(fp);
2084
2085 if (c == '\n') {
2086 ++line;
2087 col = 1;
2088 } else
2089 ++col;
2090
2091 /* Check the cursor at this position, and dump the previous one if we have
2092 * found something new.
2093 */
2094 cursor = clang_getCursor(TU, clang_getLocation(TU, file, line, col));
2095 if ((c == EOF(-1) || !clang_equalCursors(cursor, prevCursor)) &&
2096 prevCursor.kind != CXCursor_InvalidFile) {
2097 print_cursor_file_scan(TU, prevCursor, start_line, start_col,
2098 line, col, prefix);
2099 start_line = line;
2100 start_col = col;
2101 }
2102 if (c == EOF(-1))
2103 break;
2104
2105 prevCursor = cursor;
2106 }
2107
2108 fclose(fp);
2109 clang_disposeTranslationUnit(TU);
2110 clang_disposeIndex(Idx);
2111 return 0;
2112}
2113
2114/******************************************************************************/
2115/* Logic for testing clang code completion. */
2116/******************************************************************************/
2117
2118/* Parse file:line:column from the input string. Returns 0 on success, non-zero
2119 on failure. If successful, the pointer *filename will contain newly-allocated
2120 memory (that will be owned by the caller) to store the file name. */
2121int parse_file_line_column(const char *input, char **filename, unsigned *line,
2122 unsigned *column, unsigned *second_line,
2123 unsigned *second_column) {
2124 /* Find the second colon. */
2125 const char *last_colon = strrchr(input, ':');
2126 unsigned values[4], i;
2127 unsigned num_values = (second_line && second_column)? 4 : 2;
2128
2129 char *endptr = 0;
2130 if (!last_colon || last_colon == input) {
2131 if (num_values == 4)
2132 fprintf(stderrstderr, "could not parse filename:line:column:line:column in "
2133 "'%s'\n", input);
2134 else
2135 fprintf(stderrstderr, "could not parse filename:line:column in '%s'\n", input);
2136 return 1;
2137 }
2138
2139 for (i = 0; i != num_values; ++i) {
2140 const char *prev_colon;
2141
2142 /* Parse the next line or column. */
2143 values[num_values - i - 1] = strtol(last_colon + 1, &endptr, 10);
2144 if (*endptr != 0 && *endptr != ':') {
2145 fprintf(stderrstderr, "could not parse %s in '%s'\n",
2146 (i % 2 ? "column" : "line"), input);
2147 return 1;
2148 }
2149
2150 if (i + 1 == num_values)
2151 break;
2152
2153 /* Find the previous colon. */
2154 prev_colon = last_colon - 1;
2155 while (prev_colon != input && *prev_colon != ':')
2156 --prev_colon;
2157 if (prev_colon == input) {
2158 fprintf(stderrstderr, "could not parse %s in '%s'\n",
2159 (i % 2 == 0? "column" : "line"), input);
2160 return 1;
2161 }
2162
2163 last_colon = prev_colon;
2164 }
2165
2166 *line = values[0];
2167 *column = values[1];
2168
2169 if (second_line && second_column) {
2170 *second_line = values[2];
2171 *second_column = values[3];
2172 }
2173
2174 /* Copy the file name. */
2175 *filename = (char*)malloc(last_colon - input + 1);
2176 assert(*filename)((void) sizeof ((*filename) ? 1 : 0), __extension__ ({ if (*filename
) ; else __assert_fail ("*filename", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 2176, __extension__ __PRETTY_FUNCTION__); }))
;
2177 memcpy(*filename, input, last_colon - input);
2178 (*filename)[last_colon - input] = 0;
2179 return 0;
2180}
2181
2182const char *
2183clang_getCompletionChunkKindSpelling(enum CXCompletionChunkKind Kind) {
2184 switch (Kind) {
2185 case CXCompletionChunk_Optional: return "Optional";
2186 case CXCompletionChunk_TypedText: return "TypedText";
2187 case CXCompletionChunk_Text: return "Text";
2188 case CXCompletionChunk_Placeholder: return "Placeholder";
2189 case CXCompletionChunk_Informative: return "Informative";
2190 case CXCompletionChunk_CurrentParameter: return "CurrentParameter";
2191 case CXCompletionChunk_LeftParen: return "LeftParen";
2192 case CXCompletionChunk_RightParen: return "RightParen";
2193 case CXCompletionChunk_LeftBracket: return "LeftBracket";
2194 case CXCompletionChunk_RightBracket: return "RightBracket";
2195 case CXCompletionChunk_LeftBrace: return "LeftBrace";
2196 case CXCompletionChunk_RightBrace: return "RightBrace";
2197 case CXCompletionChunk_LeftAngle: return "LeftAngle";
2198 case CXCompletionChunk_RightAngle: return "RightAngle";
2199 case CXCompletionChunk_Comma: return "Comma";
2200 case CXCompletionChunk_ResultType: return "ResultType";
2201 case CXCompletionChunk_Colon: return "Colon";
2202 case CXCompletionChunk_SemiColon: return "SemiColon";
2203 case CXCompletionChunk_Equal: return "Equal";
2204 case CXCompletionChunk_HorizontalSpace: return "HorizontalSpace";
2205 case CXCompletionChunk_VerticalSpace: return "VerticalSpace";
2206 }
2207
2208 return "Unknown";
2209}
2210
2211static int checkForErrors(CXTranslationUnit TU) {
2212 unsigned Num, i;
2213 CXDiagnostic Diag;
2214 CXString DiagStr;
2215
2216 if (!getenv("CINDEXTEST_FAILONERROR"))
2217 return 0;
2218
2219 Num = clang_getNumDiagnostics(TU);
2220 for (i = 0; i != Num; ++i) {
2221 Diag = clang_getDiagnostic(TU, i);
2222 if (clang_getDiagnosticSeverity(Diag) >= CXDiagnostic_Error) {
2223 DiagStr = clang_formatDiagnostic(Diag,
2224 clang_defaultDiagnosticDisplayOptions());
2225 fprintf(stderrstderr, "%s\n", clang_getCString(DiagStr));
2226 clang_disposeString(DiagStr);
2227 clang_disposeDiagnostic(Diag);
2228 return -1;
2229 }
2230 clang_disposeDiagnostic(Diag);
2231 }
2232
2233 return 0;
2234}
2235
2236static void print_completion_string(CXCompletionString completion_string,
2237 FILE *file) {
2238 int I, N;
2239
2240 N = clang_getNumCompletionChunks(completion_string);
2241 for (I = 0; I != N; ++I) {
2242 CXString text;
2243 const char *cstr;
2244 enum CXCompletionChunkKind Kind
2245 = clang_getCompletionChunkKind(completion_string, I);
2246
2247 if (Kind == CXCompletionChunk_Optional) {
2248 fprintf(file, "{Optional ");
2249 print_completion_string(
2250 clang_getCompletionChunkCompletionString(completion_string, I),
2251 file);
2252 fprintf(file, "}");
2253 continue;
2254 }
2255
2256 if (Kind == CXCompletionChunk_VerticalSpace) {
2257 fprintf(file, "{VerticalSpace }");
2258 continue;
2259 }
2260
2261 text = clang_getCompletionChunkText(completion_string, I);
2262 cstr = clang_getCString(text);
2263 fprintf(file, "{%s %s}",
2264 clang_getCompletionChunkKindSpelling(Kind),
2265 cstr ? cstr : "");
2266 clang_disposeString(text);
2267 }
2268
2269}
2270
2271static void print_completion_result(CXCompletionResult *completion_result,
2272 FILE *file) {
2273 CXString ks = clang_getCursorKindSpelling(completion_result->CursorKind);
2274 unsigned annotationCount;
2275 enum CXCursorKind ParentKind;
2276 CXString ParentName;
2277 CXString BriefComment;
2278 CXString Annotation;
2279 const char *BriefCommentCString;
2280
2281 fprintf(file, "%s:", clang_getCString(ks));
2282 clang_disposeString(ks);
2283
2284 print_completion_string(completion_result->CompletionString, file);
2285 fprintf(file, " (%u)",
2286 clang_getCompletionPriority(completion_result->CompletionString));
2287 switch (clang_getCompletionAvailability(completion_result->CompletionString)){
2288 case CXAvailability_Available:
2289 break;
2290
2291 case CXAvailability_Deprecated:
2292 fprintf(file, " (deprecated)");
2293 break;
2294
2295 case CXAvailability_NotAvailable:
2296 fprintf(file, " (unavailable)");
2297 break;
2298
2299 case CXAvailability_NotAccessible:
2300 fprintf(file, " (inaccessible)");
2301 break;
2302 }
2303
2304 annotationCount = clang_getCompletionNumAnnotations(
2305 completion_result->CompletionString);
2306 if (annotationCount) {
2307 unsigned i;
2308 fprintf(file, " (");
2309 for (i = 0; i < annotationCount; ++i) {
2310 if (i != 0)
2311 fprintf(file, ", ");
2312 Annotation =
2313 clang_getCompletionAnnotation(completion_result->CompletionString, i);
2314 fprintf(file, "\"%s\"", clang_getCString(Annotation));
2315 clang_disposeString(Annotation);
2316 }
2317 fprintf(file, ")");
2318 }
2319
2320 if (!getenv("CINDEXTEST_NO_COMPLETION_PARENTS")) {
2321 ParentName = clang_getCompletionParent(completion_result->CompletionString,
2322 &ParentKind);
2323 if (ParentKind != CXCursor_NotImplemented) {
2324 CXString KindSpelling = clang_getCursorKindSpelling(ParentKind);
2325 fprintf(file, " (parent: %s '%s')",
2326 clang_getCString(KindSpelling),
2327 clang_getCString(ParentName));
2328 clang_disposeString(KindSpelling);
2329 }
2330 clang_disposeString(ParentName);
2331 }
2332
2333 BriefComment = clang_getCompletionBriefComment(
2334 completion_result->CompletionString);
2335 BriefCommentCString = clang_getCString(BriefComment);
2336 if (BriefCommentCString && *BriefCommentCString != '\0') {
2337 fprintf(file, "(brief comment: %s)", BriefCommentCString);
2338 }
2339 clang_disposeString(BriefComment);
2340
2341 fprintf(file, "\n");
2342}
2343
2344void print_completion_contexts(unsigned long long contexts, FILE *file) {
2345 fprintf(file, "Completion contexts:\n");
2346 if (contexts == CXCompletionContext_Unknown) {
2347 fprintf(file, "Unknown\n");
2348 }
2349 if (contexts & CXCompletionContext_AnyType) {
2350 fprintf(file, "Any type\n");
2351 }
2352 if (contexts & CXCompletionContext_AnyValue) {
2353 fprintf(file, "Any value\n");
2354 }
2355 if (contexts & CXCompletionContext_ObjCObjectValue) {
2356 fprintf(file, "Objective-C object value\n");
2357 }
2358 if (contexts & CXCompletionContext_ObjCSelectorValue) {
2359 fprintf(file, "Objective-C selector value\n");
2360 }
2361 if (contexts & CXCompletionContext_CXXClassTypeValue) {
2362 fprintf(file, "C++ class type value\n");
2363 }
2364 if (contexts & CXCompletionContext_DotMemberAccess) {
2365 fprintf(file, "Dot member access\n");
2366 }
2367 if (contexts & CXCompletionContext_ArrowMemberAccess) {
2368 fprintf(file, "Arrow member access\n");
2369 }
2370 if (contexts & CXCompletionContext_ObjCPropertyAccess) {
2371 fprintf(file, "Objective-C property access\n");
2372 }
2373 if (contexts & CXCompletionContext_EnumTag) {
2374 fprintf(file, "Enum tag\n");
2375 }
2376 if (contexts & CXCompletionContext_UnionTag) {
2377 fprintf(file, "Union tag\n");
2378 }
2379 if (contexts & CXCompletionContext_StructTag) {
2380 fprintf(file, "Struct tag\n");
2381 }
2382 if (contexts & CXCompletionContext_ClassTag) {
2383 fprintf(file, "Class name\n");
2384 }
2385 if (contexts & CXCompletionContext_Namespace) {
2386 fprintf(file, "Namespace or namespace alias\n");
2387 }
2388 if (contexts & CXCompletionContext_NestedNameSpecifier) {
2389 fprintf(file, "Nested name specifier\n");
2390 }
2391 if (contexts & CXCompletionContext_ObjCInterface) {
2392 fprintf(file, "Objective-C interface\n");
2393 }
2394 if (contexts & CXCompletionContext_ObjCProtocol) {
2395 fprintf(file, "Objective-C protocol\n");
2396 }
2397 if (contexts & CXCompletionContext_ObjCCategory) {
2398 fprintf(file, "Objective-C category\n");
2399 }
2400 if (contexts & CXCompletionContext_ObjCInstanceMessage) {
2401 fprintf(file, "Objective-C instance method\n");
2402 }
2403 if (contexts & CXCompletionContext_ObjCClassMessage) {
2404 fprintf(file, "Objective-C class method\n");
2405 }
2406 if (contexts & CXCompletionContext_ObjCSelectorName) {
2407 fprintf(file, "Objective-C selector name\n");
2408 }
2409 if (contexts & CXCompletionContext_MacroName) {
2410 fprintf(file, "Macro name\n");
2411 }
2412 if (contexts & CXCompletionContext_NaturalLanguage) {
2413 fprintf(file, "Natural language\n");
2414 }
2415}
2416
2417int perform_code_completion(int argc, const char **argv, int timing_only) {
2418 const char *input = argv[1];
2419 char *filename = 0;
2420 unsigned line;
2421 unsigned column;
2422 CXIndex CIdx;
2423 int errorCode;
2424 struct CXUnsavedFile *unsaved_files = 0;
2425 int num_unsaved_files = 0;
2426 CXCodeCompleteResults *results = 0;
2427 enum CXErrorCode Err;
2428 CXTranslationUnit TU;
2429 unsigned I, Repeats = 1;
2430 unsigned completionOptions = clang_defaultCodeCompleteOptions();
2431 const char *InvocationPath;
2432
2433 if (getenv("CINDEXTEST_CODE_COMPLETE_PATTERNS"))
2434 completionOptions |= CXCodeComplete_IncludeCodePatterns;
2435 if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
2436 completionOptions |= CXCodeComplete_IncludeBriefComments;
2437 if (getenv("CINDEXTEST_COMPLETION_SKIP_PREAMBLE"))
2438 completionOptions |= CXCodeComplete_SkipPreamble;
2439
2440 if (timing_only)
2441 input += strlen("-code-completion-timing=");
2442 else
2443 input += strlen("-code-completion-at=");
2444
2445 if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
2446 0, 0)))
2447 return errorCode;
2448
2449 if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
2450 return -1;
2451
2452 CIdx = clang_createIndex(0, 0);
2453 InvocationPath = getenv("CINDEXTEST_INVOCATION_EMISSION_PATH");
2454 if (InvocationPath)
2455 clang_CXIndex_setInvocationEmissionPathOption(CIdx, InvocationPath);
2456
2457 if (getenv("CINDEXTEST_EDITING"))
2458 Repeats = 5;
2459
2460 Err = clang_parseTranslationUnit2(CIdx, 0,
2461 argv + num_unsaved_files + 2,
2462 argc - num_unsaved_files - 2,
2463 0, 0, getDefaultParsingOptions(), &TU);
2464 if (Err != CXError_Success) {
2465 fprintf(stderrstderr, "Unable to load translation unit!\n");
2466 describeLibclangFailure(Err);
2467 return 1;
2468 }
2469
2470 Err = clang_reparseTranslationUnit(TU, 0, 0,
2471 clang_defaultReparseOptions(TU));
2472
2473 if (Err != CXError_Success) {
2474 fprintf(stderrstderr, "Unable to reparse translation unit!\n");
2475 describeLibclangFailure(Err);
2476 clang_disposeTranslationUnit(TU);
2477 return 1;
2478 }
2479
2480 for (I = 0; I != Repeats; ++I) {
2481 results = clang_codeCompleteAt(TU, filename, line, column,
2482 unsaved_files, num_unsaved_files,
2483 completionOptions);
2484 if (!results) {
2485 fprintf(stderrstderr, "Unable to perform code completion!\n");
2486 return 1;
2487 }
2488 if (I != Repeats-1)
2489 clang_disposeCodeCompleteResults(results);
2490 }
2491
2492 if (results) {
2493 unsigned i, n = results->NumResults, containerIsIncomplete = 0;
2494 unsigned long long contexts;
2495 enum CXCursorKind containerKind;
2496 CXString objCSelector;
2497 const char *selectorString;
2498 if (!timing_only) {
2499 /* Sort the code-completion results based on the typed text. */
2500 clang_sortCodeCompletionResults(results->Results, results->NumResults);
2501
2502 for (i = 0; i != n; ++i)
2503 print_completion_result(results->Results + i, stdoutstdout);
2504 }
2505 n = clang_codeCompleteGetNumDiagnostics(results);
2506 for (i = 0; i != n; ++i) {
2507 CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i);
2508 PrintDiagnostic(diag);
2509 clang_disposeDiagnostic(diag);
2510 }
2511
2512 contexts = clang_codeCompleteGetContexts(results);
2513 print_completion_contexts(contexts, stdoutstdout);
2514
2515 containerKind = clang_codeCompleteGetContainerKind(results,
2516 &containerIsIncomplete);
2517
2518 if (containerKind != CXCursor_InvalidCode) {
2519 /* We have found a container */
2520 CXString containerUSR, containerKindSpelling;
2521 containerKindSpelling = clang_getCursorKindSpelling(containerKind);
2522 printf("Container Kind: %s\n", clang_getCString(containerKindSpelling));
2523 clang_disposeString(containerKindSpelling);
2524
2525 if (containerIsIncomplete) {
2526 printf("Container is incomplete\n");
2527 }
2528 else {
2529 printf("Container is complete\n");
2530 }
2531
2532 containerUSR = clang_codeCompleteGetContainerUSR(results);
2533 printf("Container USR: %s\n", clang_getCString(containerUSR));
2534 clang_disposeString(containerUSR);
2535 }
2536
2537 objCSelector = clang_codeCompleteGetObjCSelector(results);
2538 selectorString = clang_getCString(objCSelector);
2539 if (selectorString && strlen(selectorString) > 0) {
2540 printf("Objective-C selector: %s\n", selectorString);
2541 }
2542 clang_disposeString(objCSelector);
2543
2544 clang_disposeCodeCompleteResults(results);
2545 }
2546 clang_disposeTranslationUnit(TU);
2547 clang_disposeIndex(CIdx);
2548 free(filename);
2549
2550 free_remapped_files(unsaved_files, num_unsaved_files);
2551
2552 return 0;
2553}
2554
2555typedef struct {
2556 char *filename;
2557 unsigned line;
2558 unsigned column;
2559} CursorSourceLocation;
2560
2561typedef void (*cursor_handler_t)(CXCursor cursor);
2562
2563static int inspect_cursor_at(int argc, const char **argv,
2564 const char *locations_flag,
2565 cursor_handler_t handler) {
2566 CXIndex CIdx;
2567 int errorCode;
2568 struct CXUnsavedFile *unsaved_files = 0;
2569 int num_unsaved_files = 0;
2570 enum CXErrorCode Err;
2571 CXTranslationUnit TU;
2572 CXCursor Cursor;
2573 CursorSourceLocation *Locations = 0;
2574 unsigned NumLocations = 0, Loc;
2575 unsigned Repeats = 1;
2576 unsigned I;
2577
2578 /* Count the number of locations. */
2579 while (strstr(argv[NumLocations+1], locations_flag) == argv[NumLocations+1])
2580 ++NumLocations;
2581
2582 /* Parse the locations. */
2583 assert(NumLocations > 0 && "Unable to count locations?")((void) sizeof ((NumLocations > 0 && "Unable to count locations?"
) ? 1 : 0), __extension__ ({ if (NumLocations > 0 &&
"Unable to count locations?") ; else __assert_fail ("NumLocations > 0 && \"Unable to count locations?\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 2583, __extension__ __PRETTY_FUNCTION__); }))
;
2584 Locations = (CursorSourceLocation *)malloc(
2585 NumLocations * sizeof(CursorSourceLocation));
2586 assert(Locations)((void) sizeof ((Locations) ? 1 : 0), __extension__ ({ if (Locations
) ; else __assert_fail ("Locations", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 2586, __extension__ __PRETTY_FUNCTION__); }))
;
2587 for (Loc = 0; Loc < NumLocations; ++Loc) {
2588 const char *input = argv[Loc + 1] + strlen(locations_flag);
2589 if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename,
2590 &Locations[Loc].line,
2591 &Locations[Loc].column, 0, 0)))
2592 return errorCode;
2593 }
2594
2595 if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files,
2596 &num_unsaved_files))
2597 return -1;
2598
2599 if (getenv("CINDEXTEST_EDITING"))
2600 Repeats = 5;
2601
2602 /* Parse the translation unit. When we're testing clang_getCursor() after
2603 reparsing, don't remap unsaved files until the second parse. */
2604 CIdx = clang_createIndex(1, 1);
2605 Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
2606 argv + num_unsaved_files + 1 + NumLocations,
2607 argc - num_unsaved_files - 2 - NumLocations,
2608 unsaved_files,
2609 Repeats > 1? 0 : num_unsaved_files,
2610 getDefaultParsingOptions(), &TU);
2611 if (Err != CXError_Success) {
2612 fprintf(stderrstderr, "unable to parse input\n");
2613 describeLibclangFailure(Err);
2614 return -1;
2615 }
2616
2617 if (checkForErrors(TU) != 0)
2618 return -1;
2619
2620 for (I = 0; I != Repeats; ++I) {
2621 if (Repeats > 1) {
2622 Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
2623 clang_defaultReparseOptions(TU));
2624 if (Err != CXError_Success) {
2625 describeLibclangFailure(Err);
2626 clang_disposeTranslationUnit(TU);
2627 return 1;
2628 }
2629 }
2630
2631 if (checkForErrors(TU) != 0)
2632 return -1;
2633
2634 for (Loc = 0; Loc < NumLocations; ++Loc) {
2635 CXFile file = clang_getFile(TU, Locations[Loc].filename);
2636 if (!file)
2637 continue;
2638
2639 Cursor = clang_getCursor(TU,
2640 clang_getLocation(TU, file, Locations[Loc].line,
2641 Locations[Loc].column));
2642
2643 if (checkForErrors(TU) != 0)
2644 return -1;
2645
2646 if (I + 1 == Repeats) {
2647 handler(Cursor);
2648 free(Locations[Loc].filename);
2649 }
2650 }
2651 }
2652
2653 PrintDiagnostics(TU);
2654 clang_disposeTranslationUnit(TU);
2655 clang_disposeIndex(CIdx);
2656 free(Locations);
2657 free_remapped_files(unsaved_files, num_unsaved_files);
2658 return 0;
2659}
2660
2661static void inspect_print_cursor(CXCursor Cursor) {
2662 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
2663 CXCompletionString completionString = clang_getCursorCompletionString(
2664 Cursor);
2665 CXSourceLocation CursorLoc = clang_getCursorLocation(Cursor);
2666 CXString Spelling;
2667 const char *cspell;
2668 unsigned line, column;
2669 clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0);
2670 printf("%d:%d ", line, column);
2671 PrintCursor(Cursor, NULL((void*)0));
2672 PrintCursorExtent(Cursor);
2673 Spelling = clang_getCursorSpelling(Cursor);
2674 cspell = clang_getCString(Spelling);
2675 if (cspell && strlen(cspell) != 0) {
2676 unsigned pieceIndex;
2677 printf(" Spelling=%s (", cspell);
2678 for (pieceIndex = 0; ; ++pieceIndex) {
2679 CXSourceRange range =
2680 clang_Cursor_getSpellingNameRange(Cursor, pieceIndex, 0);
2681 if (clang_Range_isNull(range))
2682 break;
2683 PrintRange(range, 0);
2684 }
2685 printf(")");
2686 }
2687 clang_disposeString(Spelling);
2688 if (clang_Cursor_getObjCSelectorIndex(Cursor) != -1)
2689 printf(" Selector index=%d",
2690 clang_Cursor_getObjCSelectorIndex(Cursor));
2691 if (clang_Cursor_isDynamicCall(Cursor))
2692 printf(" Dynamic-call");
2693 if (Cursor.kind == CXCursor_ObjCMessageExpr ||
2694 Cursor.kind == CXCursor_MemberRefExpr) {
2695 CXType T = clang_Cursor_getReceiverType(Cursor);
2696 if (T.kind != CXType_Invalid) {
2697 CXString S = clang_getTypeKindSpelling(T.kind);
2698 printf(" Receiver-type=%s", clang_getCString(S));
2699 clang_disposeString(S);
2700 }
2701 }
2702
2703 {
2704 CXModule mod = clang_Cursor_getModule(Cursor);
2705 CXFile astFile;
2706 CXString name, astFilename;
2707 unsigned i, numHeaders;
2708 if (mod) {
2709 astFile = clang_Module_getASTFile(mod);
2710 astFilename = clang_getFileName(astFile);
2711 name = clang_Module_getFullName(mod);
2712 numHeaders = clang_Module_getNumTopLevelHeaders(TU, mod);
2713 printf(" ModuleName=%s (%s) system=%d Headers(%d):",
2714 clang_getCString(name), clang_getCString(astFilename),
2715 clang_Module_isSystem(mod), numHeaders);
2716 clang_disposeString(name);
2717 clang_disposeString(astFilename);
2718 for (i = 0; i < numHeaders; ++i) {
2719 CXFile file = clang_Module_getTopLevelHeader(TU, mod, i);
2720 CXString filename = clang_getFileName(file);
2721 printf("\n%s", clang_getCString(filename));
2722 clang_disposeString(filename);
2723 }
2724 }
2725 }
2726
2727 if (completionString != NULL((void*)0)) {
2728 printf("\nCompletion string: ");
2729 print_completion_string(completionString, stdoutstdout);
2730 }
2731 printf("\n");
2732}
2733
2734static void display_evaluate_results(CXEvalResult result) {
2735 switch (clang_EvalResult_getKind(result)) {
2736 case CXEval_Int:
2737 {
2738 printf("Kind: Int, ");
2739 if (clang_EvalResult_isUnsignedInt(result)) {
2740 unsigned long long val = clang_EvalResult_getAsUnsigned(result);
2741 printf("unsigned, Value: %llu", val);
2742 } else {
2743 long long val = clang_EvalResult_getAsLongLong(result);
2744 printf("Value: %lld", val);
2745 }
2746 break;
2747 }
2748 case CXEval_Float:
2749 {
2750 double val = clang_EvalResult_getAsDouble(result);
2751 printf("Kind: Float , Value: %f", val);
2752 break;
2753 }
2754 case CXEval_ObjCStrLiteral:
2755 {
2756 const char* str = clang_EvalResult_getAsStr(result);
2757 printf("Kind: ObjCString , Value: %s", str);
2758 break;
2759 }
2760 case CXEval_StrLiteral:
2761 {
2762 const char* str = clang_EvalResult_getAsStr(result);
2763 printf("Kind: CString , Value: %s", str);
2764 break;
2765 }
2766 case CXEval_CFStr:
2767 {
2768 const char* str = clang_EvalResult_getAsStr(result);
2769 printf("Kind: CFString , Value: %s", str);
2770 break;
2771 }
2772 default:
2773 printf("Unexposed");
2774 break;
2775 }
2776}
2777
2778static void inspect_evaluate_cursor(CXCursor Cursor) {
2779 CXSourceLocation CursorLoc = clang_getCursorLocation(Cursor);
2780 CXString Spelling;
2781 const char *cspell;
2782 unsigned line, column;
2783 CXEvalResult ER;
2784
2785 clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0);
2786 printf("%d:%d ", line, column);
2787 PrintCursor(Cursor, NULL((void*)0));
2788 PrintCursorExtent(Cursor);
2789 Spelling = clang_getCursorSpelling(Cursor);
2790 cspell = clang_getCString(Spelling);
2791 if (cspell && strlen(cspell) != 0) {
2792 unsigned pieceIndex;
2793 printf(" Spelling=%s (", cspell);
2794 for (pieceIndex = 0; ; ++pieceIndex) {
2795 CXSourceRange range =
2796 clang_Cursor_getSpellingNameRange(Cursor, pieceIndex, 0);
2797 if (clang_Range_isNull(range))
2798 break;
2799 PrintRange(range, 0);
2800 }
2801 printf(")");
2802 }
2803 clang_disposeString(Spelling);
2804
2805 ER = clang_Cursor_Evaluate(Cursor);
2806 if (!ER) {
2807 printf("Not Evaluatable");
2808 } else {
2809 display_evaluate_results(ER);
2810 clang_EvalResult_dispose(ER);
2811 }
2812 printf("\n");
2813}
2814
2815static void inspect_macroinfo_cursor(CXCursor Cursor) {
2816 CXSourceLocation CursorLoc = clang_getCursorLocation(Cursor);
2817 CXString Spelling;
2818 const char *cspell;
2819 unsigned line, column;
2820 clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0);
2821 printf("%d:%d ", line, column);
2822 PrintCursor(Cursor, NULL((void*)0));
2823 PrintCursorExtent(Cursor);
2824 Spelling = clang_getCursorSpelling(Cursor);
2825 cspell = clang_getCString(Spelling);
2826 if (cspell && strlen(cspell) != 0) {
2827 unsigned pieceIndex;
2828 printf(" Spelling=%s (", cspell);
2829 for (pieceIndex = 0; ; ++pieceIndex) {
2830 CXSourceRange range =
2831 clang_Cursor_getSpellingNameRange(Cursor, pieceIndex, 0);
2832 if (clang_Range_isNull(range))
2833 break;
2834 PrintRange(range, 0);
2835 }
2836 printf(")");
2837 }
2838 clang_disposeString(Spelling);
2839
2840 if (clang_Cursor_isMacroBuiltin(Cursor)) {
2841 printf("[builtin macro]");
2842 } else if (clang_Cursor_isMacroFunctionLike(Cursor)) {
2843 printf("[function macro]");
2844 }
2845 printf("\n");
2846}
2847
2848static enum CXVisitorResult findFileRefsVisit(void *context,
2849 CXCursor cursor, CXSourceRange range) {
2850 if (clang_Range_isNull(range))
2851 return CXVisit_Continue;
2852
2853 PrintCursor(cursor, NULL((void*)0));
2854 PrintRange(range, "");
2855 printf("\n");
2856 return CXVisit_Continue;
2857}
2858
2859static int find_file_refs_at(int argc, const char **argv) {
2860 CXIndex CIdx;
2861 int errorCode;
2862 struct CXUnsavedFile *unsaved_files = 0;
2863 int num_unsaved_files = 0;
2864 enum CXErrorCode Err;
2865 CXTranslationUnit TU;
2866 CXCursor Cursor;
2867 CursorSourceLocation *Locations = 0;
2868 unsigned NumLocations = 0, Loc;
2869 unsigned Repeats = 1;
2870 unsigned I;
2871
2872 /* Count the number of locations. */
2873 while (strstr(argv[NumLocations+1], "-file-refs-at=") == argv[NumLocations+1])
2874 ++NumLocations;
2875
2876 /* Parse the locations. */
2877 assert(NumLocations > 0 && "Unable to count locations?")((void) sizeof ((NumLocations > 0 && "Unable to count locations?"
) ? 1 : 0), __extension__ ({ if (NumLocations > 0 &&
"Unable to count locations?") ; else __assert_fail ("NumLocations > 0 && \"Unable to count locations?\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 2877, __extension__ __PRETTY_FUNCTION__); }))
;
2878 Locations = (CursorSourceLocation *)malloc(
2879 NumLocations * sizeof(CursorSourceLocation));
2880 assert(Locations)((void) sizeof ((Locations) ? 1 : 0), __extension__ ({ if (Locations
) ; else __assert_fail ("Locations", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 2880, __extension__ __PRETTY_FUNCTION__); }))
;
2881 for (Loc = 0; Loc < NumLocations; ++Loc) {
2882 const char *input = argv[Loc + 1] + strlen("-file-refs-at=");
2883 if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename,
2884 &Locations[Loc].line,
2885 &Locations[Loc].column, 0, 0)))
2886 return errorCode;
2887 }
2888
2889 if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files,
2890 &num_unsaved_files))
2891 return -1;
2892
2893 if (getenv("CINDEXTEST_EDITING"))
2894 Repeats = 5;
2895
2896 /* Parse the translation unit. When we're testing clang_getCursor() after
2897 reparsing, don't remap unsaved files until the second parse. */
2898 CIdx = clang_createIndex(1, 1);
2899 Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
2900 argv + num_unsaved_files + 1 + NumLocations,
2901 argc - num_unsaved_files - 2 - NumLocations,
2902 unsaved_files,
2903 Repeats > 1? 0 : num_unsaved_files,
2904 getDefaultParsingOptions(), &TU);
2905 if (Err != CXError_Success) {
2906 fprintf(stderrstderr, "unable to parse input\n");
2907 describeLibclangFailure(Err);
2908 clang_disposeTranslationUnit(TU);
2909 return -1;
2910 }
2911
2912 if (checkForErrors(TU) != 0)
2913 return -1;
2914
2915 for (I = 0; I != Repeats; ++I) {
2916 if (Repeats > 1) {
2917 Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
2918 clang_defaultReparseOptions(TU));
2919 if (Err != CXError_Success) {
2920 describeLibclangFailure(Err);
2921 clang_disposeTranslationUnit(TU);
2922 return 1;
2923 }
2924 }
2925
2926 if (checkForErrors(TU) != 0)
2927 return -1;
2928
2929 for (Loc = 0; Loc < NumLocations; ++Loc) {
2930 CXFile file = clang_getFile(TU, Locations[Loc].filename);
2931 if (!file)
2932 continue;
2933
2934 Cursor = clang_getCursor(TU,
2935 clang_getLocation(TU, file, Locations[Loc].line,
2936 Locations[Loc].column));
2937
2938 if (checkForErrors(TU) != 0)
2939 return -1;
2940
2941 if (I + 1 == Repeats) {
2942 CXCursorAndRangeVisitor visitor = { 0, findFileRefsVisit };
2943 PrintCursor(Cursor, NULL((void*)0));
2944 printf("\n");
2945 clang_findReferencesInFile(Cursor, file, visitor);
2946 free(Locations[Loc].filename);
2947
2948 if (checkForErrors(TU) != 0)
2949 return -1;
2950 }
2951 }
2952 }
2953
2954 PrintDiagnostics(TU);
2955 clang_disposeTranslationUnit(TU);
2956 clang_disposeIndex(CIdx);
2957 free(Locations);
2958 free_remapped_files(unsaved_files, num_unsaved_files);
2959 return 0;
2960}
2961
2962static enum CXVisitorResult findFileIncludesVisit(void *context,
2963 CXCursor cursor, CXSourceRange range) {
2964 PrintCursor(cursor, NULL((void*)0));
2965 PrintRange(range, "");
2966 printf("\n");
2967 return CXVisit_Continue;
2968}
2969
2970static int find_file_includes_in(int argc, const char **argv) {
2971 CXIndex CIdx;
2972 struct CXUnsavedFile *unsaved_files = 0;
2973 int num_unsaved_files = 0;
2974 enum CXErrorCode Err;
2975 CXTranslationUnit TU;
2976 const char **Filenames = 0;
2977 unsigned NumFilenames = 0;
2978 unsigned Repeats = 1;
2979 unsigned I, FI;
2980
2981 /* Count the number of locations. */
2982 while (strstr(argv[NumFilenames+1], "-file-includes-in=") == argv[NumFilenames+1])
19
Assuming the condition is true
20
Loop condition is true. Entering loop body
21
Assuming the condition is true
22
Loop condition is true. Entering loop body
23
Assuming the condition is false
24
Loop condition is false. Execution continues on line 2986
2983 ++NumFilenames;
2984
2985 /* Parse the locations. */
2986 assert(NumFilenames > 0 && "Unable to count filenames?")((void) sizeof ((NumFilenames > 0 && "Unable to count filenames?"
) ? 1 : 0), __extension__ ({ if (NumFilenames > 0 &&
"Unable to count filenames?") ; else __assert_fail ("NumFilenames > 0 && \"Unable to count filenames?\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 2986, __extension__ __PRETTY_FUNCTION__); }))
;
2987 Filenames = (const char **)malloc(NumFilenames * sizeof(const char *));
25
Memory is allocated
2988 assert(Filenames)((void) sizeof ((Filenames) ? 1 : 0), __extension__ ({ if (Filenames
) ; else __assert_fail ("Filenames", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 2988, __extension__ __PRETTY_FUNCTION__); }))
;
26
Within the expansion of the macro 'assert':
a
Assuming 'Filenames' is non-null
2989 for (I = 0; I < NumFilenames; ++I) {
27
Loop condition is true. Entering loop body
28
Loop condition is true. Entering loop body
29
Loop condition is false. Execution continues on line 2995
2990 const char *input = argv[I + 1] + strlen("-file-includes-in=");
2991 /* Copy the file name. */
2992 Filenames[I] = input;
2993 }
2994
2995 if (parse_remapped_files(argc, argv, NumFilenames + 1, &unsaved_files,
30
Assuming the condition is true
31
Taking true branch
2996 &num_unsaved_files))
2997 return -1;
32
Potential leak of memory pointed to by 'Filenames'
2998
2999 if (getenv("CINDEXTEST_EDITING"))
3000 Repeats = 2;
3001
3002 /* Parse the translation unit. When we're testing clang_getCursor() after
3003 reparsing, don't remap unsaved files until the second parse. */
3004 CIdx = clang_createIndex(1, 1);
3005 Err = clang_parseTranslationUnit2(
3006 CIdx, argv[argc - 1],
3007 argv + num_unsaved_files + 1 + NumFilenames,
3008 argc - num_unsaved_files - 2 - NumFilenames,
3009 unsaved_files,
3010 Repeats > 1 ? 0 : num_unsaved_files, getDefaultParsingOptions(), &TU);
3011
3012 if (Err != CXError_Success) {
3013 fprintf(stderrstderr, "unable to parse input\n");
3014 describeLibclangFailure(Err);
3015 clang_disposeTranslationUnit(TU);
3016 return -1;
3017 }
3018
3019 if (checkForErrors(TU) != 0)
3020 return -1;
3021
3022 for (I = 0; I != Repeats; ++I) {
3023 if (Repeats > 1) {
3024 Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
3025 clang_defaultReparseOptions(TU));
3026 if (Err != CXError_Success) {
3027 describeLibclangFailure(Err);
3028 clang_disposeTranslationUnit(TU);
3029 return 1;
3030 }
3031 }
3032
3033 if (checkForErrors(TU) != 0)
3034 return -1;
3035
3036 for (FI = 0; FI < NumFilenames; ++FI) {
3037 CXFile file = clang_getFile(TU, Filenames[FI]);
3038 if (!file)
3039 continue;
3040
3041 if (checkForErrors(TU) != 0)
3042 return -1;
3043
3044 if (I + 1 == Repeats) {
3045 CXCursorAndRangeVisitor visitor = { 0, findFileIncludesVisit };
3046 clang_findIncludesInFile(TU, file, visitor);
3047
3048 if (checkForErrors(TU) != 0)
3049 return -1;
3050 }
3051 }
3052 }
3053
3054 PrintDiagnostics(TU);
3055 clang_disposeTranslationUnit(TU);
3056 clang_disposeIndex(CIdx);
3057 free((void *)Filenames);
3058 free_remapped_files(unsaved_files, num_unsaved_files);
3059 return 0;
3060}
3061
3062#define MAX_IMPORTED_ASTFILES200 200
3063
3064typedef struct {
3065 char **filenames;
3066 unsigned num_files;
3067} ImportedASTFilesData;
3068
3069static ImportedASTFilesData *importedASTs_create() {
3070 ImportedASTFilesData *p;
3071 p = malloc(sizeof(ImportedASTFilesData));
3072 assert(p)((void) sizeof ((p) ? 1 : 0), __extension__ ({ if (p) ; else __assert_fail
("p", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3072, __extension__ __PRETTY_FUNCTION__); }))
;
3073 p->filenames = malloc(MAX_IMPORTED_ASTFILES200 * sizeof(const char *));
3074 assert(p->filenames)((void) sizeof ((p->filenames) ? 1 : 0), __extension__ ({ if
(p->filenames) ; else __assert_fail ("p->filenames", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3074, __extension__ __PRETTY_FUNCTION__); }))
;
3075 p->num_files = 0;
3076 return p;
3077}
3078
3079static void importedASTs_dispose(ImportedASTFilesData *p) {
3080 unsigned i;
3081 if (!p)
3082 return;
3083
3084 for (i = 0; i < p->num_files; ++i)
3085 free(p->filenames[i]);
3086 free(p->filenames);
3087 free(p);
3088}
3089
3090static void importedASTS_insert(ImportedASTFilesData *p, const char *file) {
3091 unsigned i;
3092 assert(p && file)((void) sizeof ((p && file) ? 1 : 0), __extension__ (
{ if (p && file) ; else __assert_fail ("p && file"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3092, __extension__ __PRETTY_FUNCTION__); }))
;
3093 for (i = 0; i < p->num_files; ++i)
3094 if (strcmp(file, p->filenames[i]) == 0)
3095 return;
3096 assert(p->num_files + 1 < MAX_IMPORTED_ASTFILES)((void) sizeof ((p->num_files + 1 < 200) ? 1 : 0), __extension__
({ if (p->num_files + 1 < 200) ; else __assert_fail ("p->num_files + 1 < MAX_IMPORTED_ASTFILES"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3096, __extension__ __PRETTY_FUNCTION__); }))
;
3097 p->filenames[p->num_files++] = strdup(file);
3098}
3099
3100typedef struct IndexDataStringList_ {
3101 struct IndexDataStringList_ *next;
3102 char data[1]; /* Dynamically sized. */
3103} IndexDataStringList;
3104
3105typedef struct {
3106 const char *check_prefix;
3107 int first_check_printed;
3108 int fail_for_error;
3109 int abort;
3110 CXString main_filename;
3111 ImportedASTFilesData *importedASTs;
3112 IndexDataStringList *strings;
3113 CXTranslationUnit TU;
3114} IndexData;
3115
3116static void free_client_data(IndexData *index_data) {
3117 IndexDataStringList *node = index_data->strings;
3118 while (node) {
3119 IndexDataStringList *next = node->next;
3120 free(node);
3121 node = next;
3122 }
3123 index_data->strings = NULL((void*)0);
3124}
3125
3126static void printCheck(IndexData *data) {
3127 if (data->check_prefix) {
3128 if (data->first_check_printed) {
3129 printf("// %s-NEXT: ", data->check_prefix);
3130 } else {
3131 printf("// %s : ", data->check_prefix);
3132 data->first_check_printed = 1;
3133 }
3134 }
3135}
3136
3137static void printCXIndexFile(CXIdxClientFile file) {
3138 CXString filename = clang_getFileName((CXFile)file);
3139 printf("%s", clang_getCString(filename));
3140 clang_disposeString(filename);
3141}
3142
3143static void printCXIndexLoc(CXIdxLoc loc, CXClientData client_data) {
3144 IndexData *index_data;
3145 CXString filename;
3146 const char *cname;
3147 CXIdxClientFile file;
3148 unsigned line, column;
3149 const char *main_filename;
3150 int isMainFile;
3151
3152 index_data = (IndexData *)client_data;
3153 clang_indexLoc_getFileLocation(loc, &file, 0, &line, &column, 0);
3154 if (line == 0) {
3155 printf("<invalid>");
3156 return;
3157 }
3158 if (!file) {
3159 printf("<no idxfile>");
3160 return;
3161 }
3162 filename = clang_getFileName((CXFile)file);
3163 cname = clang_getCString(filename);
3164 main_filename = clang_getCString(index_data->main_filename);
3165 if (strcmp(cname, main_filename) == 0)
3166 isMainFile = 1;
3167 else
3168 isMainFile = 0;
3169 clang_disposeString(filename);
3170
3171 if (!isMainFile) {
3172 printCXIndexFile(file);
3173 printf(":");
3174 }
3175 printf("%d:%d", line, column);
3176}
3177
3178static unsigned digitCount(unsigned val) {
3179 unsigned c = 1;
3180 while (1) {
3181 if (val < 10)
3182 return c;
3183 ++c;
3184 val /= 10;
3185 }
3186}
3187
3188static CXIdxClientContainer makeClientContainer(CXClientData *client_data,
3189 const CXIdxEntityInfo *info,
3190 CXIdxLoc loc) {
3191 IndexData *index_data;
3192 IndexDataStringList *node;
3193 const char *name;
3194 char *newStr;
3195 CXIdxClientFile file;
3196 unsigned line, column;
3197
3198 name = info->name;
3199 if (!name)
3200 name = "<anon-tag>";
3201
3202 clang_indexLoc_getFileLocation(loc, &file, 0, &line, &column, 0);
3203
3204 node =
3205 (IndexDataStringList *)malloc(sizeof(IndexDataStringList) + strlen(name) +
3206 digitCount(line) + digitCount(column) + 2);
3207 assert(node)((void) sizeof ((node) ? 1 : 0), __extension__ ({ if (node) ;
else __assert_fail ("node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3207, __extension__ __PRETTY_FUNCTION__); }))
;
3208 newStr = node->data;
3209 sprintf(newStr, "%s:%d:%d", name, line, column);
3210
3211 /* Remember string so it can be freed later. */
3212 index_data = (IndexData *)client_data;
3213 node->next = index_data->strings;
3214 index_data->strings = node;
3215
3216 return (CXIdxClientContainer)newStr;
3217}
3218
3219static void printCXIndexContainer(const CXIdxContainerInfo *info) {
3220 CXIdxClientContainer container;
3221 container = clang_index_getClientContainer(info);
3222 if (!container)
3223 printf("[<<NULL>>]");
3224 else
3225 printf("[%s]", (const char *)container);
3226}
3227
3228static const char *getEntityKindString(CXIdxEntityKind kind) {
3229 switch (kind) {
3230 case CXIdxEntity_Unexposed: return "<<UNEXPOSED>>";
3231 case CXIdxEntity_Typedef: return "typedef";
3232 case CXIdxEntity_Function: return "function";
3233 case CXIdxEntity_Variable: return "variable";
3234 case CXIdxEntity_Field: return "field";
3235 case CXIdxEntity_EnumConstant: return "enumerator";
3236 case CXIdxEntity_ObjCClass: return "objc-class";
3237 case CXIdxEntity_ObjCProtocol: return "objc-protocol";
3238 case CXIdxEntity_ObjCCategory: return "objc-category";
3239 case CXIdxEntity_ObjCInstanceMethod: return "objc-instance-method";
3240 case CXIdxEntity_ObjCClassMethod: return "objc-class-method";
3241 case CXIdxEntity_ObjCProperty: return "objc-property";
3242 case CXIdxEntity_ObjCIvar: return "objc-ivar";
3243 case CXIdxEntity_Enum: return "enum";
3244 case CXIdxEntity_Struct: return "struct";
3245 case CXIdxEntity_Union: return "union";
3246 case CXIdxEntity_CXXClass: return "c++-class";
3247 case CXIdxEntity_CXXNamespace: return "namespace";
3248 case CXIdxEntity_CXXNamespaceAlias: return "namespace-alias";
3249 case CXIdxEntity_CXXStaticVariable: return "c++-static-var";
3250 case CXIdxEntity_CXXStaticMethod: return "c++-static-method";
3251 case CXIdxEntity_CXXInstanceMethod: return "c++-instance-method";
3252 case CXIdxEntity_CXXConstructor: return "constructor";
3253 case CXIdxEntity_CXXDestructor: return "destructor";
3254 case CXIdxEntity_CXXConversionFunction: return "conversion-func";
3255 case CXIdxEntity_CXXTypeAlias: return "type-alias";
3256 case CXIdxEntity_CXXInterface: return "c++-__interface";
3257 }
3258 assert(0 && "Garbage entity kind")((void) sizeof ((0 && "Garbage entity kind") ? 1 : 0)
, __extension__ ({ if (0 && "Garbage entity kind") ; else
__assert_fail ("0 && \"Garbage entity kind\"", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3258, __extension__ __PRETTY_FUNCTION__); }))
;
3259 return 0;
3260}
3261
3262static const char *getEntityTemplateKindString(CXIdxEntityCXXTemplateKind kind) {
3263 switch (kind) {
3264 case CXIdxEntity_NonTemplate: return "";
3265 case CXIdxEntity_Template: return "-template";
3266 case CXIdxEntity_TemplatePartialSpecialization:
3267 return "-template-partial-spec";
3268 case CXIdxEntity_TemplateSpecialization: return "-template-spec";
3269 }
3270 assert(0 && "Garbage entity kind")((void) sizeof ((0 && "Garbage entity kind") ? 1 : 0)
, __extension__ ({ if (0 && "Garbage entity kind") ; else
__assert_fail ("0 && \"Garbage entity kind\"", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3270, __extension__ __PRETTY_FUNCTION__); }))
;
3271 return 0;
3272}
3273
3274static const char *getEntityLanguageString(CXIdxEntityLanguage kind) {
3275 switch (kind) {
3276 case CXIdxEntityLang_None: return "<none>";
3277 case CXIdxEntityLang_C: return "C";
3278 case CXIdxEntityLang_ObjC: return "ObjC";
3279 case CXIdxEntityLang_CXX: return "C++";
3280 case CXIdxEntityLang_Swift: return "Swift";
3281 }
3282 assert(0 && "Garbage language kind")((void) sizeof ((0 && "Garbage language kind") ? 1 : 0
), __extension__ ({ if (0 && "Garbage language kind")
; else __assert_fail ("0 && \"Garbage language kind\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3282, __extension__ __PRETTY_FUNCTION__); }))
;
3283 return 0;
3284}
3285
3286static void printEntityInfo(const char *cb,
3287 CXClientData client_data,
3288 const CXIdxEntityInfo *info) {
3289 const char *name;
3290 IndexData *index_data;
3291 unsigned i;
3292 index_data = (IndexData *)client_data;
3293 printCheck(index_data);
3294
3295 if (!info) {
3296 printf("%s: <<NULL>>", cb);
3297 return;
3298 }
3299
3300 name = info->name;
3301 if (!name)
3302 name = "<anon-tag>";
3303
3304 printf("%s: kind: %s%s", cb, getEntityKindString(info->kind),
3305 getEntityTemplateKindString(info->templateKind));
3306 printf(" | name: %s", name);
3307 printf(" | USR: %s", info->USR);
3308 printf(" | lang: %s", getEntityLanguageString(info->lang));
3309
3310 for (i = 0; i != info->numAttributes; ++i) {
3311 const CXIdxAttrInfo *Attr = info->attributes[i];
3312 printf(" <attribute>: ");
3313 PrintCursor(Attr->cursor, NULL((void*)0));
3314 }
3315}
3316
3317static void printBaseClassInfo(CXClientData client_data,
3318 const CXIdxBaseClassInfo *info) {
3319 printEntityInfo(" <base>", client_data, info->base);
3320 printf(" | cursor: ");
3321 PrintCursor(info->cursor, NULL((void*)0));
3322 printf(" | loc: ");
3323 printCXIndexLoc(info->loc, client_data);
3324}
3325
3326static void printProtocolList(const CXIdxObjCProtocolRefListInfo *ProtoInfo,
3327 CXClientData client_data) {
3328 unsigned i;
3329 for (i = 0; i < ProtoInfo->numProtocols; ++i) {
3330 printEntityInfo(" <protocol>", client_data,
3331 ProtoInfo->protocols[i]->protocol);
3332 printf(" | cursor: ");
3333 PrintCursor(ProtoInfo->protocols[i]->cursor, NULL((void*)0));
3334 printf(" | loc: ");
3335 printCXIndexLoc(ProtoInfo->protocols[i]->loc, client_data);
3336 printf("\n");
3337 }
3338}
3339
3340static void printSymbolRole(CXSymbolRole role) {
3341 if (role & CXSymbolRole_Declaration)
3342 printf(" decl");
3343 if (role & CXSymbolRole_Definition)
3344 printf(" def");
3345 if (role & CXSymbolRole_Reference)
3346 printf(" ref");
3347 if (role & CXSymbolRole_Read)
3348 printf(" read");
3349 if (role & CXSymbolRole_Write)
3350 printf(" write");
3351 if (role & CXSymbolRole_Call)
3352 printf(" call");
3353 if (role & CXSymbolRole_Dynamic)
3354 printf(" dyn");
3355 if (role & CXSymbolRole_AddressOf)
3356 printf(" addr");
3357 if (role & CXSymbolRole_Implicit)
3358 printf(" implicit");
3359}
3360
3361static void index_diagnostic(CXClientData client_data,
3362 CXDiagnosticSet diagSet, void *reserved) {
3363 CXString str;
3364 const char *cstr;
3365 unsigned numDiags, i;
3366 CXDiagnostic diag;
3367 IndexData *index_data;
3368 index_data = (IndexData *)client_data;
3369 printCheck(index_data);
3370
3371 numDiags = clang_getNumDiagnosticsInSet(diagSet);
3372 for (i = 0; i != numDiags; ++i) {
3373 diag = clang_getDiagnosticInSet(diagSet, i);
3374 str = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());
3375 cstr = clang_getCString(str);
3376 printf("[diagnostic]: %s\n", cstr);
3377 clang_disposeString(str);
3378
3379 if (getenv("CINDEXTEST_FAILONERROR") &&
3380 clang_getDiagnosticSeverity(diag) >= CXDiagnostic_Error) {
3381 index_data->fail_for_error = 1;
3382 }
3383 }
3384}
3385
3386static CXIdxClientFile index_enteredMainFile(CXClientData client_data,
3387 CXFile file, void *reserved) {
3388 IndexData *index_data;
3389
3390 index_data = (IndexData *)client_data;
3391 printCheck(index_data);
3392
3393 index_data->main_filename = clang_getFileName(file);
3394
3395 printf("[enteredMainFile]: ");
3396 printCXIndexFile((CXIdxClientFile)file);
3397 printf("\n");
3398
3399 return (CXIdxClientFile)file;
3400}
3401
3402static CXIdxClientFile index_ppIncludedFile(CXClientData client_data,
3403 const CXIdxIncludedFileInfo *info) {
3404 IndexData *index_data;
3405 CXModule Mod;
3406 index_data = (IndexData *)client_data;
3407 printCheck(index_data);
3408
3409 printf("[ppIncludedFile]: ");
3410 printCXIndexFile((CXIdxClientFile)info->file);
3411 printf(" | name: \"%s\"", info->filename);
3412 printf(" | hash loc: ");
3413 printCXIndexLoc(info->hashLoc, client_data);
3414 printf(" | isImport: %d | isAngled: %d | isModule: %d",
3415 info->isImport, info->isAngled, info->isModuleImport);
3416
3417 Mod = clang_getModuleForFile(index_data->TU, (CXFile)info->file);
3418 if (Mod) {
3419 CXString str = clang_Module_getFullName(Mod);
3420 const char *cstr = clang_getCString(str);
3421 printf(" | module: %s", cstr);
3422 clang_disposeString(str);
3423 }
3424
3425 printf("\n");
3426
3427 return (CXIdxClientFile)info->file;
3428}
3429
3430static CXIdxClientFile index_importedASTFile(CXClientData client_data,
3431 const CXIdxImportedASTFileInfo *info) {
3432 IndexData *index_data;
3433 index_data = (IndexData *)client_data;
3434 printCheck(index_data);
3435
3436 if (index_data->importedASTs) {
3437 CXString filename = clang_getFileName(info->file);
3438 importedASTS_insert(index_data->importedASTs, clang_getCString(filename));
3439 clang_disposeString(filename);
3440 }
3441
3442 printf("[importedASTFile]: ");
3443 printCXIndexFile((CXIdxClientFile)info->file);
3444 if (info->module) {
3445 CXString name = clang_Module_getFullName(info->module);
3446 printf(" | loc: ");
3447 printCXIndexLoc(info->loc, client_data);
3448 printf(" | name: \"%s\"", clang_getCString(name));
3449 printf(" | isImplicit: %d\n", info->isImplicit);
3450 clang_disposeString(name);
3451 } else {
3452 /* PCH file, the rest are not relevant. */
3453 printf("\n");
3454 }
3455
3456 return (CXIdxClientFile)info->file;
3457}
3458
3459static CXIdxClientContainer
3460index_startedTranslationUnit(CXClientData client_data, void *reserved) {
3461 IndexData *index_data;
3462 index_data = (IndexData *)client_data;
3463 printCheck(index_data);
3464
3465 printf("[startedTranslationUnit]\n");
3466 return (CXIdxClientContainer)"TU";
3467}
3468
3469static void index_indexDeclaration(CXClientData client_data,
3470 const CXIdxDeclInfo *info) {
3471 IndexData *index_data;
3472 const CXIdxObjCCategoryDeclInfo *CatInfo;
3473 const CXIdxObjCInterfaceDeclInfo *InterInfo;
3474 const CXIdxObjCProtocolRefListInfo *ProtoInfo;
3475 const CXIdxObjCPropertyDeclInfo *PropInfo;
3476 const CXIdxCXXClassDeclInfo *CXXClassInfo;
3477 unsigned i;
3478 index_data = (IndexData *)client_data;
3479
3480 printEntityInfo("[indexDeclaration]", client_data, info->entityInfo);
3481 printf(" | cursor: ");
3482 PrintCursor(info->cursor, NULL((void*)0));
3483 printf(" | loc: ");
3484 printCXIndexLoc(info->loc, client_data);
3485 printf(" | semantic-container: ");
3486 printCXIndexContainer(info->semanticContainer);
3487 printf(" | lexical-container: ");
3488 printCXIndexContainer(info->lexicalContainer);
3489 printf(" | isRedecl: %d", info->isRedeclaration);
3490 printf(" | isDef: %d", info->isDefinition);
3491 if (info->flags & CXIdxDeclFlag_Skipped) {
3492 assert(!info->isContainer)((void) sizeof ((!info->isContainer) ? 1 : 0), __extension__
({ if (!info->isContainer) ; else __assert_fail ("!info->isContainer"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3492, __extension__ __PRETTY_FUNCTION__); }))
;
3493 printf(" | isContainer: skipped");
3494 } else {
3495 printf(" | isContainer: %d", info->isContainer);
3496 }
3497 printf(" | isImplicit: %d\n", info->isImplicit);
3498
3499 for (i = 0; i != info->numAttributes; ++i) {
3500 const CXIdxAttrInfo *Attr = info->attributes[i];
3501 printf(" <attribute>: ");
3502 PrintCursor(Attr->cursor, NULL((void*)0));
3503 printf("\n");
3504 }
3505
3506 if (clang_index_isEntityObjCContainerKind(info->entityInfo->kind)) {
3507 const char *kindName = 0;
3508 CXIdxObjCContainerKind K = clang_index_getObjCContainerDeclInfo(info)->kind;
3509 switch (K) {
3510 case CXIdxObjCContainer_ForwardRef:
3511 kindName = "forward-ref"; break;
3512 case CXIdxObjCContainer_Interface:
3513 kindName = "interface"; break;
3514 case CXIdxObjCContainer_Implementation:
3515 kindName = "implementation"; break;
3516 }
3517 printCheck(index_data);
3518 printf(" <ObjCContainerInfo>: kind: %s\n", kindName);
3519 }
3520
3521 if ((CatInfo = clang_index_getObjCCategoryDeclInfo(info))) {
3522 printEntityInfo(" <ObjCCategoryInfo>: class", client_data,
3523 CatInfo->objcClass);
3524 printf(" | cursor: ");
3525 PrintCursor(CatInfo->classCursor, NULL((void*)0));
3526 printf(" | loc: ");
3527 printCXIndexLoc(CatInfo->classLoc, client_data);
3528 printf("\n");
3529 }
3530
3531 if ((InterInfo = clang_index_getObjCInterfaceDeclInfo(info))) {
3532 if (InterInfo->superInfo) {
3533 printBaseClassInfo(client_data, InterInfo->superInfo);
3534 printf("\n");
3535 }
3536 }
3537
3538 if ((ProtoInfo = clang_index_getObjCProtocolRefListInfo(info))) {
3539 printProtocolList(ProtoInfo, client_data);
3540 }
3541
3542 if ((PropInfo = clang_index_getObjCPropertyDeclInfo(info))) {
3543 if (PropInfo->getter) {
3544 printEntityInfo(" <getter>", client_data, PropInfo->getter);
3545 printf("\n");
3546 }
3547 if (PropInfo->setter) {
3548 printEntityInfo(" <setter>", client_data, PropInfo->setter);
3549 printf("\n");
3550 }
3551 }
3552
3553 if ((CXXClassInfo = clang_index_getCXXClassDeclInfo(info))) {
3554 for (i = 0; i != CXXClassInfo->numBases; ++i) {
3555 printBaseClassInfo(client_data, CXXClassInfo->bases[i]);
3556 printf("\n");
3557 }
3558 }
3559
3560 if (info->declAsContainer)
3561 clang_index_setClientContainer(
3562 info->declAsContainer,
3563 makeClientContainer(client_data, info->entityInfo, info->loc));
3564}
3565
3566static void index_indexEntityReference(CXClientData client_data,
3567 const CXIdxEntityRefInfo *info) {
3568 printEntityInfo("[indexEntityReference]", client_data,
3569 info->referencedEntity);
3570 printf(" | cursor: ");
3571 PrintCursor(info->cursor, NULL((void*)0));
3572 printf(" | loc: ");
3573 printCXIndexLoc(info->loc, client_data);
3574 printEntityInfo(" | <parent>:", client_data, info->parentEntity);
3575 printf(" | container: ");
3576 printCXIndexContainer(info->container);
3577 printf(" | refkind: ");
3578 switch (info->kind) {
3579 case CXIdxEntityRef_Direct: printf("direct"); break;
3580 case CXIdxEntityRef_Implicit: printf("implicit"); break;
3581 }
3582 printf(" | role:");
3583 printSymbolRole(info->role);
3584 printf("\n");
3585}
3586
3587static int index_abortQuery(CXClientData client_data, void *reserved) {
3588 IndexData *index_data;
3589 index_data = (IndexData *)client_data;
3590 return index_data->abort;
3591}
3592
3593static IndexerCallbacks IndexCB = {
3594 index_abortQuery,
3595 index_diagnostic,
3596 index_enteredMainFile,
3597 index_ppIncludedFile,
3598 index_importedASTFile,
3599 index_startedTranslationUnit,
3600 index_indexDeclaration,
3601 index_indexEntityReference
3602};
3603
3604static unsigned getIndexOptions(void) {
3605 unsigned index_opts;
3606 index_opts = 0;
3607 if (getenv("CINDEXTEST_SUPPRESSREFS"))
3608 index_opts |= CXIndexOpt_SuppressRedundantRefs;
3609 if (getenv("CINDEXTEST_INDEXLOCALSYMBOLS"))
3610 index_opts |= CXIndexOpt_IndexFunctionLocalSymbols;
3611 if (!getenv("CINDEXTEST_DISABLE_SKIPPARSEDBODIES"))
3612 index_opts |= CXIndexOpt_SkipParsedBodiesInSession;
3613
3614 return index_opts;
3615}
3616
3617static int index_compile_args(int num_args, const char **args,
3618 CXIndexAction idxAction,
3619 ImportedASTFilesData *importedASTs,
3620 const char *check_prefix) {
3621 IndexData index_data;
3622 unsigned index_opts;
3623 int result;
3624
3625 if (num_args == 0) {
3626 fprintf(stderrstderr, "no compiler arguments\n");
3627 return -1;
3628 }
3629
3630 index_data.check_prefix = check_prefix;
3631 index_data.first_check_printed = 0;
3632 index_data.fail_for_error = 0;
3633 index_data.abort = 0;
3634 index_data.main_filename = createCXString("");
3635 index_data.importedASTs = importedASTs;
3636 index_data.strings = NULL((void*)0);
3637 index_data.TU = NULL((void*)0);
3638
3639 index_opts = getIndexOptions();
3640 result = clang_indexSourceFile(idxAction, &index_data,
3641 &IndexCB,sizeof(IndexCB), index_opts,
3642 0, args, num_args, 0, 0, 0,
3643 getDefaultParsingOptions());
3644 if (result != CXError_Success)
3645 describeLibclangFailure(result);
3646
3647 if (index_data.fail_for_error)
3648 result = -1;
3649
3650 clang_disposeString(index_data.main_filename);
3651 free_client_data(&index_data);
3652 return result;
3653}
3654
3655static int index_ast_file(const char *ast_file,
3656 CXIndex Idx,
3657 CXIndexAction idxAction,
3658 ImportedASTFilesData *importedASTs,
3659 const char *check_prefix) {
3660 CXTranslationUnit TU;
3661 IndexData index_data;
3662 unsigned index_opts;
3663 int result;
3664
3665 if (!CreateTranslationUnit(Idx, ast_file, &TU))
3666 return -1;
3667
3668 index_data.check_prefix = check_prefix;
3669 index_data.first_check_printed = 0;
3670 index_data.fail_for_error = 0;
3671 index_data.abort = 0;
3672 index_data.main_filename = createCXString("");
3673 index_data.importedASTs = importedASTs;
3674 index_data.strings = NULL((void*)0);
3675 index_data.TU = TU;
3676
3677 index_opts = getIndexOptions();
3678 result = clang_indexTranslationUnit(idxAction, &index_data,
3679 &IndexCB,sizeof(IndexCB),
3680 index_opts, TU);
3681 if (index_data.fail_for_error)
3682 result = -1;
3683
3684 clang_disposeTranslationUnit(TU);
3685 clang_disposeString(index_data.main_filename);
3686 free_client_data(&index_data);
3687 return result;
3688}
3689
3690static int index_file(int argc, const char **argv, int full) {
3691 const char *check_prefix;
3692 CXIndex Idx;
3693 CXIndexAction idxAction;
3694 ImportedASTFilesData *importedASTs;
3695 int result;
3696
3697 check_prefix = 0;
3698 if (argc > 0) {
3699 if (strstr(argv[0], "-check-prefix=") == argv[0]) {
3700 check_prefix = argv[0] + strlen("-check-prefix=");
3701 ++argv;
3702 --argc;
3703 }
3704 }
3705
3706 if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
3707 /* displayDiagnostics=*/1))) {
3708 fprintf(stderrstderr, "Could not create Index\n");
3709 return 1;
3710 }
3711 idxAction = clang_IndexAction_create(Idx);
3712 importedASTs = 0;
3713 if (full)
3714 importedASTs = importedASTs_create();
3715
3716 result = index_compile_args(argc, argv, idxAction, importedASTs, check_prefix);
3717 if (result != 0)
3718 goto finished;
3719
3720 if (full) {
3721 unsigned i;
3722 for (i = 0; i < importedASTs->num_files && result == 0; ++i) {
3723 result = index_ast_file(importedASTs->filenames[i], Idx, idxAction,
3724 importedASTs, check_prefix);
3725 }
3726 }
3727
3728finished:
3729 importedASTs_dispose(importedASTs);
3730 clang_IndexAction_dispose(idxAction);
3731 clang_disposeIndex(Idx);
3732 return result;
3733}
3734
3735static int index_tu(int argc, const char **argv) {
3736 const char *check_prefix;
3737 CXIndex Idx;
3738 CXIndexAction idxAction;
3739 int result;
3740
3741 check_prefix = 0;
3742 if (argc > 0) {
3743 if (strstr(argv[0], "-check-prefix=") == argv[0]) {
3744 check_prefix = argv[0] + strlen("-check-prefix=");
3745 ++argv;
3746 --argc;
3747 }
3748 }
3749
3750 if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
3751 /* displayDiagnostics=*/1))) {
3752 fprintf(stderrstderr, "Could not create Index\n");
3753 return 1;
3754 }
3755 idxAction = clang_IndexAction_create(Idx);
3756
3757 result = index_ast_file(argv[0], Idx, idxAction,
3758 /*importedASTs=*/0, check_prefix);
3759
3760 clang_IndexAction_dispose(idxAction);
3761 clang_disposeIndex(Idx);
3762 return result;
3763}
3764
3765static int index_compile_db(int argc, const char **argv) {
3766 const char *check_prefix;
3767 CXIndex Idx;
3768 CXIndexAction idxAction;
3769 int errorCode = 0;
3770
3771 check_prefix = 0;
3772 if (argc > 0) {
3773 if (strstr(argv[0], "-check-prefix=") == argv[0]) {
3774 check_prefix = argv[0] + strlen("-check-prefix=");
3775 ++argv;
3776 --argc;
3777 }
3778 }
3779
3780 if (argc == 0) {
3781 fprintf(stderrstderr, "no compilation database\n");
3782 return -1;
3783 }
3784
3785 if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
3786 /* displayDiagnostics=*/1))) {
3787 fprintf(stderrstderr, "Could not create Index\n");
3788 return 1;
3789 }
3790 idxAction = clang_IndexAction_create(Idx);
3791
3792 {
3793 const char *database = argv[0];
3794 CXCompilationDatabase db = 0;
3795 CXCompileCommands CCmds = 0;
3796 CXCompileCommand CCmd;
3797 CXCompilationDatabase_Error ec;
3798 CXString wd;
3799#define MAX_COMPILE_ARGS512 512
3800 CXString cxargs[MAX_COMPILE_ARGS512];
3801 const char *args[MAX_COMPILE_ARGS512];
3802 char *tmp;
3803 unsigned len;
3804 char *buildDir;
3805 int i, a, numCmds, numArgs;
3806
3807 len = strlen(database);
3808 tmp = (char *) malloc(len+1);
3809 assert(tmp)((void) sizeof ((tmp) ? 1 : 0), __extension__ ({ if (tmp) ; else
__assert_fail ("tmp", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3809, __extension__ __PRETTY_FUNCTION__); }))
;
3810 memcpy(tmp, database, len+1);
3811 buildDir = dirname(tmp);
3812
3813 db = clang_CompilationDatabase_fromDirectory(buildDir, &ec);
3814
3815 if (db) {
3816
3817 if (ec!=CXCompilationDatabase_NoError) {
3818 printf("unexpected error %d code while loading compilation database\n", ec);
3819 errorCode = -1;
3820 goto cdb_end;
3821 }
3822
3823 if (chdir(buildDir) != 0) {
3824 printf("Could not chdir to %s\n", buildDir);
3825 errorCode = -1;
3826 goto cdb_end;
3827 }
3828
3829 CCmds = clang_CompilationDatabase_getAllCompileCommands(db);
3830 if (!CCmds) {
3831 printf("compilation db is empty\n");
3832 errorCode = -1;
3833 goto cdb_end;
3834 }
3835
3836 numCmds = clang_CompileCommands_getSize(CCmds);
3837
3838 if (numCmds==0) {
3839 fprintf(stderrstderr, "should not get an empty compileCommand set\n");
3840 errorCode = -1;
3841 goto cdb_end;
3842 }
3843
3844 for (i=0; i<numCmds && errorCode == 0; ++i) {
3845 CCmd = clang_CompileCommands_getCommand(CCmds, i);
3846
3847 wd = clang_CompileCommand_getDirectory(CCmd);
3848 if (chdir(clang_getCString(wd)) != 0) {
3849 printf("Could not chdir to %s\n", clang_getCString(wd));
3850 errorCode = -1;
3851 goto cdb_end;
3852 }
3853 clang_disposeString(wd);
3854
3855 numArgs = clang_CompileCommand_getNumArgs(CCmd);
3856 if (numArgs > MAX_COMPILE_ARGS512){
3857 fprintf(stderrstderr, "got more compile arguments than maximum\n");
3858 errorCode = -1;
3859 goto cdb_end;
3860 }
3861 for (a=0; a<numArgs; ++a) {
3862 cxargs[a] = clang_CompileCommand_getArg(CCmd, a);
3863 args[a] = clang_getCString(cxargs[a]);
3864 }
3865
3866 errorCode = index_compile_args(numArgs, args, idxAction,
3867 /*importedASTs=*/0, check_prefix);
3868
3869 for (a=0; a<numArgs; ++a)
3870 clang_disposeString(cxargs[a]);
3871 }
3872 } else {
3873 printf("database loading failed with error code %d.\n", ec);
3874 errorCode = -1;
3875 }
3876
3877 cdb_end:
3878 clang_CompileCommands_dispose(CCmds);
3879 clang_CompilationDatabase_dispose(db);
3880 free(tmp);
3881
3882 }
3883
3884 clang_IndexAction_dispose(idxAction);
3885 clang_disposeIndex(Idx);
3886 return errorCode;
3887}
3888
3889int perform_token_annotation(int argc, const char **argv) {
3890 const char *input = argv[1];
3891 char *filename = 0;
3892 unsigned line, second_line;
3893 unsigned column, second_column;
3894 CXIndex CIdx;
3895 CXTranslationUnit TU = 0;
3896 int errorCode;
3897 struct CXUnsavedFile *unsaved_files = 0;
3898 int num_unsaved_files = 0;
3899 CXToken *tokens;
3900 unsigned num_tokens;
3901 CXSourceRange range;
3902 CXSourceLocation startLoc, endLoc;
3903 CXFile file = 0;
3904 CXCursor *cursors = 0;
3905 CXSourceRangeList *skipped_ranges = 0;
3906 enum CXErrorCode Err;
3907 unsigned i;
3908
3909 input += strlen("-test-annotate-tokens=");
3910 if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
3911 &second_line, &second_column)))
3912 return errorCode;
3913
3914 if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files)) {
3915 free(filename);
3916 return -1;
3917 }
3918
3919 CIdx = clang_createIndex(0, 1);
3920 Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
3921 argv + num_unsaved_files + 2,
3922 argc - num_unsaved_files - 3,
3923 unsaved_files,
3924 num_unsaved_files,
3925 getDefaultParsingOptions(), &TU);
3926 if (Err != CXError_Success) {
3927 fprintf(stderrstderr, "unable to parse input\n");
3928 describeLibclangFailure(Err);
3929 clang_disposeIndex(CIdx);
3930 free(filename);
3931 free_remapped_files(unsaved_files, num_unsaved_files);
3932 return -1;
3933 }
3934 errorCode = 0;
3935
3936 if (checkForErrors(TU) != 0) {
3937 errorCode = -1;
3938 goto teardown;
3939 }
3940
3941 if (getenv("CINDEXTEST_EDITING")) {
3942 for (i = 0; i < 5; ++i) {
3943 Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
3944 clang_defaultReparseOptions(TU));
3945 if (Err != CXError_Success) {
3946 fprintf(stderrstderr, "Unable to reparse translation unit!\n");
3947 describeLibclangFailure(Err);
3948 errorCode = -1;
3949 goto teardown;
3950 }
3951 }
3952 }
3953
3954 if (checkForErrors(TU) != 0) {
3955 errorCode = -1;
3956 goto teardown;
3957 }
3958
3959 file = clang_getFile(TU, filename);
3960 if (!file) {
3961 fprintf(stderrstderr, "file %s is not in this translation unit\n", filename);
3962 errorCode = -1;
3963 goto teardown;
3964 }
3965
3966 startLoc = clang_getLocation(TU, file, line, column);
3967 if (clang_equalLocations(clang_getNullLocation(), startLoc)) {
3968 fprintf(stderrstderr, "invalid source location %s:%d:%d\n", filename, line,
3969 column);
3970 errorCode = -1;
3971 goto teardown;
3972 }
3973
3974 endLoc = clang_getLocation(TU, file, second_line, second_column);
3975 if (clang_equalLocations(clang_getNullLocation(), endLoc)) {
3976 fprintf(stderrstderr, "invalid source location %s:%d:%d\n", filename,
3977 second_line, second_column);
3978 errorCode = -1;
3979 goto teardown;
3980 }
3981
3982 range = clang_getRange(startLoc, endLoc);
3983 clang_tokenize(TU, range, &tokens, &num_tokens);
3984
3985 if (checkForErrors(TU) != 0) {
3986 errorCode = -1;
3987 goto teardown;
3988 }
3989
3990 cursors = (CXCursor *)malloc(num_tokens * sizeof(CXCursor));
3991 assert(cursors)((void) sizeof ((cursors) ? 1 : 0), __extension__ ({ if (cursors
) ; else __assert_fail ("cursors", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 3991, __extension__ __PRETTY_FUNCTION__); }))
;
3992 clang_annotateTokens(TU, tokens, num_tokens, cursors);
3993
3994 if (checkForErrors(TU) != 0) {
3995 errorCode = -1;
3996 goto teardown;
3997 }
3998
3999 skipped_ranges = clang_getSkippedRanges(TU, file);
4000 for (i = 0; i != skipped_ranges->count; ++i) {
4001 unsigned start_line, start_column, end_line, end_column;
4002 clang_getSpellingLocation(clang_getRangeStart(skipped_ranges->ranges[i]),
4003 0, &start_line, &start_column, 0);
4004 clang_getSpellingLocation(clang_getRangeEnd(skipped_ranges->ranges[i]),
4005 0, &end_line, &end_column, 0);
4006 printf("Skipping: ");
4007 PrintExtent(stdoutstdout, start_line, start_column, end_line, end_column);
4008 printf("\n");
4009 }
4010 clang_disposeSourceRangeList(skipped_ranges);
4011
4012 for (i = 0; i != num_tokens; ++i) {
4013 const char *kind = "<unknown>";
4014 CXString spelling = clang_getTokenSpelling(TU, tokens[i]);
4015 CXSourceRange extent = clang_getTokenExtent(TU, tokens[i]);
4016 unsigned start_line, start_column, end_line, end_column;
4017
4018 switch (clang_getTokenKind(tokens[i])) {
4019 case CXToken_Punctuation: kind = "Punctuation"; break;
4020 case CXToken_Keyword: kind = "Keyword"; break;
4021 case CXToken_Identifier: kind = "Identifier"; break;
4022 case CXToken_Literal: kind = "Literal"; break;
4023 case CXToken_Comment: kind = "Comment"; break;
4024 }
4025 clang_getSpellingLocation(clang_getRangeStart(extent),
4026 0, &start_line, &start_column, 0);
4027 clang_getSpellingLocation(clang_getRangeEnd(extent),
4028 0, &end_line, &end_column, 0);
4029 printf("%s: \"%s\" ", kind, clang_getCString(spelling));
4030 clang_disposeString(spelling);
4031 PrintExtent(stdoutstdout, start_line, start_column, end_line, end_column);
4032 if (!clang_isInvalid(cursors[i].kind)) {
4033 printf(" ");
4034 PrintCursor(cursors[i], NULL((void*)0));
4035 }
4036 printf("\n");
4037 }
4038 free(cursors);
4039 clang_disposeTokens(TU, tokens, num_tokens);
4040
4041 teardown:
4042 PrintDiagnostics(TU);
4043 clang_disposeTranslationUnit(TU);
4044 clang_disposeIndex(CIdx);
4045 free(filename);
4046 free_remapped_files(unsaved_files, num_unsaved_files);
4047 return errorCode;
4048}
4049
4050static int
4051perform_test_compilation_db(const char *database, int argc, const char **argv) {
4052 CXCompilationDatabase db;
4053 CXCompileCommands CCmds;
4054 CXCompileCommand CCmd;
4055 CXCompilationDatabase_Error ec;
4056 CXString wd;
4057 CXString arg;
4058 int errorCode = 0;
4059 char *tmp;
4060 unsigned len;
4061 char *buildDir;
4062 int i, j, a, numCmds, numArgs;
4063
4064 len = strlen(database);
4065 tmp = (char *) malloc(len+1);
4066 assert(tmp)((void) sizeof ((tmp) ? 1 : 0), __extension__ ({ if (tmp) ; else
__assert_fail ("tmp", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/c-index-test/c-index-test.c"
, 4066, __extension__ __PRETTY_FUNCTION__); }))
;
4067 memcpy(tmp, database, len+1);
4068 buildDir = dirname(tmp);
4069
4070 db = clang_CompilationDatabase_fromDirectory(buildDir, &ec);
4071
4072 if (db) {
4073
4074 if (ec!=CXCompilationDatabase_NoError) {
4075 printf("unexpected error %d code while loading compilation database\n", ec);
4076 errorCode = -1;
4077 goto cdb_end;
4078 }
4079
4080 for (i=0; i<argc && errorCode==0; ) {
4081 if (strcmp(argv[i],"lookup")==0){
4082 CCmds = clang_CompilationDatabase_getCompileCommands(db, argv[i+1]);
4083
4084 if (!CCmds) {
4085 printf("file %s not found in compilation db\n", argv[i+1]);
4086 errorCode = -1;
4087 break;
4088 }
4089
4090 numCmds = clang_CompileCommands_getSize(CCmds);
4091
4092 if (numCmds==0) {
4093 fprintf(stderrstderr, "should not get an empty compileCommand set for file"
4094 " '%s'\n", argv[i+1]);
4095 errorCode = -1;
4096 break;
4097 }
4098
4099 for (j=0; j<numCmds; ++j) {
4100 CCmd = clang_CompileCommands_getCommand(CCmds, j);
4101
4102 wd = clang_CompileCommand_getDirectory(CCmd);
4103 printf("workdir:'%s'", clang_getCString(wd));
4104 clang_disposeString(wd);
4105
4106 printf(" cmdline:'");
4107 numArgs = clang_CompileCommand_getNumArgs(CCmd);
4108 for (a=0; a<numArgs; ++a) {
4109 if (a) printf(" ");
4110 arg = clang_CompileCommand_getArg(CCmd, a);
4111 printf("%s", clang_getCString(arg));
4112 clang_disposeString(arg);
4113 }
4114 printf("'\n");
4115 }
4116
4117 clang_CompileCommands_dispose(CCmds);
4118
4119 i += 2;
4120 }
4121 }
4122 clang_CompilationDatabase_dispose(db);
4123 } else {
4124 printf("database loading failed with error code %d.\n", ec);
4125 errorCode = -1;
4126 }
4127
4128cdb_end:
4129 free(tmp);
4130
4131 return errorCode;
4132}
4133
4134/******************************************************************************/
4135/* USR printing. */
4136/******************************************************************************/
4137
4138static int insufficient_usr(const char *kind, const char *usage) {
4139 fprintf(stderrstderr, "USR for '%s' requires: %s\n", kind, usage);
4140 return 1;
4141}
4142
4143static unsigned isUSR(const char *s) {
4144 return s[0] == 'c' && s[1] == ':';
4145}
4146
4147static int not_usr(const char *s, const char *arg) {
4148 fprintf(stderrstderr, "'%s' argument ('%s') is not a USR\n", s, arg);
4149 return 1;
4150}
4151
4152static void print_usr(CXString usr) {
4153 const char *s = clang_getCString(usr);
4154 printf("%s\n", s);
4155 clang_disposeString(usr);
4156}
4157
4158static void display_usrs() {
4159 fprintf(stderrstderr, "-print-usrs options:\n"
4160 " ObjCCategory <class name> <category name>\n"
4161 " ObjCClass <class name>\n"
4162 " ObjCIvar <ivar name> <class USR>\n"
4163 " ObjCMethod <selector> [0=class method|1=instance method] "
4164 "<class USR>\n"
4165 " ObjCProperty <property name> <class USR>\n"
4166 " ObjCProtocol <protocol name>\n");
4167}
4168
4169int print_usrs(const char **I, const char **E) {
4170 while (I != E) {
4171 const char *kind = *I;
4172 unsigned len = strlen(kind);
4173 switch (len) {
4174 case 8:
4175 if (memcmp(kind, "ObjCIvar", 8) == 0) {
4176 if (I + 2 >= E)
4177 return insufficient_usr(kind, "<ivar name> <class USR>");
4178 if (!isUSR(I[2]))
4179 return not_usr("<class USR>", I[2]);
4180 else {
4181 CXString x = createCXString(I[2]);
4182 print_usr(clang_constructUSR_ObjCIvar(I[1], x));
4183 }
4184
4185 I += 3;
4186 continue;
4187 }
4188 break;
4189 case 9:
4190 if (memcmp(kind, "ObjCClass", 9) == 0) {
4191 if (I + 1 >= E)
4192 return insufficient_usr(kind, "<class name>");
4193 print_usr(clang_constructUSR_ObjCClass(I[1]));
4194 I += 2;
4195 continue;
4196 }
4197 break;
4198 case 10:
4199 if (memcmp(kind, "ObjCMethod", 10) == 0) {
4200 if (I + 3 >= E)
4201 return insufficient_usr(kind, "<method selector> "
4202 "[0=class method|1=instance method] <class USR>");
4203 if (!isUSR(I[3]))
4204 return not_usr("<class USR>", I[3]);
4205 else {
4206 CXString x = createCXString(I[3]);
4207 print_usr(clang_constructUSR_ObjCMethod(I[1], atoi(I[2]), x));
4208 }
4209 I += 4;
4210 continue;
4211 }
4212 break;
4213 case 12:
4214 if (memcmp(kind, "ObjCCategory", 12) == 0) {
4215 if (I + 2 >= E)
4216 return insufficient_usr(kind, "<class name> <category name>");
4217 print_usr(clang_constructUSR_ObjCCategory(I[1], I[2]));
4218 I += 3;
4219 continue;
4220 }
4221 if (memcmp(kind, "ObjCProtocol", 12) == 0) {
4222 if (I + 1 >= E)
4223 return insufficient_usr(kind, "<protocol name>");
4224 print_usr(clang_constructUSR_ObjCProtocol(I[1]));
4225 I += 2;
4226 continue;
4227 }
4228 if (memcmp(kind, "ObjCProperty", 12) == 0) {
4229 if (I + 2 >= E)
4230 return insufficient_usr(kind, "<property name> <class USR>");
4231 if (!isUSR(I[2]))
4232 return not_usr("<class USR>", I[2]);
4233 else {
4234 CXString x = createCXString(I[2]);
4235 print_usr(clang_constructUSR_ObjCProperty(I[1], x));
4236 }
4237 I += 3;
4238 continue;
4239 }
4240 break;
4241 default:
4242 break;
4243 }
4244 break;
4245 }
4246
4247 if (I != E) {
4248 fprintf(stderrstderr, "Invalid USR kind: %s\n", *I);
4249 display_usrs();
4250 return 1;
4251 }
4252 return 0;
4253}
4254
4255int print_usrs_file(const char *file_name) {
4256 char line[2048];
4257 const char *args[128];
4258 unsigned numChars = 0;
4259
4260 FILE *fp = fopen(file_name, "r");
4261 if (!fp) {
4262 fprintf(stderrstderr, "error: cannot open '%s'\n", file_name);
4263 return 1;
4264 }
4265
4266 /* This code is not really all that safe, but it works fine for testing. */
4267 while (!feof(fp)) {
4268 char c = fgetc(fp);
4269 if (c == '\n') {
4270 unsigned i = 0;
4271 const char *s = 0;
4272
4273 if (numChars == 0)
4274 continue;
4275
4276 line[numChars] = '\0';
4277 numChars = 0;
4278
4279 if (line[0] == '/' && line[1] == '/')
4280 continue;
4281
4282 s = strtok(line, " ");
4283 while (s) {
4284 args[i] = s;
4285 ++i;
4286 s = strtok(0, " ");
4287 }
4288 if (print_usrs(&args[0], &args[i]))
4289 return 1;
4290 }
4291 else
4292 line[numChars++] = c;
4293 }
4294
4295 fclose(fp);
4296 return 0;
4297}
4298
4299/******************************************************************************/
4300/* Command line processing. */
4301/******************************************************************************/
4302int write_pch_file(const char *filename, int argc, const char *argv[]) {
4303 CXIndex Idx;
4304 CXTranslationUnit TU;
4305 struct CXUnsavedFile *unsaved_files = 0;
4306 int num_unsaved_files = 0;
4307 enum CXErrorCode Err;
4308 int result = 0;
4309
4310 Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnostics=*/1);
4311
4312 if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
4313 clang_disposeIndex(Idx);
4314 return -1;
4315 }
4316
4317 Err = clang_parseTranslationUnit2(
4318 Idx, 0, argv + num_unsaved_files, argc - num_unsaved_files,
4319 unsaved_files, num_unsaved_files,
4320 CXTranslationUnit_Incomplete |
4321 CXTranslationUnit_DetailedPreprocessingRecord |
4322 CXTranslationUnit_ForSerialization,
4323 &TU);
4324 if (Err != CXError_Success) {
4325 fprintf(stderrstderr, "Unable to load translation unit!\n");
4326 describeLibclangFailure(Err);
4327 free_remapped_files(unsaved_files, num_unsaved_files);
4328 clang_disposeTranslationUnit(TU);
4329 clang_disposeIndex(Idx);
4330 return 1;
4331 }
4332
4333 switch (clang_saveTranslationUnit(TU, filename,
4334 clang_defaultSaveOptions(TU))) {
4335 case CXSaveError_None:
4336 break;
4337
4338 case CXSaveError_TranslationErrors:
4339 fprintf(stderrstderr, "Unable to write PCH file %s: translation errors\n",
4340 filename);
4341 result = 2;
4342 break;
4343
4344 case CXSaveError_InvalidTU:
4345 fprintf(stderrstderr, "Unable to write PCH file %s: invalid translation unit\n",
4346 filename);
4347 result = 3;
4348 break;
4349
4350 case CXSaveError_Unknown:
4351 default:
4352 fprintf(stderrstderr, "Unable to write PCH file %s: unknown error \n", filename);
4353 result = 1;
4354 break;
4355 }
4356
4357 clang_disposeTranslationUnit(TU);
4358 free_remapped_files(unsaved_files, num_unsaved_files);
4359 clang_disposeIndex(Idx);
4360 return result;
4361}
4362
4363/******************************************************************************/
4364/* Serialized diagnostics. */
4365/******************************************************************************/
4366
4367static const char *getDiagnosticCodeStr(enum CXLoadDiag_Error error) {
4368 switch (error) {
4369 case CXLoadDiag_CannotLoad: return "Cannot Load File";
4370 case CXLoadDiag_None: break;
4371 case CXLoadDiag_Unknown: return "Unknown";
4372 case CXLoadDiag_InvalidFile: return "Invalid File";
4373 }
4374 return "None";
4375}
4376
4377static const char *getSeverityString(enum CXDiagnosticSeverity severity) {
4378 switch (severity) {
4379 case CXDiagnostic_Note: return "note";
4380 case CXDiagnostic_Error: return "error";
4381 case CXDiagnostic_Fatal: return "fatal";
4382 case CXDiagnostic_Ignored: return "ignored";
4383 case CXDiagnostic_Warning: return "warning";
4384 }
4385 return "unknown";
4386}
4387
4388static void printIndent(unsigned indent) {
4389 if (indent == 0)
4390 return;
4391 fprintf(stderrstderr, "+");
4392 --indent;
4393 while (indent > 0) {
4394 fprintf(stderrstderr, "-");
4395 --indent;
4396 }
4397}
4398
4399static void printLocation(CXSourceLocation L) {
4400 CXFile File;
4401 CXString FileName;
4402 unsigned line, column, offset;
4403
4404 clang_getExpansionLocation(L, &File, &line, &column, &offset);
4405 FileName = clang_getFileName(File);
4406
4407 fprintf(stderrstderr, "%s:%d:%d", clang_getCString(FileName), line, column);
4408 clang_disposeString(FileName);
4409}
4410
4411static void printRanges(CXDiagnostic D, unsigned indent) {
4412 unsigned i, n = clang_getDiagnosticNumRanges(D);
4413
4414 for (i = 0; i < n; ++i) {
4415 CXSourceLocation Start, End;
4416 CXSourceRange SR = clang_getDiagnosticRange(D, i);
4417 Start = clang_getRangeStart(SR);
4418 End = clang_getRangeEnd(SR);
4419
4420 printIndent(indent);
4421 fprintf(stderrstderr, "Range: ");
4422 printLocation(Start);
4423 fprintf(stderrstderr, " ");
4424 printLocation(End);
4425 fprintf(stderrstderr, "\n");
4426 }
4427}
4428
4429static void printFixIts(CXDiagnostic D, unsigned indent) {
4430 unsigned i, n = clang_getDiagnosticNumFixIts(D);
4431 fprintf(stderrstderr, "Number FIXITs = %d\n", n);
4432 for (i = 0 ; i < n; ++i) {
4433 CXSourceRange ReplacementRange;
4434 CXString text;
4435 text = clang_getDiagnosticFixIt(D, i, &ReplacementRange);
4436
4437 printIndent(indent);
4438 fprintf(stderrstderr, "FIXIT: (");
4439 printLocation(clang_getRangeStart(ReplacementRange));
4440 fprintf(stderrstderr, " - ");
4441 printLocation(clang_getRangeEnd(ReplacementRange));
4442 fprintf(stderrstderr, "): \"%s\"\n", clang_getCString(text));
4443 clang_disposeString(text);
4444 }
4445}
4446
4447static void printDiagnosticSet(CXDiagnosticSet Diags, unsigned indent) {
4448 unsigned i, n;
4449
4450 if (!Diags)
4451 return;
4452
4453 n = clang_getNumDiagnosticsInSet(Diags);
4454 for (i = 0; i < n; ++i) {
4455 CXSourceLocation DiagLoc;
4456 CXDiagnostic D;
4457 CXFile File;
4458 CXString FileName, DiagSpelling, DiagOption, DiagCat;
4459 unsigned line, column, offset;
4460 const char *DiagOptionStr = 0, *DiagCatStr = 0;
4461
4462 D = clang_getDiagnosticInSet(Diags, i);
4463 DiagLoc = clang_getDiagnosticLocation(D);
4464 clang_getExpansionLocation(DiagLoc, &File, &line, &column, &offset);
4465 FileName = clang_getFileName(File);
4466 DiagSpelling = clang_getDiagnosticSpelling(D);
4467
4468 printIndent(indent);
4469
4470 fprintf(stderrstderr, "%s:%d:%d: %s: %s",
4471 clang_getCString(FileName),
4472 line,
4473 column,
4474 getSeverityString(clang_getDiagnosticSeverity(D)),
4475 clang_getCString(DiagSpelling));
4476
4477 DiagOption = clang_getDiagnosticOption(D, 0);
4478 DiagOptionStr = clang_getCString(DiagOption);
4479 if (DiagOptionStr) {
4480 fprintf(stderrstderr, " [%s]", DiagOptionStr);
4481 }
4482
4483 DiagCat = clang_getDiagnosticCategoryText(D);
4484 DiagCatStr = clang_getCString(DiagCat);
4485 if (DiagCatStr) {
4486 fprintf(stderrstderr, " [%s]", DiagCatStr);
4487 }
4488
4489 fprintf(stderrstderr, "\n");
4490
4491 printRanges(D, indent);
4492 printFixIts(D, indent);
4493
4494 /* Print subdiagnostics. */
4495 printDiagnosticSet(clang_getChildDiagnostics(D), indent+2);
4496
4497 clang_disposeString(FileName);
4498 clang_disposeString(DiagSpelling);
4499 clang_disposeString(DiagOption);
4500 clang_disposeString(DiagCat);
4501 }
4502}
4503
4504static int read_diagnostics(const char *filename) {
4505 enum CXLoadDiag_Error error;
4506 CXString errorString;
4507 CXDiagnosticSet Diags = 0;
4508
4509 Diags = clang_loadDiagnostics(filename, &error, &errorString);
4510 if (!Diags) {
4511 fprintf(stderrstderr, "Trouble deserializing file (%s): %s\n",
4512 getDiagnosticCodeStr(error),
4513 clang_getCString(errorString));
4514 clang_disposeString(errorString);
4515 return 1;
4516 }
4517
4518 printDiagnosticSet(Diags, 0);
4519 fprintf(stderrstderr, "Number of diagnostics: %d\n",
4520 clang_getNumDiagnosticsInSet(Diags));
4521 clang_disposeDiagnosticSet(Diags);
4522 return 0;
4523}
4524
4525static int perform_print_build_session_timestamp(void) {
4526 printf("%lld\n", clang_getBuildSessionTimestamp());
4527 return 0;
4528}
4529
4530/******************************************************************************/
4531/* Command line processing. */
4532/******************************************************************************/
4533
4534static CXCursorVisitor GetVisitor(const char *s) {
4535 if (s[0] == '\0')
4536 return FilteredPrintingVisitor;
4537 if (strcmp(s, "-usrs") == 0)
4538 return USRVisitor;
4539 if (strncmp(s, "-memory-usage", 13) == 0)
4540 return GetVisitor(s + 13);
4541 return NULL((void*)0);
4542}
4543
4544static void print_usage(void) {
4545 fprintf(stderrstderr,
4546 "usage: c-index-test -code-completion-at=<site> <compiler arguments>\n"
4547 " c-index-test -code-completion-timing=<site> <compiler arguments>\n"
4548 " c-index-test -cursor-at=<site> <compiler arguments>\n"
4549 " c-index-test -evaluate-cursor-at=<site> <compiler arguments>\n"
4550 " c-index-test -get-macro-info-cursor-at=<site> <compiler arguments>\n"
4551 " c-index-test -file-refs-at=<site> <compiler arguments>\n"
4552 " c-index-test -file-includes-in=<filename> <compiler arguments>\n");
4553 fprintf(stderrstderr,
4554 " c-index-test -index-file [-check-prefix=<FileCheck prefix>] <compiler arguments>\n"
4555 " c-index-test -index-file-full [-check-prefix=<FileCheck prefix>] <compiler arguments>\n"
4556 " c-index-test -index-tu [-check-prefix=<FileCheck prefix>] <AST file>\n"
4557 " c-index-test -index-compile-db [-check-prefix=<FileCheck prefix>] <compilation database>\n"
4558 " c-index-test -test-file-scan <AST file> <source file> "
4559 "[FileCheck prefix]\n");
4560 fprintf(stderrstderr,
4561 " c-index-test -test-load-tu <AST file> <symbol filter> "
4562 "[FileCheck prefix]\n"
4563 " c-index-test -test-load-tu-usrs <AST file> <symbol filter> "
4564 "[FileCheck prefix]\n"
4565 " c-index-test -test-load-source <symbol filter> {<args>}*\n");
4566 fprintf(stderrstderr,
4567 " c-index-test -test-load-source-memory-usage "
4568 "<symbol filter> {<args>}*\n"
4569 " c-index-test -test-load-source-reparse <trials> <symbol filter> "
4570 " {<args>}*\n"
4571 " c-index-test -test-load-source-usrs <symbol filter> {<args>}*\n"
4572 " c-index-test -test-load-source-usrs-memory-usage "
4573 "<symbol filter> {<args>}*\n"
4574 " c-index-test -test-annotate-tokens=<range> {<args>}*\n"
4575 " c-index-test -test-inclusion-stack-source {<args>}*\n"
4576 " c-index-test -test-inclusion-stack-tu <AST file>\n");
4577 fprintf(stderrstderr,
4578 " c-index-test -test-print-linkage-source {<args>}*\n"
4579 " c-index-test -test-print-visibility {<args>}*\n"
4580 " c-index-test -test-print-type {<args>}*\n"
4581 " c-index-test -test-print-type-size {<args>}*\n"
4582 " c-index-test -test-print-bitwidth {<args>}*\n"
4583 " c-index-test -test-print-target-info {<args>}*\n"
4584 " c-index-test -test-print-type-declaration {<args>}*\n"
4585 " c-index-test -print-usr [<CursorKind> {<args>}]*\n"
4586 " c-index-test -print-usr-file <file>\n");
4587 fprintf(stderrstderr,
4588 " c-index-test -write-pch <file> <compiler arguments>\n"
4589 " c-index-test -compilation-db [lookup <filename>] database\n");
4590 fprintf(stderrstderr,
4591 " c-index-test -print-build-session-timestamp\n");
4592 fprintf(stderrstderr,
4593 " c-index-test -read-diagnostics <file>\n\n");
4594 fprintf(stderrstderr,
4595 " <symbol filter> values:\n%s",
4596 " all - load all symbols, including those from PCH\n"
4597 " local - load all symbols except those in PCH\n"
4598 " category - only load ObjC categories (non-PCH)\n"
4599 " interface - only load ObjC interfaces (non-PCH)\n"
4600 " protocol - only load ObjC protocols (non-PCH)\n"
4601 " function - only load functions (non-PCH)\n"
4602 " typedef - only load typdefs (non-PCH)\n"
4603 " scan-function - scan function bodies (non-PCH)\n\n");
4604}
4605
4606/***/
4607
4608int cindextest_main(int argc, const char **argv) {
4609 clang_enableStackTraces();
4610 if (argc > 2 && strcmp(argv[1], "-read-diagnostics") == 0)
1
Assuming 'argc' is > 2
2
Assuming the condition is false
3
Taking false branch
4611 return read_diagnostics(argv[2]);
4612 if (argc > 2 && strstr(argv[1], "-code-completion-at=") == argv[1])
4
Assuming the condition is false
5
Taking false branch
4613 return perform_code_completion(argc, argv, 0);
4614 if (argc > 2 && strstr(argv[1], "-code-completion-timing=") == argv[1])
6
Assuming the condition is false
7
Taking false branch
4615 return perform_code_completion(argc, argv, 1);
4616 if (argc > 2 && strstr(argv[1], "-cursor-at=") == argv[1])
8
Assuming the condition is false
9
Taking false branch
4617 return inspect_cursor_at(argc, argv, "-cursor-at=", inspect_print_cursor);
4618 if (argc > 2 && strstr(argv[1], "-evaluate-cursor-at=") == argv[1])
10
Assuming the condition is false
11
Taking false branch
4619 return inspect_cursor_at(argc, argv, "-evaluate-cursor-at=",
4620 inspect_evaluate_cursor);
4621 if (argc > 2 && strstr(argv[1], "-get-macro-info-cursor-at=") == argv[1])
12
Assuming the condition is false
13
Taking false branch
4622 return inspect_cursor_at(argc, argv, "-get-macro-info-cursor-at=",
4623 inspect_macroinfo_cursor);
4624 if (argc > 2 && strstr(argv[1], "-file-refs-at=") == argv[1])
14
Assuming the condition is false
15
Taking false branch
4625 return find_file_refs_at(argc, argv);
4626 if (argc > 2 && strstr(argv[1], "-file-includes-in=") == argv[1])
16
Assuming the condition is true
17
Taking true branch
4627 return find_file_includes_in(argc, argv);
18
Calling 'find_file_includes_in'
4628 if (argc > 2 && strcmp(argv[1], "-index-file") == 0)
4629 return index_file(argc - 2, argv + 2, /*full=*/0);
4630 if (argc > 2 && strcmp(argv[1], "-index-file-full") == 0)
4631 return index_file(argc - 2, argv + 2, /*full=*/1);
4632 if (argc > 2 && strcmp(argv[1], "-index-tu") == 0)
4633 return index_tu(argc - 2, argv + 2);
4634 if (argc > 2 && strcmp(argv[1], "-index-compile-db") == 0)
4635 return index_compile_db(argc - 2, argv + 2);
4636 else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) {
4637 CXCursorVisitor I = GetVisitor(argv[1] + 13);
4638 if (I)
4639 return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I,
4640 NULL((void*)0));
4641 }
4642 else if (argc >= 5 && strncmp(argv[1], "-test-load-source-reparse", 25) == 0){
4643 CXCursorVisitor I = GetVisitor(argv[1] + 25);
4644 if (I) {
4645 int trials = atoi(argv[2]);
4646 return perform_test_reparse_source(argc - 4, argv + 4, trials, argv[3], I,
4647 NULL((void*)0));
4648 }
4649 }
4650 else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) {
4651 CXCursorVisitor I = GetVisitor(argv[1] + 17);
4652
4653 PostVisitTU postVisit = 0;
4654 if (strstr(argv[1], "-memory-usage"))
4655 postVisit = PrintMemoryUsage;
4656
4657 if (I)
4658 return perform_test_load_source(argc - 3, argv + 3, argv[2], I,
4659 postVisit);
4660 }
4661 else if (argc >= 3 && strcmp(argv[1], "-single-file-parse") == 0)
4662 return perform_single_file_parse(argv[2]);
4663 else if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0)
4664 return perform_file_scan(argv[2], argv[3],
4665 argc >= 5 ? argv[4] : 0);
4666 else if (argc > 2 && strstr(argv[1], "-test-annotate-tokens=") == argv[1])
4667 return perform_token_annotation(argc, argv);
4668 else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-source") == 0)
4669 return perform_test_load_source(argc - 2, argv + 2, "all", NULL((void*)0),
4670 PrintInclusionStack);
4671 else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-tu") == 0)
4672 return perform_test_load_tu(argv[2], "all", NULL((void*)0), NULL((void*)0),
4673 PrintInclusionStack);
4674 else if (argc > 2 && strcmp(argv[1], "-test-print-linkage-source") == 0)
4675 return perform_test_load_source(argc - 2, argv + 2, "all", PrintLinkage,
4676 NULL((void*)0));
4677 else if (argc > 2 && strcmp(argv[1], "-test-print-visibility") == 0)
4678 return perform_test_load_source(argc - 2, argv + 2, "all", PrintVisibility,
4679 NULL((void*)0));
4680 else if (argc > 2 && strcmp(argv[1], "-test-print-type") == 0)
4681 return perform_test_load_source(argc - 2, argv + 2, "all",
4682 PrintType, 0);
4683 else if (argc > 2 && strcmp(argv[1], "-test-print-type-size") == 0)
4684 return perform_test_load_source(argc - 2, argv + 2, "all",
4685 PrintTypeSize, 0);
4686 else if (argc > 2 && strcmp(argv[1], "-test-print-type-declaration") == 0)
4687 return perform_test_load_source(argc - 2, argv + 2, "all",
4688 PrintTypeDeclaration, 0);
4689 else if (argc > 2 && strcmp(argv[1], "-test-print-bitwidth") == 0)
4690 return perform_test_load_source(argc - 2, argv + 2, "all",
4691 PrintBitWidth, 0);
4692 else if (argc > 2 && strcmp(argv[1], "-test-print-mangle") == 0)
4693 return perform_test_load_tu(argv[2], "all", NULL((void*)0), PrintMangledName, NULL((void*)0));
4694 else if (argc > 2 && strcmp(argv[1], "-test-print-manglings") == 0)
4695 return perform_test_load_tu(argv[2], "all", NULL((void*)0), PrintManglings, NULL((void*)0));
4696 else if (argc > 2 && strcmp(argv[1], "-test-print-target-info") == 0)
4697 return print_target_info(argc - 2, argv + 2);
4698 else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
4699 if (argc > 2)
4700 return print_usrs(argv + 2, argv + argc);
4701 else {
4702 display_usrs();
4703 return 1;
4704 }
4705 }
4706 else if (argc > 2 && strcmp(argv[1], "-print-usr-file") == 0)
4707 return print_usrs_file(argv[2]);
4708 else if (argc > 2 && strcmp(argv[1], "-write-pch") == 0)
4709 return write_pch_file(argv[2], argc - 3, argv + 3);
4710 else if (argc > 2 && strcmp(argv[1], "-compilation-db") == 0)
4711 return perform_test_compilation_db(argv[argc-1], argc - 3, argv + 2);
4712 else if (argc == 2 && strcmp(argv[1], "-print-build-session-timestamp") == 0)
4713 return perform_print_build_session_timestamp();
4714
4715 print_usage();
4716 return 1;
4717}
4718
4719/***/
4720
4721/* We intentionally run in a separate thread to ensure we at least minimal
4722 * testing of a multithreaded environment (for example, having a reduced stack
4723 * size). */
4724
4725typedef struct thread_info {
4726 int (*main_func)(int argc, const char **argv);
4727 int argc;
4728 const char **argv;
4729 int result;
4730} thread_info;
4731void thread_runner(void *client_data_v) {
4732 thread_info *client_data = client_data_v;
4733 client_data->result = client_data->main_func(client_data->argc,
4734 client_data->argv);
4735}
4736
4737static void flush_atexit(void) {
4738 /* stdout, and surprisingly even stderr, are not always flushed on process
4739 * and thread exit, particularly when the system is under heavy load. */
4740 fflush(stdoutstdout);
4741 fflush(stderrstderr);
4742}
4743
4744int main(int argc, const char **argv) {
4745 thread_info client_data;
4746
4747 atexit(flush_atexit);
4748
4749#ifdef CLANG_HAVE_LIBXML
4750 LIBXML_TEST_VERSION
4751#endif
4752
4753 if (argc > 1 && strcmp(argv[1], "core") == 0)
4754 return indextest_core_main(argc, argv);
4755
4756 client_data.main_func = cindextest_main;
4757 client_data.argc = argc;
4758 client_data.argv = argv;
4759
4760 if (getenv("CINDEXTEST_NOTHREADS"))
4761 return client_data.main_func(client_data.argc, client_data.argv);
4762
4763 clang_executeOnThread(thread_runner, &client_data, 0);
4764 return client_data.result;
4765}