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/Frontend/ASTUnit.h"
19 #include "clang/Index/USRGeneration.h"
20 #include "clang/Lex/PreprocessingRecord.h"
21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/Support/raw_ostream.h"
23
24 using namespace clang;
25 using namespace clang::index;
26
27 //===----------------------------------------------------------------------===//
28 // API hooks.
29 //===----------------------------------------------------------------------===//
30
extractUSRSuffix(StringRef s)31 static inline StringRef extractUSRSuffix(StringRef s) {
32 return s.startswith("c:") ? s.substr(2) : "";
33 }
34
getDeclCursorUSR(const Decl * D,SmallVectorImpl<char> & Buf)35 bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
36 return generateUSRForDecl(D, Buf);
37 }
38
39 extern "C" {
40
clang_getCursorUSR(CXCursor C)41 CXString 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
clang_constructUSR_ObjCIvar(const char * name,CXString classUSR)95 CXString 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
clang_constructUSR_ObjCMethod(const char * name,unsigned isInstanceMethod,CXString classUSR)103 CXString 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
clang_constructUSR_ObjCClass(const char * name)113 CXString 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
clang_constructUSR_ObjCProtocol(const char * name)120 CXString 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
clang_constructUSR_ObjCCategory(const char * class_name,const char * category_name)127 CXString 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
clang_constructUSR_ObjCProperty(const char * property,CXString classUSR)135 CXString 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