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