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

Reply via email to