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 23using namespace clang; 24using namespace clang::index; 25 26//===----------------------------------------------------------------------===// 27// API hooks. 28//===----------------------------------------------------------------------===// 29 30static inline StringRef extractUSRSuffix(StringRef s) { 31 return s.startswith("c:") ? s.substr(2) : ""; 32} 33 34bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) { 35 return generateUSRForDecl(D, Buf); 36} 37 38CXString 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 92CXString 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 100CXString 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 110CXString 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 117CXString 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 124CXString 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 132CXString 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