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