aboutsummaryrefslogtreecommitdiff
path: root/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-12-11 01:38:45 +0000
committerChris Lattner <sabre@nondot.org>2007-12-11 01:38:45 +0000
commitdf5eb710ce68ff7124cc3d78de819e6a218f6c2d (patch)
tree4898c1f8ff59122957f837fc26f249b6234c6c8f /CodeGen/CodeGenModule.cpp
parentb8b1e28964efbbf718b3bdd8331985f58d86382a (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.cpp60
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);
}