diff options
author | Chris Lattner <sabre@nondot.org> | 2007-12-11 01:38:45 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-12-11 01:38:45 +0000 |
commit | df5eb710ce68ff7124cc3d78de819e6a218f6c2d (patch) | |
tree | 4898c1f8ff59122957f837fc26f249b6234c6c8f | |
parent | b8b1e28964efbbf718b3bdd8331985f58d86382a (diff) |
Reimplement support for strings that initialize global inits now that
the types are right in sema. Thanks Steve.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44834 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | CodeGen/CodeGenModule.cpp | 60 | ||||
-rw-r--r-- | test/CodeGen/globalinit.c | 4 |
2 files changed, 28 insertions, 36 deletions
diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index a5f7df18d4..bd4df467f6 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -362,10 +362,32 @@ static llvm::Constant *GenerateConstantExpr(const Expr *Expression, // Generate constant for string literal values. case Stmt::StringLiteralClass: { - const StringLiteral *SLiteral = cast<StringLiteral>(Expression); - const char *StrData = SLiteral->getStrData(); - unsigned Len = SLiteral->getByteLength(); - return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len)); + const StringLiteral *String = cast<StringLiteral>(Expression); + const char *StrData = String->getStrData(); + unsigned Len = String->getByteLength(); + + // If the string has a pointer type, emit it as a global and use the pointer + // to the global as its value. + if (String->getType()->isPointerType()) + return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len)); + + // Otherwise this must be a string initializing an array in a static + // initializer. Don't emit it as the address of the string, emit the string + // data itself as an inline array. + const ConstantArrayType *CAT = String->getType()->getAsConstantArrayType(); + assert(CAT && "String isn't pointer or array!"); + + std::string Str(StrData, StrData + Len); + // Null terminate the string before potentially truncating it. + // FIXME: What about wchar_t strings? + Str.push_back(0); + + uint64_t RealLen = CAT->getSize().getZExtValue(); + // String or grow the initializer to the required size. + if (RealLen != Str.size()) + Str.resize(RealLen); + + return llvm::ConstantArray::get(Str, false); } // Elide parenthesis. @@ -414,36 +436,6 @@ static llvm::Constant *GenerateConstantExpr(const Expr *Expression, return llvm::ConstantExpr::getBitCast(C, DestPTy); } - // If this is an implicit cast of a string literal to an array type, this - // must be a string initializing an array. Don't emit it as the address of - // the string, emit the string data itself as an inline array. - if (const StringLiteral *String = - dyn_cast<StringLiteral>(ICExpr->getSubExpr())) - if (const ArrayType *AT = ICExpr->getType()->getAsArrayType()) { - // Verify that this is an array of char or wchar. Array of const char* - // can be initialized with a string literal, which does not expand the - // characters inline. - // FIXME: What about wchar_t?? - if (AT->getElementType()->isCharType()) { - const char *StrData = String->getStrData(); - std::string Str(StrData, StrData + String->getByteLength()); - // Null terminate the string before potentially truncating it. - Str.push_back(0); - - // FIXME: The size of the cast is not always specified yet, fix this - // in sema. - if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { - uint64_t RealLen = CAT->getSize().getZExtValue(); - // String or grow the initializer to the required size. - if (RealLen != Str.size()) - Str.resize(RealLen); - } - - - return llvm::ConstantArray::get(Str, false); - } - } - return GenerateConstantCast(ICExpr->getSubExpr(), type, CGM); } diff --git a/test/CodeGen/globalinit.c b/test/CodeGen/globalinit.c index 36cde9f45d..f47fd5c457 100644 --- a/test/CodeGen/globalinit.c +++ b/test/CodeGen/globalinit.c @@ -16,6 +16,6 @@ int latin_ptr2len (char *p); int (*mb_ptr2len) (char *p) = latin_ptr2len; -//char string[8] = "string"; // extend init -//char string2[4] = "string"; // truncate init +char string[8] = "string"; // extend init +char string2[4] = "string"; // truncate init |