Rebased, added unit tests and some overloads to avoid ambiguity.

http://reviews.llvm.org/D6372

Files:
  include/llvm/ADT/Twine.h
  include/llvm/MC/MCContext.h
  include/llvm/Option/ArgList.h
  lib/MC/MCContext.cpp
  lib/Support/Twine.cpp
  tools/clang/include/clang/Sema/CodeCompleteConsumer.h
  unittests/ADT/TwineTest.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/llvm/ADT/Twine.h
===================================================================
--- include/llvm/ADT/Twine.h
+++ include/llvm/ADT/Twine.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_ADT_TWINE_H
 #define LLVM_ADT_TWINE_H
 
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -100,6 +101,9 @@
       /// A pointer to a StringRef instance.
       StringRefKind,
 
+      /// A pointer to a SmallString instance.
+      SmallStringKind,
+
       /// A char value reinterpreted as a pointer, to render as a character.
       CharKind,
 
@@ -136,6 +140,7 @@
       const char *cString;
       const std::string *stdString;
       const StringRef *stringRef;
+      const SmallVectorImpl<char> *smallString;
       char character;
       unsigned int decUI;
       int decI;
@@ -289,6 +294,13 @@
       assert(isValid() && "Invalid twine!");
     }
 
+    /// Construct from a SmallString.
+    /*implicit*/ Twine(const SmallVectorImpl<char> &Str)
+      : LHSKind(SmallStringKind), RHSKind(EmptyKind) {
+      LHS.smallString = &Str;
+      assert(isValid() && "Invalid twine!");
+    }
+
     /// Construct from a char.
     explicit Twine(char Val)
       : LHSKind(CharKind), RHSKind(EmptyKind) {
@@ -402,6 +414,7 @@
       case CStringKind:
       case StdStringKind:
       case StringRefKind:
+      case SmallStringKind:
         return true;
       default:
         return false;
@@ -435,6 +448,8 @@
       case CStringKind:    return StringRef(LHS.cString);
       case StdStringKind:  return StringRef(*LHS.stdString);
       case StringRefKind:  return *LHS.stringRef;
+      case SmallStringKind:
+        return StringRef(LHS.smallString->data(), LHS.smallString->size());
       }
     }
 
Index: include/llvm/MC/MCContext.h
===================================================================
--- include/llvm/MC/MCContext.h
+++ include/llvm/MC/MCContext.h
@@ -234,6 +234,7 @@
     ///
     /// @param Name - The symbol name, which must be unique across all symbols.
     MCSymbol *GetOrCreateSymbol(StringRef Name);
+    MCSymbol *GetOrCreateSymbol(const SmallVectorImpl<char> &Name);
     MCSymbol *GetOrCreateSymbol(const Twine &Name);
 
     MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section);
Index: include/llvm/Option/ArgList.h
===================================================================
--- include/llvm/Option/ArgList.h
+++ include/llvm/Option/ArgList.h
@@ -283,6 +283,9 @@
   const char *MakeArgString(const char *Str) const {
     return MakeArgString(StringRef(Str));
   }
+  const char *MakeArgString(const SmallVectorImpl<char> &Str) const {
+    return MakeArgString(StringRef(Str.data(), Str.size()));
+  }
   const char *MakeArgString(std::string Str) const {
     return MakeArgString(StringRef(Str));
   }
Index: lib/MC/MCContext.cpp
===================================================================
--- lib/MC/MCContext.cpp
+++ lib/MC/MCContext.cpp
@@ -168,6 +168,10 @@
   return CreateSymbol(NameSV);
 }
 
+MCSymbol *MCContext::GetOrCreateSymbol(const SmallVectorImpl<char> &Name) {
+  return GetOrCreateSymbol(StringRef(Name.data(), Name.size()));
+}
+
 MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
   SmallString<128> NameSV;
   return GetOrCreateSymbol(Name.toStringRef(NameSV));
Index: lib/Support/Twine.cpp
===================================================================
--- lib/Support/Twine.cpp
+++ lib/Support/Twine.cpp
@@ -72,6 +72,9 @@
   case Twine::StringRefKind:
     OS << *Ptr.stringRef;
     break;
+  case Twine::SmallStringKind:
+    OS << *Ptr.smallString;
+    break;
   case Twine::CharKind:
     OS << Ptr.character;
     break;
@@ -122,6 +125,10 @@
     OS << "stringref:\""
        << Ptr.stringRef << "\"";
     break;
+  case Twine::SmallStringKind:
+    OS << "smallstring:\""
+       << *Ptr.smallString << "\"";
+    break;
   case Twine::CharKind:
     OS << "char:\"" << Ptr.character << "\"";
     break;
Index: unittests/ADT/TwineTest.cpp
===================================================================
--- unittests/ADT/TwineTest.cpp
+++ unittests/ADT/TwineTest.cpp
@@ -29,6 +29,7 @@
   EXPECT_EQ("hi", Twine(StringRef("hi")).str());
   EXPECT_EQ("hi", Twine(StringRef(std::string("hi"))).str());
   EXPECT_EQ("hi", Twine(StringRef("hithere", 2)).str());
+  EXPECT_EQ("hi", Twine(SmallString<4>("hi")).str());
 }
 
 TEST(TwineTest, Numbers) {
@@ -62,6 +63,10 @@
             repr(Twine("hi").concat(Twine())));
   EXPECT_EQ("(Twine cstring:\"hi\" empty)", 
             repr(Twine().concat(Twine("hi"))));
+  EXPECT_EQ("(Twine smallstring:\"hi\" empty)", 
+            repr(Twine().concat(Twine(SmallString<5>("hi")))));
+  EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")", 
+            repr(Twine(SmallString<7>("hey")).concat(Twine("there"))));
 
   // Concatenation of unary ropes.
   EXPECT_EQ("(Twine cstring:\"a\" cstring:\"b\")", 
@@ -72,13 +77,18 @@
             repr(Twine("a").concat(Twine("b")).concat(Twine("c"))));
   EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine cstring:\"b\" cstring:\"c\"))",
             repr(Twine("a").concat(Twine("b").concat(Twine("c")))));
+  EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine smallstring:\"b\" cstring:\"c\"))",
+            repr(Twine("a").concat(Twine(SmallString<3>("b")).concat(Twine("c")))));
 }
 
 TEST(TwineTest, toNullTerminatedStringRef) {
   SmallString<8> storage;
   EXPECT_EQ(0, *Twine("hello").toNullTerminatedStringRef(storage).end());
   EXPECT_EQ(0,
            *Twine(StringRef("hello")).toNullTerminatedStringRef(storage).end());
+  EXPECT_EQ(0, *Twine(SmallString<11>("hello"))
+                    .toNullTerminatedStringRef(storage)
+                    .end());
 }
 
   // I suppose linking in the entire code generator to add a unit test to check
Index: tools/clang/include/clang/Sema/CodeCompleteConsumer.h
===================================================================
--- tools/clang/include/clang/Sema/CodeCompleteConsumer.h
+++ tools/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -509,6 +509,11 @@
     return CopyString(StringRef(String));
   }
 
+  // \brief Copy the given string into this allocator.
+  const char *CopyString(const SmallVectorImpl<char> &String) {
+    return CopyString(StringRef(String.data(), String.size()));
+  }
+
   /// \brief Copy the given string into this allocator.
   const char *CopyString(const std::string &String) {
     return CopyString(StringRef(String));
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to