aboutsummaryrefslogtreecommitdiff
path: root/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2007-08-21 00:21:21 +0000
committerAnders Carlsson <andersca@mac.com>2007-08-21 00:21:21 +0000
commitc9e2091efcb535110474434dd12015afdc3b1637 (patch)
tree25a7c51e891e0c4355d41f6c289559415ca8a4aa /CodeGen/CodeGenModule.cpp
parent7016a706c9fab0d7c1603e424c61abbff9077037 (diff)
Implement code generation for constant CFStrings.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41206 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CodeGenModule.cpp')
-rw-r--r--CodeGen/CodeGenModule.cpp58
1 files changed, 57 insertions, 1 deletions
diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp
index 44cb91dd1d..74c7d43e1d 100644
--- a/CodeGen/CodeGenModule.cpp
+++ b/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<llvm::Constant *> &Entry =
+ CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
+
+ if (Entry.getValue())
+ return Entry.getValue();
+
+ std::vector<llvm::Constant*> 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<llvm::StructType>(Ty), Fields);
+ C = new llvm::GlobalVariable(C->getType(), true,
+ llvm::GlobalVariable::InternalLinkage,
+ C, "", &getModule());
+
+ Entry.setValue(C);
+ return C;
+}