diff options
author | Anders Carlsson <andersca@mac.com> | 2007-08-21 00:21:21 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2007-08-21 00:21:21 +0000 |
commit | b04ea61b7979117d249111f264a44edab686b744 (patch) | |
tree | d36f8b02420f31645ce13b8ec4efde6e0b0b817b /clang/CodeGen/CodeGenModule.cpp | |
parent | 8e5b2c27a34485576102ee666ea7ed37cb30207f (diff) | |
download | bcm5719-llvm-b04ea61b7979117d249111f264a44edab686b744.tar.gz bcm5719-llvm-b04ea61b7979117d249111f264a44edab686b744.zip |
Implement code generation for constant CFStrings.
llvm-svn: 41206
Diffstat (limited to 'clang/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/CodeGen/CodeGenModule.cpp | 58 |
1 files changed, 57 insertions, 1 deletions
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<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; +} |