1 //===- CIndexUSRs.cpp - Clang-C Source Indexing Library -------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the generation and use of USRs from CXEntities. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "CIndexer.h" 14 #include "CXCursor.h" 15 #include "CXString.h" 16 #include "CXTranslationUnit.h" 17 #include "clang/Frontend/ASTUnit.h" 18 #include "clang/Index/USRGeneration.h" 19 #include "clang/Lex/PreprocessingRecord.h" 20 #include "llvm/ADT/SmallString.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 using namespace clang; 24 using namespace clang::index; 25 26 //===----------------------------------------------------------------------===// 27 // API hooks. 28 //===----------------------------------------------------------------------===// 29 30 static inline StringRef extractUSRSuffix(StringRef s) { 31 return s.startswith("c:") ? s.substr(2) : ""; 32 } 33 34 bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) { 35 return generateUSRForDecl(D, Buf); 36 } 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 bool Ignore = generateUSRForMacro(cxcursor::getCursorMacroDefinition(C), 76 cxtu::getASTUnit(TU)->getSourceManager(), 77 buf->Data); 78 if (Ignore) { 79 buf->dispose(); 80 return cxstring::createEmpty(); 81 } 82 83 // Return the C-string, but don't make a copy since it is already in 84 // the string buffer. 85 buf->Data.push_back('\0'); 86 return createCXString(buf); 87 } 88 89 return cxstring::createEmpty(); 90 } 91 92 CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) { 93 SmallString<128> Buf(getUSRSpacePrefix()); 94 llvm::raw_svector_ostream OS(Buf); 95 OS << extractUSRSuffix(clang_getCString(classUSR)); 96 generateUSRForObjCIvar(name, OS); 97 return cxstring::createDup(OS.str()); 98 } 99 100 CXString clang_constructUSR_ObjCMethod(const char *name, 101 unsigned isInstanceMethod, 102 CXString classUSR) { 103 SmallString<128> Buf(getUSRSpacePrefix()); 104 llvm::raw_svector_ostream OS(Buf); 105 OS << extractUSRSuffix(clang_getCString(classUSR)); 106 generateUSRForObjCMethod(name, isInstanceMethod, OS); 107 return cxstring::createDup(OS.str()); 108 } 109 110 CXString clang_constructUSR_ObjCClass(const char *name) { 111 SmallString<128> Buf(getUSRSpacePrefix()); 112 llvm::raw_svector_ostream OS(Buf); 113 generateUSRForObjCClass(name, OS); 114 return cxstring::createDup(OS.str()); 115 } 116 117 CXString clang_constructUSR_ObjCProtocol(const char *name) { 118 SmallString<128> Buf(getUSRSpacePrefix()); 119 llvm::raw_svector_ostream OS(Buf); 120 generateUSRForObjCProtocol(name, OS); 121 return cxstring::createDup(OS.str()); 122 } 123 124 CXString clang_constructUSR_ObjCCategory(const char *class_name, 125 const char *category_name) { 126 SmallString<128> Buf(getUSRSpacePrefix()); 127 llvm::raw_svector_ostream OS(Buf); 128 generateUSRForObjCCategory(class_name, category_name, OS); 129 return cxstring::createDup(OS.str()); 130 } 131 132 CXString clang_constructUSR_ObjCProperty(const char *property, 133 CXString classUSR) { 134 SmallString<128> Buf(getUSRSpacePrefix()); 135 llvm::raw_svector_ostream OS(Buf); 136 OS << extractUSRSuffix(clang_getCString(classUSR)); 137 generateUSRForObjCProperty(property, /*isClassProp=*/false, OS); 138 return cxstring::createDup(OS.str()); 139 } 140