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