[llvm] r239669 - Bring in a BumpPtrStringSaver from lld and simplify the interface.

Rafael Espindola rafael.espindola at gmail.com
Sat Jun 13 05:49:56 PDT 2015


Author: rafael
Date: Sat Jun 13 07:49:52 2015
New Revision: 239669

URL: http://llvm.org/viewvc/llvm-project?rev=239669&view=rev
Log:
Bring in a BumpPtrStringSaver from lld and simplify the interface.

StringSaver now always saves to a BumpPtrAllocator.

The only reason for having the virtual saveImpl is so lld can have a
thread safe version.

The reason for the distinct BumpPtrStringSaver class is to avoid the
virtual destructor.

Added:
    llvm/trunk/include/llvm/Support/StringSaver.h
    llvm/trunk/lib/Support/StringSaver.cpp
Modified:
    llvm/trunk/include/llvm/Support/CommandLine.h
    llvm/trunk/lib/LibDriver/LibDriver.cpp
    llvm/trunk/lib/Support/CMakeLists.txt
    llvm/trunk/lib/Support/CommandLine.cpp
    llvm/trunk/unittests/Support/CommandLineTest.cpp

Modified: llvm/trunk/include/llvm/Support/CommandLine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=239669&r1=239668&r2=239669&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/CommandLine.h (original)
+++ llvm/trunk/include/llvm/Support/CommandLine.h Sat Jun 13 07:49:52 2015
@@ -33,6 +33,9 @@
 
 namespace llvm {
 
+class BumpPtrStringSaver;
+class StringSaver;
+
 /// cl Namespace - This namespace contains all of the command line option
 /// processing machinery.  It is intentionally a short name to make qualified
 /// usage concise.
@@ -1676,16 +1679,6 @@ StringMap<Option *> &getRegisteredOption
 // Standalone command line processing utilities.
 //
 
-/// \brief Saves strings in the inheritor's stable storage and returns a stable
-/// raw character pointer.
-class StringSaver {
-  virtual void anchor();
-
-public:
-  virtual const char *SaveString(const char *Str) = 0;
-  virtual ~StringSaver(){}; // Pacify -Wnon-virtual-dtor.
-};
-
 /// \brief Tokenizes a command line that can contain escapes and quotes.
 //
 /// The quoting rules match those used by GCC and other tools that use

Added: llvm/trunk/include/llvm/Support/StringSaver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StringSaver.h?rev=239669&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Support/StringSaver.h (added)
+++ llvm/trunk/include/llvm/Support/StringSaver.h Sat Jun 13 07:49:52 2015
@@ -0,0 +1,42 @@
+//===- llvm/Support/StringSaver.h -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STRINGSAVER_H
+#define LLVM_SUPPORT_STRINGSAVER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+
+/// \brief Saves strings in the inheritor's stable storage and returns a stable
+/// raw character pointer.
+class StringSaver {
+protected:
+  ~StringSaver() {}
+  virtual const char *saveImpl(StringRef S);
+
+public:
+  StringSaver(BumpPtrAllocator &Alloc) : Alloc(Alloc) {}
+  const char *save(const char *S) { return save(StringRef(S)); }
+  const char *save(StringRef S) { return saveImpl(S); }
+  const char *save(const Twine &S) { return save(StringRef(S.str())); }
+  const char *save(std::string &S) { return save(StringRef(S)); }
+
+private:
+  BumpPtrAllocator &Alloc;
+};
+
+class BumpPtrStringSaver final : public StringSaver {
+public:
+  BumpPtrStringSaver(BumpPtrAllocator &Alloc) : StringSaver(Alloc) {}
+};
+}
+#endif

Modified: llvm/trunk/lib/LibDriver/LibDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LibDriver/LibDriver.cpp?rev=239669&r1=239668&r2=239669&view=diff
==============================================================================
--- llvm/trunk/lib/LibDriver/LibDriver.cpp (original)
+++ llvm/trunk/lib/LibDriver/LibDriver.cpp Sat Jun 13 07:49:52 2015
@@ -19,6 +19,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/StringSaver.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -67,30 +68,10 @@ static std::string getOutputPath(llvm::o
   llvm_unreachable("internal error");
 }
 
