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