aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjCGNU.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGObjCGNU.cpp')
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp50
1 files changed, 33 insertions, 17 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 2b8f7edc05..9cbb0ed49c 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -109,18 +109,20 @@ public:
llvm::Value** ArgV,
unsigned ArgC);
virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Sender,
- const char *SuperClassName,
- llvm::Value *Receiver,
- llvm::Value *Selector,
- llvm::Value** ArgV,
- unsigned ArgC);
+ const llvm::Type *ReturnTy,
+ llvm::Value *Sender,
+ const char *SuperClassName,
+ llvm::Value *Receiver,
+ Selector Sel,
+ llvm::Value** ArgV,
+ unsigned ArgC);
virtual llvm::Value *LookupClass(llvm::IRBuilder &Builder, llvm::Value
*ClassName);
virtual llvm::Value *GetSelector(llvm::IRBuilder &Builder,
- llvm::Value *SelName,
- llvm::Value *SelTypes);
+ llvm::Value *SelName,
+ llvm::Value *SelTypes);
+ llvm::Value *GetSelector(llvm::IRBuilder &Builder, Selector Sel);
+
virtual llvm::Function *MethodPreamble(
const std::string &ClassName,
const std::string &CategoryName,
@@ -219,6 +221,20 @@ llvm::Value *CGObjCGNU::LookupClass(llvm::IRBuilder &Builder,
return Builder.CreateCall(ClassLookupFn, ClassName);
}
+/// GetSelector - Return the pointer to the unique'd string for this selector.
+llvm::Value *CGObjCGNU::GetSelector(llvm::IRBuilder &Builder, Selector Sel) {
+ // FIXME: uniquing on the string is wasteful, unique on Sel instead!
+ llvm::GlobalAlias *&US = UntypedSelectors[Sel.getName()];
+ if (US == 0)
+ US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
+ llvm::GlobalValue::InternalLinkage,
+ ".objc_untyped_selector_alias",
+ NULL, &TheModule);
+
+ return Builder.CreateLoad(US);
+
+}
+
/// Looks up the selector for the specified name / type pair.
// FIXME: Selectors should be statically cached, not looked up on every call.
llvm::Value *CGObjCGNU::GetSelector(llvm::IRBuilder &Builder,
@@ -319,17 +335,17 @@ llvm::Constant *CGObjCGNU::GenerateConstantString(const char *String, const
///send to self with special delivery semantics indicating which class's method
///should be called.
llvm::Value *CGObjCGNU::GenerateMessageSendSuper(llvm::IRBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Sender,
- const char *SuperClassName,
- llvm::Value *Receiver,
- llvm::Value *Selector,
- llvm::Value** ArgV,
- unsigned ArgC) {
+ const llvm::Type *ReturnTy,
+ llvm::Value *Sender,
+ const char *SuperClassName,
+ llvm::Value *Receiver,
+ Selector Sel,
+ llvm::Value** ArgV,
+ unsigned ArgC) {
// TODO: This should be cached, not looked up every time.
llvm::Value *ReceiverClass = LookupClass(Builder,
MakeConstantString(SuperClassName));
- llvm::Value *cmd = GetSelector(Builder, Selector, 0);
+ llvm::Value *cmd = GetSelector(Builder, Sel);
std::vector<const llvm::Type*> impArgTypes;
impArgTypes.push_back(Receiver->getType());
impArgTypes.push_back(SelectorTy);