aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-01-12 02:07:58 +0000
committerTed Kremenek <kremenek@apple.com>2010-01-12 02:07:58 +0000
commit8776382f7ed8c6bf34cfa196357ca0d7b51a776a (patch)
tree23ab9b9e00e2a1be8a2297c340bdc914011c47a5
parent66867c526ce9ae5402bb3d0caf1458ccd8576a5e (diff)
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
-rw-r--r--tools/CIndex/CIndexUSRs.cpp82
1 files changed, 80 insertions, 2 deletions
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<USRGenerator> {
+ 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<Decl>(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<ObjCCategoryDecl>(D);
+ Out << "objc_cat_" << CD->getClassInterface()->getName()
+ << '_' << CD->getName();
+ break;
+ }
+ case Decl::ObjCCategoryImpl: {
+ ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
+ Out << "objc_cat_" << CD->getClassInterface()->getName()
+ << '_' << CD->getName();
+ break;
+ }
+ case Decl::ObjCProtocol:
+ Out << "objc_prot_" << cast<ObjCProtocolDecl>(D)->getName();
+ break;
+ }
+}
+
+void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+ Visit(cast<Decl>(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"