diff options
author | Chris Lattner <sabre@nondot.org> | 2008-02-11 00:02:17 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-02-11 00:02:17 +0000 |
commit | a7ad98ff0919d6a24ea7c46634ea29bea551c1a0 (patch) | |
tree | 81b36b35fcba035193d751e5de0470fad9cc212c /CodeGen | |
parent | 68f624e9eb2d80b2e5c1a51471a76782cb1bc70b (diff) |
Fix PR1992 by computing the right type for string literals, which
is an array type not a pointer type. This requires updating some
diags that change and updating the code generator to handle the
proper form of strings.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46941 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen')
-rw-r--r-- | CodeGen/CGExprConstant.cpp | 16 | ||||
-rw-r--r-- | CodeGen/CodeGenModule.cpp | 9 | ||||
-rw-r--r-- | CodeGen/CodeGenModule.h | 3 |
3 files changed, 11 insertions, 17 deletions
diff --git a/CodeGen/CGExprConstant.cpp b/CodeGen/CGExprConstant.cpp index 8c319a0eb3..569547549f 100644 --- a/CodeGen/CGExprConstant.cpp +++ b/CodeGen/CGExprConstant.cpp @@ -205,9 +205,7 @@ public: // Note that VLAs can't exist for global variables. // The only thing that can have array type like this is a // DeclRefExpr(FileVarDecl)? - const DeclRefExpr *DRE = cast<DeclRefExpr>(ICExpr->getSubExpr()); - const VarDecl *VD = cast<VarDecl>(DRE->getDecl()); - llvm::Constant *C = CGM.GetAddrOfGlobalVar(VD, false); + llvm::Constant *C = EmitLValue(ICExpr->getSubExpr()); assert(isa<llvm::PointerType>(C->getType()) && isa<llvm::ArrayType>(cast<llvm::PointerType>(C->getType()) ->getElementType())); @@ -232,11 +230,7 @@ public: llvm::Constant *VisitStringLiteral(StringLiteral *E) { const char *StrData = E->getStrData(); unsigned Len = E->getByteLength(); - - // If the string has a pointer type, emit it as a global and use the pointer - // to the global as its value. - if (E->getType()->isPointerType()) - return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len)); + assert(!E->getType()->isPointerType() && "Strings are always arrays"); // 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 @@ -532,7 +526,7 @@ public: // to be the only use of the variable, so we just generate it here. CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E); llvm::Constant* C = Visit(CLE->getInitializer()); - C = new llvm::GlobalVariable(C->getType(), E->getType().isConstQualified(), + C = new llvm::GlobalVariable(C->getType(),E->getType().isConstQualified(), llvm::GlobalValue::InternalLinkage, C, ".compoundliteral", &CGM.getModule()); return C; @@ -541,8 +535,8 @@ public: ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl(); if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl)) return CGM.GetAddrOfFunctionDecl(FD, false); - if (const FileVarDecl* FVD = dyn_cast<FileVarDecl>(Decl)) - return CGM.GetAddrOfGlobalVar(FVD, false); + if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) + return CGM.GetAddrOfGlobalVar(VD, false); // We can end up here with static block-scope variables (and others?) // FIXME: How do we implement block-scope variables?! assert(0 && "Unimplemented Decl type"); diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index e1aec690e9..ef05586fcc 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -384,7 +384,7 @@ GetAddrOfConstantCFString(const std::string &str) { return GV; } -/// GenerateWritableString -- Creates storage for a string literal +/// GenerateWritableString -- Creates storage for a string literal. static llvm::Constant *GenerateStringLiteral(const std::string &str, bool constant, CodeGenModule &CGM) { @@ -395,14 +395,11 @@ static llvm::Constant *GenerateStringLiteral(const std::string &str, 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; } -/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the first -/// element of a character array containing the literal. +/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the character +/// array containing the literal. The result is pointer to array type. llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str) { // Don't share any string literals if writable-strings is turned on. if (Features.WritableStrings) diff --git a/CodeGen/CodeGenModule.h b/CodeGen/CodeGenModule.h index 7c236e0ce8..92060887af 100644 --- a/CodeGen/CodeGenModule.h +++ b/CodeGen/CodeGenModule.h @@ -80,6 +80,9 @@ public: /// llvm::Function *getBuiltinLibFunction(unsigned BuiltinID); llvm::Constant *GetAddrOfConstantCFString(const std::string& str); + + /// GetAddrOfConstantString -- returns a pointer to the character + /// array containing the literal. The result is pointer to array type. llvm::Constant *GetAddrOfConstantString(const std::string& str); llvm::Function *getMemCpyFn(); llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0, |