-namespace {
-// FIXME: Should re-use StringSaver from lld.
-class StrDupSaver : public cl::StringSaver {
-  std::vector<char *> Dups;
-
-public:
-  ~StrDupSaver() override {
-    for (std::vector<char *>::iterator I = Dups.begin(), E = Dups.end(); I != E;
-         ++I) {
-      char *Dup = *I;
-      free(Dup);
-    }
-  }
-  const char *SaveString(const char *Str) override {
-    char *Dup = strdup(Str);
-    Dups.push_back(Dup);
-    return Dup;
-  }
-};
-}
-
 int llvm::libDriverMain(int Argc, const char **Argv) {
   SmallVector<const char *, 20> NewArgv(Argv, Argv + Argc);
-  StrDupSaver Saver;
+  BumpPtrAllocator Alloc;
+  BumpPtrStringSaver Saver(Alloc);
   cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine, NewArgv);
   Argv = &NewArgv[0];
   Argc = static_cast<int>(NewArgv.size());

Modified: llvm/trunk/lib/Support/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=239669&r1=239668&r2=239669&view=diff
==============================================================================
--- llvm/trunk/lib/Support/CMakeLists.txt (original)
+++ llvm/trunk/lib/Support/CMakeLists.txt Sat Jun 13 07:49:52 2015
@@ -83,6 +83,7 @@ add_llvm_library(LLVMSupport
   StringExtras.cpp
   StringMap.cpp
   StringPool.cpp
+  StringSaver.cpp
   StringRef.cpp
   SystemUtils.cpp
   TargetParser.cpp

Modified: llvm/trunk/lib/Support/CommandLine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=239669&r1=239668&r2=239669&view=diff
==============================================================================
--- llvm/trunk/lib/Support/CommandLine.cpp (original)
+++ llvm/trunk/lib/Support/CommandLine.cpp Sat Jun 13 07:49:52 2015
@@ -32,6 +32,7 @@
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/StringSaver.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdlib>
 #include <map>
@@ -78,7 +79,6 @@ void parser<double>::anchor() {}
 void parser<float>::anchor() {}
 void parser<std::string>::anchor() {}
 void parser<char>::anchor() {}
-void StringSaver::anchor() {}
 
 //===----------------------------------------------------------------------===//
 
@@ -564,7 +564,7 @@ void cl::TokenizeGNUCommandLine(StringRe
     // End the token if this is whitespace.
     if (isWhitespace(Src[I])) {
       if (!Token.empty())
-        NewArgv.push_back(Saver.SaveString(Token.c_str()));
+        NewArgv.push_back(Saver.save(Token.c_str()));
       Token.clear();
       continue;
     }
@@ -575,7 +575,7 @@ void cl::TokenizeGNUCommandLine(StringRe
 
   // Append the last token after hitting EOF with no whitespace.
   if (!Token.empty())
-    NewArgv.push_back(Saver.SaveString(Token.c_str()));
+    NewArgv.push_back(Saver.save(Token.c_str()));
   // Mark the end of response files
   if (MarkEOLs)
     NewArgv.push_back(nullptr);
@@ -656,7 +656,7 @@ void cl::TokenizeWindowsCommandLine(Stri
     if (State == UNQUOTED) {
       // Whitespace means the end of the token.
       if (isWhitespace(Src[I])) {
-        NewArgv.push_back(Saver.SaveString(Token.c_str()));
+        NewArgv.push_back(Saver.save(Token.c_str()));
         Token.clear();
         State = INIT;
         // Mark the end of lines in response files
@@ -691,7 +691,7 @@ void cl::TokenizeWindowsCommandLine(Stri
   }
   // Append the last token after hitting EOF with no whitespace.
   if (!Token.empty())
-    NewArgv.push_back(Saver.SaveString(Token.c_str()));
+    NewArgv.push_back(Saver.save(Token.c_str()));
   // Mark the end of response files
   if (MarkEOLs)
     NewArgv.push_back(nullptr);
@@ -779,26 +779,6 @@ bool cl::ExpandResponseFiles(StringSaver
   return AllExpanded;
 }
 
-namespace {
-class StrDupSaver : public StringSaver {
-  std::vector<char *> Dups;
-
-public:
-  ~StrDupSaver() override {
-    for (std::vector<char *>::iterator I = Dups.begin(), E = Dups.end(); I != E;
-         ++I) {
-      char *Dup = *I;
-      free(Dup);
-    }
-  }
-  const char *SaveString(const char *Str) override {
-    char *Dup = strdup(Str);
-    Dups.push_back(Dup);
-    return Dup;
-  }
-};
-}
-
 /// ParseEnvironmentOptions - An alternative entry point to the
 /// CommandLine library, which allows you to read the program's name
 /// from the caller (as PROGNAME) and its command-line arguments from
@@ -818,8 +798,9 @@ void cl::ParseEnvironmentOptions(const c
   // Get program's "name", which we wouldn't know without the caller
   // telling us.
   SmallVector<const char *, 20> newArgv;
-  StrDupSaver Saver;
-  newArgv.push_back(Saver.SaveString(progName));
+  BumpPtrAllocator A;
+  BumpPtrStringSaver Saver(A);
+  newArgv.push_back(Saver.save(progName));
 
   // Parse the value of the environment variable into a "command line"
   // and hand it off to ParseCommandLineOptions().
@@ -840,7 +821,8 @@ void CommandLineParser::ParseCommandLine
 
   // Expand response files.
   SmallVector<const char *, 20> newArgv(argv, argv + argc);
-  StrDupSaver Saver;
+  BumpPtrAllocator A;
+  BumpPtrStringSaver Saver(A);
   ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv);
   argv = &newArgv[0];
   argc = static_cast<int>(newArgv.size());

Added: llvm/trunk/lib/Support/StringSaver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringSaver.cpp?rev=239669&view=auto
==============================================================================
--- llvm/trunk/lib/Support/StringSaver.cpp (added)
+++ llvm/trunk/lib/Support/StringSaver.cpp Sat Jun 13 07:49:52 2015
@@ -0,0 +1,19 @@
+//===-- StringSaver.cpp ---------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/StringSaver.h"
+
+using namespace llvm;
+
+const char *StringSaver::saveImpl(StringRef S) {
+  char *P = Alloc.Allocate<char>(S.size() + 1);
+  memcpy(P, S.data(), S.size());
+  P[S.size()] = '\0';
+  return P;
+}

Modified: llvm/trunk/unittests/Support/CommandLineTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CommandLineTest.cpp?rev=239669&r1=239668&r2=239669&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/CommandLineTest.cpp (original)
+++ llvm/trunk/unittests/Support/CommandLineTest.cpp Sat Jun 13 07:49:52 2015
@@ -10,6 +10,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Config/config.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/StringSaver.h"
 #include "gtest/gtest.h"
 #include <stdlib.h>
 #include <string>
@@ -146,26 +147,20 @@ TEST(CommandLineTest, UseOptionCategory)
                                                   "Category.";
 }
 
-class StrDupSaver : public cl::StringSaver {
-  const char *SaveString(const char *Str) override {
-    return strdup(Str);
-  }
-};
-
-typedef void ParserFunction(StringRef Source, llvm::cl::StringSaver &Saver,
+typedef void ParserFunction(StringRef Source, StringSaver &Saver,
                             SmallVectorImpl<const char *> &NewArgv,
                             bool MarkEOLs);
 
 void testCommandLineTokenizer(ParserFunction *parse, const char *Input,
                               const char *const Output[], size_t OutputSize) {
   SmallVector<const char *, 0> Actual;
-  StrDupSaver Saver;
+  BumpPtrAllocator A;
+  BumpPtrStringSaver Saver(A);
   parse(Input, Saver, Actual, /*MarkEOLs=*/false);
   EXPECT_EQ(OutputSize, Actual.size());
   for (unsigned I = 0, E = Actual.size(); I != E; ++I) {
     if (I < OutputSize)
       EXPECT_STREQ(Output[I], Actual[I]);
-    free(const_cast<char *>(Actual[I]));
   }
 }
 





More information about the llvm-commits mailing list