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