From b04ea61b7979117d249111f264a44edab686b744 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 21 Aug 2007 00:21:21 +0000 Subject: Implement code generation for constant CFStrings. llvm-svn: 41206 --- clang/CodeGen/CodeGenModule.cpp | 58 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'clang/CodeGen/CodeGenModule.cpp') diff --git a/clang/CodeGen/CodeGenModule.cpp b/clang/CodeGen/CodeGenModule.cpp index 44cb91dd1de..74c7d43e1d2 100644 --- a/clang/CodeGen/CodeGenModule.cpp +++ b/clang/CodeGen/CodeGenModule.cpp @@ -26,7 +26,7 @@ using namespace CodeGen; CodeGenModule::CodeGenModule(ASTContext &C, llvm::Module &M) - : Context(C), TheModule(M), Types(C, M) {} + : Context(C), TheModule(M), Types(C, M), CFConstantStringClassRef(0) {} llvm::Constant *CodeGenModule::GetAddrOfGlobalDecl(const Decl *D) { // See if it is already in the map. @@ -113,3 +113,59 @@ llvm::Function *CodeGenModule::getMemCpyFn() { } return MemCpyFn = llvm::Intrinsic::getDeclaration(&TheModule, IID); } + +llvm::Constant *CodeGenModule::GetAddrOfConstantCFString(const std::string &str) +{ + llvm::StringMapEntry &Entry = + CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]); + + if (Entry.getValue()) + return Entry.getValue(); + + std::vector Fields; + + if (!CFConstantStringClassRef) { + const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); + Ty = llvm::ArrayType::get(Ty, 0); + + CFConstantStringClassRef = + new llvm::GlobalVariable(Ty, false, + llvm::GlobalVariable::ExternalLinkage, 0, + "__CFConstantStringClassReference", + &getModule()); + } + + // 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); + + // Flags. + const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); + Fields.push_back(llvm::ConstantInt::get(Ty, 1992)); + + // String pointer. + 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); + + // String length. + Ty = getTypes().ConvertType(getContext().LongTy); + Fields.push_back(llvm::ConstantInt::get(Ty, str.length())); + + // The struct. + Ty = getTypes().ConvertType(getContext().getCFConstantStringType()); + C = llvm::ConstantStruct::get(cast(Ty), Fields); + C = new llvm::GlobalVariable(C->getType(), true, + llvm::GlobalVariable::InternalLinkage, + C, "", &getModule()); + + Entry.setValue(C); + return C; +} -- cgit v1.2.3