NeXT: Clean up constant CFString handling.

- Use CodeGenModule::GetAddrOfConstantCFString

Some tweaks of CodeGenModule::GetAddrOfConstantCFString

llvm-svn: 55243
This commit is contained in:
Daniel Dunbar 2008-08-23 18:37:06 +00:00
parent 22a4aee8e3
commit d644ad61e9
3 changed files with 32 additions and 89 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;