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#include "clang/AST/Decl.h"
16ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/AST/DeclVisitor.h"
17ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/AST/StmtVisitor.h"
18ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Basic/FileManager.h"
19ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Basic/SourceManager.h"
20ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Basic/Version.h"
21ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Sema/CodeCompleteConsumer.h"
22ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/ADT/StringExtras.h"
231770e0dadcab966990cca4d7516253c886fd907cDylan Noblesmith#include "llvm/Config/llvm-config.h"
24ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/Support/Compiler.h"
25ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/Support/MemoryBuffer.h"
2603013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Program.h"
27f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/Support/raw_ostream.h"
28ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <cstdio>
29ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <sstream>
30f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include <vector>
31ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
323b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#ifdef __CYGWIN__
33893793b34c0f84c2239a153200b40ba1674d2400NAKAMURA Takumi#include <cygwin/version.h>
343b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#include <sys/cygwin.h>
353b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#define LLVM_ON_WIN32 1
363b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#endif
373b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi
38ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#ifdef LLVM_ON_WIN32
39ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <windows.h>
40ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#else
41ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include <dlfcn.h>
42ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#endif
43ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
44ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekusing namespace clang;
45ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
46082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramerconst std::string &CIndexer::getClangResourcesPath() {
47ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Did we already compute the path?
48d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor  if (!ResourcesPath.empty())
49082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer    return ResourcesPath;
50082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer
51082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer  SmallString<128> LibClangPath;
52082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer
53d1e6fdb4c5325c61fedfa62751f70ee373880a52Douglas Gregor  // Find the location where this library lives (libclang.dylib).
54ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#ifdef LLVM_ON_WIN32
55ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  MEMORY_BASIC_INFORMATION mbi;
56ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  char path[MAX_PATH];
57ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi,
58ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek               sizeof(mbi));
59ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH);
603b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi
613b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#ifdef __CYGWIN__
623b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi  char w32path[MAX_PATH];
633b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi  strcpy(w32path, path);
64893793b34c0f84c2239a153200b40ba1674d2400NAKAMURA Takumi#if CYGWIN_VERSION_API_MAJOR > 0 || CYGWIN_VERSION_API_MINOR >= 181
65893793b34c0f84c2239a153200b40ba1674d2400NAKAMURA Takumi  cygwin_conv_path(CCP_WIN_A_TO_POSIX, w32path, path, MAX_PATH);
66893793b34c0f84c2239a153200b40ba1674d2400NAKAMURA Takumi#else
673b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi  cygwin_conv_to_full_posix_path(w32path, path);
683b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi#endif
69893793b34c0f84c2239a153200b40ba1674d2400NAKAMURA Takumi#endif
703b35a4d21c9f6e48ee7e64fdf78fde39a61f602eNAKAMURA Takumi
71082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer  LibClangPath += llvm::sys::path::parent_path(path);
72ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#else
73ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // This silly cast below avoids a C++ warning.
74ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  Dl_info info;
75ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
76b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("Call to dladdr() failed");
77082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer
78ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // We now have the CIndex directory, locate clang relative to it.
79082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer  LibClangPath += llvm::sys::path::parent_path(info.dli_fname);
80ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#endif
81082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer
82082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer  llvm::sys::path::append(LibClangPath, "clang", CLANG_VERSION_STRING);
83ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
84ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Cache our result.
85082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer  ResourcesPath = LibClangPath.str();
86082ad2bd3f6fb0aef727f6c9ab53d2c4aa75fd53Benjamin Kramer  return ResourcesPath;
87ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
88