CIndexer.cpp revision 03013fa9a0bf1ef4b907f5fec006c8f4000fdd21
1ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// 2ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// 3ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// The LLVM Compiler Infrastructure 4ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// 5ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// This file is distributed under the University of Illinois Open Source 6ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// License. See LICENSE.TXT for details. 7ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// 8ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//===----------------------------------------------------------------------===// 9ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// 10ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// This file implements the Clang-C Source Indexing library. 11ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// 12ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//===----------------------------------------------------------------------===// 13ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 14ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "CIndexer.h" 15ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 16ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/AST/Decl.h" 17ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/AST/DeclVisitor.h" 18ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/AST/StmtVisitor.h" 19ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Basic/FileManager.h" 20ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Basic/SourceManager.h" 21ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Basic/Version.h" 22ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Sema/CodeCompleteConsumer.h" 23ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/ADT/StringExtras.h" 24ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/Config/config.h" 25ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/Support/Compiler.h" 26ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/Support/MemoryBuffer.h" 27ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/Support/raw_ostream.h" 2803013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Program.h" 29ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 30ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <cstdio> 31ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <vector> 32ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <sstream> 33ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 343b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#ifdef __CYGWIN__ 353b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#include <sys/cygwin.h> 363b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#define LLVM_ON_WIN32 1 373b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#endif 383b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi 39ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#ifdef LLVM_ON_WIN32 40ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <windows.h> 41ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#else 42ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <dlfcn.h> 43ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#endif 44ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 45ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekusing namespace clang; 46ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 47d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregorstd::string CIndexer::getClangResourcesPath() { 48ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek // Did we already compute the path? 49d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor if (!ResourcesPath.empty()) 50d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor return ResourcesPath.str(); 51d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor 52d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor // Find the location where this library lives (libclang.dylib). 53ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#ifdef LLVM_ON_WIN32 54ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek MEMORY_BASIC_INFORMATION mbi; 55ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek char path[MAX_PATH]; 56ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi, 57ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek sizeof(mbi)); 58ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH); 593b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi 603b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#ifdef __CYGWIN__ 613b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi char w32path[MAX_PATH]; 623b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi strcpy(w32path, path); 633b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi cygwin_conv_to_full_posix_path(w32path, path); 643b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#endif 653b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi 66d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor llvm::sys::Path LibClangPath(path); 67d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor LibClangPath.eraseComponent(); 68ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#else 69ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek // This silly cast below avoids a C++ warning. 70ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek Dl_info info; 71ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0) 72ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek assert(0 && "Call to dladdr() failed"); 73d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor 74d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor llvm::sys::Path LibClangPath(info.dli_fname); 75d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor 76ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek // We now have the CIndex directory, locate clang relative to it. 77d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor LibClangPath.eraseComponent(); 78ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#endif 79d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor 80d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor LibClangPath.appendComponent("clang"); 81d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor LibClangPath.appendComponent(CLANG_VERSION_STRING); 82ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 83ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek // Cache our result. 84d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor ResourcesPath = LibClangPath; 85d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor return LibClangPath.str(); 86ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek} 874db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 88c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramerstatic llvm::sys::Path GetTemporaryPath() { 8974198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar // FIXME: This is lame; sys::Path should provide this function (in particular, 9074198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar // it should know how to find the temporary files dir). 9174198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar std::string Error; 9274198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar const char *TmpDir = ::getenv("TMPDIR"); 9374198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar if (!TmpDir) 9474198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar TmpDir = ::getenv("TEMP"); 9574198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar if (!TmpDir) 9674198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar TmpDir = ::getenv("TMP"); 9774198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar if (!TmpDir) 9874198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar TmpDir = "/tmp"; 9974198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar llvm::sys::Path P(TmpDir); 100c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer P.appendComponent("remap"); 10174198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar if (P.makeUnique(false, &Error)) 10274198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar return llvm::sys::Path(""); 10374198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar 10474198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar // FIXME: Grumble, makeUnique sometimes leaves the file around!? PR3837. 10574198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar P.eraseFromDisk(false, 0); 10674198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar 10774198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar return P; 10874198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar} 10974198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar 1104db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregorbool clang::RemapFiles(unsigned num_unsaved_files, 1114db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor struct CXUnsavedFile *unsaved_files, 1124db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor std::vector<std::string> &RemapArgs, 1134db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor std::vector<llvm::sys::Path> &TemporaryFiles) { 1144db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned i = 0; i != num_unsaved_files; ++i) { 1154db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Write the contents of this unsaved file into the temporary file. 116c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer llvm::sys::Path SavedFile(GetTemporaryPath()); 11774198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar if (SavedFile.empty()) 11874198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar return true; 11974198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar 1204db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor std::string ErrorInfo; 121c44fe4bf2962bfcb323e93a63ba4a72d67839cdeFrancois Pichet llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo, 122c44fe4bf2962bfcb323e93a63ba4a72d67839cdeFrancois Pichet llvm::raw_fd_ostream::F_Binary); 1234db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor if (!ErrorInfo.empty()) 1244db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor return true; 1254db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 1264db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor OS.write(unsaved_files[i].Contents, unsaved_files[i].Length); 1274db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor OS.close(); 1284db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor if (OS.has_error()) { 1294db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor SavedFile.eraseFromDisk(); 130ebaf2573ccfcfef179904db1aae965b5b778c72dDan Gohman OS.clear_error(); 1314db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor return true; 1324db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 1334db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 1344db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Remap the file. 1354db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor std::string RemapArg = unsaved_files[i].Filename; 1364db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemapArg += ';'; 13774198af85ea647d6483b643859adae4f2bed330bDaniel Dunbar RemapArg += SavedFile.str(); 1384db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemapArgs.push_back("-Xclang"); 1394db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemapArgs.push_back("-remap-file"); 1404db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemapArgs.push_back("-Xclang"); 1414db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemapArgs.push_back(RemapArg); 1424db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor TemporaryFiles.push_back(SavedFile); 1434db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 1444db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 1454db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor return false; 1464db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor} 1474db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 148