diff options
author | Anders Carlsson <andersca@mac.com> | 2008-11-15 18:54:24 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-11-15 18:54:24 +0000 |
commit | c2480a55899ae9dfd3d9f8242e2b19bd4f9f400b (patch) | |
tree | 1f00fa376abaa2b320679a6602706675dfcc491d /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | c9dacf4fddc763fb7be021882b002f974fc6a8b6 (diff) | |
download | bcm5719-llvm-c2480a55899ae9dfd3d9f8242e2b19bd4f9f400b.tar.gz bcm5719-llvm-c2480a55899ae9dfd3d9f8242e2b19bd4f9f400b.zip |
Handle padding in the constant CFString struct. Fixes PR3046.
llvm-svn: 59372
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c4877a67453..a101e389b28 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -784,6 +784,34 @@ llvm::Function *CodeGenModule::getMemSetFn() { return MemSetFn = getIntrinsic(IID); } +static void appendFieldAndPadding(CodeGenModule &CGM, + std::vector<llvm::Constant*>& Fields, + int FieldNo, llvm::Constant* Field, + RecordDecl* RD, const llvm::StructType *STy) +{ + // Append the field. + Fields.push_back(Field); + + int StructFieldNo = + CGM.getTypes().getLLVMFieldNo(RD->getMember(FieldNo)); + + int NextStructFieldNo; + if (FieldNo + 1 == RD->getNumMembers()) { + NextStructFieldNo = STy->getNumElements(); + } else { + NextStructFieldNo = + CGM.getTypes().getLLVMFieldNo(RD->getMember(FieldNo + 1)); + } + + // Append padding + for (int i = StructFieldNo + 1; i < NextStructFieldNo; i++) { + llvm::Constant *C = + llvm::Constant::getNullValue(STy->getElementType(StructFieldNo + 1)); + + Fields.push_back(C); + } +} + // We still need to work out the details of handling UTF-16. // See: <rdr://2996215> llvm::Constant *CodeGenModule:: @@ -817,29 +845,39 @@ GetAddrOfConstantCFString(const std::string &str) { llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); } - std::vector<llvm::Constant*> Fields(4); + QualType CFTy = getContext().getCFConstantStringType(); + RecordDecl *CFRD = CFTy->getAsRecordType()->getDecl(); + const llvm::StructType *STy = + cast<llvm::StructType>(getTypes().ConvertType(CFTy)); + + std::vector<llvm::Constant*> Fields; + + // Class pointer. - Fields[0] = CFConstantStringClassRef; + appendFieldAndPadding(*this, Fields, 0, CFConstantStringClassRef, CFRD, STy); // Flags. const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy); - Fields[1] = llvm::ConstantInt::get(Ty, 0x07C8); + appendFieldAndPadding(*this, Fields, 1, llvm::ConstantInt::get(Ty, 0x07C8), + CFRD, STy); // String pointer. llvm::Constant *C = llvm::ConstantArray::get(str); C = new llvm::GlobalVariable(C->getType(), true, llvm::GlobalValue::InternalLinkage, - C, ".str", &getModule()); - Fields[2] = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2); + C, ".str", &getModule()); + appendFieldAndPadding(*this, Fields, 2, + llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2), + CFRD, STy); // String length. Ty = getTypes().ConvertType(getContext().LongTy); - Fields[3] = llvm::ConstantInt::get(Ty, str.length()); + appendFieldAndPadding(*this, Fields, 3, llvm::ConstantInt::get(Ty, str.length()), + CFRD, STy); // The struct. - Ty = getTypes().ConvertType(getContext().getCFConstantStringType()); - C = llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Fields); + C = llvm::ConstantStruct::get(STy, Fields); llvm::GlobalVariable *GV = new llvm::GlobalVariable(C->getType(), true, llvm::GlobalVariable::InternalLinkage, |