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