diff options
Diffstat (limited to 'tools/CIndex')
-rw-r--r-- | tools/CIndex/CIndex.cpp | 41 | ||||
-rw-r--r-- | tools/CIndex/CIndexCodeCompletion.cpp | 31 | ||||
-rw-r--r-- | tools/CIndex/CIndexer.cpp | 37 | ||||
-rw-r--r-- | tools/CIndex/CIndexer.h | 14 |
4 files changed, 90 insertions, 33 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index ddbdf531d0..6cd545f53f 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -873,10 +873,22 @@ CXTranslationUnit clang_createTranslationUnitFromSourceFile(CXIndex CIdx, const char *source_filename, int num_command_line_args, - const char **command_line_args) { + const char **command_line_args, + unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files) { assert(CIdx && "Passed null CXIndex"); CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); + llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; + for (unsigned I = 0; I != num_unsaved_files; ++I) { + const llvm::MemoryBuffer *Buffer + = llvm::MemoryBuffer::getMemBuffer(unsaved_files[I].Contents, + unsaved_files[I].Contents + unsaved_files[I].Length, + unsaved_files[I].Filename); + RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, + Buffer)); + } + if (!CXXIdx->getUseExternalASTGeneration()) { llvm::SmallVector<const char *, 16> Args; @@ -899,7 +911,9 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, CXXIdx->getDiags(), CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(), - /* UseBumpAllocator = */ true)); + /* UseBumpAllocator = */ true, + RemappedFiles.data(), + RemappedFiles.size())); // FIXME: Until we have broader testing, just drop the entire AST if we // encountered an error. @@ -930,6 +944,17 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, char astTmpFile[L_tmpnam]; argv.push_back(tmpnam(astTmpFile)); + // Remap any unsaved files to temporary files. + std::vector<llvm::sys::Path> TemporaryFiles; + std::vector<std::string> RemapArgs; + if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles)) + return 0; + + // The pointers into the elements of RemapArgs are stable because we + // won't be adding anything to RemapArgs after this point. + for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i) + argv.push_back(RemapArgs[i].c_str()); + // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'. for (int i = 0; i < num_command_line_args; ++i) if (const char *arg = command_line_args[i]) { @@ -970,11 +995,17 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, llvm::errs() << '\n'; } - // Finally, we create the translation unit from the ast file. - ASTUnit *ATU = static_cast<ASTUnit *>( - clang_createTranslationUnit(CIdx, astTmpFile)); + ASTUnit *ATU = ASTUnit::LoadFromPCHFile(astTmpFile, CXXIdx->getDiags(), + CXXIdx->getOnlyLocalDecls(), + /* UseBumpAllocator = */ true, + RemappedFiles.data(), + RemappedFiles.size()); if (ATU) ATU->unlinkTemporaryFile(); + + for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) + TemporaryFiles[i].eraseFromDisk(); + return ATU; } diff --git a/tools/CIndex/CIndexCodeCompletion.cpp b/tools/CIndex/CIndexCodeCompletion.cpp index f70479b5e8..f3b60dc8b0 100644 --- a/tools/CIndex/CIndexCodeCompletion.cpp +++ b/tools/CIndex/CIndexCodeCompletion.cpp @@ -221,35 +221,10 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, argv.push_back("-Xclang"); argv.push_back("-code-completion-macros"); + // Remap any unsaved files to temporary files. std::vector<std::string> RemapArgs; - for (unsigned i = 0; i != num_unsaved_files; ++i) { - char tmpFile[L_tmpnam]; - char *tmpFileName = tmpnam(tmpFile); - - // Write the contents of this unsaved file into the temporary file. - llvm::sys::Path SavedFile(tmpFileName); - std::string ErrorInfo; - llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo); - if (!ErrorInfo.empty()) - continue; - - OS.write(unsaved_files[i].Contents, unsaved_files[i].Length); - OS.close(); - if (OS.has_error()) { - SavedFile.eraseFromDisk(); - continue; - } - - // Remap the file. - std::string RemapArg = unsaved_files[i].Filename; - RemapArg += ';'; - RemapArg += tmpFileName; - RemapArgs.push_back("-Xclang"); - RemapArgs.push_back("-remap-file"); - RemapArgs.push_back("-Xclang"); - RemapArgs.push_back(RemapArg); - TemporaryFiles.push_back(SavedFile); - } + if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles)) + return 0; // The pointers into the elements of RemapArgs are stable because we // won't be adding anything to RemapArgs after this point. diff --git a/tools/CIndex/CIndexer.cpp b/tools/CIndex/CIndexer.cpp index f26c8ce813..53636a4ff3 100644 --- a/tools/CIndex/CIndexer.cpp +++ b/tools/CIndex/CIndexer.cpp @@ -94,3 +94,40 @@ std::string CIndexer::getClangResourcesPath() { return P.str(); } + +bool clang::RemapFiles(unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files, + std::vector<std::string> &RemapArgs, + std::vector<llvm::sys::Path> &TemporaryFiles) { + for (unsigned i = 0; i != num_unsaved_files; ++i) { + char tmpFile[L_tmpnam]; + char *tmpFileName = tmpnam(tmpFile); + + // Write the contents of this unsaved file into the temporary file. + llvm::sys::Path SavedFile(tmpFileName); + std::string ErrorInfo; + llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo); + if (!ErrorInfo.empty()) + return true; + + OS.write(unsaved_files[i].Contents, unsaved_files[i].Length); + OS.close(); + if (OS.has_error()) { + SavedFile.eraseFromDisk(); + return true; + } + + // Remap the file. + std::string RemapArg = unsaved_files[i].Filename; + RemapArg += ';'; + RemapArg += tmpFileName; + RemapArgs.push_back("-Xclang"); + RemapArgs.push_back("-remap-file"); + RemapArgs.push_back("-Xclang"); + RemapArgs.push_back(RemapArg); + TemporaryFiles.push_back(SavedFile); + } + + return false; +} + diff --git a/tools/CIndex/CIndexer.h b/tools/CIndex/CIndexer.h index 1a4e4b7b8f..d01454f9dc 100644 --- a/tools/CIndex/CIndexer.h +++ b/tools/CIndex/CIndexer.h @@ -19,6 +19,7 @@ #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/ASTUnit.h" #include "llvm/System/Path.h" +#include <vector> using namespace clang; @@ -77,4 +78,17 @@ public: static CXString createCXString(const char *String, bool DupString = false); }; +namespace clang { + /** + * \brief Given a set of "unsaved" files, create temporary files and + * construct the clang -cc1 argument list needed to perform the remapping. + * + * \returns true if an error occurred. + */ + bool RemapFiles(unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files, + std::vector<std::string> &RemapArgs, + std::vector<llvm::sys::Path> &TemporaryFiles); +} + #endif |