CIndexUSRs.cpp revision 12161968f3bcb7bb1053d2da36ac066d795ba7dd
1//===- CIndexUSR.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 generation and use of USRs from CXEntities.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CIndexer.h"
15#include "CXCursor.h"
16#include "CXString.h"
17#include "clang/IDE/USRGeneration.h"
18#include "clang/Lex/PreprocessingRecord.h"
19#include "llvm/ADT/SmallString.h"
20#include "llvm/Support/raw_ostream.h"
21
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25// API hooks.
26//===----------------------------------------------------------------------===//
27
28static inline StringRef extractUSRSuffix(StringRef s) {
29  return s.startswith("c:") ? s.substr(2) : "";
30}
31
32bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
33  return ide::generateUSRForDecl(D, Buf);
34}
35
36extern "C" {
37
38CXString clang_getCursorUSR(CXCursor C) {
39  const CXCursorKind &K = clang_getCursorKind(C);
40
41  if (clang_isDeclaration(K)) {
42    const Decl *D = cxcursor::getCursorDecl(C);
43    if (!D)
44      return cxstring::createEmpty();
45
46    CXTranslationUnit TU = cxcursor::getCursorTU(C);
47    if (!TU)
48      return cxstring::createEmpty();
49
50    cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
51    if (!buf)
52      return cxstring::createEmpty();
53
54    bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
55    if (Ignore) {
56      buf->dispose();
57      return cxstring::createEmpty();
58    }
59
60    // Return the C-string, but don't make a copy since it is already in
61    // the string buffer.
62    buf->Data.push_back('\0');
63    return createCXString(buf);
64  }
65
66  if (K == CXCursor_MacroDefinition) {
67    CXTranslationUnit TU = cxcursor::getCursorTU(C);
68    if (!TU)
69      return cxstring::createEmpty();
70
71    cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
72    if (!buf)
73      return cxstring::createEmpty();
74
75    buf->Data += ide::getUSRSpacePrefix();
76    buf->Data += "macro@";
77    buf->Data +=
78        cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
79    buf->Data.push_back('\0');
80    return createCXString(buf);
81  }
82
83  return cxstring::createEmpty();
84}
85
86CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
87  SmallString<128> Buf(ide::getUSRSpacePrefix());
88  llvm::raw_svector_ostream OS(Buf);
89  OS << extractUSRSuffix(clang_getCString(classUSR));
90  ide::generateUSRForObjCIvar(name, OS);
91  return cxstring::createDup(OS.str());
92}
93
94CXString clang_constructUSR_ObjCMethod(const char *name,
95                                       unsigned isInstanceMethod,
96                                       CXString classUSR) {
97  SmallString<128> Buf(ide::getUSRSpacePrefix());
98  llvm::raw_svector_ostream OS(Buf);
99  OS << extractUSRSuffix(clang_getCString(classUSR));
100  ide::generateUSRForObjCMethod(name, isInstanceMethod, OS);
101  return cxstring::createDup(OS.str());
102}
103
104CXString clang_constructUSR_ObjCClass(const char *name) {
105  SmallString<128> Buf(ide::getUSRSpacePrefix());
106  llvm::raw_svector_ostream OS(Buf);
107  ide::generateUSRForObjCClass(name, OS);
108  return cxstring::createDup(OS.str());
109}
110
111CXString clang_constructUSR_ObjCProtocol(const char *name) {
112  SmallString<128> Buf(ide::getUSRSpacePrefix());
113  llvm::raw_svector_ostream OS(Buf);
114  ide::generateUSRForObjCProtocol(name, OS);
115  return cxstring::createDup(OS.str());
116}
117
118CXString clang_constructUSR_ObjCCategory(const char *class_name,
119                                         const char *category_name) {
120  SmallString<128> Buf(ide::getUSRSpacePrefix());
121  llvm::raw_svector_ostream OS(Buf);
122  ide::generateUSRForObjCCategory(class_name, category_name, OS);
123  return cxstring::createDup(OS.str());
124}
125
126CXString clang_constructUSR_ObjCProperty(const char *property,
127                                         CXString classUSR) {
128  SmallString<128> Buf(ide::getUSRSpacePrefix());
129  llvm::raw_svector_ostream OS(Buf);
130  OS << extractUSRSuffix(clang_getCString(classUSR));
131  ide::generateUSRForObjCProperty(property, OS);
132  return cxstring::createDup(OS.str());
133}
134
135} // end extern "C"
136