silence some -Wnon-pod-memset warnings, since std::pair is not POD.
[oota-llvm.git] / include / llvm / ADT / Twine.h
index 93ff52c83f96df1cfb9763bf06fdc245b96d6670..ab8d3653e33f2043829f48f8b03b32452d10d0e2 100644 (file)
@@ -11,6 +11,7 @@
 #define LLVM_ADT_TWINE_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
 #include <cassert>
 #include <string>
 
@@ -41,7 +42,7 @@ namespace llvm {
   /// Twines support a special 'null' value, which always concatenates to form
   /// itself, and renders as an empty string. This can be returned from APIs to
   /// effectively nullify any concatenations performed on the result.
-  /// 
+  ///
   /// \b Implementation \n
   ///
   /// Given the nature of a Twine, it is not possible for the Twine's
@@ -86,6 +87,9 @@ namespace llvm {
       /// The empty string.
       EmptyKind,
 
+      /// A pointer to a Twine instance.
+      TwineKind,
+
       /// A pointer to a C string instance.
       CStringKind,
 
@@ -95,8 +99,31 @@ namespace llvm {
       /// A pointer to a StringRef instance.
       StringRefKind,
 
-      /// A pointer to a Twine instance.
-      TwineKind
+      /// An unsigned int value reinterpreted as a pointer, to render as an
+      /// unsigned decimal integer.
+      DecUIKind,
+
+      /// An int value reinterpreted as a pointer, to render as a signed
+      /// decimal integer.
+      DecIKind,
+
+      /// A pointer to an unsigned long value, to render as an unsigned decimal
+      /// integer.
+      DecULKind,
+
+      /// A pointer to a long value, to render as a signed decimal integer.
+      DecLKind,
+
+      /// A pointer to an unsigned long long value, to render as an unsigned
+      /// decimal integer.
+      DecULLKind,
+
+      /// A pointer to a long long value, to render as a signed decimal integer.
+      DecLLKind,
+
+      /// A pointer to a uint64_t value, to render as an unsigned hexadecimal
+      /// integer.
+      UHexKind
     };
 
   private:
@@ -107,9 +134,9 @@ namespace llvm {
     /// Null or Empty kinds.
     const void *RHS;
     /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
-    NodeKind LHSKind : 8;
+    unsigned char LHSKind;
     /// RHSKind - The NodeKind of the left hand side, \see getLHSKind().
-    NodeKind RHSKind : 8;
+    unsigned char RHSKind;
 
   private:
     /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
@@ -183,10 +210,10 @@ namespace llvm {
     }
 
     /// getLHSKind - Get the NodeKind of the left-hand side.
-    NodeKind getLHSKind() const { return LHSKind; }
+    NodeKind getLHSKind() const { return (NodeKind) LHSKind; }
 
     /// getRHSKind - Get the NodeKind of the left-hand side.
-    NodeKind getRHSKind() const { return RHSKind; }
+    NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
 
     /// printOneChild - Print one child from a twine.
     void printOneChild(raw_ostream &OS, const void *Ptr, NodeKind Kind) const;
@@ -232,10 +259,34 @@ namespace llvm {
       assert(isValid() && "Invalid twine!");
     }
 
-    /// Create a 'null' string, which is an empty string that always
-    /// concatenates to form another empty string.
-    static Twine createNull() {
-      return Twine(NullKind);
+    /// Construct a twine to print \arg Val as an unsigned decimal integer.
+    explicit Twine(unsigned Val)
+      : LHS((void*)(intptr_t)Val), LHSKind(DecUIKind), RHSKind(EmptyKind) {
+    }
+
+    /// Construct a twine to print \arg Val as a signed decimal integer.
+    explicit Twine(int Val)
+      : LHS((void*)(intptr_t)Val), LHSKind(DecIKind), RHSKind(EmptyKind) {
+    }
+
+    /// Construct a twine to print \arg Val as an unsigned decimal integer.
+    explicit Twine(const unsigned long &Val)
+      : LHS(&Val), LHSKind(DecULKind), RHSKind(EmptyKind) {
+    }
+
+    /// Construct a twine to print \arg Val as a signed decimal integer.
+    explicit Twine(const long &Val)
+      : LHS(&Val), LHSKind(DecLKind), RHSKind(EmptyKind) {
+    }
+
+    /// Construct a twine to print \arg Val as an unsigned decimal integer.
+    explicit Twine(const unsigned long long &Val)
+      : LHS(&Val), LHSKind(DecULLKind), RHSKind(EmptyKind) {
+    }
+
+    /// Construct a twine to print \arg Val as a signed decimal integer.
+    explicit Twine(const long long &Val)
+      : LHS(&Val), LHSKind(DecLLKind), RHSKind(EmptyKind) {
     }
 
     // FIXME: Unfortunately, to make sure this is as efficient as possible we
@@ -255,6 +306,47 @@ namespace llvm {
       assert(isValid() && "Invalid twine!");
     }
 
+    /// Create a 'null' string, which is an empty string that always
+    /// concatenates to form another empty string.
+    static Twine createNull() {
+      return Twine(NullKind);
+    }
+
+    /// @}
+    /// @name Numeric Conversions
+    /// @{
+
+    // Construct a twine to print \arg Val as an unsigned hexadecimal integer.
+    static Twine utohexstr(const uint64_t &Val) {
+      return Twine(&Val, UHexKind, 0, EmptyKind);
+    }
+
+    /// @}
+    /// @name Predicate Operations
+    /// @{
+
+    /// isTriviallyEmpty - Check if this twine is trivially empty; a false
+    /// return value does not necessarily mean the twine is empty.
+    bool isTriviallyEmpty() const {
+      return isNullary();
+    }
+
+    /// isSingleStringRef - Return true if this twine can be dynamically
+    /// accessed as a single StringRef value with getSingleStringRef().
+    bool isSingleStringRef() const {
+      if (getRHSKind() != EmptyKind) return false;
+
+      switch (getLHSKind()) {
+      case EmptyKind:
+      case CStringKind:
+      case StdStringKind:
+      case StringRefKind:
+        return true;
+      default:
+        return false;
+      }
+    }
+
     /// @}
     /// @name String Operations
     /// @{
@@ -272,6 +364,32 @@ namespace llvm {
     /// SmallVector.
     void toVector(SmallVectorImpl<char> &Out) const;
 
+    /// getSingleStringRef - This returns the twine as a single StringRef.  This
+    /// method is only valid if isSingleStringRef() is true.
+    StringRef getSingleStringRef() const {
+      assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
+      switch (getLHSKind()) {
+      default: assert(0 && "Out of sync with isSingleStringRef");
+      case EmptyKind:      return StringRef();
+      case CStringKind:    return StringRef((const char*)LHS);
+      case StdStringKind:  return StringRef(*(const std::string*)LHS);
+      case StringRefKind:  return *(const StringRef*)LHS;
+      }
+    }
+
+    /// toStringRef - This returns the twine as a single StringRef if it can be
+    /// represented as such. Otherwise the twine is written into the given
+    /// SmallVector and a StringRef to the SmallVector's data is returned.
+    StringRef toStringRef(SmallVectorImpl<char> &Out) const;
+
+    /// toNullTerminatedStringRef - This returns the twine as a single null
+    /// terminated StringRef if it can be represented as such. Otherwise the
+    /// twine is written into the given SmallVector and a StringRef to the
+    /// SmallVector's data is returned.
+    ///
+    /// The returned StringRef's size does not include the null terminator.
+    StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
+
     /// print - Write the concatenated string represented by this twine to the
     /// stream \arg OS.
     void print(raw_ostream &OS) const;