blob: 21027999e6d058c213e3a38ba7bfb743caaf7e5f [file] [log] [blame]
Ted Kremenekab188932010-01-05 19:32:54 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Clang-C Source Indexing library.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CIndexer.h"
15
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclVisitor.h"
18#include "clang/AST/StmtVisitor.h"
19#include "clang/Basic/FileManager.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/Version.h"
22#include "clang/Sema/CodeCompleteConsumer.h"
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/Config/config.h"
25#include "llvm/Support/Compiler.h"
26#include "llvm/Support/MemoryBuffer.h"
27#include "llvm/Support/raw_ostream.h"
28#include "llvm/System/Program.h"
29
30#include <cstdio>
31#include <vector>
32#include <sstream>
33
34#ifdef LLVM_ON_WIN32
35#include <windows.h>
36#else
37#include <dlfcn.h>
38#endif
39
40using namespace clang;
41using namespace idx;
42
43const llvm::sys::Path& CIndexer::getClangPath() {
44 // Did we already compute the path?
45 if (!ClangPath.empty())
46 return ClangPath;
47
48 // Find the location where this library lives (libCIndex.dylib).
49#ifdef LLVM_ON_WIN32
50 MEMORY_BASIC_INFORMATION mbi;
51 char path[MAX_PATH];
52 VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi,
53 sizeof(mbi));
54 GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH);
55
56 llvm::sys::Path CIndexPath(path);
57
58 CIndexPath.eraseComponent();
59 CIndexPath.appendComponent("clang");
60 CIndexPath.appendSuffix("exe");
61 CIndexPath.makeAbsolute();
62#else
63 // This silly cast below avoids a C++ warning.
64 Dl_info info;
65 if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
66 assert(0 && "Call to dladdr() failed");
67
68 llvm::sys::Path CIndexPath(info.dli_fname);
69
70 // We now have the CIndex directory, locate clang relative to it.
71 CIndexPath.eraseComponent();
Chandler Carruthf1f70b42010-01-27 07:37:16 +000072 CIndexPath.appendComponent("..");
Ted Kremenekab188932010-01-05 19:32:54 +000073 CIndexPath.appendComponent("bin");
74 CIndexPath.appendComponent("clang");
75#endif
76
77 // Cache our result.
78 ClangPath = CIndexPath;
79 return ClangPath;
80}
81
82std::string CIndexer::getClangResourcesPath() {
83 llvm::sys::Path P = getClangPath();
84
85 if (!P.empty()) {
86 P.eraseComponent(); // Remove /clang from foo/bin/clang
87 P.eraseComponent(); // Remove /bin from foo/bin
88
89 // Get foo/lib/clang/<version>/include
90 P.appendComponent("lib");
91 P.appendComponent("clang");
92 P.appendComponent(CLANG_VERSION_STRING);
93 }
94
95 return P.str();
96}
Douglas Gregor4db64a42010-01-23 00:14:00 +000097
98bool clang::RemapFiles(unsigned num_unsaved_files,
99 struct CXUnsavedFile *unsaved_files,
100 std::vector<std::string> &RemapArgs,
101 std::vector<llvm::sys::Path> &TemporaryFiles) {
102 for (unsigned i = 0; i != num_unsaved_files; ++i) {
103 char tmpFile[L_tmpnam];
104 char *tmpFileName = tmpnam(tmpFile);
105
106 // Write the contents of this unsaved file into the temporary file.
107 llvm::sys::Path SavedFile(tmpFileName);
108 std::string ErrorInfo;
109 llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo);
110 if (!ErrorInfo.empty())
111 return true;
112
113 OS.write(unsaved_files[i].Contents, unsaved_files[i].Length);
114 OS.close();
115 if (OS.has_error()) {
116 SavedFile.eraseFromDisk();
117 return true;
118 }
119
120 // Remap the file.
121 std::string RemapArg = unsaved_files[i].Filename;
122 RemapArg += ';';
123 RemapArg += tmpFileName;
124 RemapArgs.push_back("-Xclang");
125 RemapArgs.push_back("-remap-file");
126 RemapArgs.push_back("-Xclang");
127 RemapArgs.push_back(RemapArg);
128 TemporaryFiles.push_back(SavedFile);
129 }
130
131 return false;
132}
133