aboutsummaryrefslogtreecommitdiff
path: root/tools/CIndex/CIndex.cpp
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2009-10-15 20:04:39 +0000
committerSteve Naroff <snaroff@apple.com>2009-10-15 20:04:39 +0000
commit5b7d8e254f6c2855b37b5521c0aee0a560dab237 (patch)
treed25bc79066528e00af81dc5162272f47bc870999 /tools/CIndex/CIndex.cpp
parent0ebd9321ba380471010341f24c874f46f56e7581 (diff)
Implement <rdar://problem/7303432> [Clang/Index] In-memory-style AST generation API (initial API implementation).
Added clang_createTranslationUnitFromSourceFile(). Changed clang_createIndex() to lookup the location of clang (using dladdr). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84198 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/CIndex/CIndex.cpp')
-rw-r--r--tools/CIndex/CIndex.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 9204d1863d..9ab3f790ec 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -23,6 +23,9 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/ASTUnit.h"
#include <cstdio>
+#include <dlfcn.h>
+#include "llvm/System/Path.h"
+
using namespace clang;
using namespace idx;
@@ -241,9 +244,27 @@ public:
extern "C" {
+static const char *clangPath;
+
CXIndex clang_createIndex()
{
// FIXME: Program is leaked.
+
+ // Find the location where this library lives (libCIndex.dylib).
+ // We do the lookup here to avoid poking dladdr too many times.
+ // This silly cast below avoids a C++ warning.
+ Dl_info info;
+ if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
+ assert(0 && "Call to dladdr() failed");
+
+ llvm::sys::Path CIndexPath(info.dli_fname);
+ std::string CIndexDir = CIndexPath.getDirname();
+
+ // We now have the CIndex directory, locate clang relative to it.
+ std::string ClangPath = CIndexDir + "/../bin/clang";
+
+ clangPath = ClangPath.c_str();
+
return new Indexer(*new Program());
}
@@ -266,6 +287,47 @@ CXTranslationUnit clang_createTranslationUnit(
CXXIdx->getFileManager(), &ErrMsg);
}
+CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+ CXIndex CIdx,
+ const char *source_filename,
+ int num_command_line_args, const char **command_line_args)
+{
+ // Generate a temporary name for the AST file.
+ char astTmpFile[L_tmpnam];
+
+ // Build up the arguments for involking clang.
+ const char * argv[ARG_MAX];
+ int argc = 0;
+ argv[argc++] = clangPath;
+ argv[argc++] = "-emit-ast";
+ argv[argc++] = source_filename;
+ argv[argc++] = "-o";
+ argv[argc++] = tmpnam(astTmpFile);
+ for (int i = num_command_line_args; i < num_command_line_args; i++)
+ argv[argc++] = command_line_args[i];
+ argv[argc] = 0;
+
+ // Generate the AST file in a separate process.
+ pid_t child_pid = fork();
+ if (child_pid == 0) { // Child process
+
+ // Execute the command, passing the appropriate arguments.
+ execv(argv[0], (char *const *)argv);
+
+ // If execv returns, it failed.
+ assert(0 && "execv() failed");
+ } else { // This is run by the parent.
+ int child_status;
+ pid_t tpid;
+ do { // Wait for the child to terminate.
+ tpid = wait(&child_status);
+ } while (tpid != child_pid);
+
+ // Finally, we create the translation unit from the ast file.
+ return clang_createTranslationUnit(CIdx, astTmpFile);
+ }
+}
+
void clang_disposeTranslationUnit(
CXTranslationUnit CTUnit)
{