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