summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-06-13 12:49:52 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-06-13 12:49:52 +0000
commit454adf645480245725c74fdbe8840ceff039ef64 (patch)
tree0412a6ae637df95d5eb30d87e35bb26cd220069c
parentd9ad0cbd70426f1b85d37d9059e66b2e5f1f0c8b (diff)
downloadbcm5719-llvm-454adf645480245725c74fdbe8840ceff039ef64.tar.gz
bcm5719-llvm-454adf645480245725c74fdbe8840ceff039ef64.zip
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. llvm-svn: 239669
-rw-r--r--llvm/include/llvm/Support/CommandLine.h13
-rw-r--r--llvm/include/llvm/Support/StringSaver.h42
-rw-r--r--llvm/lib/LibDriver/LibDriver.cpp25
-rw-r--r--llvm/lib/Support/CMakeLists.txt1
-rw-r--r--llvm/lib/Support/CommandLine.cpp38
-rw-r--r--llvm/lib/Support/StringSaver.cpp19
-rw-r--r--llvm/unittests/Support/CommandLineTest.cpp13
7 files changed, 82 insertions, 69 deletions
diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
index 1ad8a3bfd93..ed809211ea9 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -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 *> &getRegisteredOptions();
// 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
diff --git a/llvm/include/llvm/Support/StringSaver.h b/llvm/include/llvm/Support/StringSaver.h
new file mode 100644
index 00000000000..f3853ee9157
--- /dev/null
+++ b/llvm/include/llvm/Support/StringSaver.h
@@ -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
diff --git a/llvm/lib/LibDriver/LibDriver.cpp b/llvm/lib/LibDriver/LibDriver.cpp
index d028e4bbca5..44929580f82 100644
--- a/llvm/lib/LibDriver/LibDriver.cpp
+++ b/llvm/lib/LibDriver/LibDriver.cpp
@@ -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::opt::InputArgList *Args) {
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());
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 79aae158435..eac189b67a4 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -83,6 +83,7 @@ add_llvm_library(LLVMSupport
StringExtras.cpp
StringMap.cpp
StringPool.cpp
+ StringSaver.cpp
StringRef.cpp
SystemUtils.cpp
TargetParser.cpp
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 3cabc54a73a..dcaacf6248d 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -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(StringRef Src, StringSaver &Saver,
// 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(StringRef Src, StringSaver &Saver,
// 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(StringRef Src, StringSaver &Saver,
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(StringRef Src, StringSaver &Saver,
}
// 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 &Saver, TokenizerCallback Tokenizer,
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 char *progName, const char *envVar,
// 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::ParseCommandLineOptions(int argc,
// 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());
diff --git a/llvm/lib/Support/StringSaver.cpp b/llvm/lib/Support/StringSaver.cpp
new file mode 100644
index 00000000000..d6b84e53dcc
--- /dev/null
+++ b/llvm/lib/Support/StringSaver.cpp
@@ -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;
+}
diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp
index 328c4b7fcf3..e0fbf5b09e5 100644
--- a/llvm/unittests/Support/CommandLineTest.cpp
+++ b/llvm/unittests/Support/CommandLineTest.cpp
@@ -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]));
}
}
OpenPOWER on IntegriCloud