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