forked from OSchip/llvm-project
Emit wide string literals with the appropriate alignment.
Patch by Craig Topper and Sundeep! llvm-svn: 136856
This commit is contained in:
parent
e4df09f7ba
commit
9b24df470d
|
@ -1923,7 +1923,10 @@ llvm::Constant *
|
|||
CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
|
||||
// FIXME: This can be more efficient.
|
||||
// FIXME: We shouldn't need to bitcast the constant in the wide string case.
|
||||
llvm::Constant *C = GetAddrOfConstantString(GetStringForStringLiteral(S));
|
||||
CharUnits Align = getContext().getTypeAlignInChars(S->getType());
|
||||
llvm::Constant *C = GetAddrOfConstantString(GetStringForStringLiteral(S),
|
||||
/* GlobalName */ 0,
|
||||
Align.getQuantity());
|
||||
if (S->isWide() || S->isUTF16() || S->isUTF32()) {
|
||||
llvm::Type *DestTy =
|
||||
llvm::PointerType::getUnqual(getTypes().ConvertType(S->getType()));
|
||||
|
@ -1944,10 +1947,11 @@ CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) {
|
|||
|
||||
|
||||
/// GenerateWritableString -- Creates storage for a string literal.
|
||||
static llvm::Constant *GenerateStringLiteral(StringRef str,
|
||||
static llvm::GlobalVariable *GenerateStringLiteral(StringRef str,
|
||||
bool constant,
|
||||
CodeGenModule &CGM,
|
||||
const char *GlobalName) {
|
||||
const char *GlobalName,
|
||||
unsigned Alignment) {
|
||||
// Create Constant for this string literal. Don't add a '\0'.
|
||||
llvm::Constant *C =
|
||||
llvm::ConstantArray::get(CGM.getLLVMContext(), str, false);
|
||||
|
@ -1957,7 +1961,7 @@ static llvm::Constant *GenerateStringLiteral(StringRef str,
|
|||
new llvm::GlobalVariable(CGM.getModule(), C->getType(), constant,
|
||||
llvm::GlobalValue::PrivateLinkage,
|
||||
C, GlobalName);
|
||||
GV->setAlignment(1);
|
||||
GV->setAlignment(Alignment);
|
||||
GV->setUnnamedAddr(true);
|
||||
return GV;
|
||||
}
|
||||
|
@ -1971,7 +1975,8 @@ static llvm::Constant *GenerateStringLiteral(StringRef str,
|
|||
///
|
||||
/// The result has pointer to array type.
|
||||
llvm::Constant *CodeGenModule::GetAddrOfConstantString(StringRef Str,
|
||||
const char *GlobalName) {
|
||||
const char *GlobalName,
|
||||
unsigned Alignment) {
|
||||
bool IsConstant = !Features.WritableStrings;
|
||||
|
||||
// Get the default prefix if a name wasn't specified.
|
||||
|
@ -1980,27 +1985,32 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantString(StringRef Str,
|
|||
|
||||
// Don't share any string literals if strings aren't constant.
|
||||
if (!IsConstant)
|
||||
return GenerateStringLiteral(Str, false, *this, GlobalName);
|
||||
return GenerateStringLiteral(Str, false, *this, GlobalName, Alignment);
|
||||
|
||||
llvm::StringMapEntry<llvm::Constant *> &Entry =
|
||||
llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
|
||||
ConstantStringMap.GetOrCreateValue(Str);
|
||||
|
||||
if (Entry.getValue())
|
||||
return Entry.getValue();
|
||||
if (llvm::GlobalVariable *GV = Entry.getValue()) {
|
||||
if (Alignment > GV->getAlignment()) {
|
||||
GV->setAlignment(Alignment);
|
||||
}
|
||||
return GV;
|
||||
}
|
||||
|
||||
// Create a global variable for this.
|
||||
llvm::Constant *C = GenerateStringLiteral(Str, true, *this, GlobalName);
|
||||
Entry.setValue(C);
|
||||
return C;
|
||||
llvm::GlobalVariable *GV = GenerateStringLiteral(Str, true, *this, GlobalName, Alignment);
|
||||
Entry.setValue(GV);
|
||||
return GV;
|
||||
}
|
||||
|
||||
/// GetAddrOfConstantCString - Returns a pointer to a character
|
||||
/// array containing the literal and a terminating '\0'
|
||||
/// character. The result has pointer to array type.
|
||||
llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &Str,
|
||||
const char *GlobalName){
|
||||
const char *GlobalName,
|
||||
unsigned Alignment) {
|
||||
StringRef StrWithNull(Str.c_str(), Str.size() + 1);
|
||||
return GetAddrOfConstantString(StrWithNull, GlobalName);
|
||||
return GetAddrOfConstantString(StrWithNull, GlobalName, Alignment);
|
||||
}
|
||||
|
||||
/// EmitObjCPropertyImplementations - Emit information for synthesized
|
||||
|
|
|
@ -263,7 +263,7 @@ class CodeGenModule : public CodeGenTypeCache {
|
|||
std::vector<llvm::Constant*> Annotations;
|
||||
|
||||
llvm::StringMap<llvm::Constant*> CFConstantStringMap;
|
||||
llvm::StringMap<llvm::Constant*> ConstantStringMap;
|
||||
llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap;
|
||||
llvm::DenseMap<const Decl*, llvm::Value*> StaticLocalDeclMap;
|
||||
|
||||
/// CXXGlobalInits - Global variables with initializers that need to run
|
||||
|
@ -545,7 +545,8 @@ public:
|
|||
/// \param GlobalName If provided, the name to use for the global
|
||||
/// (if one is created).
|
||||
llvm::Constant *GetAddrOfConstantString(StringRef Str,
|
||||
const char *GlobalName=0);
|
||||
const char *GlobalName=0,
|
||||
unsigned Alignment=1);
|
||||
|
||||
/// GetAddrOfConstantCString - Returns a pointer to a character array
|
||||
/// containing the literal and a terminating '\0' character. The result has
|
||||
|
@ -554,7 +555,8 @@ public:
|
|||
/// \param GlobalName If provided, the name to use for the global (if one is
|
||||
/// created).
|
||||
llvm::Constant *GetAddrOfConstantCString(const std::string &str,
|
||||
const char *GlobalName=0);
|
||||
const char *GlobalName=0,
|
||||
unsigned Alignment=1);
|
||||
|
||||
/// GetAddrOfCXXConstructor - Return the address of the constructor of the
|
||||
/// given type.
|
||||
|
|
|
@ -14,26 +14,26 @@ int main() {
|
|||
// CHECK-CPP0X: internal unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1
|
||||
char b[10] = "\u1120\u0220\U00102030";
|
||||
|
||||
// CHECK-C: private unnamed_addr constant [12 x i8] c"A\00\00\00B\00\00\00\00\00\00\00", align 1
|
||||
// CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"A\00\00\00B\00\00\00\00\00\00\00", align 1
|
||||
// CHECK-C: private unnamed_addr constant [12 x i8] c"A\00\00\00B\00\00\00\00\00\00\00", align 4
|
||||
// CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"A\00\00\00B\00\00\00\00\00\00\00", align 4
|
||||
const wchar_t *foo = L"AB";
|
||||
|
||||
// CHECK-C: private unnamed_addr constant [12 x i8] c"4\12\00\00\0B\F0\10\00\00\00\00\00", align 1
|
||||
// CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"4\12\00\00\0B\F0\10\00\00\00\00\00", align 1
|
||||
// CHECK-C: private unnamed_addr constant [12 x i8] c"4\12\00\00\0B\F0\10\00\00\00\00\00", align 4
|
||||
// CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"4\12\00\00\0B\F0\10\00\00\00\00\00", align 4
|
||||
const wchar_t *bar = L"\u1234\U0010F00B";
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"C\00\00\00D\00\00\00\00\00\00\00", align 1
|
||||
// CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"C\00\00\00D\00\00\00\00\00\00\00", align 4
|
||||
const char32_t *c = U"CD";
|
||||
|
||||
// CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"5\12\00\00\0C\F0\10\00\00\00\00\00", align 1
|
||||
// CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"5\12\00\00\0C\F0\10\00\00\00\00\00", align 4
|
||||
const char32_t *d = U"\u1235\U0010F00C";
|
||||
|
||||
// CHECK-CPP0X: private unnamed_addr constant [6 x i8] c"E\00F\00\00\00", align 1
|
||||
// CHECK-CPP0X: private unnamed_addr constant [6 x i8] c"E\00F\00\00\00", align 2
|
||||
const char16_t *e = u"EF";
|
||||
|
||||
// This should convert to utf16.
|
||||
// CHECK-CPP0X: private unnamed_addr constant [10 x i8] c" \11 \02\C8\DB0\DC\00\00", align 1
|
||||
// CHECK-CPP0X: private unnamed_addr constant [10 x i8] c" \11 \02\C8\DB0\DC\00\00", align 2
|
||||
const char16_t *f = u"\u1120\u0220\U00102030";
|
||||
|
||||
// CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"def\00", align 1
|
||||
|
|
Loading…
Reference in New Issue