Introduce a new libclang API, clang_reparseTranslationUnit(), which
reparses an already-parsed translation unit. At the moment it's just a
convenience function, but we hope to use it for performance
optimizations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108756 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 4ed24b1..569ef20 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -558,7 +558,7 @@
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
int result;
-
+
Idx = clang_createIndex(/* excludeDeclsFromPCH */
!strcmp(filter, "local") ? 1 : 0,
/* displayDiagnosics=*/1);
@@ -578,6 +578,7 @@
unsaved_files);
if (!TU) {
fprintf(stderr, "Unable to load translation unit!\n");
+ free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
return 1;
}
@@ -588,6 +589,57 @@
return result;
}
+int perform_test_reparse_source(int argc, const char **argv, int trials,
+ const char *filter, CXCursorVisitor Visitor,
+ PostVisitTU PV) {
+ const char *UseExternalASTs =
+ getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION");
+ CXIndex Idx;
+ CXTranslationUnit TU;
+ struct CXUnsavedFile *unsaved_files = 0;
+ int num_unsaved_files = 0;
+ int result;
+ int trial;
+
+ Idx = clang_createIndex(/* excludeDeclsFromPCH */
+ !strcmp(filter, "local") ? 1 : 0,
+ /* displayDiagnosics=*/1);
+
+ if (UseExternalASTs && strlen(UseExternalASTs))
+ clang_setUseExternalASTGeneration(Idx, 1);
+
+ if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
+ clang_disposeIndex(Idx);
+ 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");
+ free_remapped_files(unsaved_files, num_unsaved_files);
+ clang_disposeIndex(Idx);
+ return 1;
+ }
+
+ for (trial = 0; trial < trials; ++trial) {
+ if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files)) {
+ clang_disposeTranslationUnit(TU);
+ free_remapped_files(unsaved_files, num_unsaved_files);
+ clang_disposeIndex(Idx);
+ return -1;
+ }
+ }
+
+ result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
+ free_remapped_files(unsaved_files, num_unsaved_files);
+ clang_disposeIndex(Idx);
+ return result;
+}
+
/******************************************************************************/
/* Logic for testing clang_getCursor(). */
/******************************************************************************/
@@ -1219,6 +1271,8 @@
"[FileCheck prefix]\n"
" c-index-test -test-load-source <symbol filter> {<args>}*\n");
fprintf(stderr,
+ " c-index-test -test-load-source-reparse <trials> <symbol filter> "
+ " {<args>}*\n"
" c-index-test -test-load-source-usrs <symbol filter> {<args>}*\n"
" c-index-test -test-annotate-tokens=<range> {<args>}*\n"
" c-index-test -test-inclusion-stack-source {<args>}*\n"
@@ -1252,6 +1306,14 @@
return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I,
NULL);
}
+ else if (argc >= 5 && strncmp(argv[1], "-test-load-source-reparse", 25) == 0){
+ CXCursorVisitor I = GetVisitor(argv[1] + 25);
+ if (I) {
+ int trials = atoi(argv[2]);
+ return perform_test_reparse_source(argc - 4, argv + 4, trials, argv[3], I,
+ NULL);
+ }
+ }
else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) {
CXCursorVisitor I = GetVisitor(argv[1] + 17);
if (I)
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 7f32a1c..efc61a0 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -1390,6 +1390,25 @@
delete static_cast<ASTUnit *>(CTUnit);
}
+int clang_reparseTranslationUnit(CXTranslationUnit TU,
+ unsigned num_unsaved_files,
+ struct CXUnsavedFile *unsaved_files) {
+ if (!TU)
+ return 1;
+
+ llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
+ for (unsigned I = 0; I != num_unsaved_files; ++I) {
+ llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+ const llvm::MemoryBuffer *Buffer
+ = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
+ RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
+ Buffer));
+ }
+
+ return static_cast<ASTUnit *>(TU)->Reparse(RemappedFiles.data(),
+ RemappedFiles.size())? 1 : 0;
+}
+
CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
if (!CTUnit)
return createCXString("");
diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports
index f21fec6..e09a6a0 100644
--- a/tools/libclang/libclang.darwin.exports
+++ b/tools/libclang/libclang.darwin.exports
@@ -86,6 +86,7 @@
_clang_isStatement
_clang_isTranslationUnit
_clang_isUnexposed
+_clang_reparseTranslationUnit
_clang_setUseExternalASTGeneration
_clang_tokenize
_clang_visitChildren
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index dcb40d4..4b6ddd1 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -86,6 +86,7 @@
clang_isStatement
clang_isTranslationUnit
clang_isUnexposed
+clang_reparseTranslationUnit
clang_setUseExternalASTGeneration
clang_tokenize
clang_visitChildren