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