Patch to support Gnu runtime's typed selectors.

Patch by David Chisnall.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71023 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2009-05-05 21:36:57 +00:00
Родитель a021e7c4ce
Коммит df9ccc6381
4 изменённых файлов: 72 добавлений и 15 удалений

Просмотреть файл

@ -95,7 +95,8 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
Args); Args);
} }
return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(), return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
Receiver, isClassMessage, Args); Receiver, isClassMessage, Args,
E->getMethodDecl());
} }
/// StartObjCMethod - Begin emission of an ObjCMethod. This generates /// StartObjCMethod - Begin emission of an ObjCMethod. This generates

Просмотреть файл

@ -106,7 +106,8 @@ public:
Selector Sel, Selector Sel,
llvm::Value *Receiver, llvm::Value *Receiver,
bool IsClassMessage, bool IsClassMessage,
const CallArgList &CallArgs); const CallArgList &CallArgs,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
QualType ResultType, QualType ResultType,
@ -119,6 +120,8 @@ public:
virtual llvm::Value *GetClass(CGBuilderTy &Builder, virtual llvm::Value *GetClass(CGBuilderTy &Builder,
const ObjCInterfaceDecl *OID); const ObjCInterfaceDecl *OID);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
*Method);
virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
const ObjCContainerDecl *CD); const ObjCContainerDecl *CD);
@ -160,7 +163,7 @@ public:
static std::string SymbolNameForClass(const std::string &ClassName) { static std::string SymbolNameForClass(const std::string &ClassName) {
return ".objc_class_" + ClassName; return "___objc_class_name_" + ClassName;
} }
static std::string SymbolNameForMethod(const std::string &ClassName, const static std::string SymbolNameForMethod(const std::string &ClassName, const
@ -218,9 +221,7 @@ llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder,
return Builder.CreateCall(ClassLookupFn, ClassName); return Builder.CreateCall(ClassLookupFn, ClassName);
} }
/// GetSelector - Return the pointer to the unique'd string for this selector.
llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) { llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
// FIXME: uniquing on the string is wasteful, unique on Sel instead!
llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()]; llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()];
if (US == 0) if (US == 0)
US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy), US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
@ -229,7 +230,32 @@ llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
NULL, &TheModule); NULL, &TheModule);
return Builder.CreateLoad(US); return Builder.CreateLoad(US);
}
llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
*Method) {
std::string SelName = Method->getSelector().getAsString();
std::string SelTypes;
CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
// Typed selectors
TypedSelector Selector = TypedSelector(SelName,
SelTypes);
// If it's already cached, return it.
if (TypedSelectors[Selector])
{
return Builder.CreateLoad(TypedSelectors[Selector]);
}
// If it isn't, cache it.
llvm::GlobalAlias *Sel = new llvm::GlobalAlias(
llvm::PointerType::getUnqual(SelectorTy),
llvm::GlobalValue::InternalLinkage, SelName,
NULL, &TheModule);
TypedSelectors[Selector] = Sel;
return Builder.CreateLoad(Sel);
} }
llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str, llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
@ -360,8 +386,13 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Selector Sel, Selector Sel,
llvm::Value *Receiver, llvm::Value *Receiver,
bool IsClassMessage, bool IsClassMessage,
const CallArgList &CallArgs) { const CallArgList &CallArgs,
llvm::Value *cmd = GetSelector(CGF.Builder, Sel); const ObjCMethodDecl *Method) {
llvm::Value *cmd;
if (Method)
cmd = GetSelector(CGF.Builder, Method);
else
cmd = GetSelector(CGF.Builder, Sel);
CallArgList ActualArgs; CallArgList ActualArgs;
ActualArgs.push_back( ActualArgs.push_back(

Просмотреть файл

@ -1016,7 +1016,8 @@ private:
Selector Sel, Selector Sel,
llvm::Value *Receiver, llvm::Value *Receiver,
bool IsClassMessage, bool IsClassMessage,
const CallArgList &CallArgs); const CallArgList &CallArgs,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
@ -1033,6 +1034,11 @@ private:
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
/// The NeXT/Apple runtimes do not support typed selectors; just emit an
/// untyped one.
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
const ObjCMethodDecl *Method);
virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
@ -1200,7 +1206,8 @@ public:
Selector Sel, Selector Sel,
llvm::Value *Receiver, llvm::Value *Receiver,
bool IsClassMessage, bool IsClassMessage,
const CallArgList &CallArgs); const CallArgList &CallArgs,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
@ -1218,6 +1225,12 @@ public:
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel) virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel)
{ return EmitSelector(Builder, Sel); } { return EmitSelector(Builder, Sel); }
/// The NeXT/Apple runtimes do not support typed selectors; just emit an
/// untyped one.
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
const ObjCMethodDecl *Method)
{ return EmitSelector(Builder, Method->getSelector()); }
virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
@ -1303,6 +1316,10 @@ llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) { llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) {
return EmitSelector(Builder, Sel); return EmitSelector(Builder, Sel);
} }
llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
*Method) {
return EmitSelector(Builder, Method->getSelector());
}
/// Generate a constant CFString object. /// Generate a constant CFString object.
/* /*
@ -1382,7 +1399,8 @@ CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Selector Sel, Selector Sel,
llvm::Value *Receiver, llvm::Value *Receiver,
bool IsClassMessage, bool IsClassMessage,
const CallArgList &CallArgs) { const CallArgList &CallArgs,
const ObjCMethodDecl *Method) {
return EmitMessageSend(CGF, ResultType, Sel, return EmitMessageSend(CGF, ResultType, Sel,
Receiver, CGF.getContext().getObjCIdType(), Receiver, CGF.getContext().getObjCIdType(),
false, CallArgs); false, CallArgs);
@ -4983,7 +5001,8 @@ CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
Selector Sel, Selector Sel,
llvm::Value *Receiver, llvm::Value *Receiver,
bool IsClassMessage, bool IsClassMessage,
const CallArgList &CallArgs) { const CallArgList &CallArgs,
const ObjCMethodDecl *Method) {
return EmitMessageSend(CGF, ResultType, Sel, return EmitMessageSend(CGF, ResultType, Sel,
Receiver, CGF.getContext().getObjCIdType(), Receiver, CGF.getContext().getObjCIdType(),
false, CallArgs); false, CallArgs);

Просмотреть файл

@ -17,6 +17,7 @@
#define CLANG_CODEGEN_OBCJRUNTIME_H #define CLANG_CODEGEN_OBCJRUNTIME_H
#include "clang/Basic/IdentifierTable.h" // Selector #include "clang/Basic/IdentifierTable.h" // Selector
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "clang/AST/DeclObjC.h"
#include <string> #include <string>
#include "CGBuilder.h" #include "CGBuilder.h"
@ -100,6 +101,10 @@ public:
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
Selector Sel) = 0; Selector Sel) = 0;
/// Get a typed selector.
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
const ObjCMethodDecl *Method) = 0;
/// Generate a constant string object. /// Generate a constant string object.
virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *) = 0; virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *) = 0;
@ -117,7 +122,8 @@ public:
Selector Sel, Selector Sel,
llvm::Value *Receiver, llvm::Value *Receiver,
bool IsClassMessage, bool IsClassMessage,
const CallArgList &CallArgs) = 0; const CallArgList &CallArgs,
const ObjCMethodDecl *Method=0) = 0;
/// Generate an Objective-C message send operation to the super /// Generate an Objective-C message send operation to the super
/// class initiated in a method for Class and with the given Self /// class initiated in a method for Class and with the given Self