зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
a021e7c4ce
Коммит
df9ccc6381
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче