[cfe-commits] r94258 - in /cfe/trunk: include/clang-c/Index.h include/clang/Frontend/ASTUnit.h include/clang/Frontend/PreprocessorOptions.h lib/Frontend/ASTUnit.cpp lib/Frontend/InitPreprocessor.cpp test/Index/Inputs/remap-load-to.c test/Index/remap-cursor-at.c test/Index/remap-load.c tools/CIndex/CIndex.cpp tools/CIndex/CIndexCodeCompletion.cpp tools/CIndex/CIndexer.cpp tools/CIndex/CIndexer.h tools/c-index-test/c-index-test.c
Douglas Gregor
dgregor at apple.com
Fri Jan 22 16:14:00 PST 2010
Author: dgregor
Date: Fri Jan 22 18:14:00 2010
New Revision: 94258
URL: http://llvm.org/viewvc/llvm-project?rev=94258&view=rev
Log:
Extend clang_createTranslationUnitFromSourceFile() to support creating
translation units that include unsaved files.
Added:
cfe/trunk/test/Index/Inputs/remap-load-to.c
cfe/trunk/test/Index/remap-cursor-at.c
cfe/trunk/test/Index/remap-load.c
Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/include/clang/Frontend/ASTUnit.h
cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Frontend/InitPreprocessor.cpp
cfe/trunk/tools/CIndex/CIndex.cpp
cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp
cfe/trunk/tools/CIndex/CIndexer.cpp
cfe/trunk/tools/CIndex/CIndexer.h
cfe/trunk/tools/c-index-test/c-index-test.c
Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Fri Jan 22 18:14:00 2010
@@ -222,13 +222,21 @@
*
* \param source_filename - The name of the source file to load, or NULL if the
* source file is included in clang_command_line_args.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for code completion, including the contents of
+ * those files.
*/
CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
- CXIndex CIdx,
- const char *source_filename,
- int num_clang_command_line_args,
- const char **clang_command_line_args
-);
+ CXIndex CIdx,
+ const char *source_filename,
+ int num_clang_command_line_args,
+ const char **clang_command_line_args,
+ unsigned num_unsaved_files,
+ struct CXUnsavedFile *unsaved_files);
/**
* \defgroup CINDEX_FILES File manipulation routines
Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Fri Jan 22 18:14:00 2010
@@ -21,6 +21,11 @@
#include <string>
#include <vector>
#include <cassert>
+#include <utility>
+
+namespace llvm {
+ class MemoryBuffer;
+}
namespace clang {
class ASTContext;
@@ -111,6 +116,10 @@
return TopLevelDecls;
}
+ /// \brief A mapping from a file name to the memory buffer that stores the
+ /// remapped contents of that file.
+ typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile;
+
/// \brief Create a ASTUnit from a PCH file.
///
/// \param Filename - The PCH file to load.
@@ -122,7 +131,9 @@
static ASTUnit *LoadFromPCHFile(const std::string &Filename,
Diagnostic &Diags,
bool OnlyLocalDecls = false,
- bool UseBumpAllocator = false);
+ bool UseBumpAllocator = false,
+ RemappedFile *RemappedFiles = 0,
+ unsigned NumRemappedFiles = 0);
/// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
/// CompilerInvocation object.
@@ -158,7 +169,9 @@
Diagnostic &Diags,
llvm::StringRef ResourceFilesPath,
bool OnlyLocalDecls = false,
- bool UseBumpAllocator = false);
+ bool UseBumpAllocator = false,
+ RemappedFile *RemappedFiles = 0,
+ unsigned NumRemappedFiles = 0);
};
} // namespace clang
Modified: cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PreprocessorOptions.h?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PreprocessorOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/PreprocessorOptions.h Fri Jan 22 18:14:00 2010
@@ -16,6 +16,10 @@
#include <utility>
#include <vector>
+namespace llvm {
+ class MemoryBuffer;
+}
+
namespace clang {
class Preprocessor;
@@ -48,6 +52,12 @@
/// pair).
std::vector<std::pair<std::string, std::string> > RemappedFiles;
+ /// \brief The set of file-to-buffer remappings, which take existing files
+ /// on the system (the first part of each pair) and gives them the contents
+ /// of the specified memory buffer (the second part of each pair).
+ std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >
+ RemappedFileBuffers;
+
typedef std::vector<std::pair<std::string, std::string> >::const_iterator
remapped_file_iterator;
remapped_file_iterator remapped_file_begin() const {
@@ -57,6 +67,15 @@
return RemappedFiles.end();
}
+ typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >::
+ const_iterator remapped_file_buffer_iterator;
+ remapped_file_buffer_iterator remapped_file_buffer_begin() const {
+ return RemappedFileBuffers.begin();
+ }
+ remapped_file_buffer_iterator remapped_file_buffer_end() const {
+ return RemappedFileBuffers.end();
+ }
+
public:
PreprocessorOptions() : UsePredefines(true) {}
@@ -69,6 +88,9 @@
void addRemappedFile(llvm::StringRef From, llvm::StringRef To) {
RemappedFiles.push_back(std::make_pair(From, To));
}
+ void addRemappedFile(llvm::StringRef From, const llvm::MemoryBuffer * To) {
+ RemappedFileBuffers.push_back(std::make_pair(From, To));
+ }
};
} // end namespace clang
Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Fri Jan 22 18:14:00 2010
@@ -30,6 +30,7 @@
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Diagnostic.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
using namespace clang;
@@ -103,11 +104,31 @@
ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
Diagnostic &Diags,
bool OnlyLocalDecls,
- bool UseBumpAllocator) {
+ bool UseBumpAllocator,
+ RemappedFile *RemappedFiles,
+ unsigned NumRemappedFiles) {
llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
+ for (unsigned I = 0; I != NumRemappedFiles; ++I) {
+ // Create the file entry for the file that we're mapping from.
+ const FileEntry *FromFile
+ = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
+ RemappedFiles[I].second->getBufferSize(),
+ 0);
+ if (!FromFile) {
+ Diags.Report(diag::err_fe_remap_missing_from_file)
+ << RemappedFiles[I].first;
+ continue;
+ }
+
+ // Override the contents of the "from" file with the contents of
+ // the "to" file.
+ AST->getSourceManager().overrideFileContents(FromFile,
+ RemappedFiles[I].second);
+ }
+
// Gather Info for preprocessor construction later on.
LangOptions LangInfo;
@@ -289,7 +310,9 @@
Diagnostic &Diags,
llvm::StringRef ResourceFilesPath,
bool OnlyLocalDecls,
- bool UseBumpAllocator) {
+ bool UseBumpAllocator,
+ RemappedFile *RemappedFiles,
+ unsigned NumRemappedFiles) {
llvm::SmallVector<const char *, 16> Args;
Args.push_back("<clang>"); // FIXME: Remove dummy argument.
Args.insert(Args.end(), ArgBegin, ArgEnd);
@@ -327,6 +350,11 @@
(const char**) CCArgs.data()+CCArgs.size(),
Diags);
+ // Override any files that need remapping
+ for (unsigned I = 0; I != NumRemappedFiles; ++I)
+ CI.getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
+ RemappedFiles[I].second);
+
// Override the resources path.
CI.getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Fri Jan 22 18:14:00 2010
@@ -424,40 +424,61 @@
SourceManager &SourceMgr,
FileManager &FileMgr,
const PreprocessorOptions &InitOpts) {
- // Remap files in the source manager.
+ // Remap files in the source manager (with buffers).
+ for (PreprocessorOptions::remapped_file_buffer_iterator
+ Remap = InitOpts.remapped_file_buffer_begin(),
+ RemapEnd = InitOpts.remapped_file_buffer_end();
+ Remap != RemapEnd;
+ ++Remap) {
+ // Create the file entry for the file that we're mapping from.
+ const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
+ Remap->second->getBufferSize(),
+ 0);
+ if (!FromFile) {
+ Diags.Report(diag::err_fe_remap_missing_from_file)
+ << Remap->first;
+ continue;
+ }
+
+ // Override the contents of the "from" file with the contents of
+ // the "to" file.
+ SourceMgr.overrideFileContents(FromFile, Remap->second);
+ }
+
+ // Remap files in the source manager (with other files).
for (PreprocessorOptions::remapped_file_iterator
- Remap = InitOpts.remapped_file_begin(),
- RemapEnd = InitOpts.remapped_file_end();
+ Remap = InitOpts.remapped_file_begin(),
+ RemapEnd = InitOpts.remapped_file_end();
Remap != RemapEnd;
++Remap) {
// Find the file that we're mapping to.
const FileEntry *ToFile = FileMgr.getFile(Remap->second);
if (!ToFile) {
Diags.Report(diag::err_fe_remap_missing_to_file)
- << Remap->first << Remap->second;
+ << Remap->first << Remap->second;
continue;
}
-
+
// Create the file entry for the file that we're mapping from.
const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
ToFile->getSize(),
0);
if (!FromFile) {
Diags.Report(diag::err_fe_remap_missing_from_file)
- << Remap->first;
+ << Remap->first;
continue;
}
-
+
// Load the contents of the file we're mapping to.
std::string ErrorStr;
const llvm::MemoryBuffer *Buffer
- = llvm::MemoryBuffer::getFile(ToFile->getName(), &ErrorStr);
+ = llvm::MemoryBuffer::getFile(ToFile->getName(), &ErrorStr);
if (!Buffer) {
Diags.Report(diag::err_fe_error_opening)
- << Remap->second << ErrorStr;
+ << Remap->second << ErrorStr;
continue;
}
-
+
// Override the contents of the "from" file with the contents of
// the "to" file.
SourceMgr.overrideFileContents(FromFile, Buffer);
Added: cfe/trunk/test/Index/Inputs/remap-load-to.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/remap-load-to.c?rev=94258&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/remap-load-to.c (added)
+++ cfe/trunk/test/Index/Inputs/remap-load-to.c Fri Jan 22 18:14:00 2010
@@ -0,0 +1,3 @@
+int foo(int parm1, float parm2) {
+ return parm1 + parm2;
+}
Added: cfe/trunk/test/Index/remap-cursor-at.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/remap-cursor-at.c?rev=94258&view=auto
==============================================================================
--- cfe/trunk/test/Index/remap-cursor-at.c (added)
+++ cfe/trunk/test/Index/remap-cursor-at.c Fri Jan 22 18:14:00 2010
@@ -0,0 +1,5 @@
+// RUN: c-index-test -cursor-at=%s:1:15 -cursor-at=%s:2:21 -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck %s
+// RUN: CINDEXTEST_USE_EXTERNAL_AST_GENERATION=1 c-index-test -cursor-at=%s:1:15 -cursor-at=%s:2:21 -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck %s
+
+// CHECK: ParmDecl=parm1:1:13 (Definition)
+// CHECK: DeclRefExpr=parm2:1:26
Added: cfe/trunk/test/Index/remap-load.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/remap-load.c?rev=94258&view=auto
==============================================================================
--- cfe/trunk/test/Index/remap-load.c (added)
+++ cfe/trunk/test/Index/remap-load.c Fri Jan 22 18:14:00 2010
@@ -0,0 +1,13 @@
+// RUN: c-index-test -test-load-source all -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck -check-prefix=CHECK %s
+// RUN: CINDEXTEST_USE_EXTERNAL_AST_GENERATION=1 c-index-test -test-load-source all -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck -check-prefix=CHECK %s
+
+// CHECK: remap-load.c:1:5: FunctionDecl=foo:1:5 (Definition) [Extent=1:5:3:1]
+// CHECK: remap-load.c:1:13: ParmDecl=parm1:1:13 (Definition) [Extent=1:9:1:17]
+// CHECK: remap-load.c:1:26: ParmDecl=parm2:1:26 (Definition) [Extent=1:20:1:30]
+// CHECK: remap-load.c:1:5: UnexposedStmt=foo [Extent=1:33:3:1]
+// CHECK: remap-load.c:1:5: UnexposedStmt=foo [Extent=2:3:2:22]
+// CHECK: remap-load.c:2:10: UnexposedExpr= [Extent=2:10:2:22]
+// CHECK: remap-load.c:2:10: UnexposedExpr= [Extent=2:10:2:22]
+// CHECK: remap-load.c:2:10: UnexposedExpr=parm1:1:13 [Extent=2:10:2:14]
+// CHECK: remap-load.c:2:10: DeclRefExpr=parm1:1:13 [Extent=2:10:2:14]
+// CHECK: remap-load.c:2:18: DeclRefExpr=parm2:1:26 [Extent=2:18:2:22]
Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Fri Jan 22 18:14:00 2010
@@ -873,10 +873,22 @@
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 @@
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 @@
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 @@
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;
}
Modified: cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp Fri Jan 22 18:14:00 2010
@@ -221,35 +221,10 @@
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.
Modified: cfe/trunk/tools/CIndex/CIndexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexer.cpp?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndexer.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndexer.cpp Fri Jan 22 18:14:00 2010
@@ -94,3 +94,40 @@
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;
+}
+
Modified: cfe/trunk/tools/CIndex/CIndexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexer.h?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndexer.h (original)
+++ cfe/trunk/tools/CIndex/CIndexer.h Fri Jan 22 18:14:00 2010
@@ -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 @@
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
Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=94258&r1=94257&r2=94258&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Fri Jan 22 18:14:00 2010
@@ -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;
More information about the cfe-commits
mailing list