forked from OSchip/llvm-project
NeXT: Clean up constant CFString handling.
- Use CodeGenModule::GetAddrOfConstantCFString Some tweaks of CodeGenModule::GetAddrOfConstantCFString llvm-svn: 55243
This commit is contained in:
parent
22a4aee8e3
commit
d644ad61e9
|
@ -38,8 +38,6 @@ class ObjCTypesHelper {
|
|||
private:
|
||||
CodeGen::CodeGenModule &CGM;
|
||||
|
||||
const llvm::StructType *CFStringType;
|
||||
llvm::Constant *CFConstantStringClassReference;
|
||||
llvm::Function *MessageSendFn, *MessageSendStretFn;
|
||||
llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
|
||||
|
||||
|
@ -129,8 +127,6 @@ public:
|
|||
ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
|
||||
~ObjCTypesHelper();
|
||||
|
||||
llvm::Constant *getCFConstantStringClassReference();
|
||||
const llvm::StructType *getCFStringType();
|
||||
llvm::Value *getMessageSendFn(bool IsSuper, const llvm::Type *ReturnTy);
|
||||
};
|
||||
|
||||
|
@ -388,40 +384,7 @@ llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
|
|||
*/
|
||||
|
||||
llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
|
||||
// FIXME: I have no idea what this constant is (it is a magic
|
||||
// constant in GCC as well). Most likely the encoding of the string
|
||||
// and at least one part of it relates to UTF-16. Is this just the
|
||||
// code for UTF-8? Where is this handled for us?
|
||||
// See: <rdr://2996215>
|
||||
unsigned flags = 0x07c8;
|
||||
|
||||
// FIXME: Use some machinery to unique this. We can't reuse the CGM
|
||||
// one since we put them in a different section.
|
||||
llvm::Constant *StringC = llvm::ConstantArray::get(String);
|
||||
llvm::Constant *StringGV =
|
||||
new llvm::GlobalVariable(StringC->getType(), true,
|
||||
llvm::GlobalValue::InternalLinkage,
|
||||
StringC, ".str", &CGM.getModule());
|
||||
llvm::Constant *Values[4] = {
|
||||
ObjCTypes.getCFConstantStringClassReference(),
|
||||
llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
|
||||
getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
|
||||
llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
|
||||
};
|
||||
|
||||
llvm::Constant *CFStringC =
|
||||
llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
|
||||
std::vector<llvm::Constant*>(Values, Values+4));
|
||||
|
||||
llvm::GlobalVariable *CFStringGV =
|
||||
new llvm::GlobalVariable(CFStringC->getType(), true,
|
||||
llvm::GlobalValue::InternalLinkage,
|
||||
CFStringC, "",
|
||||
&CGM.getModule());
|
||||
|
||||
CFStringGV->setSection("__DATA, __cfstring");
|
||||
|
||||
return CFStringGV;
|
||||
return CGM.GetAddrOfConstantCFString(String);
|
||||
}
|
||||
|
||||
/// Generates a message send where the super is the receiver. This is
|
||||
|
@ -1537,9 +1500,7 @@ void CGObjCMac::FinishModule() {
|
|||
/* *** */
|
||||
|
||||
ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
||||
: CGM(cgm),
|
||||
CFStringType(0),
|
||||
CFConstantStringClassReference(0)
|
||||
: CGM(cgm)
|
||||
{
|
||||
CodeGen::CodeGenTypes &Types = CGM.getTypes();
|
||||
ASTContext &Ctx = CGM.getContext();
|
||||
|
@ -1770,37 +1731,6 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
ObjCTypesHelper::~ObjCTypesHelper() {
|
||||
}
|
||||
|
||||
const llvm::StructType *ObjCTypesHelper::getCFStringType() {
|
||||
if (!CFStringType) {
|
||||
CFStringType =
|
||||
llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
|
||||
llvm::Type::Int32Ty,
|
||||
Int8PtrTy,
|
||||
LongTy,
|
||||
NULL);
|
||||
|
||||
CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
|
||||
}
|
||||
|
||||
return CFStringType;
|
||||
}
|
||||
|
||||
llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
|
||||
if (!CFConstantStringClassReference) {
|
||||
llvm::GlobalValue *GV =
|
||||
new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
|
||||
false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0, "__CFConstantStringClassReference",
|
||||
&CGM.getModule());
|
||||
|
||||
// Decay to pointer.
|
||||
CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
|
||||
}
|
||||
|
||||
return CFConstantStringClassReference;
|
||||
}
|
||||
|
||||
llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
|
||||
const llvm::Type *ReturnTy) {
|
||||
llvm::Function *F;
|
||||
|
|
|
@ -694,7 +694,8 @@ llvm::Function *CodeGenModule::getMemSetFn() {
|
|||
return MemSetFn = getIntrinsic(IID);
|
||||
}
|
||||
|
||||
// FIXME: This needs moving into an Apple Objective-C runtime class
|
||||
// We still need to work out the details of handling UTF-16.
|
||||
// See: <rdr://2996215>
|
||||
llvm::Constant *CodeGenModule::
|
||||
GetAddrOfConstantCFString(const std::string &str) {
|
||||
llvm::StringMapEntry<llvm::Constant *> &Entry =
|
||||
|
@ -703,42 +704,48 @@ GetAddrOfConstantCFString(const std::string &str) {
|
|||
if (Entry.getValue())
|
||||
return Entry.getValue();
|
||||
|
||||
std::vector<llvm::Constant*> Fields;
|
||||
llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
|
||||
llvm::Constant *Zeros[] = { Zero, Zero };
|
||||
|
||||
if (!CFConstantStringClassRef) {
|
||||
const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
|
||||
Ty = llvm::ArrayType::get(Ty, 0);
|
||||
|
||||
CFConstantStringClassRef =
|
||||
|
||||
// FIXME: This is fairly broken if
|
||||
// __CFConstantStringClassReference is already defined, in that it
|
||||
// will get renamed and the user will most likely see an opaque
|
||||
// error message. This is a general issue with relying on
|
||||
// particular names.
|
||||
llvm::GlobalVariable *GV =
|
||||
new llvm::GlobalVariable(Ty, false,
|
||||
llvm::GlobalVariable::ExternalLinkage, 0,
|
||||
"__CFConstantStringClassReference",
|
||||
&getModule());
|
||||
|
||||
// Decay array -> ptr
|
||||
CFConstantStringClassRef =
|
||||
llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
|
||||
}
|
||||
|
||||
std::vector<llvm::Constant*> Fields(4);
|
||||
|
||||
// Class pointer.
|
||||
llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
|
||||
llvm::Constant *Zeros[] = { Zero, Zero };
|
||||
llvm::Constant *C =
|
||||
llvm::ConstantExpr::getGetElementPtr(CFConstantStringClassRef, Zeros, 2);
|
||||
Fields.push_back(C);
|
||||
Fields[0] = CFConstantStringClassRef;
|
||||
|
||||
// Flags.
|
||||
const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
|
||||
Fields.push_back(llvm::ConstantInt::get(Ty, 1992));
|
||||
const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
|
||||
Fields[1] = llvm::ConstantInt::get(Ty, 0x07C8);
|
||||
|
||||
// String pointer.
|
||||
C = llvm::ConstantArray::get(str);
|
||||
llvm::Constant *C = llvm::ConstantArray::get(str);
|
||||
C = new llvm::GlobalVariable(C->getType(), true,
|
||||
llvm::GlobalValue::InternalLinkage,
|
||||
C, ".str", &getModule());
|
||||
|
||||
C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
|
||||
Fields.push_back(C);
|
||||
C, ".str", &getModule());
|
||||
Fields[2] = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
|
||||
|
||||
// String length.
|
||||
Ty = getTypes().ConvertType(getContext().LongTy);
|
||||
Fields.push_back(llvm::ConstantInt::get(Ty, str.length()));
|
||||
Fields[3] = llvm::ConstantInt::get(Ty, str.length());
|
||||
|
||||
// The struct.
|
||||
Ty = getTypes().ConvertType(getContext().getCFConstantStringType());
|
||||
|
@ -747,8 +754,10 @@ GetAddrOfConstantCFString(const std::string &str) {
|
|||
new llvm::GlobalVariable(C->getType(), true,
|
||||
llvm::GlobalVariable::InternalLinkage,
|
||||
C, "", &getModule());
|
||||
|
||||
GV->setSection("__DATA,__cfstring");
|
||||
Entry.setValue(GV);
|
||||
|
||||
return GV;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,10 @@ class CodeGenModule {
|
|||
|
||||
llvm::StringMap<llvm::Constant*> CFConstantStringMap;
|
||||
llvm::StringMap<llvm::Constant*> ConstantStringMap;
|
||||
|
||||
/// CFConstantStringClassRef - Cached reference to the class for
|
||||
/// constant strings. This value has type int * but is actually an
|
||||
/// Obj-C class pointer.
|
||||
llvm::Constant *CFConstantStringClassRef;
|
||||
|
||||
std::vector<llvm::Function *> BuiltinFunctions;
|
||||
|
|
Loading…
Reference in New Issue