Files
clang-p2996/lld/ELF/Strings.h
Rui Ueyama a13efc2a73 Introduce StringRefZ class to represent null-terminated strings.
StringRefZ is a class to represent a null-terminated string. String
length is computed lazily, so it's more efficient than StringRef to
represent strings in string table.

The motivation of defining this new class is to merge functions
that only differ in string types; we have many constructors that takes
`const char *` or `StringRef`. With StringRefZ, we can merge them.

Differential Revision: https://reviews.llvm.org/D27037

llvm-svn: 288172
2016-11-29 18:05:04 +00:00

107 lines
2.9 KiB
C++

//===- Strings.h ------------------------------------------------*- C++ -*-===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_ELF_STRINGS_H
#define LLD_ELF_STRINGS_H
#include "lld/Core/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include <vector>
namespace lld {
namespace elf {
int getPriority(StringRef S);
bool hasWildcard(StringRef S);
std::vector<uint8_t> parseHex(StringRef S);
bool isValidCIdentifier(StringRef S);
StringRef unquote(StringRef S);
// This is a lazy version of StringRef. String size is computed lazily
// when it is needed. It is more efficient than StringRef to instantiate
// if you have a string whose size is unknown.
//
// ELF string tables contain a lot of null-terminated strings.
// Most of them are not necessary for the linker because they are names
// of local symbols and the linker doesn't use local symbol names for
// name resolution. So, we use this class to represents strings read
// from string tables.
class StringRefZ {
public:
StringRefZ() : Start(nullptr), Size(0) {}
StringRefZ(const char *S, size_t Size) : Start(S), Size(Size) {}
/*implicit*/ StringRefZ(const char *S) : Start(S), Size(-1) {}
/*implicit*/ StringRefZ(llvm::StringRef S)
: Start(S.data()), Size(S.size()) {}
operator llvm::StringRef() const {
if (Size == (size_t)-1)
Size = strlen(Start);
return {Start, Size};
}
private:
const char *Start;
mutable size_t Size;
};
// This class represents a glob pattern. Supported metacharacters
// are "*", "?", "[<chars>]" and "[^<chars>]".
class GlobPattern {
public:
explicit GlobPattern(StringRef Pat);
bool match(StringRef S) const;
private:
bool matchOne(ArrayRef<llvm::BitVector> Pat, StringRef S) const;
llvm::BitVector scan(StringRef &S);
llvm::BitVector expand(StringRef S);
// Parsed glob pattern.
std::vector<llvm::BitVector> Tokens;
// A glob pattern given to this class. This is for error reporting.
StringRef Original;
// The following members are for optimization.
llvm::Optional<StringRef> Exact;
llvm::Optional<StringRef> Prefix;
llvm::Optional<StringRef> Suffix;
};
// This class represents multiple glob patterns.
class StringMatcher {
public:
StringMatcher() = default;
explicit StringMatcher(const std::vector<StringRef> &Pat);
bool match(StringRef S) const;
private:
std::vector<GlobPattern> Patterns;
};
// Returns a demangled C++ symbol name. If Name is not a mangled
// name or the system does not provide __cxa_demangle function,
// it returns an unmodified string.
std::string demangle(StringRef Name);
inline StringRef toStringRef(ArrayRef<uint8_t> Arr) {
return {(const char *)Arr.data(), Arr.size()};
}
}
}
#endif