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