CIndexer.cpp revision d1e6fdb4c5325c61fedfa62751f70ee373880a52
174b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// 274b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs// 3c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne// The LLVM Compiler Infrastructure 474b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs// 574b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs// This file is distributed under the University of Illinois Open Source 674b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs// License. See LICENSE.TXT for details. 774b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs// 8c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne//===----------------------------------------------------------------------===// 9c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne// 10c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne// This file implements the Clang-C Source Indexing library. 11c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne// 12c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne//===----------------------------------------------------------------------===// 13c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 14c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne#include "CIndexer.h" 15c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 1697f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs#include "clang/AST/Decl.h" 1797f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs#include "clang/AST/DeclVisitor.h" 1874b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "clang/AST/StmtVisitor.h" 1974b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "clang/Basic/FileManager.h" 2074b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "clang/Basic/SourceManager.h" 2174b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "clang/Basic/Version.h" 2274b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "clang/Sema/CodeCompleteConsumer.h" 2374b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "llvm/ADT/StringExtras.h" 2474b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "llvm/Config/config.h" 2574b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "llvm/Support/Compiler.h" 2674b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "llvm/Support/MemoryBuffer.h" 2774b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "llvm/Support/raw_ostream.h" 2874b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include "llvm/System/Program.h" 2974b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs 3074b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include <cstdio> 3174b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include <vector> 3274b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include <sstream> 3374b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs 3474b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#ifdef LLVM_ON_WIN32 3574b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include <windows.h> 3674b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#else 3774b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#include <dlfcn.h> 3874b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs#endif 3974b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs 4074b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbsusing namespace clang; 4174b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbs 4274b9fa16e5d1e1a5f3adb065043db46ad20a4575Andy Gibbsstd::string CIndexer::getClangResourcesPath() { 43 // Did we already compute the path? 44 if (!ResourcesPath.empty()) 45 return ResourcesPath.str(); 46 47 // Find the location where this library lives (libclang.dylib). 48#ifdef LLVM_ON_WIN32 49 MEMORY_BASIC_INFORMATION mbi; 50 char path[MAX_PATH]; 51 VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi, 52 sizeof(mbi)); 53 GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH); 54 55 llvm::sys::Path LibClangPath(path); 56 LibClangPath.eraseComponent(); 57#else 58 // This silly cast below avoids a C++ warning. 59 Dl_info info; 60 if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0) 61 assert(0 && "Call to dladdr() failed"); 62 63 llvm::sys::Path LibClangPath(info.dli_fname); 64 65 // We now have the CIndex directory, locate clang relative to it. 66 LibClangPath.eraseComponent(); 67#endif 68 69 LibClangPath.appendComponent("clang"); 70 LibClangPath.appendComponent(CLANG_VERSION_STRING); 71 72 // Cache our result. 73 ResourcesPath = LibClangPath; 74 return LibClangPath.str(); 75} 76 77static llvm::sys::Path GetTemporaryPath() { 78 // FIXME: This is lame; sys::Path should provide this function (in particular, 79 // it should know how to find the temporary files dir). 80 std::string Error; 81 const char *TmpDir = ::getenv("TMPDIR"); 82 if (!TmpDir) 83 TmpDir = ::getenv("TEMP"); 84 if (!TmpDir) 85 TmpDir = ::getenv("TMP"); 86 if (!TmpDir) 87 TmpDir = "/tmp"; 88 llvm::sys::Path P(TmpDir); 89 P.appendComponent("remap"); 90 if (P.makeUnique(false, &Error)) 91 return llvm::sys::Path(""); 92 93 // FIXME: Grumble, makeUnique sometimes leaves the file around!? PR3837. 94 P.eraseFromDisk(false, 0); 95 96 return P; 97} 98 99bool clang::RemapFiles(unsigned num_unsaved_files, 100 struct CXUnsavedFile *unsaved_files, 101 std::vector<std::string> &RemapArgs, 102 std::vector<llvm::sys::Path> &TemporaryFiles) { 103 for (unsigned i = 0; i != num_unsaved_files; ++i) { 104 // Write the contents of this unsaved file into the temporary file. 105 llvm::sys::Path SavedFile(GetTemporaryPath()); 106 if (SavedFile.empty()) 107 return true; 108 109 std::string ErrorInfo; 110 llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo); 111 if (!ErrorInfo.empty()) 112 return true; 113 114 OS.write(unsaved_files[i].Contents, unsaved_files[i].Length); 115 OS.close(); 116 if (OS.has_error()) { 117 SavedFile.eraseFromDisk(); 118 OS.clear_error(); 119 return true; 120 } 121 122 // Remap the file. 123 std::string RemapArg = unsaved_files[i].Filename; 124 RemapArg += ';'; 125 RemapArg += SavedFile.str(); 126 RemapArgs.push_back("-Xclang"); 127 RemapArgs.push_back("-remap-file"); 128 RemapArgs.push_back("-Xclang"); 129 RemapArgs.push_back(RemapArg); 130 TemporaryFiles.push_back(SavedFile); 131 } 132 133 return false; 134} 135 136