Author: kastiglione Date: Fri Sep 22 09:58:57 2017 New Revision: 313997 URL: http://llvm.org/viewvc/llvm-project?rev=313997&view=rev Log: [index] Generate class & metaclass manglings for objc
Summary: ObjC classes have two associated symbols, one for the class and one for the metaclass. This change overloads `CodegenNameGenerator::getAllManglings` to produce both class and metaclass symbols. While this function is called by `clang_Cursor_getCXXManglings`, it's only called for CXXRecordDecl and CXXMethodDecl, and so libclang's behavior is unchanged. Reviewers: arphaman, abdulras, alexshap, compnerd Reviewed By: compnerd Subscribers: compnerd Differential Revision: https://reviews.llvm.org/D37671 Added: cfe/trunk/test/Index/print-objc-manglings.m Modified: cfe/trunk/include/clang-c/Index.h cfe/trunk/lib/Index/CodegenNameGenerator.cpp cfe/trunk/tools/c-index-test/c-index-test.c cfe/trunk/tools/libclang/CIndex.cpp cfe/trunk/tools/libclang/libclang.exports Modified: cfe/trunk/include/clang-c/Index.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=313997&r1=313996&r2=313997&view=diff ============================================================================== --- cfe/trunk/include/clang-c/Index.h (original) +++ cfe/trunk/include/clang-c/Index.h Fri Sep 22 09:58:57 2017 @@ -4293,6 +4293,12 @@ CINDEX_LINKAGE CXString clang_Cursor_get CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor); /** + * \brief Retrieve the CXStrings representing the mangled symbols of the ObjC + * class interface or implementation at the cursor. + */ +CINDEX_LINKAGE CXStringSet *clang_Cursor_getObjCManglings(CXCursor); + +/** * @} */ Modified: cfe/trunk/lib/Index/CodegenNameGenerator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/CodegenNameGenerator.cpp?rev=313997&r1=313996&r2=313997&view=diff ============================================================================== --- cfe/trunk/lib/Index/CodegenNameGenerator.cpp (original) +++ cfe/trunk/lib/Index/CodegenNameGenerator.cpp Fri Sep 22 09:58:57 2017 @@ -68,7 +68,38 @@ struct CodegenNameGenerator::Implementat return Name; } + enum ObjCKind { + ObjCClass, + ObjCMetaclass, + }; + + std::vector<std::string> getAllManglings(const ObjCContainerDecl *OCD) { + StringRef ClassName; + if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) + ClassName = OID->getObjCRuntimeNameAsString(); + else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD)) + ClassName = OID->getObjCRuntimeNameAsString(); + + if (ClassName.empty()) + return {}; + + auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string { + SmallString<40> Mangled; + auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext()); + llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL); + return Mangled.str(); + }; + + return { + Mangle(ObjCClass, ClassName), + Mangle(ObjCMetaclass, ClassName), + }; + } + std::vector<std::string> getAllManglings(const Decl *D) { + if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D)) + return getAllManglings(OCD); + if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D))) return {}; @@ -135,12 +166,14 @@ private: } void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) { - OS << getClassSymbolPrefix(); + OS << getClassSymbolPrefix(ObjCClass, D->getASTContext()); OS << D->getObjCRuntimeNameAsString(); } - static StringRef getClassSymbolPrefix() { - return "OBJC_CLASS_$_"; + static StringRef getClassSymbolPrefix(ObjCKind Kind, const ASTContext &Context) { + if (Context.getLangOpts().ObjCRuntime.isGNUFamily()) + return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_"; + return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_"; } std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) { Added: cfe/trunk/test/Index/print-objc-manglings.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-objc-manglings.m?rev=313997&view=auto ============================================================================== --- cfe/trunk/test/Index/print-objc-manglings.m (added) +++ cfe/trunk/test/Index/print-objc-manglings.m Fri Sep 22 09:58:57 2017 @@ -0,0 +1,18 @@ +// RUN: c-index-test -write-pch %t.macho.ast -target i686-apple-darwin %s +// RUN: c-index-test -test-print-manglings %t.macho.ast | FileCheck --check-prefix=MACHO %s + +// RUN: c-index-test -write-pch %t.itanium.ast -target i686-pc-linux-gnu %s +// RUN: c-index-test -test-print-manglings %t.itanium.ast | FileCheck --check-prefix=ITANIUM %s + +@interface C +@end + +// MACHO: ObjCInterfaceDecl=C{{.*}} [mangled=_OBJC_CLASS_$_C] [mangled=_OBJC_METACLASS_$_C] +// ITANIUM: ObjCInterfaceDecl=C{{.*}} [mangled=_OBJC_CLASS_C] [mangled=_OBJC_METACLASS_C] + +@implementation C +@end + +// MACHO: ObjCImplementationDecl=C{{.*}} (Definition) [mangled=_OBJC_CLASS_$_C] [mangled=_OBJC_METACLASS_$_C] +// ITANIUM: ObjCImplementationDecl=C{{.*}} (Definition) [mangled=_OBJC_CLASS_C] [mangled=_OBJC_METACLASS_C] + Modified: cfe/trunk/tools/c-index-test/c-index-test.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=313997&r1=313996&r2=313997&view=diff ============================================================================== --- cfe/trunk/tools/c-index-test/c-index-test.c (original) +++ cfe/trunk/tools/c-index-test/c-index-test.c Fri Sep 22 09:58:57 2017 @@ -1563,10 +1563,19 @@ static enum CXChildVisitResult PrintMang return CXChildVisit_Continue; PrintCursor(cursor, NULL); Manglings = clang_Cursor_getCXXManglings(cursor); - for (I = 0, E = Manglings->Count; I < E; ++I) - printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I])); - clang_disposeStringSet(Manglings); - printf("\n"); + if (Manglings) { + for (I = 0, E = Manglings->Count; I < E; ++I) + printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I])); + clang_disposeStringSet(Manglings); + printf("\n"); + } + Manglings = clang_Cursor_getObjCManglings(cursor); + if (Manglings) { + for (I = 0, E = Manglings->Count; I < E; ++I) + printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I])); + clang_disposeStringSet(Manglings); + printf("\n"); + } return CXChildVisit_Recurse; } Modified: cfe/trunk/tools/libclang/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=313997&r1=313996&r2=313997&view=diff ============================================================================== --- cfe/trunk/tools/libclang/CIndex.cpp (original) +++ cfe/trunk/tools/libclang/CIndex.cpp Fri Sep 22 09:58:57 2017 @@ -4639,6 +4639,20 @@ CXStringSet *clang_Cursor_getCXXMangling return cxstring::createSet(Manglings); } +CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) { + if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind)) + return nullptr; + + const Decl *D = getCursorDecl(C); + if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D))) + return nullptr; + + ASTContext &Ctx = D->getASTContext(); + index::CodegenNameGenerator CGNameGen(Ctx); + std::vector<std::string> Manglings = CGNameGen.getAllManglings(D); + return cxstring::createSet(Manglings); +} + CXString clang_getCursorDisplayName(CXCursor C) { if (!clang_isDeclaration(C.kind)) return clang_getCursorSpelling(C); Modified: cfe/trunk/tools/libclang/libclang.exports URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=313997&r1=313996&r2=313997&view=diff ============================================================================== --- cfe/trunk/tools/libclang/libclang.exports (original) +++ cfe/trunk/tools/libclang/libclang.exports Fri Sep 22 09:58:57 2017 @@ -23,6 +23,7 @@ clang_Cursor_getBriefCommentText clang_Cursor_getCommentRange clang_Cursor_getCXXManglings clang_Cursor_getMangling +clang_Cursor_getObjCManglings clang_Cursor_getParsedComment clang_Cursor_getRawCommentText clang_Cursor_getNumArguments _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits