Add various "string" methods to ConstantDataSequential, which have the
same semantics as ConstantArray's but much more efficient because they
don't have to return std::string's.  The ConstantArray methods will
eventually be removed.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148792 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 958ebb8..21400e7 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -371,6 +371,9 @@
     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;
@@ -626,6 +629,30 @@
   /// byte.
   uint64_t getElementByteSize() const;
 
+  
+  /// isString - This method returns true if this is an array of i8.
+  bool isString() const;
+  
+  /// isCString - This method returns true if the array "isString", ends with a
+  /// nul byte, and does not contains any other nul bytes.
+  bool isCString() const;
+  
+  /// getAsString - If this array is isString(), then this method returns the
+  /// array as a StringRef.  Otherwise, it asserts out.
+  ///
+  StringRef getAsString() const;
+  
+  /// getAsCString - If this array is isCString(), then this method returns the
+  /// array (without the trailing null byte) as a StringRef. Otherwise, it
+  /// asserts out.
+  ///
+  StringRef getAsCString() const {
+    assert(isCString() && "Isn't a C string");
+    StringRef Str = getAsString();
+    return Str.substr(0, Str.size()-1);
+  }
+  
+  
   virtual void destroyConstant();
   
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 55b97ef..0525882 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -2221,7 +2221,34 @@
   return ConstantInt::get(getElementType(), getElementAsInteger(Elt));
 }
 
+/// isString - This method returns true if this is an array of i8.
+bool ConstantDataSequential::isString() const {
+  return isa<ArrayType>(getType()) && getElementType()->isIntegerTy(8);
+}
 
+/// getAsString - If this array is isString(), then this method returns the
+/// array as a StringRef.  Otherwise, it asserts out.
+///
+StringRef ConstantDataSequential::getAsString() const {
+  assert(isString() && "Not a string");
+  return StringRef(DataElements, getType()->getNumElements());
+}
+
+
+/// isCString - This method returns true if the array "isString", ends with a
+/// nul byte, and does not contains any other nul bytes.
+bool ConstantDataSequential::isCString() const {
+  if (!isString())
+    return false;
+  
+  StringRef Str = getAsString();
+  
+  // The last value must be nul.
+  if (Str.back() != 0) return false;
+  
+  // Other elements must be non-nul.
+  return Str.drop_back().find(0) == StringRef::npos;
+}
 
 
 //===----------------------------------------------------------------------===//