Home | History | Annotate | Line # | Download | only in libclang
      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