]> granicus.if.org Git - clang/commitdiff
Mangle static variables inside Objective-C methods in Objective-C++. We currently...
authorAnders Carlsson <andersca@mac.com>
Thu, 10 Dec 2009 03:14:39 +0000 (03:14 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 10 Dec 2009 03:14:39 +0000 (03:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91042 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/Mangle.cpp
test/CodeGenObjCXX/mangle.mm [new file with mode: 0644]

index 2d86709f8fe8e7f7e3ab51ceffa2165356091c3d..d156ba549ee0be06a896d5a17c014d4bcab72bfc 100644 (file)
@@ -106,6 +106,8 @@ private:
   void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
   void mangleQualifiers(Qualifiers Quals);
 
+  void mangleObjCMethodName(const ObjCMethodDecl *MD);
+  
   // Declare manglers for every type class.
 #define ABSTRACT_TYPE(CLASS, PARENT)
 #define NON_CANONICAL_TYPE(CLASS, PARENT)
@@ -325,7 +327,7 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
     return;
   }
 
-  if (isa<FunctionDecl>(DC)) {
+  if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) {
     mangleLocalName(ND);
     return;
   }
@@ -539,7 +541,12 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
   //              := Z <function encoding> E s [<discriminator>]
   // <discriminator> := _ <non-negative number>
   Out << 'Z';
-  mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext()));
+  
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ND->getDeclContext()))
+    mangleObjCMethodName(MD);
+  else  
+    mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext()));
+
   Out << 'E';
   mangleSourceName(ND->getIdentifier());
 }
@@ -550,7 +557,6 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC) {
   //           ::= <template-param>
   //           ::= # empty
   //           ::= <substitution>
-  // FIXME: We only handle mangling of namespaces and classes at the moment.
 
   while (isa<LinkageSpecDecl>(DC))
     DC = DC->getParent();
@@ -703,6 +709,21 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
   // FIXME: For now, just drop all extension qualifiers on the floor.
 }
 
+void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
+  llvm::SmallString<64> Name;
+  llvm::raw_svector_ostream OS(Name);
+  
+  const ObjCContainerDecl *CD = 
+    dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
+  assert (CD && "Missing container decl in GetNameForMethod");
+  OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
+  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
+    OS << '(' << CID->getNameAsString() << ')';
+  OS << ' ' << MD->getSelector().getAsString() << ']';
+  
+  Out << OS.str().size() << OS.str();
+}
+
 void CXXNameMangler::mangleType(QualType T) {
   // Only operate on the canonical type!
   T = Context.getASTContext().getCanonicalType(T);
diff --git a/test/CodeGenObjCXX/mangle.mm b/test/CodeGenObjCXX/mangle.mm
new file mode 100644 (file)
index 0000000..00df14b
--- /dev/null
@@ -0,0 +1,32 @@
+// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @"_ZZ11+[A shared]E1a" = internal global
+// CHECK: @"_ZZ11-[A(Foo) f]E1a" = internal global
+
+@interface A
+@end
+
+@implementation A
+
++ (A *)shared {
+  static A* a;
+  
+  return a;
+}
+
+@end
+
+@interface A(Foo)
+@end
+
+@implementation A(Foo)
+- (int)f {
+  // FIXME: Add a member function to s and make sure that it's mangled correctly.
+  struct s {
+  };
+  
+  static s a;
+
+  return 0;
+}
+@end