From cb674f94927727f7d250c984b91597125edbd156 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 12 Jan 2010 23:33:42 +0000 Subject: [PATCH] Rename clang_getUSR() -> clang_getDeclUSR(). For now we take a CXDecl instead of a CXEntity. Enhance USR generation a bit with support for records. llvm-svn: 93267 --- clang/include/clang-c/Index.h | 2 +- clang/tools/CIndex/CIndexUSRs.cpp | 173 ++++++++++++++++-------------- 2 files changed, 93 insertions(+), 82 deletions(-) diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index ae797573a21d..47f10e366358 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -329,7 +329,6 @@ CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile); * in a specified translation unit. */ CINDEX_LINKAGE CXDecl clang_getDeclaration(CXEntity, CXTranslationUnit); -CINDEX_LINKAGE CXString clang_getUSR(CXEntity); /* * CXDecl Operations. */ @@ -338,6 +337,7 @@ CINDEX_LINKAGE CXEntity clang_getEntityFromDecl(CXIndex, CXDecl); CINDEX_LINKAGE CXString clang_getDeclSpelling(CXDecl); CINDEX_LINKAGE unsigned clang_getDeclLine(CXDecl); CINDEX_LINKAGE unsigned clang_getDeclColumn(CXDecl); +CINDEX_LINKAGE CXString clang_getDeclUSR(CXDecl); CINDEX_LINKAGE const char *clang_getDeclSource(CXDecl); /* deprecate */ CINDEX_LINKAGE CXFile clang_getDeclSourceFile(CXDecl); diff --git a/clang/tools/CIndex/CIndexUSRs.cpp b/clang/tools/CIndex/CIndexUSRs.cpp index 70006bcf3a02..b1170eb96200 100644 --- a/clang/tools/CIndex/CIndexUSRs.cpp +++ b/clang/tools/CIndex/CIndexUSRs.cpp @@ -62,6 +62,93 @@ static inline Program &GetProgram(CXIndex CIdx) { return ((CIndexer*) CIdx)->getProgram(); } +//===----------------------------------------------------------------------===// +// USR generation. +//===----------------------------------------------------------------------===// + +namespace { + class USRGenerator : public DeclVisitor { + llvm::raw_ostream &Out; + public: + USRGenerator(llvm::raw_ostream &out) : Out(out) {} + + void VisitNamedDecl(NamedDecl *D); + void VisitObjCContainerDecl(ObjCContainerDecl *CD); + void VisitObjCMethodDecl(ObjCMethodDecl *MD); + void VisitObjCPropertyDecl(ObjCPropertyDecl *D); + void VisitRecordDecl(RecordDecl *D); + void VisitTypedefDecl(TypedefDecl *D); + }; +} // end anonymous namespace + + +void USRGenerator::VisitNamedDecl(NamedDecl *D) { + DeclContext *DC = D->getDeclContext(); + if (NamedDecl *DCN = dyn_cast(DC)) + Visit(DCN); + + const std::string &s = D->getNameAsString(); + assert(!s.empty()); + Out << '@' << s; +} + +void USRGenerator::VisitRecordDecl(RecordDecl *D) { + DeclContext *DC = D->getDeclContext(); + if (NamedDecl *DCN = dyn_cast(DC)) + Visit(DCN); + + Out << "@struct^"; + const std::string &s = D->getNameAsString(); + if (s.empty()) + Out << "^anon"; + else + Out << s; +} + +void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { + Visit(cast(D->getDeclContext())); + Out << (D->isInstanceMethod() ? "(im)" : "(cm)"); + Out << DeclarationName(D->getSelector()).getAsString(); +} + +void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { + switch (D->getKind()) { + default: + assert(false && "Invalid ObjC container."); + case Decl::ObjCInterface: + case Decl::ObjCImplementation: + Out << "objc(cs)" << D->getName(); + break; + case Decl::ObjCCategory: { + ObjCCategoryDecl *CD = cast(D); + Out << "objc(cy)" << CD->getClassInterface()->getName() + << '_' << CD->getName(); + break; + } + case Decl::ObjCCategoryImpl: { + ObjCCategoryImplDecl *CD = cast(D); + Out << "objc(cy)" << CD->getClassInterface()->getName() + << '_' << CD->getName(); + break; + } + case Decl::ObjCProtocol: + Out << "objc(pl)" << cast(D)->getName(); + break; + } +} + +void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { + Visit(cast(D->getDeclContext())); + Out << "(py)" << D->getName(); +} + +void USRGenerator::VisitTypedefDecl(TypedefDecl *D) { + DeclContext *DC = D->getDeclContext(); + if (NamedDecl *DCN = dyn_cast(DC)) + Visit(DCN); + Out << "typedef@" << D->getName(); +} + extern "C" { /// clang_getDeclaration() maps from a CXEntity to the matching CXDecl (if any) @@ -76,91 +163,15 @@ CXEntity clang_getEntityFromDecl(CXIndex CIdx, CXDecl CE) { return MakeEntity(CIdx, Entity::get(D, GetProgram(CIdx))); return NullCXEntity(); } - -//===----------------------------------------------------------------------===// -// USR generation. -//===----------------------------------------------------------------------===// - -namespace { -class USRGenerator : public DeclVisitor { - llvm::raw_ostream &Out; -public: - USRGenerator(llvm::raw_ostream &out) : Out(out) {} - - void VisitNamedDecl(NamedDecl *D); - void VisitObjCContainerDecl(ObjCContainerDecl *CD); - void VisitObjCMethodDecl(ObjCMethodDecl *MD); - void VisitObjCPropertyDecl(ObjCPropertyDecl *D); -}; -} // end anonymous namespace - - -void USRGenerator::VisitNamedDecl(NamedDecl *D) { - DeclContext *DC = D->getDeclContext(); - if (NamedDecl *DCN = dyn_cast(DC)) { - Visit(DCN); - Out << '_'; - } - else { - Out << '_'; - } - Out << D->getName(); -} - -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(cs)" << D->getName(); - break; - case Decl::ObjCCategory: { - ObjCCategoryDecl *CD = cast(D); - Out << "objc(cy)" << CD->getClassInterface()->getName() - << '_' << CD->getName(); - break; - } - case Decl::ObjCCategoryImpl: { - ObjCCategoryImplDecl *CD = cast(D); - Out << "objc(cy)" << CD->getClassInterface()->getName() - << '_' << CD->getName(); - break; - } - case Decl::ObjCProtocol: - Out << "objc(pl)" << cast(D)->getName(); - break; - } -} - -void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { - Visit(cast(D->getDeclContext())); - Out << "(py)" << 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); - +CXString clang_getDeclUSR(CXDecl D) { + assert(D && "Null CXDecl passed to clang_getDeclUSR()"); llvm::SmallString<1024> StrBuf; { llvm::raw_svector_ostream Out(StrBuf); USRGenerator UG(Out); - UG.Visit(D); + UG.Visit(static_cast(D)); } if (StrBuf.empty()) @@ -168,6 +179,6 @@ CXString clang_getUSR(CXEntity CE) { // Return a copy of the string that must be disposed by the caller. return CIndexer::createCXString(StrBuf.c_str(), true); -} +} } // end extern "C"