140 lines · cpp
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-exception6//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.starts_with("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 in61 // 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 in84 // 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