diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 61 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCRuntime.h | 6 |
5 files changed, 63 insertions, 26 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 81209da6c6..ca775bf050 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -701,6 +701,14 @@ public: CGM.GetStringForStringLiteral(E), false); } + llvm::Constant *VisitObjCSelectorExpr(const ObjCSelectorExpr *E) { + ObjCMethodDecl *OMD = E->getMethodDecl(); + if (OMD) + return CGM.getObjCRuntime().GetConstantTypedSelector(OMD); + else + return CGM.getObjCRuntime().GetConstantSelector(E->getSelector()); + } + llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E) { // This must be an @encode initializing an array in a static initializer. // Don't emit it as the address of the string, emit the string data itself diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 896d2207ea..e4421670ff 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -38,7 +38,11 @@ llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) { // Note that this implementation allows for non-constant strings to be passed // as arguments to @selector(). Currently, the only thing preventing this // behaviour is the type checking in the front end. - return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector()); + ObjCMethodDecl *OMD = E->getMethodDecl(); + if (OMD) + return CGM.getObjCRuntime().GetSelector(Builder, OMD); + else + return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector()); } llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 3a0ac994d8..d69477852a 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -146,9 +146,17 @@ 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, const ObjCMethodDecl - *Method); + virtual llvm::Constant *GetConstantSelector(Selector Sel); + virtual llvm::Constant *GetConstantTypedSelector( + const ObjCMethodDecl *Method); + llvm::Value *GetSelector(CGBuilderTy &Builder, + Selector Sel) { + return cast<llvm::Constant>((GetConstantSelector(Sel))); + } + llvm::Value *GetSelector(CGBuilderTy &Builder, + const ObjCMethodDecl *Method) { + return cast<llvm::Constant>(GetConstantTypedSelector(Method)); + } virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD); @@ -287,18 +295,18 @@ llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder, return Builder.CreateCall(ClassLookupFn, ClassName); } -llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) { +llvm::Constant *CGObjCGNU::GetConstantSelector(Selector Sel) { llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()]; if (US == 0) - US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy), + US = new llvm::GlobalAlias(SelectorTy, llvm::GlobalValue::PrivateLinkage, ".objc_untyped_selector_alias"+Sel.getAsString(), NULL, &TheModule); - return Builder.CreateLoad(US); + return US; } -llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl +llvm::Constant *CGObjCGNU::GetConstantTypedSelector(const ObjCMethodDecl *Method) { std::string SelName = Method->getSelector().getAsString(); @@ -310,17 +318,17 @@ llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl // If it's already cached, return it. if (TypedSelectors[Selector]) { - return Builder.CreateLoad(TypedSelectors[Selector]); + return TypedSelectors[Selector]; } // If it isn't, cache it. llvm::GlobalAlias *Sel = new llvm::GlobalAlias( - llvm::PointerType::getUnqual(SelectorTy), + SelectorTy, llvm::GlobalValue::PrivateLinkage, ".objc_selector_alias" + SelName, NULL, &TheModule); TypedSelectors[Selector] = Sel; - return Builder.CreateLoad(Sel); + return Sel; } llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str, @@ -1461,40 +1469,43 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() { // Now that all of the static selectors exist, create pointers to them. int index = 0; + llvm::SmallVector<std::pair<llvm::GlobalAlias*,llvm::Value*>, 16> selectors; for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end(); iter != iterEnd; ++iter) { llvm::Constant *Idxs[] = {Zeros[0], llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]}; - llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy, - true, llvm::GlobalValue::InternalLinkage, - llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), - ".objc_sel_ptr"); + llvm::Constant *SelPtr = + llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2); // If selectors are defined as an opaque type, cast the pointer to this // type. if (isSelOpaque) { - SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, - llvm::PointerType::getUnqual(SelectorTy)); + SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,SelectorTy); } - (*iter).second->setAliasee(SelPtr); + selectors.push_back( + std::pair<llvm::GlobalAlias*,llvm::Value*>((*iter).second, SelPtr)); } for (llvm::StringMap<llvm::GlobalAlias*>::iterator iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end(); iter != iterEnd; iter++) { llvm::Constant *Idxs[] = {Zeros[0], llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]}; - llvm::Constant *SelPtr = new llvm::GlobalVariable - (TheModule, SelStructPtrTy, - true, llvm::GlobalValue::InternalLinkage, - llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), - ".objc_sel_ptr"); + llvm::Constant *SelPtr = + llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2); // If selectors are defined as an opaque type, cast the pointer to this // type. if (isSelOpaque) { - SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, - llvm::PointerType::getUnqual(SelectorTy)); + SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, SelectorTy); } - (*iter).second->setAliasee(SelPtr); + selectors.push_back( + std::pair<llvm::GlobalAlias*,llvm::Value*>((*iter).second, SelPtr)); + } + for (llvm::SmallVectorImpl<std::pair< + llvm::GlobalAlias*,llvm::Value*> >::iterator + iter=selectors.begin(), iterEnd =selectors.end(); + iter != iterEnd; ++iter) { + iter->first->replaceAllUsesWith(iter->second); + iter->first->eraseFromParent(); } // Number of classes defined. Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext), diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 0dcbe829e2..361afbc58e 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -953,6 +953,14 @@ public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm), VMContext(cgm.getLLVMContext()) { } + virtual llvm::Constant *GetConstantSelector(Selector Sel) { + assert(0 && "Constant Selectors are not yet supported on the Mac runtimes"); + return 0; + } + virtual llvm::Constant *GetConstantTypedSelector( + const ObjCMethodDecl *Method) { + return GetConstantSelector(Method->getSelector()); + } virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL); virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index ff5d40bfbc..2c27c14031 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -95,6 +95,12 @@ public: /// this compilation unit with the runtime library. virtual llvm::Function *ModuleInitFunction() = 0; + virtual llvm::Constant *GetConstantSelector(Selector Sel) = 0; + + /// Get a typed selector. + virtual llvm::Constant *GetConstantTypedSelector( + const ObjCMethodDecl *Method) = 0; + /// Get a selector for the specified name and type values. The /// return value should have the LLVM type for pointer-to /// ASTContext::getObjCSelType(). |