mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 04:09:45 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239669 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2111b5758f
commit
8e2ed1643a
@ -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
|
||||
|
42
include/llvm/Support/StringSaver.h
Normal file
42
include/llvm/Support/StringSaver.h
Normal file
@ -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
|
@ -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());
|
||||
|
@ -83,6 +83,7 @@ add_llvm_library(LLVMSupport
|
||||
StringExtras.cpp
|
||||
StringMap.cpp
|
||||
StringPool.cpp
|
||||
StringSaver.cpp
|
||||
StringRef.cpp
|
||||
SystemUtils.cpp
|
||||
TargetParser.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());
|
||||
|
19
lib/Support/StringSaver.cpp
Normal file
19
lib/Support/StringSaver.cpp
Normal file
@ -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;
|
||||
}
|
@ -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]));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user