forked from OSchip/llvm-project
refactor more objc codegen interfaces to pass around selectors so
we don't push strings into LLVM IR and then have to read them back out. llvm-svn: 52765
This commit is contained in:
parent
882034dd99
commit
bf231a61fd
|
@ -24,16 +24,6 @@
|
|||
#include "llvm/ADT/StringMap.h"
|
||||
#include <map>
|
||||
using namespace clang;
|
||||
|
||||
// FIXME: Remove THIS!
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
std::string getStringValue(llvm::Constant *C) {
|
||||
std::string R;
|
||||
bool V = GetConstantStringInfo(C, R);
|
||||
assert(V && "Couldn't convert string");
|
||||
return R;
|
||||
}
|
||||
|
||||
using llvm::dyn_cast;
|
||||
|
||||
// The version of the runtime that this class targets. Must match the version
|
||||
|
@ -73,7 +63,7 @@ private:
|
|||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets);
|
||||
llvm::Constant *GenerateMethodList(const std::string &ClassName,
|
||||
const std::string &CategoryName,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &MethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
|
||||
bool isClassMethodList);
|
||||
llvm::Constant *GenerateProtocolList(
|
||||
|
@ -131,9 +121,9 @@ public:
|
|||
bool isClassMethod,
|
||||
bool isVarArg);
|
||||
virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
|
||||
const llvm::SmallVectorImpl<std::string> &Protocols);
|
||||
virtual void GenerateClass(
|
||||
|
@ -143,9 +133,9 @@ public:
|
|||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
|
||||
const llvm::SmallVectorImpl<std::string> &Protocols);
|
||||
virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder &Builder, const char
|
||||
|
@ -376,8 +366,8 @@ llvm::Value *CGObjCGNU::GenerateMessageSend(llvm::IRBuilder &Builder,
|
|||
/// Generates a MethodList. Used in construction of a objc_class and
|
||||
/// objc_category structures.
|
||||
llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
|
||||
const std::string &CategoryName,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames,
|
||||
const std::string &CategoryName,
|
||||
const llvm::SmallVectorImpl<Selector> &MethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
|
||||
bool isClassMethodList) {
|
||||
// Get the method structure type.
|
||||
|
@ -390,13 +380,13 @@ llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
|
|||
std::vector<llvm::Constant*> Elements;
|
||||
for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
|
||||
Elements.clear();
|
||||
Elements.push_back(llvm::ConstantExpr::getGetElementPtr(MethodNames[i],
|
||||
Zeros, 2));
|
||||
llvm::Constant *C = CGM.GetAddrOfConstantString(MethodSels[i].getName());
|
||||
Elements.push_back(llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2));
|
||||
Elements.push_back(
|
||||
llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2));
|
||||
llvm::Constant *Method =
|
||||
TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
|
||||
getStringValue(MethodNames[i]),
|
||||
MethodSels[i].getName(),
|
||||
isClassMethodList));
|
||||
Method = llvm::ConstantExpr::getBitCast(Method,
|
||||
llvm::PointerType::getUnqual(IMPTy));
|
||||
|
@ -406,7 +396,7 @@ llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
|
|||
|
||||
// Array of method structures
|
||||
llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
|
||||
MethodNames.size());
|
||||
MethodSels.size());
|
||||
llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
|
||||
Methods);
|
||||
|
||||
|
@ -625,9 +615,9 @@ void CGObjCGNU::GenerateProtocol(const char *ProtocolName,
|
|||
void CGObjCGNU::GenerateCategory(
|
||||
const char *ClassName,
|
||||
const char *CategoryName,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
|
||||
const llvm::SmallVectorImpl<std::string> &Protocols) {
|
||||
std::vector<llvm::Constant*> Elements;
|
||||
|
@ -635,11 +625,11 @@ void CGObjCGNU::GenerateCategory(
|
|||
Elements.push_back(MakeConstantString(ClassName));
|
||||
// Instance method list
|
||||
Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
|
||||
ClassName, CategoryName, InstanceMethodNames, InstanceMethodTypes,
|
||||
ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
|
||||
false), PtrTy));
|
||||
// Class method list
|
||||
Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
|
||||
ClassName, CategoryName, ClassMethodNames, ClassMethodTypes, true),
|
||||
ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true),
|
||||
PtrTy));
|
||||
// Protocol list
|
||||
Elements.push_back(llvm::ConstantExpr::getBitCast(
|
||||
|
@ -655,9 +645,9 @@ void CGObjCGNU::GenerateClass(
|
|||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
|
||||
const llvm::SmallVectorImpl<std::string> &Protocols) {
|
||||
// Get the superclass pointer.
|
||||
|
@ -672,9 +662,9 @@ void CGObjCGNU::GenerateClass(
|
|||
llvm::SmallVector<llvm::Constant*, 1> empty;
|
||||
// Generate the method and instance variable lists
|
||||
llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
|
||||
InstanceMethodNames, InstanceMethodTypes, false);
|
||||
InstanceMethodSels, InstanceMethodTypes, false);
|
||||
llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
|
||||
ClassMethodNames, ClassMethodTypes, true);
|
||||
ClassMethodSels, ClassMethodTypes, true);
|
||||
llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
|
||||
IvarOffsets);
|
||||
//Generate metaclass for class methods
|
||||
|
|
|
@ -60,9 +60,9 @@ public:
|
|||
/// Generate a category. A category contains a list of methods (and
|
||||
/// accompanying metadata) and a list of protocols.
|
||||
virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
|
||||
const llvm::SmallVectorImpl<std::string> &Protocols) =0;
|
||||
/// Generate a class stucture for this class.
|
||||
|
@ -73,9 +73,9 @@ public:
|
|||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
|
||||
const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
|
||||
const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
|
||||
const llvm::SmallVectorImpl<std::string> &Protocols) =0;
|
||||
/// Generate a reference to the named protocol.
|
||||
|
|
|
@ -229,9 +229,11 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
|
|||
unsigned ParamAttrs = 0;
|
||||
if (ParamType->isRecordType())
|
||||
ParamAttrs |= llvm::ParamAttr::ByVal;
|
||||
if (ParamType->isSignedIntegerType() && ParamType->isPromotableIntegerType())
|
||||
if (ParamType->isSignedIntegerType() &&
|
||||
ParamType->isPromotableIntegerType())
|
||||
ParamAttrs |= llvm::ParamAttr::SExt;
|
||||
if (ParamType->isUnsignedIntegerType() && ParamType->isPromotableIntegerType())
|
||||
if (ParamType->isUnsignedIntegerType() &&
|
||||
ParamType->isPromotableIntegerType())
|
||||
ParamAttrs |= llvm::ParamAttr::ZExt;
|
||||
if (ParamAttrs)
|
||||
ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(i + increment,
|
||||
|
@ -273,7 +275,7 @@ llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D,
|
|||
const std::string& aliaseeName = D->getAttr<AliasAttr>()->getAliasee();
|
||||
llvm::Function *aliasee = getModule().getFunction(aliaseeName);
|
||||
llvm::GlobalValue *alias = new llvm::GlobalAlias(aliasee->getType(),
|
||||
llvm::Function::ExternalLinkage,
|
||||
llvm::Function::ExternalLinkage,
|
||||
D->getName(),
|
||||
aliasee,
|
||||
&getModule());
|
||||
|
@ -390,26 +392,24 @@ void CodeGenModule::EmitObjCProtocolImplementation(const ObjCProtocolDecl *PD){
|
|||
void CodeGenModule::EmitObjCCategoryImpl(const ObjCCategoryImplDecl *OCD) {
|
||||
|
||||
// Collect information about instance methods
|
||||
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
|
||||
llvm::SmallVector<Selector, 16> InstanceMethodSels;
|
||||
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
|
||||
for (ObjCCategoryDecl::instmeth_iterator iter = OCD->instmeth_begin(),
|
||||
endIter = OCD->instmeth_end() ; iter != endIter ; iter++) {
|
||||
InstanceMethodSels.push_back((*iter)->getSelector());
|
||||
std::string TypeStr;
|
||||
Context.getObjCEncodingForMethodDecl(*iter,TypeStr);
|
||||
InstanceMethodNames.push_back(
|
||||
GetAddrOfConstantString((*iter)->getSelector().getName()));
|
||||
InstanceMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
|
||||
}
|
||||
|
||||
// Collect information about class methods
|
||||
llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
|
||||
llvm::SmallVector<Selector, 16> ClassMethodSels;
|
||||
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
|
||||
for (ObjCCategoryDecl::classmeth_iterator iter = OCD->classmeth_begin(),
|
||||
endIter = OCD->classmeth_end() ; iter != endIter ; iter++) {
|
||||
ClassMethodSels.push_back((*iter)->getSelector());
|
||||
std::string TypeStr;
|
||||
Context.getObjCEncodingForMethodDecl(*iter,TypeStr);
|
||||
ClassMethodNames.push_back(
|
||||
GetAddrOfConstantString((*iter)->getSelector().getName()));
|
||||
ClassMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
|
||||
}
|
||||
|
||||
|
@ -421,8 +421,8 @@ void CodeGenModule::EmitObjCCategoryImpl(const ObjCCategoryImplDecl *OCD) {
|
|||
|
||||
// Generate the category
|
||||
Runtime->GenerateCategory(OCD->getClassInterface()->getName(),
|
||||
OCD->getName(), InstanceMethodNames, InstanceMethodTypes,
|
||||
ClassMethodNames, ClassMethodTypes, Protocols);
|
||||
OCD->getName(), InstanceMethodSels, InstanceMethodTypes,
|
||||
ClassMethodSels, ClassMethodTypes, Protocols);
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitObjCClassImplementation(
|
||||
|
@ -473,26 +473,24 @@ void CodeGenModule::EmitObjCClassImplementation(
|
|||
}
|
||||
|
||||
// Collect information about instance methods
|
||||
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
|
||||
llvm::SmallVector<Selector, 16> InstanceMethodSels;
|
||||
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
|
||||
for (ObjCImplementationDecl::instmeth_iterator iter = OID->instmeth_begin(),
|
||||
endIter = OID->instmeth_end() ; iter != endIter ; iter++) {
|
||||
InstanceMethodSels.push_back((*iter)->getSelector());
|
||||
std::string TypeStr;
|
||||
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
|
||||
InstanceMethodNames.push_back(
|
||||
GetAddrOfConstantString((*iter)->getSelector().getName()));
|
||||
InstanceMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
|
||||
}
|
||||
|
||||
// Collect information about class methods
|
||||
llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
|
||||
llvm::SmallVector<Selector, 16> ClassMethodSels;
|
||||
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
|
||||
for (ObjCImplementationDecl::classmeth_iterator iter = OID->classmeth_begin(),
|
||||
endIter = OID->classmeth_end() ; iter != endIter ; iter++) {
|
||||
ClassMethodSels.push_back((*iter)->getSelector());
|
||||
std::string TypeStr;
|
||||
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
|
||||
ClassMethodNames.push_back(
|
||||
GetAddrOfConstantString((*iter)->getSelector().getName()));
|
||||
ClassMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
|
||||
}
|
||||
// Collect the names of referenced protocols
|
||||
|
@ -502,8 +500,8 @@ void CodeGenModule::EmitObjCClassImplementation(
|
|||
|
||||
// Generate the category
|
||||
Runtime->GenerateClass(ClassName, SCName, instanceSize, IvarNames, IvarTypes,
|
||||
IvarOffsets, InstanceMethodNames, InstanceMethodTypes, ClassMethodNames,
|
||||
ClassMethodTypes, Protocols);
|
||||
IvarOffsets, InstanceMethodSels, InstanceMethodTypes,
|
||||
ClassMethodSels, ClassMethodTypes, Protocols);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue