Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h (revision 46191) +++ include/clang/AST/ASTContext.h (working copy) @@ -188,6 +188,10 @@ /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined /// in . The sizeof operator requires this (C99 6.5.3.4p4). QualType getSizeType() const; + + /// getWcharType - Return the unique type for "wchar_t" (C99 7.17), defined + /// in . Wide strings require this (C99 6.4.5p5). + QualType getWcharType() const; /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?) /// defined in . Pointer - pointer requires this (C99 6.5.6p9). Index: Sema/SemaExpr.cpp =================================================================== --- Sema/SemaExpr.cpp (revision 46191) +++ Sema/SemaExpr.cpp (working copy) @@ -45,12 +45,22 @@ // FIXME: handle wchar_t QualType t; + + llvm::APSInt length(32); + length = Literal.GetStringLength() + 1; + if (Literal.Pascal) { + t = Context.getConstantArrayType(Context.UnsignedCharTy, length, ArrayType::Normal, 0); + // FIXME: Check for wide string so we can output error + } else if (Literal.AnyWide) { + QualType wcharType = Context.getWcharType(); + uint64_t byteWidth = Context.getTypeSize(wcharType, StringToks[0].getLocation()) / + Context.getTypeSize(Context.CharTy, StringToks[0].getLocation()); + length = (Literal.GetStringLength() + 1) / byteWidth; + t = Context.getConstantArrayType(wcharType, length, ArrayType::Normal, 0); + } else { + t = Context.getConstantArrayType(Context.CharTy, length, ArrayType::Normal, 0); + } - if (Literal.Pascal) - t = Context.getPointerType(Context.UnsignedCharTy); - else - t = Context.getPointerType(Context.CharTy); - if (Literal.Pascal && Literal.GetStringLength() > 256) return Diag(StringToks[0].getLocation(), diag::err_pascal_string_too_long, SourceRange(StringToks[0].getLocation(), Index: AST/ASTContext.cpp =================================================================== --- AST/ASTContext.cpp (revision 46191) +++ AST/ASTContext.cpp (working copy) @@ -801,6 +801,15 @@ return UnsignedLongTy; } +/// getWcharType - Return the unique type for "wchar_t" (C99 7.17), the +/// width of characters in wide strings, The value is target dependent and +/// needs to agree with the definition in . +QualType ASTContext::getWcharType() const { + // On Darwin, wchar_t is defined as a "int". + // FIXME: should derive from "Target". + return IntTy; +} + /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?) /// defined in . Pointer - pointer requires this (C99 6.5.6p9). QualType ASTContext::getPointerDiffType() const { Index: CodeGen/CodeGenModule.cpp =================================================================== --- CodeGen/CodeGenModule.cpp (revision 46191) +++ CodeGen/CodeGenModule.cpp (working copy) @@ -390,16 +390,13 @@ // Generate constant for string literal values. case Stmt::StringLiteralClass: { const StringLiteral *String = cast(Expression); + assert(!String->isWide() && "Cannot codegen wide strings yet"); 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 + // This must be a string initializing an array in a static + // initializer, else we wouldn't be here. 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!"); @@ -472,6 +469,25 @@ } case Stmt::ImplicitCastExprClass: { const ImplicitCastExpr *ICExpr = cast(Expression); + + if (ICExpr->getSubExpr()->getStmtClass() == Stmt::StringLiteralClass) { + // FIXME: This isn't really factored correctly, but + // fixing that requires a GetAddrOfConstant method that + // takes an llvm::Constant*. + assert(ICExpr->getType()->isPointerType() && + "Implicit cast of string to non-pointer?"); + const StringLiteral *String = cast(ICExpr->getSubExpr()); + assert(!String->isWide() && "Cannot codegen wide strings yet"); + const char *StrData = String->getStrData(); + unsigned Len = String->getByteLength(); + + llvm::Constant *C = + CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len)); + llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty); + llvm::Constant *Zeros[] = { Zero, Zero }; + C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2); + return C; + } // If this is due to array->pointer conversion, emit the array expression as // an l-value. @@ -705,9 +721,7 @@ C = new llvm::GlobalVariable(C->getType(), constant, llvm::GlobalValue::InternalLinkage, C, ".str", &CGM.getModule()); - llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty); - llvm::Constant *Zeros[] = { Zero, Zero }; - C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2); + return C; }