blob: 75bb3b01299f10b16f8f9290db1b2d6c13aac333 [file] [log] [blame]
Fangrui Song524b3c12019-03-01 06:49:51 +00001//===- CIndexUSRs.cpp - Clang-C Source Indexing Library -------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Guy Benyei11169dd2012-12-18 14:30:41 +00006//
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"
Dmitri Gribenko237769e2014-03-28 22:21:26 +000016#include "CXTranslationUnit.h"
Chandler Carruth575bc3ba2015-01-14 11:23:58 +000017#include "clang/Frontend/ASTUnit.h"
Argyrios Kyrtzidis15a2fcc2013-08-17 00:40:41 +000018#include "clang/Index/USRGeneration.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000019#include "clang/Lex/PreprocessingRecord.h"
20#include "llvm/ADT/SmallString.h"
21#include "llvm/Support/raw_ostream.h"
22
23using namespace clang;
Argyrios Kyrtzidis5234b492013-08-21 00:49:25 +000024using namespace clang::index;
Guy Benyei11169dd2012-12-18 14:30:41 +000025
26//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +000027// 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) {
Argyrios Kyrtzidis5234b492013-08-21 00:49:25 +000035 return generateUSRForDecl(D, Buf);
Guy Benyei11169dd2012-12-18 14:30:41 +000036}
37
Guy Benyei11169dd2012-12-18 14:30:41 +000038CXString clang_getCursorUSR(CXCursor C) {
39 const CXCursorKind &K = clang_getCursorKind(C);
40
41 if (clang_isDeclaration(K)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +000042 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +000043 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000044 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +000045
46 CXTranslationUnit TU = cxcursor::getCursorTU(C);
47 if (!TU)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000048 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +000049
Dmitri Gribenko74895212013-02-03 13:52:47 +000050 cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +000051 if (!buf)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000052 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +000053
54 bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
55 if (Ignore) {
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +000056 buf->dispose();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000057 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +000058 }
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)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000069 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +000070
Dmitri Gribenko74895212013-02-03 13:52:47 +000071 cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +000072 if (!buf)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000073 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +000074
Dmitri Gribenko237769e2014-03-28 22:21:26 +000075 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.
Guy Benyei11169dd2012-12-18 14:30:41 +000085 buf->Data.push_back('\0');
86 return createCXString(buf);
87 }
88
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000089 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +000090}
91
92CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
Argyrios Kyrtzidis7aa49d82013-08-21 01:51:19 +000093 SmallString<128> Buf(getUSRSpacePrefix());
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +000094 llvm::raw_svector_ostream OS(Buf);
95 OS << extractUSRSuffix(clang_getCString(classUSR));
Argyrios Kyrtzidis5234b492013-08-21 00:49:25 +000096 generateUSRForObjCIvar(name, OS);
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +000097 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +000098}
99
100CXString clang_constructUSR_ObjCMethod(const char *name,
101 unsigned isInstanceMethod,
102 CXString classUSR) {
Argyrios Kyrtzidis7aa49d82013-08-21 01:51:19 +0000103 SmallString<128> Buf(getUSRSpacePrefix());
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000104 llvm::raw_svector_ostream OS(Buf);
105 OS << extractUSRSuffix(clang_getCString(classUSR));
Argyrios Kyrtzidis5234b492013-08-21 00:49:25 +0000106 generateUSRForObjCMethod(name, isInstanceMethod, OS);
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000107 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +0000108}
109
110CXString clang_constructUSR_ObjCClass(const char *name) {
Argyrios Kyrtzidis7aa49d82013-08-21 01:51:19 +0000111 SmallString<128> Buf(getUSRSpacePrefix());
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000112 llvm::raw_svector_ostream OS(Buf);
Argyrios Kyrtzidis5234b492013-08-21 00:49:25 +0000113 generateUSRForObjCClass(name, OS);
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000114 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +0000115}
116
117CXString clang_constructUSR_ObjCProtocol(const char *name) {
Argyrios Kyrtzidis7aa49d82013-08-21 01:51:19 +0000118 SmallString<128> Buf(getUSRSpacePrefix());
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000119 llvm::raw_svector_ostream OS(Buf);
Argyrios Kyrtzidis5234b492013-08-21 00:49:25 +0000120 generateUSRForObjCProtocol(name, OS);
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000121 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +0000122}
123
124CXString clang_constructUSR_ObjCCategory(const char *class_name,
125 const char *category_name) {
Argyrios Kyrtzidis7aa49d82013-08-21 01:51:19 +0000126 SmallString<128> Buf(getUSRSpacePrefix());
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000127 llvm::raw_svector_ostream OS(Buf);
Argyrios Kyrtzidis5234b492013-08-21 00:49:25 +0000128 generateUSRForObjCCategory(class_name, category_name, OS);
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000129 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +0000130}
131
132CXString clang_constructUSR_ObjCProperty(const char *property,
133 CXString classUSR) {
Argyrios Kyrtzidis7aa49d82013-08-21 01:51:19 +0000134 SmallString<128> Buf(getUSRSpacePrefix());
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000135 llvm::raw_svector_ostream OS(Buf);
136 OS << extractUSRSuffix(clang_getCString(classUSR));
Argyrios Kyrtzidisd9849a92016-07-15 22:18:19 +0000137 generateUSRForObjCProperty(property, /*isClassProp=*/false, OS);
Argyrios Kyrtzidis4b2b4602013-08-16 18:17:55 +0000138 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +0000139}