]> granicus.if.org Git - clang/commitdiff
Objective-c++ IRGen. Support for @selector expression as
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 17 Jun 2010 19:56:20 +0000 (19:56 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 17 Jun 2010 19:56:20 +0000 (19:56 +0000)
an lvalue. Fixes PR7390.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106235 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Expr.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGObjCRuntime.h
lib/CodeGen/CodeGenFunction.h
test/CodeGenObjCXX/selactor-expr-lvalue.mm [new file with mode: 0644]

index e36ae41ce46ec872defee3135a021a84c734c148..1d715b004d705ea4f43f5a16acffa5fc2f3c6d3f 100644 (file)
@@ -1194,6 +1194,7 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
   case ObjCIsaExprClass:
   case StringLiteralClass:  // C99 6.5.1p4
   case ObjCEncodeExprClass: // @encode behaves like its string in every way.
+  case ObjCSelectorExprClass: // @selector
     return LV_Valid;
   case ArraySubscriptExprClass: // C99 6.5.3p4 (e1[e2] == (*((e1)+(e2))))
     // For vectors, make sure base is an lvalue (i.e. not a function call).
index 4b66ec277e02f23af0562db5833fc3fa82b3f30d..aab54099fde9131d5492f1a6601d5fbf14b0f76b 100644 (file)
@@ -568,6 +568,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
   switch (E->getStmtClass()) {
   default: return EmitUnsupportedLValue(E, "l-value expression");
 
+  case Expr::ObjCSelectorExprClass:
+  return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));
   case Expr::ObjCIsaExprClass:
     return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));
   case Expr::BinaryOperatorClass:
@@ -1977,6 +1979,12 @@ LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
   return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
 }
 
+LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) {
+  llvm::Value *V = 
+    CGM.getObjCRuntime().GetSelector(Builder, E->getSelector(), true);
+  return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
+}
+
 llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
                                              const ObjCIvarDecl *Ivar) {
   return CGM.getObjCRuntime().EmitIvarOffset(*this, Interface, Ivar);
index 81b038bdf1fc1adaa3236057404e5aee03c7adbc..0835e52b527221560aa3c316c5611629d6325aaf 100644 (file)
@@ -162,7 +162,8 @@ public:
                            const ObjCMethodDecl *Method);
   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
                                 const ObjCInterfaceDecl *OID);
-  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
+                                   bool lval = false);
   virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
       *Method);
 
@@ -360,14 +361,16 @@ llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder,
   return Builder.CreateCall(ClassLookupFn, ClassName);
 }
 
-llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
+llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel,
+                                    bool lval) {
   llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()];
   if (US == 0)
     US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
                                llvm::GlobalValue::PrivateLinkage,
                                ".objc_untyped_selector_alias"+Sel.getAsString(),
                                NULL, &TheModule);
-
+  if (lval)
+    return US;
   return Builder.CreateLoad(US);
 }
 
index 24c7511a513311cc2c345a98e4ede8514debbaaf..8374aa8c555369c70bb578faffe5aaa9b0298437 100644 (file)
@@ -1129,7 +1129,8 @@ private:
 
   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
   /// for the given selector.
-  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
+  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 
+                            bool lval=false);
 
 public:
   CGObjCMac(CodeGen::CodeGenModule &cgm);
@@ -1160,7 +1161,8 @@ public:
   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
                                 const ObjCInterfaceDecl *ID);
 
-  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 
+                                   bool lval = false);
 
   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
   /// untyped one.
@@ -1328,7 +1330,8 @@ private:
 
   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
   /// for the given selector.
-  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
+  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 
+                            bool lval=false);
 
   /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
   /// interface. The return value has type EHTypePtrTy.
@@ -1391,8 +1394,9 @@ public:
   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
                                 const ObjCInterfaceDecl *ID);
 
-  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel)
-    { return EmitSelector(Builder, Sel); }
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
+                                   bool lvalue = false)
+    { return EmitSelector(Builder, Sel, lvalue); }
 
   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
   /// untyped one.
@@ -1492,8 +1496,9 @@ llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
 }
 
 /// GetSelector - Return the pointer to the unique'd string for this selector.
-llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) {
-  return EmitSelector(Builder, Sel);
+llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel, 
+                                    bool lval) {
+  return EmitSelector(Builder, Sel, lval);
 }
 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
                                     *Method) {
@@ -3107,7 +3112,8 @@ llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
   return Builder.CreateLoad(Entry, "tmp");
 }
 
-llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) {
+llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
+                                     bool lvalue) {
   llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
 
   if (!Entry) {
@@ -3120,6 +3126,8 @@ llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) {
                         4, true);
   }
 
+  if (lvalue)
+    return Entry;
   return Builder.CreateLoad(Entry, "tmp");
 }
 
@@ -5408,7 +5416,7 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
 }
 
 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
-                                                  Selector Sel) {
+                                                  Selector Sel, bool lval) {
   llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
 
   if (!Entry) {
@@ -5423,6 +5431,8 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
     CGM.AddUsedGlobal(Entry);
   }
 
+  if (lval)
+    return Entry;
   return Builder.CreateLoad(Entry, "tmp");
 }
 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
index 1f6d63b8abbc185e19ce5b5f83fcc2307d47c0aa..28c77c61b574cb5b1eaa2c8b5e275af79e26c601 100644 (file)
@@ -97,7 +97,7 @@ public:
   /// return value should have the LLVM type for pointer-to
   /// ASTContext::getObjCSelType().
   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
-                                   Selector Sel) = 0;
+                                   Selector Sel, bool lval=false) = 0;
 
   /// Get a typed selector.
   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
index f8ca34c614a737662758f7ea5d9ba4da9b22e3c9..f2a35ac5c7f4c0aebbc15b12bf99dd228e360e5f 100644 (file)
@@ -1087,6 +1087,7 @@ public:
   LValue EmitObjCSuperExprLValue(const ObjCSuperExpr *E);
   LValue EmitStmtExprLValue(const StmtExpr *E);
   LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E);
+  LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E);
   
   //===--------------------------------------------------------------------===//
   //                         Scalar Expression Emission
diff --git a/test/CodeGenObjCXX/selactor-expr-lvalue.mm b/test/CodeGenObjCXX/selactor-expr-lvalue.mm
new file mode 100644 (file)
index 0000000..69b82e9
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -emit-llvm -o - %s 
+// PR7390
+
+@interface NSObject {}
+- (void)respondsToSelector:(SEL&)s : (SEL*)s1;
+- (void) setPriority:(int)p;
+- (void)Meth;
+@end
+
+@implementation  NSObject
+- (void)Meth {
+    [self respondsToSelector:@selector(setPriority:) : &@selector(setPriority:)];
+}
+- (void) setPriority:(int)p{}
+- (void)respondsToSelector:(SEL&)s : (SEL*)s1 {}
+@end