[llvm-commits] [llvm] r149800 - in /llvm/trunk: include/llvm/ include/llvm/Analysis/ lib/Analysis/ lib/AsmParser/ lib/Bitcode/Writer/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/Target/CBackend/ lib/Target/CppBackend/ lib/Transforms/Instrumentation/ lib/Transforms/Scalar/ lib/VMCore/ tools/bugpoint/ tools/lto/

Chris Lattner sabre at nondot.org
Sun Feb 5 10:13:43 PST 2012


On Feb 4, 2012, at 10:03 PM, Chad Rosier wrote:

> Hi Chris,
> This commit is causing our llvm-gcc build bot to fail at stage 1.

Yep, llvm-gcc is dead.

-Chris

> 
> ../../llvm-gcc.src/gcc/llvm-backend.cpp: In function 'void readLLVMValues()':
> ../../llvm-gcc.src/gcc/llvm-backend.cpp:282: error: 'class llvm::ConstantArray' has no member named 'getAsString'
> ../../llvm-gcc.src/gcc/llvm-backend.cpp: In function 'llvm::Constant* ConvertMetadataStringToGV(const char*)':
> ../../llvm-gcc.src/gcc/llvm-backend.cpp:1302: error: no matching function for call to 'llvm::ConstantArray::get(llvm::LLVMContext&, std::string)'
> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.llvm-gcc-i386-darwin9-RA/llvm.src/include/llvm/Constants.h:353: note: candidates are: static llvm::Constant* llvm::ConstantArray::get(llvm::ArrayType*, llvm::ArrayRef<llvm::Constant*>)
>  Chad
> 
> On Feb 4, 2012, at 6:29 PM, Chris Lattner wrote:
> 
>> Author: lattner
>> Date: Sat Feb  4 20:29:43 2012
>> New Revision: 149800
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=149800&view=rev
>> Log:
>> reapply the patches reverted in r149470 that reenable ConstantDataArray,
>> but with a critical fix to the SelectionDAG code that optimizes copies
>> from strings into immediate stores: the previous code was stopping reading
>> string data at the first nul.  Address this by adding a new argument to
>> llvm::getConstantStringInfo, preserving the behavior before the patch.
>> 
>> 
>> Modified:
>>    llvm/trunk/include/llvm/Analysis/ValueTracking.h
>>    llvm/trunk/include/llvm/Constants.h
>>    llvm/trunk/lib/Analysis/ConstantFolding.cpp
>>    llvm/trunk/lib/Analysis/ValueTracking.cpp
>>    llvm/trunk/lib/AsmParser/LLParser.cpp
>>    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>>    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
>>    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
>>    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>>    llvm/trunk/lib/Target/CBackend/CBackend.cpp
>>    llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
>>    llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
>>    llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
>>    llvm/trunk/lib/VMCore/AsmWriter.cpp
>>    llvm/trunk/lib/VMCore/Constants.cpp
>>    llvm/trunk/lib/VMCore/Core.cpp
>>    llvm/trunk/lib/VMCore/IRBuilder.cpp
>>    llvm/trunk/tools/bugpoint/Miscompilation.cpp
>>    llvm/trunk/tools/lto/LTOModule.cpp
>> 
>> Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original)
>> +++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Sat Feb  4 20:29:43 2012
>> @@ -17,14 +17,13 @@
>> 
>> #include "llvm/ADT/ArrayRef.h"
>> #include "llvm/Support/DataTypes.h"
>> -#include <string>
>> 
>> namespace llvm {
>> -  template <typename T> class SmallVectorImpl;
>>   class Value;
>>   class Instruction;
>>   class APInt;
>>   class TargetData;
>> +  class StringRef;
>> 
>>   /// ComputeMaskedBits - Determine which of the bits specified in Mask are
>>   /// known to be either zero or one and return them in the KnownZero/KnownOne
>> @@ -125,16 +124,15 @@
>>     return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
>>   }
>> 
>> -  /// GetConstantStringInfo - This function computes the length of a
>> +  /// getConstantStringInfo - This function computes the length of a
>>   /// null-terminated C string pointed to by V.  If successful, it returns true
>> -  /// and returns the string in Str.  If unsuccessful, it returns false.  If
>> -  /// StopAtNul is set to true (the default), the returned string is truncated
>> -  /// by a nul character in the global.  If StopAtNul is false, the nul
>> -  /// character is included in the result string.
>> -  bool GetConstantStringInfo(const Value *V, std::string &Str,
>> -                             uint64_t Offset = 0,
>> -                             bool StopAtNul = true);
>> -                        
>> +  /// and returns the string in Str.  If unsuccessful, it returns false.  This
>> +  /// does not include the trailing nul character by default.  If TrimAtNul is
>> +  /// set to false, then this returns any trailing nul characters as well as any
>> +  /// other characters that come after it.
>> +  bool getConstantStringInfo(const Value *V, StringRef &Str,
>> +                             uint64_t Offset = 0, bool TrimAtNul = true);
>> +
>>   /// GetStringLength - If we can compute the length of the string pointed to by
>>   /// the specified pointer, return 'len+1'.  If we can't, return 0.
>>   uint64_t GetStringLength(Value *V);
>> 
>> Modified: llvm/trunk/include/llvm/Constants.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Constants.h (original)
>> +++ llvm/trunk/include/llvm/Constants.h Sat Feb  4 20:29:43 2012
>> @@ -352,17 +352,6 @@
>>   // ConstantArray accessors
>>   static Constant *get(ArrayType *T, ArrayRef<Constant*> V);
>> 
>> -  /// This method constructs a ConstantArray and initializes it with a text
>> -  /// string. The default behavior (AddNull==true) causes a null terminator to
>> -  /// be placed at the end of the array. This effectively increases the length
>> -  /// of the array by one (you've been warned).  However, in some situations 
>> -  /// this is not desired so if AddNull==false then the string is copied without
>> -  /// null termination.
>> -  
>> -  // FIXME Remove this.
>> -  static Constant *get(LLVMContext &Context, StringRef Initializer,
>> -                       bool AddNull = true);
>> -  
>>   /// Transparently provide more efficient getOperand methods.
>>   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
>> 
>> @@ -373,31 +362,6 @@
>>     return reinterpret_cast<ArrayType*>(Value::getType());
>>   }
>> 
>> -  // FIXME: String methods will eventually be removed.
>> -  
>> -  
>> -  /// isString - This method returns true if the array is an array of i8 and
>> -  /// the elements of the array are all ConstantInt's.
>> -  bool isString() const;
>> -
>> -  /// isCString - This method returns true if the array is a string (see
>> -  /// @verbatim
>> -  /// isString) and it ends in a null byte \0 and does not contains any other
>> -  /// @endverbatim
>> -  /// null bytes except its terminator.
>> -  bool isCString() const;
>> -
>> -  /// getAsString - If this array is isString(), then this method converts the
>> -  /// array to an std::string and returns it.  Otherwise, it asserts out.
>> -  ///
>> -  std::string getAsString() const;
>> -
>> -  /// getAsCString - If this array is isCString(), then this method converts the
>> -  /// array (without the trailing null byte) to an std::string and returns it.
>> -  /// Otherwise, it asserts out.
>> -  ///
>> -  std::string getAsCString() const;
>> -
>>   virtual void destroyConstant();
>>   virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
>> 
>> 
>> Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
>> +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Sat Feb  4 20:29:43 2012
>> @@ -476,9 +476,9 @@
>> 
>>   // Instead of loading constant c string, use corresponding integer value
>>   // directly if string length is small enough.
>> -  std::string Str;
>> -  if (TD && GetConstantStringInfo(CE, Str) && !Str.empty()) {
>> -    unsigned StrLen = Str.length();
>> +  StringRef Str;
>> +  if (TD && getConstantStringInfo(CE, Str) && !Str.empty()) {
>> +    unsigned StrLen = Str.size();
>>     Type *Ty = cast<PointerType>(CE->getType())->getElementType();
>>     unsigned NumBits = Ty->getPrimitiveSizeInBits();
>>     // Replace load with immediate integer if the result is an integer or fp
>> 
>> Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
>> +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Sat Feb  4 20:29:43 2012
>> @@ -1369,25 +1369,21 @@
>>     }
>>   }
>> 
>> -  // A ConstantArray is splatable if all its members are equal and also
>> -  // splatable.
>> -  if (ConstantArray *CA = dyn_cast<ConstantArray>(V)) {
>> -    if (CA->getNumOperands() == 0)
>> -      return 0;
>> -    
>> -    Value *Val = isBytewiseValue(CA->getOperand(0));
>> +  // A ConstantDataArray/Vector is splatable if all its members are equal and
>> +  // also splatable.
>> +  if (ConstantDataSequential *CA = dyn_cast<ConstantDataSequential>(V)) {
>> +    Value *Elt = CA->getElementAsConstant(0);
>> +    Value *Val = isBytewiseValue(Elt);
>>     if (!Val)
>>       return 0;
>> 
>> -    for (unsigned I = 1, E = CA->getNumOperands(); I != E; ++I)
>> -      if (CA->getOperand(I-1) != CA->getOperand(I))
>> +    for (unsigned I = 1, E = CA->getNumElements(); I != E; ++I)
>> +      if (CA->getElementAsConstant(I) != Elt)
>>         return 0;
>> 
>>     return Val;
>>   }
>> 
>> -  // FIXME: Vector types (e.g., <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>).
>> -  
>>   // Conceptually, we could handle things like:
>>   //   %a = zext i8 %X to i16
>>   //   %b = shl i16 %a, 8
>> @@ -1607,33 +1603,19 @@
>> }
>> 
>> 
>> -/// GetConstantStringInfo - This function computes the length of a
>> +/// getConstantStringInfo - This function computes the length of a
>> /// null-terminated C string pointed to by V.  If successful, it returns true
>> /// and returns the string in Str.  If unsuccessful, it returns false.
>> -bool llvm::GetConstantStringInfo(const Value *V, std::string &Str,
>> -                                 uint64_t Offset, bool StopAtNul) {
>> -  // If V is NULL then return false;
>> -  if (V == NULL) return false;
>> -
>> -  // Look through bitcast instructions.
>> -  if (const BitCastInst *BCI = dyn_cast<BitCastInst>(V))
>> -    return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul);
>> -  
>> -  // If the value is not a GEP instruction nor a constant expression with a
>> -  // GEP instruction, then return false because ConstantArray can't occur
>> -  // any other way.
>> -  const User *GEP = 0;
>> -  if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
>> -    GEP = GEPI;
>> -  } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
>> -    if (CE->getOpcode() == Instruction::BitCast)
>> -      return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul);
>> -    if (CE->getOpcode() != Instruction::GetElementPtr)
>> -      return false;
>> -    GEP = CE;
>> -  }
>> -  
>> -  if (GEP) {
>> +bool llvm::getConstantStringInfo(const Value *V, StringRef &Str,
>> +                                 uint64_t Offset, bool TrimAtNul) {
>> +  assert(V);
>> +
>> +  // Look through bitcast instructions and geps.
>> +  V = V->stripPointerCasts();
>> +  
>> +  // If the value is a GEP instructionor  constant expression, treat it as an
>> +  // offset.
>> +  if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
>>     // Make sure the GEP has exactly three arguments.
>>     if (GEP->getNumOperands() != 3)
>>       return false;
>> @@ -1658,51 +1640,48 @@
>>       StartIdx = CI->getZExtValue();
>>     else
>>       return false;
>> -    return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset,
>> -                                 StopAtNul);
>> +    return getConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset);
>>   }
>> 
>>   // The GEP instruction, constant or instruction, must reference a global
>>   // variable that is a constant and is initialized. The referenced constant
>>   // initializer is the array that we'll use for optimization.
>> -  const GlobalVariable* GV = dyn_cast<GlobalVariable>(V);
>> +  const GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
>>   if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
>>     return false;
>> -  const Constant *GlobalInit = GV->getInitializer();
>> -  
>> +
>>   // Handle the all-zeros case
>> -  if (GlobalInit->isNullValue()) {
>> +  if (GV->getInitializer()->isNullValue()) {
>>     // This is a degenerate case. The initializer is constant zero so the
>>     // length of the string must be zero.
>> -    Str.clear();
>> +    Str = "";
>>     return true;
>>   }
>> 
>>   // Must be a Constant Array
>> -  const ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
>> -  if (Array == 0 || !Array->getType()->getElementType()->isIntegerTy(8))
>> +  const ConstantDataArray *Array =
>> +    dyn_cast<ConstantDataArray>(GV->getInitializer());
>> +  if (Array == 0 || !Array->isString())
>>     return false;
>> 
>>   // Get the number of elements in the array
>> -  uint64_t NumElts = Array->getType()->getNumElements();
>> -  
>> +  uint64_t NumElts = Array->getType()->getArrayNumElements();
>> +
>> +  // Start out with the entire array in the StringRef.
>> +  Str = Array->getAsString();
>> +
>>   if (Offset > NumElts)
>>     return false;
>> 
>> -  // Traverse the constant array from 'Offset' which is the place the GEP refers
>> -  // to in the array.
>> -  Str.reserve(NumElts-Offset);
>> -  for (unsigned i = Offset; i != NumElts; ++i) {
>> -    const Constant *Elt = Array->getOperand(i);
>> -    const ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
>> -    if (!CI) // This array isn't suitable, non-int initializer.
>> -      return false;
>> -    if (StopAtNul && CI->isZero())
>> -      return true; // we found end of string, success!
>> -    Str += (char)CI->getZExtValue();
>> -  }
>> +  // Skip over 'offset' bytes.
>> +  Str = Str.substr(Offset);
>> 
>> -  // The array isn't null terminated, but maybe this is a memcpy, not a strcpy.
>> +  if (TrimAtNul) {
>> +    // Trim off the \0 and anything after it.  If the array is not nul
>> +    // terminated, we just return the whole end of string.  The client may know
>> +    // some other way that the string is length-bound.
>> +    Str = Str.substr(0, Str.find('\0'));
>> +  }
>>   return true;
>> }
>> 
>> @@ -1714,8 +1693,7 @@
>> /// the specified pointer, return 'len+1'.  If we can't, return 0.
>> static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) {
>>   // Look through noop bitcast instructions.
>> -  if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
>> -    return GetStringLengthH(BCI->getOperand(0), PHIs);
>> +  V = V->stripPointerCasts();
>> 
>>   // If this is a PHI node, there are two cases: either we have already seen it
>>   // or we haven't.
>> @@ -1751,83 +1729,13 @@
>>     if (Len1 != Len2) return 0;
>>     return Len1;
>>   }
>> -
>> -  // As a special-case, "@string = constant i8 0" is also a string with zero
>> -  // length, not wrapped in a bitcast or GEP.
>> -  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
>> -    if (GV->isConstant() && GV->hasDefinitiveInitializer())
>> -      if (GV->getInitializer()->isNullValue()) return 1;
>> -    return 0;
>> -  }
>> -
>> -  // If the value is not a GEP instruction nor a constant expression with a
>> -  // GEP instruction, then return unknown.
>> -  User *GEP = 0;
>> -  if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
>> -    GEP = GEPI;
>> -  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
>> -    if (CE->getOpcode() != Instruction::GetElementPtr)
>> -      return 0;
>> -    GEP = CE;
>> -  } else {
>> -    return 0;
>> -  }
>> -
>> -  // Make sure the GEP has exactly three arguments.
>> -  if (GEP->getNumOperands() != 3)
>> -    return 0;
>> -
>> -  // Check to make sure that the first operand of the GEP is an integer and
>> -  // has value 0 so that we are sure we're indexing into the initializer.
>> -  if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
>> -    if (!Idx->isZero())
>> -      return 0;
>> -  } else
>> -    return 0;
>> -
>> -  // If the second index isn't a ConstantInt, then this is a variable index
>> -  // into the array.  If this occurs, we can't say anything meaningful about
>> -  // the string.
>> -  uint64_t StartIdx = 0;
>> -  if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
>> -    StartIdx = CI->getZExtValue();
>> -  else
>> -    return 0;
>> -
>> -  // The GEP instruction, constant or instruction, must reference a global
>> -  // variable that is a constant and is initialized. The referenced constant
>> -  // initializer is the array that we'll use for optimization.
>> -  GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
>> -  if (!GV || !GV->isConstant() || !GV->hasInitializer() ||
>> -      GV->mayBeOverridden())
>> +  
>> +  // Otherwise, see if we can read the string.
>> +  StringRef StrData;
>> +  if (!getConstantStringInfo(V, StrData))
>>     return 0;
>> -  Constant *GlobalInit = GV->getInitializer();
>> -
>> -  // Handle the ConstantAggregateZero case, which is a degenerate case. The
>> -  // initializer is constant zero so the length of the string must be zero.
>> -  if (isa<ConstantAggregateZero>(GlobalInit))
>> -    return 1;  // Len = 0 offset by 1.
>> -
>> -  // Must be a Constant Array
>> -  ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
>> -  if (!Array || !Array->getType()->getElementType()->isIntegerTy(8))
>> -    return false;
>> -
>> -  // Get the number of elements in the array
>> -  uint64_t NumElts = Array->getType()->getNumElements();
>> -
>> -  // Traverse the constant array from StartIdx (derived above) which is
>> -  // the place the GEP refers to in the array.
>> -  for (unsigned i = StartIdx; i != NumElts; ++i) {
>> -    Constant *Elt = Array->getOperand(i);
>> -    ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
>> -    if (!CI) // This array isn't suitable, non-int initializer.
>> -      return 0;
>> -    if (CI->isZero())
>> -      return i-StartIdx+1; // We found end of string, success!
>> -  }
>> 
>> -  return 0; // The array isn't null terminated, conservatively return 'unknown'.
>> +  return StrData.size()+1;
>> }
>> 
>> /// GetStringLength - If we can compute the length of the string pointed to by
>> 
>> Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
>> +++ llvm/trunk/lib/AsmParser/LLParser.cpp Sat Feb  4 20:29:43 2012
>> @@ -2018,7 +2018,8 @@
>>   }
>>   case lltok::kw_c:  // c "foo"
>>     Lex.Lex();
>> -    ID.ConstantVal = ConstantArray::get(Context, Lex.getStrVal(), false);
>> +    ID.ConstantVal = ConstantDataArray::getString(Context, Lex.getStrVal(),
>> +                                                  false);
>>     if (ParseToken(lltok::StringConstant, "expected string")) return true;
>>     ID.Kind = ValID::t_Constant;
>>     return false;
>> 
>> Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
>> +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Sat Feb  4 20:29:43 2012
>> @@ -845,32 +845,6 @@
>>       } else {
>>         assert (0 && "Unknown FP type!");
>>       }
>> -    } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
>> -      const ConstantArray *CA = cast<ConstantArray>(C);
>> -      // Emit constant strings specially.
>> -      unsigned NumOps = CA->getNumOperands();
>> -      // If this is a null-terminated string, use the denser CSTRING encoding.
>> -      if (CA->getOperand(NumOps-1)->isNullValue()) {
>> -        Code = bitc::CST_CODE_CSTRING;
>> -        --NumOps;  // Don't encode the null, which isn't allowed by char6.
>> -      } else {
>> -        Code = bitc::CST_CODE_STRING;
>> -        AbbrevToUse = String8Abbrev;
>> -      }
>> -      bool isCStr7 = Code == bitc::CST_CODE_CSTRING;
>> -      bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING;
>> -      for (unsigned i = 0; i != NumOps; ++i) {
>> -        unsigned char V = cast<ConstantInt>(CA->getOperand(i))->getZExtValue();
>> -        Record.push_back(V);
>> -        isCStr7 &= (V & 128) == 0;
>> -        if (isCStrChar6)
>> -          isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
>> -      }
>> -
>> -      if (isCStrChar6)
>> -        AbbrevToUse = CString6Abbrev;
>> -      else if (isCStr7)
>> -        AbbrevToUse = CString7Abbrev;
>>     } else if (isa<ConstantDataSequential>(C) &&
>>                cast<ConstantDataSequential>(C)->isString()) {
>>       const ConstantDataSequential *Str = cast<ConstantDataSequential>(C);
>> 
>> Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
>> +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Sat Feb  4 20:29:43 2012
>> @@ -321,10 +321,6 @@
>>   if (const Constant *C = dyn_cast<Constant>(V)) {
>>     if (isa<GlobalValue>(C)) {
>>       // Initializers for globals are handled explicitly elsewhere.
>> -    } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
>> -      // Do not enumerate the initializers for an array of simple characters.
>> -      // The initializers just pollute the value table, and we emit the strings
>> -      // specially.
>>     } else if (C->getNumOperands()) {
>>       // If a constant has operands, enumerate them.  This makes sure that if a
>>       // constant has uses (for example an array of const ints), that they are
>> 
>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Sat Feb  4 20:29:43 2012
>> @@ -1684,31 +1684,18 @@
>> 
>> static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
>>                                     AsmPrinter &AP) {
>> -  if (AddrSpace != 0 || !CA->isString()) {
>> -    // Not a string.  Print the values in successive locations.
>> -
>> -    // See if we can aggregate some values.  Make sure it can be
>> -    // represented as a series of bytes of the constant value.
>> -    int Value = isRepeatedByteSequence(CA, AP.TM);
>> -
>> -    if (Value != -1) {
>> -      uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType());
>> -      AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
>> -    }
>> -    else {
>> -      for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
>> -        EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
>> -    }
>> -    return;
>> +  // See if we can aggregate some values.  Make sure it can be
>> +  // represented as a series of bytes of the constant value.
>> +  int Value = isRepeatedByteSequence(CA, AP.TM);
>> +
>> +  if (Value != -1) {
>> +    uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType());
>> +    AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
>> +  }
>> +  else {
>> +    for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
>> +      EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
>>   }
>> -
>> -  // Otherwise, it can be emitted as .ascii.
>> -  SmallVector<char, 128> TmpVec;
>> -  TmpVec.reserve(CA->getNumOperands());
>> -  for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
>> -    TmpVec.push_back(cast<ConstantInt>(CA->getOperand(i))->getZExtValue());
>> -
>> -  AP.OutStreamer.EmitBytes(StringRef(TmpVec.data(), TmpVec.size()), AddrSpace);
>> }
>> 
>> static void EmitGlobalConstantVector(const ConstantVector *CV,
>> 
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Feb  4 20:29:43 2012
>> @@ -3298,8 +3298,7 @@
>> /// used when a memcpy is turned into a memset when the source is a constant
>> /// string ptr.
>> static SDValue getMemsetStringVal(EVT VT, DebugLoc dl, SelectionDAG &DAG,
>> -                                  const TargetLowering &TLI,
>> -                                  std::string &Str, unsigned Offset) {
>> +                                  const TargetLowering &TLI, StringRef Str) {
>>   // Handle vector with all elements zero.
>>   if (Str.empty()) {
>>     if (VT.isInteger())
>> @@ -3317,15 +3316,18 @@
>>   }
>> 
>>   assert(!VT.isVector() && "Can't handle vector type here!");
>> -  unsigned NumBits = VT.getSizeInBits();
>> -  unsigned MSB = NumBits / 8;
>> +  unsigned NumVTBytes = VT.getSizeInBits() / 8;
>> +  unsigned NumBytes = std::min(NumVTBytes, unsigned(Str.size()));
>> +
>>   uint64_t Val = 0;
>> -  if (TLI.isLittleEndian())
>> -    Offset = Offset + MSB - 1;
>> -  for (unsigned i = 0; i != MSB; ++i) {
>> -    Val = (Val << 8) | (unsigned char)Str[Offset];
>> -    Offset += TLI.isLittleEndian() ? -1 : 1;
>> +  if (TLI.isLittleEndian()) {
>> +    for (unsigned i = 0; i != NumBytes; ++i)
>> +      Val |= (uint64_t)(unsigned char)Str[i] << i*8;
>> +  } else {
>> +    for (unsigned i = 0; i != NumBytes; ++i)
>> +      Val |= (uint64_t)(unsigned char)Str[i] << (NumVTBytes-i-1)*8;
>>   }
>> +
>>   return DAG.getConstant(Val, VT);
>> }
>> 
>> @@ -3340,7 +3342,7 @@
>> 
>> /// isMemSrcFromString - Returns true if memcpy source is a string constant.
>> ///
>> -static bool isMemSrcFromString(SDValue Src, std::string &Str) {
>> +static bool isMemSrcFromString(SDValue Src, StringRef &Str) {
>>   unsigned SrcDelta = 0;
>>   GlobalAddressSDNode *G = NULL;
>>   if (Src.getOpcode() == ISD::GlobalAddress)
>> @@ -3354,11 +3356,7 @@
>>   if (!G)
>>     return false;
>> 
>> -  const GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getGlobal());
>> -  if (GV && GetConstantStringInfo(GV, Str, SrcDelta, false))
>> -    return true;
>> -
>> -  return false;
>> +  return getConstantStringInfo(G->getGlobal(), Str, SrcDelta, false);
>> }
>> 
>> /// FindOptimalMemOpLowering - Determines the optimial series memory ops
>> @@ -3461,7 +3459,7 @@
>>   unsigned SrcAlign = DAG.InferPtrAlignment(Src);
>>   if (Align > SrcAlign)
>>     SrcAlign = Align;
>> -  std::string Str;
>> +  StringRef Str;
>>   bool CopyFromStr = isMemSrcFromString(Src, Str);
>>   bool isZeroStr = CopyFromStr && Str.empty();
>>   unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemcpy(OptSize);
>> @@ -3498,7 +3496,7 @@
>>       // We only handle zero vectors here.
>>       // FIXME: Handle other cases where store of vector immediate is done in
>>       // a single instruction.
>> -      Value = getMemsetStringVal(VT, dl, DAG, TLI, Str, SrcOff);
>> +      Value = getMemsetStringVal(VT, dl, DAG, TLI, Str.substr(SrcOff));
>>       Store = DAG.getStore(Chain, dl, Value,
>>                            getMemBasePlusOffset(Dst, DstOff, DAG),
>>                            DstPtrInfo.getWithOffset(DstOff), isVol,
>> 
>> Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
>> +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sat Feb  4 20:29:43 2012
>> @@ -558,73 +558,21 @@
>> }
>> 
>> void CWriter::printConstantArray(ConstantArray *CPA, bool Static) {
>> -  // As a special case, print the array as a string if it is an array of
>> -  // ubytes or an array of sbytes with positive values.
>> -  //
>> -  if (CPA->isCString()) {
>> -    Out << '\"';
>> -    // Keep track of whether the last number was a hexadecimal escape.
>> -    bool LastWasHex = false;
>> -
>> -    // Do not include the last character, which we know is null
>> -    for (unsigned i = 0, e = CPA->getNumOperands()-1; i != e; ++i) {
>> -      unsigned char C = cast<ConstantInt>(CPA->getOperand(i))->getZExtValue();
>> -
>> -      // Print it out literally if it is a printable character.  The only thing
>> -      // to be careful about is when the last letter output was a hex escape
>> -      // code, in which case we have to be careful not to print out hex digits
>> -      // explicitly (the C compiler thinks it is a continuation of the previous
>> -      // character, sheesh...)
>> -      //
>> -      if (isprint(C) && (!LastWasHex || !isxdigit(C))) {
>> -        LastWasHex = false;
>> -        if (C == '"' || C == '\\')
>> -          Out << "\\" << (char)C;
>> -        else
>> -          Out << (char)C;
>> -      } else {
>> -        LastWasHex = false;
>> -        switch (C) {
>> -        case '\n': Out << "\\n"; break;
>> -        case '\t': Out << "\\t"; break;
>> -        case '\r': Out << "\\r"; break;
>> -        case '\v': Out << "\\v"; break;
>> -        case '\a': Out << "\\a"; break;
>> -        case '\"': Out << "\\\""; break;
>> -        case '\'': Out << "\\\'"; break;
>> -        default:
>> -          Out << "\\x";
>> -          Out << (char)(( C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'));
>> -          Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
>> -          LastWasHex = true;
>> -          break;
>> -        }
>> -      }
>> -    }
>> -    Out << '\"';
>> -  } else {
>> -    Out << '{';
>> -    if (CPA->getNumOperands()) {
>> -      Out << ' ';
>> -      printConstant(cast<Constant>(CPA->getOperand(0)), Static);
>> -      for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) {
>> -        Out << ", ";
>> -        printConstant(cast<Constant>(CPA->getOperand(i)), Static);
>> -      }
>> -    }
>> -    Out << " }";
>> +  Out << "{ ";
>> +  printConstant(cast<Constant>(CPA->getOperand(0)), Static);
>> +  for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) {
>> +    Out << ", ";
>> +    printConstant(cast<Constant>(CPA->getOperand(i)), Static);
>>   }
>> +  Out << " }";
>> }
>> 
>> void CWriter::printConstantVector(ConstantVector *CP, bool Static) {
>> -  Out << '{';
>> -  if (CP->getNumOperands()) {
>> -    Out << ' ';
>> -    printConstant(cast<Constant>(CP->getOperand(0)), Static);
>> -    for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
>> -      Out << ", ";
>> -      printConstant(cast<Constant>(CP->getOperand(i)), Static);
>> -    }
>> +  Out << "{ ";
>> +  printConstant(cast<Constant>(CP->getOperand(0)), Static);
>> +  for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
>> +    Out << ", ";
>> +    printConstant(cast<Constant>(CP->getOperand(i)), Static);
>>   }
>>   Out << " }";
>> }
>> 
>> Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original)
>> +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Sat Feb  4 20:29:43 2012
>> @@ -698,36 +698,17 @@
>>     printCFP(CFP);
>>     Out << ";";
>>   } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
>> -    if (CA->isString()) {
>> -      Out << "Constant* " << constName <<
>> -             " = ConstantArray::get(mod->getContext(), \"";
>> -      std::string tmp = CA->getAsString();
>> -      bool nullTerminate = false;
>> -      if (tmp[tmp.length()-1] == 0) {
>> -        tmp.erase(tmp.length()-1);
>> -        nullTerminate = true;
>> -      }
>> -      printEscapedString(tmp);
>> -      // Determine if we want null termination or not.
>> -      if (nullTerminate)
>> -        Out << "\", true"; // Indicate that the null terminator should be
>> -                           // added.
>> -      else
>> -        Out << "\", false";// No null terminator
>> -      Out << ");";
>> -    } else {
>> -      Out << "std::vector<Constant*> " << constName << "_elems;";
>> +    Out << "std::vector<Constant*> " << constName << "_elems;";
>> +    nl(Out);
>> +    unsigned N = CA->getNumOperands();
>> +    for (unsigned i = 0; i < N; ++i) {
>> +      printConstant(CA->getOperand(i)); // recurse to print operands
>> +      Out << constName << "_elems.push_back("
>> +          << getCppName(CA->getOperand(i)) << ");";
>>       nl(Out);
>> -      unsigned N = CA->getNumOperands();
>> -      for (unsigned i = 0; i < N; ++i) {
>> -        printConstant(CA->getOperand(i)); // recurse to print operands
>> -        Out << constName << "_elems.push_back("
>> -            << getCppName(CA->getOperand(i)) << ");";
>> -        nl(Out);
>> -      }
>> -      Out << "Constant* " << constName << " = ConstantArray::get("
>> -          << typeName << ", " << constName << "_elems);";
>>     }
>> +    Out << "Constant* " << constName << " = ConstantArray::get("
>> +        << typeName << ", " << constName << "_elems);";
>>   } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
>>     Out << "std::vector<Constant*> " << constName << "_fields;";
>>     nl(Out);
>> @@ -740,14 +721,14 @@
>>     }
>>     Out << "Constant* " << constName << " = ConstantStruct::get("
>>         << typeName << ", " << constName << "_fields);";
>> -  } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
>> +  } else if (const ConstantVector *CV = dyn_cast<ConstantVector>(CV)) {
>>     Out << "std::vector<Constant*> " << constName << "_elems;";
>>     nl(Out);
>> -    unsigned N = CP->getNumOperands();
>> +    unsigned N = CV->getNumOperands();
>>     for (unsigned i = 0; i < N; ++i) {
>> -      printConstant(CP->getOperand(i));
>> +      printConstant(CV->getOperand(i));
>>       Out << constName << "_elems.push_back("
>> -          << getCppName(CP->getOperand(i)) << ");";
>> +          << getCppName(CV->getOperand(i)) << ");";
>>       nl(Out);
>>     }
>>     Out << "Constant* " << constName << " = ConstantVector::get("
>> @@ -760,7 +741,7 @@
>>     if (CDS->isString()) {
>>       Out << "Constant *" << constName <<
>>       " = ConstantDataArray::getString(mod->getContext(), \"";
>> -      StringRef Str = CA->getAsString();
>> +      StringRef Str = CDS->getAsString();
>>       bool nullTerminate = false;
>>       if (Str.back() == 0) {
>>         Str = Str.drop_back();
>> 
>> Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Sat Feb  4 20:29:43 2012
>> @@ -213,7 +213,7 @@
>> 
>> // Create a constant for Str so that we can pass it to the run-time lib.
>> static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str) {
>> -  Constant *StrConst = ConstantArray::get(M.getContext(), Str);
>> +  Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
>>   return new GlobalVariable(M, StrConst->getType(), true,
>>                             GlobalValue::PrivateLinkage, StrConst, "");
>> }
>> 
>> Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Sat Feb  4 20:29:43 2012
>> @@ -256,19 +256,18 @@
>>                         ConstantInt::get(TD->getIntPtrType(*Context), Len),
>>                         B, TD);
>>     }
>> -
>> +    
>>     // Otherwise, the character is a constant, see if the first argument is
>>     // a string literal.  If so, we can constant fold.
>> -    std::string Str;
>> -    if (!GetConstantStringInfo(SrcStr, Str))
>> +    StringRef Str;
>> +    if (!getConstantStringInfo(SrcStr, Str))
>>       return 0;
>> 
>> -    // strchr can find the nul character.
>> -    Str += '\0';
>> -
>> -    // Compute the offset.
>> -    size_t I = Str.find(CharC->getSExtValue());
>> -    if (I == std::string::npos) // Didn't find the char.  strchr returns null.
>> +    // Compute the offset, make sure to handle the case when we're searching for
>> +    // zero (a weird way to spell strlen).
>> +    size_t I = CharC->getSExtValue() == 0 ?
>> +        Str.size() : Str.find(CharC->getSExtValue());
>> +    if (I == StringRef::npos) // Didn't find the char.  strchr returns null.
>>       return Constant::getNullValue(CI->getType());
>> 
>>     // strchr(s+n,c)  -> gep(s+n+i,c)
>> @@ -296,20 +295,18 @@
>>     if (!CharC)
>>       return 0;
>> 
>> -    std::string Str;
>> -    if (!GetConstantStringInfo(SrcStr, Str)) {
>> +    StringRef Str;
>> +    if (!getConstantStringInfo(SrcStr, Str)) {
>>       // strrchr(s, 0) -> strchr(s, 0)
>>       if (TD && CharC->isZero())
>>         return EmitStrChr(SrcStr, '\0', B, TD);
>>       return 0;
>>     }
>> 
>> -    // strrchr can find the nul character.
>> -    Str += '\0';
>> -
>>     // Compute the offset.
>> -    size_t I = Str.rfind(CharC->getSExtValue());
>> -    if (I == std::string::npos) // Didn't find the char. Return null.
>> +    size_t I = CharC->getSExtValue() == 0 ?
>> +        Str.size() : Str.rfind(CharC->getSExtValue());
>> +    if (I == StringRef::npos) // Didn't find the char. Return null.
>>       return Constant::getNullValue(CI->getType());
>> 
>>     // strrchr(s+n,c) -> gep(s+n+i,c)
>> @@ -334,14 +331,13 @@
>>     if (Str1P == Str2P)      // strcmp(x,x)  -> 0
>>       return ConstantInt::get(CI->getType(), 0);
>> 
>> -    std::string Str1, Str2;
>> -    bool HasStr1 = GetConstantStringInfo(Str1P, Str1);
>> -    bool HasStr2 = GetConstantStringInfo(Str2P, Str2);
>> +    StringRef Str1, Str2;
>> +    bool HasStr1 = getConstantStringInfo(Str1P, Str1);
>> +    bool HasStr2 = getConstantStringInfo(Str2P, Str2);
>> 
>>     // strcmp(x, y)  -> cnst  (if both x and y are constant strings)
>>     if (HasStr1 && HasStr2)
>> -      return ConstantInt::get(CI->getType(),
>> -                              StringRef(Str1).compare(Str2));
>> +      return ConstantInt::get(CI->getType(), Str1.compare(Str2));
>> 
>>     if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x
>>       return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"),
>> @@ -397,14 +393,14 @@
>>     if (TD && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1)
>>       return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, TD);
>> 
>> -    std::string Str1, Str2;
>> -    bool HasStr1 = GetConstantStringInfo(Str1P, Str1);
>> -    bool HasStr2 = GetConstantStringInfo(Str2P, Str2);
>> +    StringRef Str1, Str2;
>> +    bool HasStr1 = getConstantStringInfo(Str1P, Str1);
>> +    bool HasStr2 = getConstantStringInfo(Str2P, Str2);
>> 
>>     // strncmp(x, y)  -> cnst  (if both x and y are constant strings)
>>     if (HasStr1 && HasStr2) {
>> -      StringRef SubStr1 = StringRef(Str1).substr(0, Length);
>> -      StringRef SubStr2 = StringRef(Str2).substr(0, Length);
>> +      StringRef SubStr1 = Str1.substr(0, Length);
>> +      StringRef SubStr2 = Str2.substr(0, Length);
>>       return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2));
>>     }
>> 
>> @@ -549,9 +545,9 @@
>>         FT->getReturnType() != FT->getParamType(0))
>>       return 0;
>> 
>> -    std::string S1, S2;
>> -    bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1);
>> -    bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2);
>> +    StringRef S1, S2;
>> +    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
>> +    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
>> 
>>     // strpbrk(s, "") -> NULL
>>     // strpbrk("", s) -> NULL
>> @@ -609,9 +605,9 @@
>>         !FT->getReturnType()->isIntegerTy())
>>       return 0;
>> 
>> -    std::string S1, S2;
>> -    bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1);
>> -    bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2);
>> +    StringRef S1, S2;
>> +    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
>> +    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
>> 
>>     // strspn(s, "") -> 0
>>     // strspn("", s) -> 0
>> @@ -619,8 +615,11 @@
>>       return Constant::getNullValue(CI->getType());
>> 
>>     // Constant folding.
>> -    if (HasS1 && HasS2)
>> -      return ConstantInt::get(CI->getType(), strspn(S1.c_str(), S2.c_str()));
>> +    if (HasS1 && HasS2) {
>> +      size_t Pos = S1.find_first_not_of(S2);
>> +      if (Pos == StringRef::npos) Pos = S1.size();
>> +      return ConstantInt::get(CI->getType(), Pos);
>> +    }
>> 
>>     return 0;
>>   }
>> @@ -638,17 +637,20 @@
>>         !FT->getReturnType()->isIntegerTy())
>>       return 0;
>> 
>> -    std::string S1, S2;
>> -    bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1);
>> -    bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2);
>> +    StringRef S1, S2;
>> +    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
>> +    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
>> 
>>     // strcspn("", s) -> 0
>>     if (HasS1 && S1.empty())
>>       return Constant::getNullValue(CI->getType());
>> 
>>     // Constant folding.
>> -    if (HasS1 && HasS2)
>> -      return ConstantInt::get(CI->getType(), strcspn(S1.c_str(), S2.c_str()));
>> +    if (HasS1 && HasS2) {
>> +      size_t Pos = S1.find_first_of(S2);
>> +      if (Pos == StringRef::npos) Pos = S1.size();
>> +      return ConstantInt::get(CI->getType(), Pos);
>> +    }
>> 
>>     // strcspn(s, "") -> strlen(s)
>>     if (TD && HasS2 && S2.empty())
>> @@ -692,9 +694,9 @@
>>     }
>> 
>>     // See if either input string is a constant string.
>> -    std::string SearchStr, ToFindStr;
>> -    bool HasStr1 = GetConstantStringInfo(CI->getArgOperand(0), SearchStr);
>> -    bool HasStr2 = GetConstantStringInfo(CI->getArgOperand(1), ToFindStr);
>> +    StringRef SearchStr, ToFindStr;
>> +    bool HasStr1 = getConstantStringInfo(CI->getArgOperand(0), SearchStr);
>> +    bool HasStr2 = getConstantStringInfo(CI->getArgOperand(1), ToFindStr);
>> 
>>     // fold strstr(x, "") -> x.
>>     if (HasStr2 && ToFindStr.empty())
>> @@ -704,7 +706,7 @@
>>     if (HasStr1 && HasStr2) {
>>       std::string::size_type Offset = SearchStr.find(ToFindStr);
>> 
>> -      if (Offset == std::string::npos) // strstr("foo", "bar") -> null
>> +      if (Offset == StringRef::npos) // strstr("foo", "bar") -> null
>>         return Constant::getNullValue(CI->getType());
>> 
>>       // strstr("abcd", "bc") -> gep((char*)"abcd", 1)
>> @@ -756,11 +758,11 @@
>>     }
>> 
>>     // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant)
>> -    std::string LHSStr, RHSStr;
>> -    if (GetConstantStringInfo(LHS, LHSStr) &&
>> -        GetConstantStringInfo(RHS, RHSStr)) {
>> +    StringRef LHSStr, RHSStr;
>> +    if (getConstantStringInfo(LHS, LHSStr) &&
>> +        getConstantStringInfo(RHS, RHSStr)) {
>>       // Make sure we're not reading out-of-bounds memory.
>> -      if (Len > LHSStr.length() || Len > RHSStr.length())
>> +      if (Len > LHSStr.size() || Len > RHSStr.size())
>>         return 0;
>>       uint64_t Ret = memcmp(LHSStr.data(), RHSStr.data(), Len);
>>       return ConstantInt::get(CI->getType(), Ret);
>> @@ -1116,8 +1118,8 @@
>>   Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
>>                                    IRBuilder<> &B) {
>>     // Check for a fixed format string.
>> -    std::string FormatStr;
>> -    if (!GetConstantStringInfo(CI->getArgOperand(0), FormatStr))
>> +    StringRef FormatStr;
>> +    if (!getConstantStringInfo(CI->getArgOperand(0), FormatStr))
>>       return 0;
>> 
>>     // Empty format string -> noop.
>> @@ -1143,7 +1145,7 @@
>>         FormatStr.find('%') == std::string::npos) {  // no format characters.
>>       // Create a string literal with no \n on it.  We expect the constant merge
>>       // pass to be run after this pass, to merge duplicate strings.
>> -      FormatStr.erase(FormatStr.end()-1);
>> +      FormatStr = FormatStr.drop_back();
>>       Value *GV = B.CreateGlobalString(FormatStr, "str");
>>       EmitPutS(GV, B, TD);
>>       return CI->use_empty() ? (Value*)CI :
>> @@ -1203,8 +1205,8 @@
>>   Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
>>                                    IRBuilder<> &B) {
>>     // Check for a fixed format string.
>> -    std::string FormatStr;
>> -    if (!GetConstantStringInfo(CI->getArgOperand(1), FormatStr))
>> +    StringRef FormatStr;
>> +    if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr))
>>       return 0;
>> 
>>     // If we just have a format string (nothing else crazy) transform it.
>> @@ -1358,8 +1360,8 @@
>>   Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
>>                                    IRBuilder<> &B) {
>>     // All the optimizations depend on the format string.
>> -    std::string FormatStr;
>> -    if (!GetConstantStringInfo(CI->getArgOperand(1), FormatStr))
>> +    StringRef FormatStr;
>> +    if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr))
>>       return 0;
>> 
>>     // fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
>> @@ -1442,8 +1444,8 @@
>>       return 0;
>> 
>>     // Check for a constant string.
>> -    std::string Str;
>> -    if (!GetConstantStringInfo(CI->getArgOperand(0), Str))
>> +    StringRef Str;
>> +    if (!getConstantStringInfo(CI->getArgOperand(0), Str))
>>       return 0;
>> 
>>     if (Str.empty() && CI->use_empty()) {
>> @@ -2413,6 +2415,8 @@
>> //   * stpcpy(str, "literal") ->
>> //           llvm.memcpy(str,"literal",strlen("literal")+1,1)
>> //
>> +// strchr:
>> +//   * strchr(p, 0) -> strlen(p)
>> // tan, tanf, tanl:
>> //   * tan(atan(x)) -> x
>> //
>> 
>> Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
>> +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Sat Feb  4 20:29:43 2012
>> @@ -827,30 +827,21 @@
>>   }
>> 
>>   if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
>> -    // As a special case, print the array as a string if it is an array of
>> -    // i8 with ConstantInt values.
>> -    //
>>     Type *ETy = CA->getType()->getElementType();
>> -    if (CA->isString()) {
>> -      Out << "c\"";
>> -      PrintEscapedString(CA->getAsString(), Out);
>> -      Out << '"';
>> -    } else {                // Cannot output in string format...
>> -      Out << '[';
>> +    Out << '[';
>> +    TypePrinter.print(ETy, Out);
>> +    Out << ' ';
>> +    WriteAsOperandInternal(Out, CA->getOperand(0),
>> +                           &TypePrinter, Machine,
>> +                           Context);
>> +    for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
>> +      Out << ", ";
>>       TypePrinter.print(ETy, Out);
>>       Out << ' ';
>> -      WriteAsOperandInternal(Out, CA->getOperand(0),
>> -                             &TypePrinter, Machine,
>> +      WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
>>                              Context);
>> -      for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
>> -        Out << ", ";
>> -        TypePrinter.print(ETy, Out);
>> -        Out << ' ';
>> -        WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
>> -                               Context);
>> -      }
>> -      Out << ']';
>>     }
>> +    Out << ']';
>>     return;
>>   }
>> 
>> 
>> Modified: llvm/trunk/lib/VMCore/Constants.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/VMCore/Constants.cpp (original)
>> +++ llvm/trunk/lib/VMCore/Constants.cpp Sat Feb  4 20:29:43 2012
>> @@ -176,7 +176,7 @@
>>     return UV->getElementValue(Elt);
>> 
>>   if (const ConstantDataSequential *CDS =dyn_cast<ConstantDataSequential>(this))
>> -    return CDS->getElementAsConstant(Elt);
>> +    return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) : 0;
>>   return 0;
>> }
>> 
>> @@ -666,6 +666,13 @@
>> //                            ConstantXXX Classes
>> //===----------------------------------------------------------------------===//
>> 
>> +template <typename ItTy, typename EltTy>
>> +static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) {
>> +  for (; Start != End; ++Start)
>> +    if (*Start != Elt)
>> +      return false;
>> +  return true;
>> +}
>> 
>> ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
>>   : Constant(T, ConstantArrayVal,
>> @@ -680,54 +687,97 @@
>> }
>> 
>> Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
>> +  // Empty arrays are canonicalized to ConstantAggregateZero.
>> +  if (V.empty())
>> +    return ConstantAggregateZero::get(Ty);
>> +
>>   for (unsigned i = 0, e = V.size(); i != e; ++i) {
>>     assert(V[i]->getType() == Ty->getElementType() &&
>>            "Wrong type in array element initializer");
>>   }
>>   LLVMContextImpl *pImpl = Ty->getContext().pImpl;
>> -  // If this is an all-zero array, return a ConstantAggregateZero object
>> -  bool isAllZero = true;
>> -  bool isUndef = false;
>> -  if (!V.empty()) {
>> -    Constant *C = V[0];
>> -    isAllZero = C->isNullValue();
>> -    isUndef = isa<UndefValue>(C);
>> -
>> -    if (isAllZero || isUndef)
>> -      for (unsigned i = 1, e = V.size(); i != e; ++i)
>> -        if (V[i] != C) {
>> -          isAllZero = false;
>> -          isUndef = false;
>> -          break;
>> -        }
>> -  }
>> +  
>> +  // If this is an all-zero array, return a ConstantAggregateZero object.  If
>> +  // all undef, return an UndefValue, if "all simple", then return a
>> +  // ConstantDataArray.
>> +  Constant *C = V[0];
>> +  if (isa<UndefValue>(C) && rangeOnlyContains(V.begin(), V.end(), C))
>> +    return UndefValue::get(Ty);
>> 
>> -  if (isAllZero)
>> +  if (C->isNullValue() && rangeOnlyContains(V.begin(), V.end(), C))
>>     return ConstantAggregateZero::get(Ty);
>> -  if (isUndef)
>> -    return UndefValue::get(Ty);
>> -  return pImpl->ArrayConstants.getOrCreate(Ty, V);
>> -}
>> 
>> -/// ConstantArray::get(const string&) - Return an array that is initialized to
>> -/// contain the specified string.  If length is zero then a null terminator is 
>> -/// added to the specified string so that it may be used in a natural way. 
>> -/// Otherwise, the length parameter specifies how much of the string to use 
>> -/// and it won't be null terminated.
>> -///
>> -Constant *ConstantArray::get(LLVMContext &Context, StringRef Str,
>> -                             bool AddNull) {
>> -  SmallVector<Constant*, 8> ElementVals;
>> -  ElementVals.reserve(Str.size() + size_t(AddNull));
>> -  for (unsigned i = 0; i < Str.size(); ++i)
>> -    ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), Str[i]));
>> -
>> -  // Add a null terminator to the string...
>> -  if (AddNull)
>> -    ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0));
>> +  // Check to see if all of the elements are ConstantFP or ConstantInt and if
>> +  // the element type is compatible with ConstantDataVector.  If so, use it.
>> +  if (ConstantDataSequential::isElementTypeCompatible(C->getType())) {
>> +    // We speculatively build the elements here even if it turns out that there
>> +    // is a constantexpr or something else weird in the array, since it is so
>> +    // uncommon for that to happen.
>> +    if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) {
>> +      if (CI->getType()->isIntegerTy(8)) {
>> +        SmallVector<uint8_t, 16> Elts;
>> +        for (unsigned i = 0, e = V.size(); i != e; ++i)
>> +          if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
>> +            Elts.push_back(CI->getZExtValue());
>> +          else
>> +            break;
>> +        if (Elts.size() == V.size())
>> +          return ConstantDataArray::get(C->getContext(), Elts);
>> +      } else if (CI->getType()->isIntegerTy(16)) {
>> +        SmallVector<uint16_t, 16> Elts;
>> +        for (unsigned i = 0, e = V.size(); i != e; ++i)
>> +          if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
>> +            Elts.push_back(CI->getZExtValue());
>> +          else
>> +            break;
>> +        if (Elts.size() == V.size())
>> +          return ConstantDataArray::get(C->getContext(), Elts);
>> +      } else if (CI->getType()->isIntegerTy(32)) {
>> +        SmallVector<uint32_t, 16> Elts;
>> +        for (unsigned i = 0, e = V.size(); i != e; ++i)
>> +          if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
>> +            Elts.push_back(CI->getZExtValue());
>> +          else
>> +            break;
>> +        if (Elts.size() == V.size())
>> +          return ConstantDataArray::get(C->getContext(), Elts);
>> +      } else if (CI->getType()->isIntegerTy(64)) {
>> +        SmallVector<uint64_t, 16> Elts;
>> +        for (unsigned i = 0, e = V.size(); i != e; ++i)
>> +          if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i]))
>> +            Elts.push_back(CI->getZExtValue());
>> +          else
>> +            break;
>> +        if (Elts.size() == V.size())
>> +          return ConstantDataArray::get(C->getContext(), Elts);
>> +      }
>> +    }
>> +    
>> +    if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
>> +      if (CFP->getType()->isFloatTy()) {
>> +        SmallVector<float, 16> Elts;
>> +        for (unsigned i = 0, e = V.size(); i != e; ++i)
>> +          if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
>> +            Elts.push_back(CFP->getValueAPF().convertToFloat());
>> +          else
>> +            break;
>> +        if (Elts.size() == V.size())
>> +          return ConstantDataArray::get(C->getContext(), Elts);
>> +      } else if (CFP->getType()->isDoubleTy()) {
>> +        SmallVector<double, 16> Elts;
>> +        for (unsigned i = 0, e = V.size(); i != e; ++i)
>> +          if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i]))
>> +            Elts.push_back(CFP->getValueAPF().convertToDouble());
>> +          else
>> +            break;
>> +        if (Elts.size() == V.size())
>> +          return ConstantDataArray::get(C->getContext(), Elts);
>> +      }
>> +    }
>> +  }
>> 
>> -  ArrayType *ATy = ArrayType::get(Type::getInt8Ty(Context), ElementVals.size());
>> -  return get(ATy, ElementVals);
>> +  // Otherwise, we really do want to create a ConstantArray.
>> +  return pImpl->ArrayConstants.getOrCreate(Ty, V);
>> }
>> 
>> /// getTypeForElements - Return an anonymous struct type to use for a constant
>> @@ -839,8 +889,7 @@
>> 
>>   // Check to see if all of the elements are ConstantFP or ConstantInt and if
>>   // the element type is compatible with ConstantDataVector.  If so, use it.
>> -  if (ConstantDataSequential::isElementTypeCompatible(C->getType()) &&
>> -      (isa<ConstantFP>(C) || isa<ConstantInt>(C))) {
>> +  if (ConstantDataSequential::isElementTypeCompatible(C->getType())) {
>>     // We speculatively build the elements here even if it turns out that there
>>     // is a constantexpr or something else weird in the array, since it is so
>>     // uncommon for that to happen.
>> @@ -1146,69 +1195,6 @@
>>   destroyConstantImpl();
>> }
>> 
>> -/// isString - This method returns true if the array is an array of i8, and 
>> -/// if the elements of the array are all ConstantInt's.
>> -bool ConstantArray::isString() const {
>> -  // Check the element type for i8...
>> -  if (!getType()->getElementType()->isIntegerTy(8))
>> -    return false;
>> -  // Check the elements to make sure they are all integers, not constant
>> -  // expressions.
>> -  for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
>> -    if (!isa<ConstantInt>(getOperand(i)))
>> -      return false;
>> -  return true;
>> -}
>> -
>> -/// isCString - This method returns true if the array is a string (see
>> -/// isString) and it ends in a null byte \\0 and does not contains any other
>> -/// null bytes except its terminator.
>> -bool ConstantArray::isCString() const {
>> -  // Check the element type for i8...
>> -  if (!getType()->getElementType()->isIntegerTy(8))
>> -    return false;
>> -
>> -  // Last element must be a null.
>> -  if (!getOperand(getNumOperands()-1)->isNullValue())
>> -    return false;
>> -  // Other elements must be non-null integers.
>> -  for (unsigned i = 0, e = getNumOperands()-1; i != e; ++i) {
>> -    if (!isa<ConstantInt>(getOperand(i)))
>> -      return false;
>> -    if (getOperand(i)->isNullValue())
>> -      return false;
>> -  }
>> -  return true;
>> -}
>> -
>> -
>> -/// convertToString - Helper function for getAsString() and getAsCString().
>> -static std::string convertToString(const User *U, unsigned len) {
>> -  std::string Result;
>> -  Result.reserve(len);
>> -  for (unsigned i = 0; i != len; ++i)
>> -    Result.push_back((char)cast<ConstantInt>(U->getOperand(i))->getZExtValue());
>> -  return Result;
>> -}
>> -
>> -/// getAsString - If this array is isString(), then this method converts the
>> -/// array to an std::string and returns it.  Otherwise, it asserts out.
>> -///
>> -std::string ConstantArray::getAsString() const {
>> -  assert(isString() && "Not a string!");
>> -  return convertToString(this, getNumOperands());
>> -}
>> -
>> -
>> -/// getAsCString - If this array is isCString(), then this method converts the
>> -/// array (without the trailing null byte) to an std::string and returns it.
>> -/// Otherwise, it asserts out.
>> -///
>> -std::string ConstantArray::getAsCString() const {
>> -  assert(isCString() && "Not a string!");
>> -  return convertToString(this, getNumOperands() - 1);
>> -}
>> -
>> 
>> //---- ConstantStruct::get() implementation...
>> //
>> 
>> Modified: llvm/trunk/lib/VMCore/Core.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/VMCore/Core.cpp (original)
>> +++ llvm/trunk/lib/VMCore/Core.cpp Sat Feb  4 20:29:43 2012
>> @@ -634,8 +634,8 @@
>>                                       LLVMBool DontNullTerminate) {
>>   /* Inverted the sense of AddNull because ', 0)' is a
>>      better mnemonic for null termination than ', 1)'. */
>> -  return wrap(ConstantArray::get(*unwrap(C), StringRef(Str, Length),
>> -                                 DontNullTerminate == 0));
>> +  return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length),
>> +                                           DontNullTerminate == 0));
>> }
>> LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, 
>>                                       LLVMValueRef *ConstantVals,
>> 
>> Modified: llvm/trunk/lib/VMCore/IRBuilder.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/IRBuilder.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/VMCore/IRBuilder.cpp (original)
>> +++ llvm/trunk/lib/VMCore/IRBuilder.cpp Sat Feb  4 20:29:43 2012
>> @@ -24,7 +24,7 @@
>> /// specified.  If Name is specified, it is the name of the global variable
>> /// created.
>> Value *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) {
>> -  Constant *StrConstant = ConstantArray::get(Context, Str, true);
>> +  Constant *StrConstant = ConstantDataArray::getString(Context, Str);
>>   Module &M = *BB->getParent()->getParent();
>>   GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
>>                                           true, GlobalValue::PrivateLinkage,
>> 
>> Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original)
>> +++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Sat Feb  4 20:29:43 2012
>> @@ -820,7 +820,8 @@
>>       // Don't forward functions which are external in the test module too.
>>       if (TestFn && !TestFn->isDeclaration()) {
>>         // 1. Add a string constant with its name to the global file
>> -        Constant *InitArray = ConstantArray::get(F->getContext(), F->getName());
>> +        Constant *InitArray =
>> +          ConstantDataArray::getString(F->getContext(), F->getName());
>>         GlobalVariable *funcName =
>>           new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/,
>>                              GlobalValue::InternalLinkage, InitArray,
>> 
>> Modified: llvm/trunk/tools/lto/LTOModule.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=149800&r1=149799&r2=149800&view=diff
>> ==============================================================================
>> --- llvm/trunk/tools/lto/LTOModule.cpp (original)
>> +++ llvm/trunk/tools/lto/LTOModule.cpp Sat Feb  4 20:29:43 2012
>> @@ -190,9 +190,9 @@
>>     Constant *op = ce->getOperand(0);
>>     if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) {
>>       Constant *cn = gvn->getInitializer();
>> -      if (ConstantArray *ca = dyn_cast<ConstantArray>(cn)) {
>> +      if (ConstantDataArray *ca = dyn_cast<ConstantDataArray>(cn)) {
>>         if (ca->isCString()) {
>> -          name = ".objc_class_name_" + ca->getAsCString();
>> +          name = ".objc_class_name_" + ca->getAsCString().str();
>>           return true;
>>         }
>>       }
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20120205/55c42df2/attachment.html>


More information about the llvm-commits mailing list