summaryrefslogtreecommitdiffstats
path: root/tools/c-index-test/c-index-test.c
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-11-24 09:15:30 +0000
committerdim <dim@FreeBSD.org>2014-11-24 09:15:30 +0000
commit173a4f43a911175643bda81ee675e8d9269056ea (patch)
tree47df2c12b57214af6c31e47404b005675b8b7ffc /tools/c-index-test/c-index-test.c
parent88f7a7d5251a2d813460274c92decc143a11569b (diff)
downloadFreeBSD-src-173a4f43a911175643bda81ee675e8d9269056ea.zip
FreeBSD-src-173a4f43a911175643bda81ee675e8d9269056ea.tar.gz
Vendor import of clang RELEASE_350/final tag r216957 (effectively, 3.5.0 release):
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_350/final@216957
Diffstat (limited to 'tools/c-index-test/c-index-test.c')
-rw-r--r--tools/c-index-test/c-index-test.c553
1 files changed, 390 insertions, 163 deletions
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 90a6528..07be22a 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1,8 +1,10 @@
/* c-index-test.c */
+#include "clang/Config/config.h"
#include "clang-c/Index.h"
#include "clang-c/CXCompilationDatabase.h"
-#include "llvm/Config/config.h"
+#include "clang-c/BuildSystem.h"
+#include "clang-c/Documentation.h"
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
@@ -78,8 +80,33 @@ static unsigned getDefaultParsingOptions() {
return options;
}
+/** \brief Returns 0 in case of success, non-zero in case of a failure. */
static int checkForErrors(CXTranslationUnit TU);
+static void describeLibclangFailure(enum CXErrorCode Err) {
+ switch (Err) {
+ case CXError_Success:
+ fprintf(stderr, "Success\n");
+ return;
+
+ case CXError_Failure:
+ fprintf(stderr, "Failure (no details available)\n");
+ return;
+
+ case CXError_Crashed:
+ fprintf(stderr, "Failure: libclang crashed\n");
+ return;
+
+ case CXError_InvalidArguments:
+ fprintf(stderr, "Failure: invalid arguments passed to a libclang routine\n");
+ return;
+
+ case CXError_ASTReadError:
+ fprintf(stderr, "Failure: AST deserialization error occurred\n");
+ return;
+ }
+}
+
static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column,
unsigned end_line, unsigned end_column) {
fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column,
@@ -88,10 +115,11 @@ static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column,
static unsigned CreateTranslationUnit(CXIndex Idx, const char *file,
CXTranslationUnit *TU) {
-
- *TU = clang_createTranslationUnit(Idx, file);
- if (!*TU) {
+ enum CXErrorCode Err = clang_createTranslationUnit2(Idx, file, TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit from '%s'!\n", file);
+ describeLibclangFailure(Err);
+ *TU = 0;
return 0;
}
return 1;
@@ -107,20 +135,25 @@ void free_remapped_files(struct CXUnsavedFile *unsaved_files,
free(unsaved_files);
}
-int parse_remapped_files(int argc, const char **argv, int start_arg,
- struct CXUnsavedFile **unsaved_files,
- int *num_unsaved_files) {
+static int parse_remapped_files_with_opt(const char *opt_name,
+ int argc, const char **argv,
+ int start_arg,
+ struct CXUnsavedFile **unsaved_files,
+ int *num_unsaved_files) {
int i;
int arg;
- int prefix_len = strlen("-remap-file=");
+ int prefix_len = strlen(opt_name);
+ int arg_indices[20];
*unsaved_files = 0;
*num_unsaved_files = 0;
/* Count the number of remapped files. */
for (arg = start_arg; arg < argc; ++arg) {
- if (strncmp(argv[arg], "-remap-file=", prefix_len))
- break;
+ if (strncmp(argv[arg], opt_name, prefix_len))
+ continue;
+ assert(*num_unsaved_files < (int)(sizeof(arg_indices)/sizeof(int)));
+ arg_indices[*num_unsaved_files] = arg;
++*num_unsaved_files;
}
@@ -130,17 +163,17 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
*unsaved_files
= (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
*num_unsaved_files);
- for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) {
+ for (i = 0; i != *num_unsaved_files; ++i) {
struct CXUnsavedFile *unsaved = *unsaved_files + i;
- const char *arg_string = argv[arg] + prefix_len;
+ const char *arg_string = argv[arg_indices[i]] + prefix_len;
int filename_len;
char *filename;
char *contents;
FILE *to_file;
- const char *semi = strchr(arg_string, ';');
- if (!semi) {
+ const char *sep = strchr(arg_string, ',');
+ if (!sep) {
fprintf(stderr,
- "error: -remap-file=from;to argument is missing semicolon\n");
+ "error: %sfrom:to argument is missing comma\n", opt_name);
free_remapped_files(*unsaved_files, i);
*unsaved_files = 0;
*num_unsaved_files = 0;
@@ -148,10 +181,10 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
}
/* Open the file that we're remapping to. */
- to_file = fopen(semi + 1, "rb");
+ to_file = fopen(sep + 1, "rb");
if (!to_file) {
fprintf(stderr, "error: cannot open file %s that we are remapping to\n",
- semi + 1);
+ sep + 1);
free_remapped_files(*unsaved_files, i);
*unsaved_files = 0;
*num_unsaved_files = 0;
@@ -167,7 +200,7 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
contents = (char *)malloc(unsaved->Length + 1);
if (fread(contents, 1, unsaved->Length, to_file) != unsaved->Length) {
fprintf(stderr, "error: unexpected %s reading 'to' file %s\n",
- (feof(to_file) ? "EOF" : "error"), semi + 1);
+ (feof(to_file) ? "EOF" : "error"), sep + 1);
fclose(to_file);
free_remapped_files(*unsaved_files, i);
free(contents);
@@ -182,7 +215,7 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
fclose(to_file);
/* Copy the file name that we're remapping from. */
- filename_len = semi - arg_string;
+ filename_len = sep - arg_string;
filename = (char *)malloc(filename_len + 1);
memcpy(filename, arg_string, filename_len);
filename[filename_len] = 0;
@@ -192,6 +225,48 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
return 0;
}
+static int parse_remapped_files(int argc, const char **argv, int start_arg,
+ struct CXUnsavedFile **unsaved_files,
+ int *num_unsaved_files) {
+ return parse_remapped_files_with_opt("-remap-file=", argc, argv, start_arg,
+ unsaved_files, num_unsaved_files);
+}
+
+static int parse_remapped_files_with_try(int try_idx,
+ int argc, const char **argv,
+ int start_arg,
+ struct CXUnsavedFile **unsaved_files,
+ int *num_unsaved_files) {
+ struct CXUnsavedFile *unsaved_files_no_try_idx;
+ int num_unsaved_files_no_try_idx;
+ struct CXUnsavedFile *unsaved_files_try_idx;
+ int num_unsaved_files_try_idx;
+ int ret;
+ char opt_name[32];
+
+ ret = parse_remapped_files(argc, argv, start_arg,
+ &unsaved_files_no_try_idx, &num_unsaved_files_no_try_idx);
+ if (ret)
+ return ret;
+
+ sprintf(opt_name, "-remap-file-%d=", try_idx);
+ ret = parse_remapped_files_with_opt(opt_name, argc, argv, start_arg,
+ &unsaved_files_try_idx, &num_unsaved_files_try_idx);
+ if (ret)
+ return ret;
+
+ *num_unsaved_files = num_unsaved_files_no_try_idx + num_unsaved_files_try_idx;
+ *unsaved_files
+ = (struct CXUnsavedFile *)realloc(unsaved_files_no_try_idx,
+ sizeof(struct CXUnsavedFile) *
+ *num_unsaved_files);
+ memcpy(*unsaved_files + num_unsaved_files_no_try_idx,
+ unsaved_files_try_idx, sizeof(struct CXUnsavedFile) *
+ num_unsaved_files_try_idx);
+ free(unsaved_files_try_idx);
+ return 0;
+}
+
static const char *parse_comments_schema(int argc, const char **argv) {
const char *CommentsSchemaArg = "-comments-xml-schema=";
const char *CommentSchemaFile = NULL;
@@ -467,33 +542,23 @@ static void DumpCXComment(CXComment Comment) {
printf("]");
}
-typedef struct {
- const char *CommentSchemaFile;
+static void ValidateCommentXML(const char *Str, const char *CommentSchemaFile) {
#ifdef CLANG_HAVE_LIBXML
xmlRelaxNGParserCtxtPtr RNGParser;
xmlRelaxNGPtr Schema;
-#endif
-} CommentXMLValidationData;
-
-static void ValidateCommentXML(const char *Str,
- CommentXMLValidationData *ValidationData) {
-#ifdef CLANG_HAVE_LIBXML
xmlDocPtr Doc;
xmlRelaxNGValidCtxtPtr ValidationCtxt;
int status;
- if (!ValidationData || !ValidationData->CommentSchemaFile)
+ if (!CommentSchemaFile)
return;
- if (!ValidationData->RNGParser) {
- ValidationData->RNGParser =
- xmlRelaxNGNewParserCtxt(ValidationData->CommentSchemaFile);
- ValidationData->Schema = xmlRelaxNGParse(ValidationData->RNGParser);
- }
- if (!ValidationData->RNGParser) {
+ RNGParser = xmlRelaxNGNewParserCtxt(CommentSchemaFile);
+ if (!RNGParser) {
printf(" libXMLError");
return;
}
+ Schema = xmlRelaxNGParse(RNGParser);
Doc = xmlParseDoc((const xmlChar *) Str);
@@ -503,7 +568,7 @@ static void ValidateCommentXML(const char *Str,
return;
}
- ValidationCtxt = xmlRelaxNGNewValidCtxt(ValidationData->Schema);
+ ValidationCtxt = xmlRelaxNGNewValidCtxt(Schema);
status = xmlRelaxNGValidateDoc(ValidationCtxt, Doc);
if (!status)
printf(" CommentXMLValid");
@@ -515,11 +580,13 @@ static void ValidateCommentXML(const char *Str,
xmlRelaxNGFreeValidCtxt(ValidationCtxt);
xmlFreeDoc(Doc);
+ xmlRelaxNGFree(Schema);
+ xmlRelaxNGFreeParserCtxt(RNGParser);
#endif
}
static void PrintCursorComments(CXCursor Cursor,
- CommentXMLValidationData *ValidationData) {
+ const char *CommentSchemaFile) {
{
CXString RawComment;
const char *RawCommentCString;
@@ -550,7 +617,7 @@ static void PrintCursorComments(CXCursor Cursor,
CXString XML;
XML = clang_FullComment_getAsXML(Comment);
PrintCXStringWithPrefix("FullCommentAsXML", XML);
- ValidateCommentXML(clang_getCString(XML), ValidationData);
+ ValidateCommentXML(clang_getCString(XML), CommentSchemaFile);
clang_disposeString(XML);
}
@@ -572,8 +639,7 @@ static int lineCol_cmp(const void *p1, const void *p2) {
return (int)lhs->col - (int)rhs->col;
}
-static void PrintCursor(CXCursor Cursor,
- CommentXMLValidationData *ValidationData) {
+static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
if (clang_isInvalid(Cursor.kind)) {
CXString ks = clang_getCursorKindSpelling(Cursor.kind);
@@ -694,6 +760,8 @@ static void PrintCursor(CXCursor Cursor,
printf(" (static)");
if (clang_CXXMethod_isVirtual(Cursor))
printf(" (virtual)");
+ if (clang_CXXMethod_isConst(Cursor))
+ printf(" (const)");
if (clang_CXXMethod_isPureVirtual(Cursor))
printf(" (pure)");
if (clang_Cursor_isVariadic(Cursor))
@@ -792,7 +860,7 @@ static void PrintCursor(CXCursor Cursor,
PrintRange(RefNameRange, "RefName");
}
- PrintCursorComments(Cursor, ValidationData);
+ PrintCursorComments(Cursor, CommentSchemaFile);
{
unsigned PropAttrs = clang_Cursor_getObjCPropertyAttributes(Cursor, 0);
@@ -909,7 +977,6 @@ void PrintDiagnostic(CXDiagnostic Diagnostic) {
PrintExtent(out, start_line, start_column, end_line, end_column);
fprintf(out, " with \"%s\"\n", clang_getCString(insertion_text));
}
- break;
}
clang_disposeString(insertion_text);
}
@@ -962,7 +1029,7 @@ static void PrintCursorExtent(CXCursor C) {
typedef struct {
CXTranslationUnit TU;
enum CXCursorKind *Filter;
- CommentXMLValidationData ValidationData;
+ const char *CommentSchemaFile;
} VisitorData;
@@ -976,7 +1043,7 @@ enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor,
clang_getSpellingLocation(Loc, 0, &line, &column, 0);
printf("// %s: %s:%d:%d: ", FileCheckPrefix,
GetCursorSource(Cursor), line, column);
- PrintCursor(Cursor, &Data->ValidationData);
+ PrintCursor(Cursor, Data->CommentSchemaFile);
PrintCursorExtent(Cursor);
if (clang_isDeclaration(Cursor.kind)) {
enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
@@ -1046,7 +1113,7 @@ static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
} else if (Ref.kind != CXCursor_FunctionDecl) {
printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
curLine, curColumn);
- PrintCursor(Ref, &Data->ValidationData);
+ PrintCursor(Ref, Data->CommentSchemaFile);
printf("\n");
}
}
@@ -1189,11 +1256,11 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
}
/* Print the argument types if they exist. */
{
- int numArgs = clang_Cursor_getNumArguments(cursor);
- if (numArgs != -1 && numArgs != 0) {
+ int NumArgs = clang_Cursor_getNumArguments(cursor);
+ if (NumArgs != -1 && NumArgs != 0) {
int i;
printf(" [args=");
- for (i = 0; i < numArgs; ++i) {
+ for (i = 0; i < NumArgs; ++i) {
CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
if (T.kind != CXType_Invalid) {
PrintTypeAndTypeKind(T, " [%s] [%s]");
@@ -1202,8 +1269,30 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
printf("]");
}
}
+ /* Print the template argument types if they exist. */
+ {
+ int NumTArgs = clang_Type_getNumTemplateArguments(T);
+ if (NumTArgs != -1 && NumTArgs != 0) {
+ int i;
+ printf(" [templateargs/%d=", NumTArgs);
+ for (i = 0; i < NumTArgs; ++i) {
+ CXType TArg = clang_Type_getTemplateArgumentAsType(T, i);
+ if (TArg.kind != CXType_Invalid) {
+ PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]");
+ }
+ }
+ printf("]");
+ }
+ }
/* Print if this is a non-POD type. */
printf(" [isPOD=%d]", clang_isPODType(T));
+ /* Print the pointee type. */
+ {
+ CXType PT = clang_getPointeeType(T);
+ if (PT.kind != CXType_Invalid) {
+ PrintTypeAndTypeKind(PT, " [pointeetype=%s] [pointeekind=%s]");
+ }
+ }
printf("\n");
}
@@ -1235,18 +1324,25 @@ static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
}
/* Print the record field offset if applicable. */
{
- const char *FieldName = clang_getCString(clang_getCursorSpelling(cursor));
+ CXString FieldSpelling = clang_getCursorSpelling(cursor);
+ const char *FieldName = clang_getCString(FieldSpelling);
/* recurse to get the root anonymous record parent */
CXCursor Parent, Root;
- if (clang_getCursorKind(cursor) == CXCursor_FieldDecl ) {
- const char *RootParentName;
- Root = Parent = p;
+ if (clang_getCursorKind(cursor) == CXCursor_FieldDecl) {
+ CXString RootParentSpelling;
+ const char *RootParentName = 0;
+ Parent = p;
do {
+ if (RootParentName != 0)
+ clang_disposeString(RootParentSpelling);
+
Root = Parent;
- RootParentName = clang_getCString(clang_getCursorSpelling(Root));
+ RootParentSpelling = clang_getCursorSpelling(Root);
+ RootParentName = clang_getCString(RootParentSpelling);
Parent = clang_getCursorSemanticParent(Root);
- } while ( clang_getCursorType(Parent).kind == CXType_Record &&
- !strcmp(RootParentName, "") );
+ } while (clang_getCursorType(Parent).kind == CXType_Record &&
+ !strcmp(RootParentName, ""));
+ clang_disposeString(RootParentSpelling);
/* if RootParentName is "", record is anonymous. */
{
long long Offset = clang_Type_getOffsetOf(clang_getCursorType(Root),
@@ -1254,6 +1350,7 @@ static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
printf(" [offsetof=%lld]", Offset);
}
}
+ clang_disposeString(FieldSpelling);
}
/* Print if its a bitfield */
{
@@ -1323,11 +1420,7 @@ static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
Data.TU = TU;
Data.Filter = ck;
- Data.ValidationData.CommentSchemaFile = CommentSchemaFile;
-#ifdef CLANG_HAVE_LIBXML
- Data.ValidationData.RNGParser = NULL;
- Data.ValidationData.Schema = NULL;
-#endif
+ Data.CommentSchemaFile = CommentSchemaFile;
clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
}
@@ -1372,8 +1465,9 @@ int perform_test_load_source(int argc, const char **argv,
const char *CommentSchemaFile;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
int result;
-
+
Idx = clang_createIndex(/* excludeDeclsFromPCH */
(!strcmp(filter, "local") ||
!strcmp(filter, "local-display"))? 1 : 0,
@@ -1389,13 +1483,14 @@ int perform_test_load_source(int argc, const char **argv,
return -1;
}
- TU = clang_parseTranslationUnit(Idx, 0,
- argv + num_unsaved_files,
- argc - num_unsaved_files,
- unsaved_files, num_unsaved_files,
- getDefaultParsingOptions());
- if (!TU) {
+ Err = clang_parseTranslationUnit2(Idx, 0,
+ argv + num_unsaved_files,
+ argc - num_unsaved_files,
+ unsaved_files, num_unsaved_files,
+ getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
return 1;
@@ -1415,7 +1510,9 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
CXTranslationUnit TU;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
- int result;
+ int compiler_arg_idx = 0;
+ enum CXErrorCode Err;
+ int result, i;
int trial;
int remap_after_trial = 0;
char *endptr = 0;
@@ -1428,15 +1525,25 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
clang_disposeIndex(Idx);
return -1;
}
+
+ for (i = 0; i < argc; ++i) {
+ if (strcmp(argv[i], "--") == 0)
+ break;
+ }
+ if (i < argc)
+ compiler_arg_idx = i+1;
+ if (num_unsaved_files > compiler_arg_idx)
+ compiler_arg_idx = num_unsaved_files;
/* Load the initial translation unit -- we do this without honoring remapped
* files, so that we have a way to test results after changing the source. */
- TU = clang_parseTranslationUnit(Idx, 0,
- argv + num_unsaved_files,
- argc - num_unsaved_files,
- 0, 0, getDefaultParsingOptions());
- if (!TU) {
+ Err = clang_parseTranslationUnit2(Idx, 0,
+ argv + compiler_arg_idx,
+ argc - compiler_arg_idx,
+ 0, 0, getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
return 1;
@@ -1451,11 +1558,22 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
}
for (trial = 0; trial < trials; ++trial) {
- if (clang_reparseTranslationUnit(TU,
- trial >= remap_after_trial ? num_unsaved_files : 0,
- trial >= remap_after_trial ? unsaved_files : 0,
- clang_defaultReparseOptions(TU))) {
+ free_remapped_files(unsaved_files, num_unsaved_files);
+ if (parse_remapped_files_with_try(trial, argc, argv, 0,
+ &unsaved_files, &num_unsaved_files)) {
+ clang_disposeTranslationUnit(TU);
+ clang_disposeIndex(Idx);
+ return -1;
+ }
+
+ Err = clang_reparseTranslationUnit(
+ TU,
+ trial >= remap_after_trial ? num_unsaved_files : 0,
+ trial >= remap_after_trial ? unsaved_files : 0,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to reparse translation unit!\n");
+ describeLibclangFailure(Err);
clang_disposeTranslationUnit(TU);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
@@ -1669,7 +1787,8 @@ static int checkForErrors(CXTranslationUnit TU) {
return 0;
}
-void print_completion_string(CXCompletionString completion_string, FILE *file) {
+static void print_completion_string(CXCompletionString completion_string,
+ FILE *file) {
int I, N;
N = clang_getNumCompletionChunks(completion_string);
@@ -1703,9 +1822,8 @@ void print_completion_string(CXCompletionString completion_string, FILE *file) {
}
-void print_completion_result(CXCompletionResult *completion_result,
- CXClientData client_data) {
- FILE *file = (FILE *)client_data;
+static void print_completion_result(CXCompletionResult *completion_result,
+ FILE *file) {
CXString ks = clang_getCursorKindSpelling(completion_result->CursorKind);
unsigned annotationCount;
enum CXCursorKind ParentKind;
@@ -1877,7 +1995,8 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
CXCodeCompleteResults *results = 0;
- CXTranslationUnit TU = 0;
+ enum CXErrorCode Err;
+ CXTranslationUnit TU;
unsigned I, Repeats = 1;
unsigned completionOptions = clang_defaultCodeCompleteOptions();
@@ -1902,21 +2021,27 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
if (getenv("CINDEXTEST_EDITING"))
Repeats = 5;
-
- TU = clang_parseTranslationUnit(CIdx, 0,
- argv + num_unsaved_files + 2,
- argc - num_unsaved_files - 2,
- 0, 0, getDefaultParsingOptions());
- if (!TU) {
+
+ Err = clang_parseTranslationUnit2(CIdx, 0,
+ argv + num_unsaved_files + 2,
+ argc - num_unsaved_files - 2,
+ 0, 0, getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
return 1;
}
- if (clang_reparseTranslationUnit(TU, 0, 0, clang_defaultReparseOptions(TU))) {
+ Err = clang_reparseTranslationUnit(TU, 0, 0,
+ clang_defaultReparseOptions(TU));
+
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to reparse translation init!\n");
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
return 1;
}
-
+
for (I = 0; I != Repeats; ++I) {
results = clang_codeCompleteAt(TU, filename, line, column,
unsaved_files, num_unsaved_files,
@@ -2003,6 +2128,7 @@ static int inspect_cursor_at(int argc, const char **argv) {
int errorCode;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
CXTranslationUnit TU;
CXCursor Cursor;
CursorSourceLocation *Locations = 0;
@@ -2036,15 +2162,15 @@ static int inspect_cursor_at(int argc, const char **argv) {
/* Parse the translation unit. When we're testing clang_getCursor() after
reparsing, don't remap unsaved files until the second parse. */
CIdx = clang_createIndex(1, 1);
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
- argv + num_unsaved_files + 1 + NumLocations,
- argc - num_unsaved_files - 2 - NumLocations,
- unsaved_files,
- Repeats > 1? 0 : num_unsaved_files,
- getDefaultParsingOptions());
-
- if (!TU) {
+ Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
+ argv + num_unsaved_files + 1 + NumLocations,
+ argc - num_unsaved_files - 2 - NumLocations,
+ unsaved_files,
+ Repeats > 1? 0 : num_unsaved_files,
+ getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "unable to parse input\n");
+ describeLibclangFailure(Err);
return -1;
}
@@ -2052,11 +2178,14 @@ static int inspect_cursor_at(int argc, const char **argv) {
return -1;
for (I = 0; I != Repeats; ++I) {
- if (Repeats > 1 &&
- clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
- clang_defaultReparseOptions(TU))) {
- clang_disposeTranslationUnit(TU);
- return 1;
+ if (Repeats > 1) {
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
+ return 1;
+ }
}
if (checkForErrors(TU) != 0)
@@ -2101,7 +2230,8 @@ static int inspect_cursor_at(int argc, const char **argv) {
}
clang_disposeString(Spelling);
if (clang_Cursor_getObjCSelectorIndex(Cursor) != -1)
- printf(" Selector index=%d",clang_Cursor_getObjCSelectorIndex(Cursor));
+ printf(" Selector index=%d",
+ clang_Cursor_getObjCSelectorIndex(Cursor));
if (clang_Cursor_isDynamicCall(Cursor))
printf(" Dynamic-call");
if (Cursor.kind == CXCursor_ObjCMessageExpr) {
@@ -2121,9 +2251,9 @@ static int inspect_cursor_at(int argc, const char **argv) {
astFilename = clang_getFileName(astFile);
name = clang_Module_getFullName(mod);
numHeaders = clang_Module_getNumTopLevelHeaders(TU, mod);
- printf(" ModuleName=%s (%s) Headers(%d):",
+ printf(" ModuleName=%s (%s) system=%d Headers(%d):",
clang_getCString(name), clang_getCString(astFilename),
- numHeaders);
+ clang_Module_isSystem(mod), numHeaders);
clang_disposeString(name);
clang_disposeString(astFilename);
for (i = 0; i < numHeaders; ++i) {
@@ -2169,6 +2299,7 @@ static int find_file_refs_at(int argc, const char **argv) {
int errorCode;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
CXTranslationUnit TU;
CXCursor Cursor;
CursorSourceLocation *Locations = 0;
@@ -2202,15 +2333,16 @@ static int find_file_refs_at(int argc, const char **argv) {
/* Parse the translation unit. When we're testing clang_getCursor() after
reparsing, don't remap unsaved files until the second parse. */
CIdx = clang_createIndex(1, 1);
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
- argv + num_unsaved_files + 1 + NumLocations,
- argc - num_unsaved_files - 2 - NumLocations,
- unsaved_files,
- Repeats > 1? 0 : num_unsaved_files,
- getDefaultParsingOptions());
-
- if (!TU) {
+ Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
+ argv + num_unsaved_files + 1 + NumLocations,
+ argc - num_unsaved_files - 2 - NumLocations,
+ unsaved_files,
+ Repeats > 1? 0 : num_unsaved_files,
+ getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "unable to parse input\n");
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
return -1;
}
@@ -2218,11 +2350,14 @@ static int find_file_refs_at(int argc, const char **argv) {
return -1;
for (I = 0; I != Repeats; ++I) {
- if (Repeats > 1 &&
- clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
- clang_defaultReparseOptions(TU))) {
- clang_disposeTranslationUnit(TU);
- return 1;
+ if (Repeats > 1) {
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
+ return 1;
+ }
}
if (checkForErrors(TU) != 0)
@@ -2273,6 +2408,7 @@ static int find_file_includes_in(int argc, const char **argv) {
CXIndex CIdx;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
CXTranslationUnit TU;
const char **Filenames = 0;
unsigned NumFilenames = 0;
@@ -2302,15 +2438,17 @@ static int find_file_includes_in(int argc, const char **argv) {
/* Parse the translation unit. When we're testing clang_getCursor() after
reparsing, don't remap unsaved files until the second parse. */
CIdx = clang_createIndex(1, 1);
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
- argv + num_unsaved_files + 1 + NumFilenames,
- argc - num_unsaved_files - 2 - NumFilenames,
- unsaved_files,
- Repeats > 1? 0 : num_unsaved_files,
- getDefaultParsingOptions());
-
- if (!TU) {
+ Err = clang_parseTranslationUnit2(
+ CIdx, argv[argc - 1],
+ argv + num_unsaved_files + 1 + NumFilenames,
+ argc - num_unsaved_files - 2 - NumFilenames,
+ unsaved_files,
+ Repeats > 1 ? 0 : num_unsaved_files, getDefaultParsingOptions(), &TU);
+
+ if (Err != CXError_Success) {
fprintf(stderr, "unable to parse input\n");
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
return -1;
}
@@ -2318,11 +2456,14 @@ static int find_file_includes_in(int argc, const char **argv) {
return -1;
for (I = 0; I != Repeats; ++I) {
- if (Repeats > 1 &&
- clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
- clang_defaultReparseOptions(TU))) {
- clang_disposeTranslationUnit(TU);
- return 1;
+ if (Repeats > 1) {
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
+ return 1;
+ }
}
if (checkForErrors(TU) != 0)
@@ -2390,6 +2531,11 @@ static void importedASTS_insert(ImportedASTFilesData *p, const char *file) {
p->filenames[p->num_files++] = strdup(file);
}
+typedef struct IndexDataStringList_ {
+ struct IndexDataStringList_ *next;
+ char data[1]; /* Dynamically sized. */
+} IndexDataStringList;
+
typedef struct {
const char *check_prefix;
int first_check_printed;
@@ -2397,8 +2543,20 @@ typedef struct {
int abort;
const char *main_filename;
ImportedASTFilesData *importedASTs;
+ IndexDataStringList *strings;
+ CXTranslationUnit TU;
} IndexData;
+static void free_client_data(IndexData *index_data) {
+ IndexDataStringList *node = index_data->strings;
+ while (node) {
+ IndexDataStringList *next = node->next;
+ free(node);
+ node = next;
+ }
+ index_data->strings = NULL;
+}
+
static void printCheck(IndexData *data) {
if (data->check_prefix) {
if (data->first_check_printed) {
@@ -2459,8 +2617,11 @@ static unsigned digitCount(unsigned val) {
}
}
-static CXIdxClientContainer makeClientContainer(const CXIdxEntityInfo *info,
+static CXIdxClientContainer makeClientContainer(CXClientData *client_data,
+ const CXIdxEntityInfo *info,
CXIdxLoc loc) {
+ IndexData *index_data;
+ IndexDataStringList *node;
const char *name;
char *newStr;
CXIdxClientFile file;
@@ -2471,10 +2632,18 @@ static CXIdxClientContainer makeClientContainer(const CXIdxEntityInfo *info,
name = "<anon-tag>";
clang_indexLoc_getFileLocation(loc, &file, 0, &line, &column, 0);
- /* FIXME: free these.*/
- newStr = (char *)malloc(strlen(name) +
- digitCount(line) + digitCount(column) + 3);
+
+ node =
+ (IndexDataStringList *)malloc(sizeof(IndexDataStringList) + strlen(name) +
+ digitCount(line) + digitCount(column) + 2);
+ newStr = node->data;
sprintf(newStr, "%s:%d:%d", name, line, column);
+
+ /* Remember string so it can be freed later. */
+ index_data = (IndexData *)client_data;
+ node->next = index_data->strings;
+ index_data->strings = node;
+
return (CXIdxClientContainer)newStr;
}
@@ -2645,6 +2814,7 @@ static CXIdxClientFile index_enteredMainFile(CXClientData client_data,
static CXIdxClientFile index_ppIncludedFile(CXClientData client_data,
const CXIdxIncludedFileInfo *info) {
IndexData *index_data;
+ CXModule Mod;
index_data = (IndexData *)client_data;
printCheck(index_data);
@@ -2653,8 +2823,18 @@ static CXIdxClientFile index_ppIncludedFile(CXClientData client_data,
printf(" | name: \"%s\"", info->filename);
printf(" | hash loc: ");
printCXIndexLoc(info->hashLoc, client_data);
- printf(" | isImport: %d | isAngled: %d | isModule: %d\n",
+ printf(" | isImport: %d | isAngled: %d | isModule: %d",
info->isImport, info->isAngled, info->isModuleImport);
+
+ Mod = clang_getModuleForFile(index_data->TU, (CXFile)info->file);
+ if (Mod) {
+ CXString str = clang_Module_getFullName(Mod);
+ const char *cstr = clang_getCString(str);
+ printf(" | module: %s", cstr);
+ clang_disposeString(str);
+ }
+
+ printf("\n");
return (CXIdxClientFile)info->file;
}
@@ -2688,8 +2868,8 @@ static CXIdxClientFile index_importedASTFile(CXClientData client_data,
return (CXIdxClientFile)info->file;
}
-static CXIdxClientContainer index_startedTranslationUnit(CXClientData client_data,
- void *reserved) {
+static CXIdxClientContainer
+index_startedTranslationUnit(CXClientData client_data, void *reserved) {
IndexData *index_data;
index_data = (IndexData *)client_data;
printCheck(index_data);
@@ -2790,13 +2970,15 @@ static void index_indexDeclaration(CXClientData client_data,
}
if (info->declAsContainer)
- clang_index_setClientContainer(info->declAsContainer,
- makeClientContainer(info->entityInfo, info->loc));
+ clang_index_setClientContainer(
+ info->declAsContainer,
+ makeClientContainer(client_data, info->entityInfo, info->loc));
}
static void index_indexEntityReference(CXClientData client_data,
const CXIdxEntityRefInfo *info) {
- printEntityInfo("[indexEntityReference]", client_data, info->referencedEntity);
+ printEntityInfo("[indexEntityReference]", client_data,
+ info->referencedEntity);
printf(" | cursor: ");
PrintCursor(info->cursor, NULL);
printf(" | loc: ");
@@ -2861,15 +3043,21 @@ static int index_compile_args(int num_args, const char **args,
index_data.abort = 0;
index_data.main_filename = "";
index_data.importedASTs = importedASTs;
+ index_data.strings = NULL;
+ index_data.TU = NULL;
index_opts = getIndexOptions();
result = clang_indexSourceFile(idxAction, &index_data,
&IndexCB,sizeof(IndexCB), index_opts,
0, args, num_args, 0, 0, 0,
getDefaultParsingOptions());
+ if (result != CXError_Success)
+ describeLibclangFailure(result);
+
if (index_data.fail_for_error)
result = -1;
+ free_client_data(&index_data);
return result;
}
@@ -2892,6 +3080,8 @@ static int index_ast_file(const char *ast_file,
index_data.abort = 0;
index_data.main_filename = "";
index_data.importedASTs = importedASTs;
+ index_data.strings = NULL;
+ index_data.TU = TU;
index_opts = getIndexOptions();
result = clang_indexTranslationUnit(idxAction, &index_data,
@@ -2901,6 +3091,7 @@ static int index_ast_file(const char *ast_file,
result = -1;
clang_disposeTranslationUnit(TU);
+ free_client_data(&index_data);
return result;
}
@@ -3118,6 +3309,8 @@ int perform_token_annotation(int argc, const char **argv) {
CXSourceLocation startLoc, endLoc;
CXFile file = 0;
CXCursor *cursors = 0;
+ CXSourceRangeList *skipped_ranges = 0;
+ enum CXErrorCode Err;
unsigned i;
input += strlen("-test-annotate-tokens=");
@@ -3131,14 +3324,15 @@ int perform_token_annotation(int argc, const char **argv) {
}
CIdx = clang_createIndex(0, 1);
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
- argv + num_unsaved_files + 2,
- argc - num_unsaved_files - 3,
- unsaved_files,
- num_unsaved_files,
- getDefaultParsingOptions());
- if (!TU) {
+ Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
+ argv + num_unsaved_files + 2,
+ argc - num_unsaved_files - 3,
+ unsaved_files,
+ num_unsaved_files,
+ getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "unable to parse input\n");
+ describeLibclangFailure(Err);
clang_disposeIndex(CIdx);
free(filename);
free_remapped_files(unsaved_files, num_unsaved_files);
@@ -3153,9 +3347,11 @@ int perform_token_annotation(int argc, const char **argv) {
if (getenv("CINDEXTEST_EDITING")) {
for (i = 0; i < 5; ++i) {
- if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
- clang_defaultReparseOptions(TU))) {
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to reparse translation unit!\n");
+ describeLibclangFailure(Err);
errorCode = -1;
goto teardown;
}
@@ -3206,6 +3402,19 @@ int perform_token_annotation(int argc, const char **argv) {
goto teardown;
}
+ skipped_ranges = clang_getSkippedRanges(TU, file);
+ for (i = 0; i != skipped_ranges->count; ++i) {
+ unsigned start_line, start_column, end_line, end_column;
+ clang_getSpellingLocation(clang_getRangeStart(skipped_ranges->ranges[i]),
+ 0, &start_line, &start_column, 0);
+ clang_getSpellingLocation(clang_getRangeEnd(skipped_ranges->ranges[i]),
+ 0, &end_line, &end_column, 0);
+ printf("Skipping: ");
+ PrintExtent(stdout, start_line, start_column, end_line, end_column);
+ printf("\n");
+ }
+ clang_disposeSourceRangeList(skipped_ranges);
+
for (i = 0; i != num_tokens; ++i) {
const char *kind = "<unknown>";
CXString spelling = clang_getTokenSpelling(TU, tokens[i]);
@@ -3506,6 +3715,7 @@ int write_pch_file(const char *filename, int argc, const char *argv[]) {
CXTranslationUnit TU;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
int result = 0;
Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnostics=*/1);
@@ -3514,18 +3724,19 @@ int write_pch_file(const char *filename, int argc, const char *argv[]) {
clang_disposeIndex(Idx);
return -1;
}
-
- TU = clang_parseTranslationUnit(Idx, 0,
- argv + num_unsaved_files,
- argc - num_unsaved_files,
- unsaved_files,
- num_unsaved_files,
- CXTranslationUnit_Incomplete |
- CXTranslationUnit_DetailedPreprocessingRecord|
- CXTranslationUnit_ForSerialization);
- if (!TU) {
+
+ Err = clang_parseTranslationUnit2(
+ Idx, 0, argv + num_unsaved_files, argc - num_unsaved_files,
+ unsaved_files, num_unsaved_files,
+ CXTranslationUnit_Incomplete |
+ CXTranslationUnit_DetailedPreprocessingRecord |
+ CXTranslationUnit_ForSerialization,
+ &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
free_remapped_files(unsaved_files, num_unsaved_files);
+ clang_disposeTranslationUnit(TU);
clang_disposeIndex(Idx);
return 1;
}
@@ -3697,6 +3908,7 @@ static void printDiagnosticSet(CXDiagnosticSet Diags, unsigned indent) {
clang_disposeString(FileName);
clang_disposeString(DiagSpelling);
clang_disposeString(DiagOption);
+ clang_disposeString(DiagCat);
}
}
@@ -3721,6 +3933,11 @@ static int read_diagnostics(const char *filename) {
return 0;
}
+static int perform_print_build_session_timestamp(void) {
+ printf("%lld\n", clang_getBuildSessionTimestamp());
+ return 0;
+}
+
/******************************************************************************/
/* Command line processing. */
/******************************************************************************/
@@ -3777,6 +3994,8 @@ static void print_usage(void) {
fprintf(stderr,
" c-index-test -compilation-db [lookup <filename>] database\n");
fprintf(stderr,
+ " c-index-test -print-build-session-timestamp\n");
+ fprintf(stderr,
" c-index-test -read-diagnostics <file>\n\n");
fprintf(stderr,
" <symbol filter> values:\n%s",
@@ -3876,6 +4095,8 @@ int cindextest_main(int argc, const char **argv) {
return write_pch_file(argv[2], argc - 3, argv + 3);
else if (argc > 2 && strcmp(argv[1], "-compilation-db") == 0)
return perform_test_compilation_db(argv[argc-1], argc - 3, argv + 2);
+ else if (argc == 2 && strcmp(argv[1], "-print-build-session-timestamp") == 0)
+ return perform_print_build_session_timestamp();
print_usage();
return 1;
@@ -3895,14 +4116,20 @@ typedef struct thread_info {
void thread_runner(void *client_data_v) {
thread_info *client_data = client_data_v;
client_data->result = cindextest_main(client_data->argc, client_data->argv);
-#ifdef __CYGWIN__
- fflush(stdout); /* stdout is not flushed on Cygwin. */
-#endif
+}
+
+static void flush_atexit(void) {
+ /* stdout, and surprisingly even stderr, are not always flushed on process
+ * and thread exit, particularly when the system is under heavy load. */
+ fflush(stdout);
+ fflush(stderr);
}
int main(int argc, const char **argv) {
thread_info client_data;
+ atexit(flush_atexit);
+
#ifdef CLANG_HAVE_LIBXML
LIBXML_TEST_VERSION
#endif
OpenPOWER on IntegriCloud