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 /CodeGen/CodeGenModule.cpp | |
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
Diffstat (limited to 'CodeGen/CodeGenModule.cpp')
-rw-r--r-- | CodeGen/CodeGenModule.cpp | 60 |
1 files changed, 26 insertions, 34 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); } |