Extend clang_createTranslationUnitFromSourceFile() to support creating
translation units that include unsaved files.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94258 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 98ed772..4ef3904 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -39,6 +39,99 @@
return 1;
}
+void free_remapped_files(struct CXUnsavedFile *unsaved_files,
+ int num_unsaved_files) {
+ int i;
+ for (i = 0; i != num_unsaved_files; ++i) {
+ free((char *)unsaved_files[i].Filename);
+ free((char *)unsaved_files[i].Contents);
+ }
+}
+
+int parse_remapped_files(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=");
+ *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;
+
+ ++*num_unsaved_files;
+ }
+
+ if (*num_unsaved_files == 0)
+ return 0;
+
+ *unsaved_files
+ = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
+ *num_unsaved_files);
+ for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) {
+ struct CXUnsavedFile *unsaved = *unsaved_files + i;
+ const char *arg_string = argv[arg] + prefix_len;
+ int filename_len;
+ char *filename;
+ char *contents;
+ FILE *to_file;
+ const char *semi = strchr(arg_string, ';');
+ if (!semi) {
+ fprintf(stderr,
+ "error: -remap-file=from;to argument is missing semicolon\n");
+ free_remapped_files(*unsaved_files, i);
+ *unsaved_files = 0;
+ *num_unsaved_files = 0;
+ return -1;
+ }
+
+ /* Open the file that we're remapping to. */
+ to_file = fopen(semi + 1, "r");
+ if (!to_file) {
+ fprintf(stderr, "error: cannot open file %s that we are remapping to\n",
+ semi + 1);
+ free_remapped_files(*unsaved_files, i);
+ *unsaved_files = 0;
+ *num_unsaved_files = 0;
+ return -1;
+ }
+
+ /* Determine the length of the file we're remapping to. */
+ fseek(to_file, 0, SEEK_END);
+ unsaved->Length = ftell(to_file);
+ fseek(to_file, 0, SEEK_SET);
+
+ /* Read the contents of the file we're remapping to. */
+ 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);
+ fclose(to_file);
+ free_remapped_files(*unsaved_files, i);
+ *unsaved_files = 0;
+ *num_unsaved_files = 0;
+ return -1;
+ }
+ contents[unsaved->Length] = 0;
+ unsaved->Contents = contents;
+
+ /* Close the file. */
+ fclose(to_file);
+
+ /* Copy the file name that we're remapping from. */
+ filename_len = semi - arg_string;
+ filename = (char *)malloc(filename_len + 1);
+ memcpy(filename, arg_string, filename_len);
+ filename[filename_len] = 0;
+ unsaved->Filename = filename;
+ }
+
+ return 0;
+}
+
/******************************************************************************/
/* Pretty-printing. */
/******************************************************************************/
@@ -258,6 +351,10 @@
getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION");
CXIndex Idx;
CXTranslationUnit TU;
+ struct CXUnsavedFile *unsaved_files = 0;
+ int num_unsaved_files = 0;
+ int result;
+
Idx = clang_createIndex(/* excludeDeclsFromPCH */
!strcmp(filter, "local") ? 1 : 0,
/* displayDiagnostics */ 1);
@@ -265,13 +362,22 @@
if (UseExternalASTs && strlen(UseExternalASTs))
clang_setUseExternalASTGeneration(Idx, 1);
- TU = clang_createTranslationUnitFromSourceFile(Idx, 0, argc, argv);
+ if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files))
+ return -1;
+
+ TU = clang_createTranslationUnitFromSourceFile(Idx, 0,
+ argc - num_unsaved_files,
+ argv + num_unsaved_files,
+ num_unsaved_files,
+ unsaved_files);
if (!TU) {
fprintf(stderr, "Unable to load translation unit!\n");
return 1;
}
- return perform_test_load(Idx, TU, filter, NULL, Visitor);
+ result = perform_test_load(Idx, TU, filter, NULL, Visitor);
+ free_remapped_files(unsaved_files, num_unsaved_files);
+ return result;
}
/******************************************************************************/
@@ -477,99 +583,6 @@
fprintf(file, "\n");
}
-void free_remapped_files(struct CXUnsavedFile *unsaved_files,
- int num_unsaved_files) {
- int i;
- for (i = 0; i != num_unsaved_files; ++i) {
- free((char *)unsaved_files[i].Filename);
- free((char *)unsaved_files[i].Contents);
- }
-}
-
-int parse_remapped_files(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=");
- *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;
-
- ++*num_unsaved_files;
- }
-
- if (*num_unsaved_files == 0)
- return 0;
-
- *unsaved_files
- = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
- *num_unsaved_files);
- for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) {
- struct CXUnsavedFile *unsaved = *unsaved_files + i;
- const char *arg_string = argv[arg] + prefix_len;
- int filename_len;
- char *filename;
- char *contents;
- FILE *to_file;
- const char *semi = strchr(arg_string, ';');
- if (!semi) {
- fprintf(stderr,
- "error: -remap-file=from;to argument is missing semicolon\n");
- free_remapped_files(*unsaved_files, i);
- *unsaved_files = 0;
- *num_unsaved_files = 0;
- return -1;
- }
-
- /* Open the file that we're remapping to. */
- to_file = fopen(semi + 1, "r");
- if (!to_file) {
- fprintf(stderr, "error: cannot open file %s that we are remapping to\n",
- semi + 1);
- free_remapped_files(*unsaved_files, i);
- *unsaved_files = 0;
- *num_unsaved_files = 0;
- return -1;
- }
-
- /* Determine the length of the file we're remapping to. */
- fseek(to_file, 0, SEEK_END);
- unsaved->Length = ftell(to_file);
- fseek(to_file, 0, SEEK_SET);
-
- /* Read the contents of the file we're remapping to. */
- 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);
- fclose(to_file);
- free_remapped_files(*unsaved_files, i);
- *unsaved_files = 0;
- *num_unsaved_files = 0;
- return -1;
- }
- contents[unsaved->Length] = 0;
- unsaved->Contents = contents;
-
- /* Close the file. */
- fclose(to_file);
-
- /* Copy the file name that we're remapping from. */
- filename_len = semi - arg_string;
- filename = (char *)malloc(filename_len + 1);
- memcpy(filename, arg_string, filename_len);
- filename[filename_len] = 0;
- unsaved->Filename = filename;
- }
-
- return 0;
-}
-
int perform_code_completion(int argc, const char **argv) {
const char *input = argv[1];
char *filename = 0;
@@ -624,7 +637,7 @@
CXCursor Cursor;
CursorSourceLocation *Locations = 0;
unsigned NumLocations = 0, Loc;
-
+
/* Count the number of locations. */
while (strstr(argv[NumLocations+1], "-cursor-at=") == argv[NumLocations+1])
++NumLocations;
@@ -645,15 +658,12 @@
&num_unsaved_files))
return -1;
- if (num_unsaved_files > 0) {
- fprintf(stderr, "cannot remap files when looking for a cursor\n");
- return -1;
- }
-
CIdx = clang_createIndex(0, 1);
TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
argc - num_unsaved_files - 2 - NumLocations,
- argv + num_unsaved_files + 1 + NumLocations);
+ argv + num_unsaved_files + 1 + NumLocations,
+ num_unsaved_files,
+ unsaved_files);
if (!TU) {
fprintf(stderr, "unable to parse input\n");
return -1;