From: Ted Kremenek Date: Tue, 12 Jan 2010 02:07:58 +0000 (+0000) Subject: Add a boilerplate implementation for clang_getUSR(). WIP. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8776382f7ed8c6bf34cfa196357ca0d7b51a776a;p=clang Add a boilerplate implementation for clang_getUSR(). WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93223 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/CIndex/CIndexUSRs.cpp b/tools/CIndex/CIndexUSRs.cpp index e0ee3acd30..edf3406356 100644 --- a/tools/CIndex/CIndexUSRs.cpp +++ b/tools/CIndex/CIndexUSRs.cpp @@ -12,6 +12,9 @@ //===----------------------------------------------------------------------===// #include "CIndexer.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/raw_ostream.h"; +#include "clang/AST/DeclVisitor.h"; extern "C" { @@ -74,8 +77,83 @@ CXEntity clang_getEntityFromDecl(CXIndex CIdx, CXDecl CE) { return NullCXEntity(); } -CXString clang_getUSR(CXEntity) { - return CIndexer::createCXString(""); +//===----------------------------------------------------------------------===// +// USR generation. +//===----------------------------------------------------------------------===// + +namespace { +class USRGenerator : public DeclVisitor { + llvm::raw_ostream &Out; +public: + USRGenerator(llvm::raw_ostream &out) : Out(out) {} + + void VisitObjCContainerDecl(ObjCContainerDecl *CD); + void VisitObjCMethodDecl(ObjCMethodDecl *MD); + void VisitObjCPropertyDecl(ObjCPropertyDecl *D); +}; +} // end anonymous namespace + +void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { + Visit(cast(D->getDeclContext())); + Out << (D->isInstanceMethod() ? "_IM_" : "_CM_"); + Out << DeclarationName(D->getSelector()); +} + +void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { + switch (D->getKind()) { + default: + assert(false && "Invalid ObjC container."); + case Decl::ObjCInterface: + case Decl::ObjCImplementation: + Out << "objc_class_" << D->getName(); + break; + case Decl::ObjCCategory: { + ObjCCategoryDecl *CD = cast(D); + Out << "objc_cat_" << CD->getClassInterface()->getName() + << '_' << CD->getName(); + break; + } + case Decl::ObjCCategoryImpl: { + ObjCCategoryImplDecl *CD = cast(D); + Out << "objc_cat_" << CD->getClassInterface()->getName() + << '_' << CD->getName(); + break; + } + case Decl::ObjCProtocol: + Out << "objc_prot_" << cast(D)->getName(); + break; + } +} + +void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { + Visit(cast(D->getDeclContext())); + Out << "_prop_" << D->getName(); +} + +// FIXME: This is a skeleton implementation. It will be overhauled. +CXString clang_getUSR(CXEntity CE) { + const Entity &E = GetEntity(CE); + + // FIXME: Support cross-translation unit CXEntities. + if (!E.isInternalToTU()) + return CIndexer::createCXString(NULL); + + Decl *D = E.getInternalDecl(); + if (!D) + return CIndexer::createCXString(NULL); + + llvm::SmallString<1024> StrBuf; + { + llvm::raw_svector_ostream Out(StrBuf); + USRGenerator UG(Out); + UG.Visit(D); + } + + if (StrBuf.empty()) + return CIndexer::createCXString(NULL); + + // Return a copy of the string that must be disposed by the caller. + return CIndexer::createCXString(StrBuf.c_str(), true); } } // end extern "C"