diff options
author | Steve Naroff <snaroff@apple.com> | 2009-10-15 20:04:39 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-10-15 20:04:39 +0000 |
commit | 5b7d8e254f6c2855b37b5521c0aee0a560dab237 (patch) | |
tree | d25bc79066528e00af81dc5162272f47bc870999 /tools/CIndex/CIndex.cpp | |
parent | 0ebd9321ba380471010341f24c874f46f56e7581 (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.cpp | 62 |
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) { |