changeset 176:a074a5ff709c trunk

[svn r192] Fixed: String literals as constant expression was broken for utf16/32.
author lindquist
date Wed, 07 May 2008 00:58:36 +0200
parents c44e6a711885
children cea8dcfa76df
files gen/arrays.cpp gen/toir.cpp
diffstat 2 files changed, 37 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/gen/arrays.cpp	Wed May 07 00:01:13 2008 +0200
+++ b/gen/arrays.cpp	Wed May 07 00:58:36 2008 +0200
@@ -340,8 +340,10 @@
         assert(v);
 
         inits[i] = v;
+        Logger::cout() << "llval: " << *v << '\n';
     }
 
+    Logger::println("building constant array");
     const llvm::ArrayType* arrty = llvm::ArrayType::get(elemty,tdim);
     llvm::Constant* constarr = llvm::ConstantArray::get(arrty, inits);
 
--- a/gen/toir.cpp	Wed May 07 00:01:13 2008 +0200
+++ b/gen/toir.cpp	Wed May 07 00:58:36 2008 +0200
@@ -490,15 +490,43 @@
     Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
-    uint8_t* str = (uint8_t*)string;
-    std::string cont((char*)str, len);
-
     Type* t = DtoDType(type);
-
-    if (t->ty == Tsarray) {
-        return llvm::ConstantArray::get(cont,false);
+    Type* cty = DtoDType(t->next);
+
+    bool nullterm = (t->ty != Tsarray);
+    size_t endlen = nullterm ? len+1 : len;
+
+    const llvm::Type* ct = DtoType(cty);
+    const llvm::ArrayType* at = llvm::ArrayType::get(ct,endlen);
+
+    llvm::Constant* _init;
+    if (cty->ty == Tchar || cty->ty == Tvoid) {
+        uint8_t* str = (uint8_t*)string;
+        std::string cont((char*)str, len);
+        _init = llvm::ConstantArray::get(cont, nullterm);
     }
-    llvm::Constant* _init = llvm::ConstantArray::get(cont,true);
+    else if (cty->ty == Twchar) {
+        uint16_t* str = (uint16_t*)string;
+        std::vector<llvm::Constant*> vals;
+        for(size_t i=0; i<len; ++i) {
+            vals.push_back(llvm::ConstantInt::get(ct, str[i], false));;
+        }
+        if (nullterm)
+            vals.push_back(llvm::ConstantInt::get(ct, 0, false));
+        _init = llvm::ConstantArray::get(at,vals);
+    }
+    else if (cty->ty == Tdchar) {
+        uint32_t* str = (uint32_t*)string;
+        std::vector<llvm::Constant*> vals;
+        for(size_t i=0; i<len; ++i) {
+            vals.push_back(llvm::ConstantInt::get(ct, str[i], false));;
+        }
+        if (nullterm)
+            vals.push_back(llvm::ConstantInt::get(ct, 0, false));
+        _init = llvm::ConstantArray::get(at,vals);
+    }
+    else
+    assert(0);
 
     llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,"stringliteral",gIR->module);