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 using namespace clang::index;
24 
25 //===----------------------------------------------------------------------===//
26 // API hooks.
27 //===----------------------------------------------------------------------===//
28 
29 static inline StringRef extractUSRSuffix(StringRef s) {
30   return s.startswith("c:") ? s.substr(2) : "";
31 }
32 
33 bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
34   return generateUSRForDecl(D, Buf);
35 }
36 
37 extern "C" {
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     buf->Data += getUSRSpacePrefix();
77     buf->Data += "macro@";
78     buf->Data +=
79         cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
80     buf->Data.push_back('\0');
81     return createCXString(buf);
82   }
83 
84   return cxstring::createEmpty();
85 }
86 
87 CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
88   SmallString<128> Buf(getUSRSpacePrefix());
89   llvm::raw_svector_ostream OS(Buf);
90   OS << extractUSRSuffix(clang_getCString(classUSR));
91   generateUSRForObjCIvar(name, OS);
92   return cxstring::createDup(OS.str());
93 }
94 
95 CXString clang_constructUSR_ObjCMethod(const char *name,
96                                        unsigned isInstanceMethod,
97                                        CXString classUSR) {
98   SmallString<128> Buf(getUSRSpacePrefix());
99   llvm::raw_svector_ostream OS(Buf);
100   OS << extractUSRSuffix(clang_getCString(classUSR));
101   generateUSRForObjCMethod(name, isInstanceMethod, OS);
102   return cxstring::createDup(OS.str());
103 }
104 
105 CXString clang_constructUSR_ObjCClass(const char *name) {
106   SmallString<128> Buf(getUSRSpacePrefix());
107   llvm::raw_svector_ostream OS(Buf);
108   generateUSRForObjCClass(name, OS);
109   return cxstring::createDup(OS.str());
110 }
111 
112 CXString clang_constructUSR_ObjCProtocol(const char *name) {
113   SmallString<128> Buf(getUSRSpacePrefix());
114   llvm::raw_svector_ostream OS(Buf);
115   generateUSRForObjCProtocol(name, OS);
116   return cxstring::createDup(OS.str());
117 }
118 
119 CXString clang_constructUSR_ObjCCategory(const char *class_name,
120                                          const char *category_name) {
121   SmallString<128> Buf(getUSRSpacePrefix());
122   llvm::raw_svector_ostream OS(Buf);
123   generateUSRForObjCCategory(class_name, category_name, OS);
124   return cxstring::createDup(OS.str());
125 }
126 
127 CXString clang_constructUSR_ObjCProperty(const char *property,
128                                          CXString classUSR) {
129   SmallString<128> Buf(getUSRSpacePrefix());
130   llvm::raw_svector_ostream OS(Buf);
131   OS << extractUSRSuffix(clang_getCString(classUSR));
132   generateUSRForObjCProperty(property, OS);
133   return cxstring::createDup(OS.str());
134 }
135 
136 } // end extern "C"
137