mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
933a42da48
Summary: This transforms the Itanium demangler into a generic reusable library that can be used to build, traverse, and transform Itanium mangled name trees. This is in preparation for adding a canonicalizing demangler, which cannot live in the Demangle library for layering reasons. In order to keep the diffs simpler, this patch moves more code to the new header than is strictly necessary: in particular, all of the printLeft / printRight implementations can be moved to the implementation file. (And indeed we could make them non-virtual now if we wished, and remove the vptr from Node.) All nodes are now included in the Kind enumeration, rather than omitting some of the Expr nodes, and the three different floating-point literal node types now have distinct Kind values. As a proof of concept for the visitation / matching mechanism, this patch implements a Node dumping facility on top of it, replacing the prior mechanism that produced the pretty-printed output rather than a tree dump. Sample dump output: FunctionEncoding( NameType("int"), NameWithTemplateArgs( NestedName( NameWithTemplateArgs( NameType("A"), TemplateArgs( {NameType("B")})), NameType("f")), TemplateArgs( {NameType("int")})), {}, <null>, QualConst, FunctionRefQual::FrefQualLValue) As a next step, it would make sense to move the LLVM high-level interface to the demangler (the itaniumDemangler function and ItaniumPartialDemangler class) into the Support library, and implement them in terms of the Demangle library. This would allow the libc++abi demangler implementation to be an identical copy of the llvm Demangle library, and would allow the LLVM implementation to reuse LLVM components such as llvm::BumpPtrAllocator, but we'll need to decide how to coordinate that with the MS ABI demangler, so I'm not doing that in this patch. No functionality change intended other than the behavior of dump(). Reviewers: erik.pilkington, zturner, chandlerc, dlj Subscribers: aheejin, llvm-commits Differential Revision: https://reviews.llvm.org/D50930 llvm-svn: 340203
122 lines
3.2 KiB
C++
122 lines
3.2 KiB
C++
//===--- StringView.h -------------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//
|
|
// This file contains a limited version of LLVM's StringView class. It is
|
|
// copied here so that LLVMDemangle need not take a dependency on LLVMSupport.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_DEMANGLE_STRINGVIEW_H
|
|
#define LLVM_DEMANGLE_STRINGVIEW_H
|
|
|
|
#include <algorithm>
|
|
#include <cassert>
|
|
#include <cstring>
|
|
|
|
class StringView {
|
|
const char *First;
|
|
const char *Last;
|
|
|
|
public:
|
|
static const size_t npos = ~size_t(0);
|
|
|
|
template <size_t N>
|
|
StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
|
|
StringView(const char *First_, const char *Last_)
|
|
: First(First_), Last(Last_) {}
|
|
StringView(const char *First_, size_t Len)
|
|
: First(First_), Last(First_ + Len) {}
|
|
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
|
|
StringView() : First(nullptr), Last(nullptr) {}
|
|
|
|
StringView substr(size_t From) const {
|
|
return StringView(begin() + From, size() - From);
|
|
}
|
|
|
|
size_t find(char C, size_t From = 0) const {
|
|
size_t FindBegin = std::min(From, size());
|
|
// Avoid calling memchr with nullptr.
|
|
if (FindBegin < size()) {
|
|
// Just forward to memchr, which is faster than a hand-rolled loop.
|
|
if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
|
|
return static_cast<const char *>(P) - First;
|
|
}
|
|
return npos;
|
|
}
|
|
|
|
StringView substr(size_t From, size_t To) const {
|
|
if (To >= size())
|
|
To = size() - 1;
|
|
if (From >= size())
|
|
From = size() - 1;
|
|
return StringView(First + From, First + To);
|
|
}
|
|
|
|
StringView dropFront(size_t N = 1) const {
|
|
if (N >= size())
|
|
N = size();
|
|
return StringView(First + N, Last);
|
|
}
|
|
|
|
StringView dropBack(size_t N = 1) const {
|
|
if (N >= size())
|
|
N = size();
|
|
return StringView(First, Last - N);
|
|
}
|
|
|
|
char front() const {
|
|
assert(!empty());
|
|
return *begin();
|
|
}
|
|
|
|
char back() const {
|
|
assert(!empty());
|
|
return *(end() - 1);
|
|
}
|
|
|
|
char popFront() {
|
|
assert(!empty());
|
|
return *First++;
|
|
}
|
|
|
|
bool consumeFront(char C) {
|
|
if (!startsWith(C))
|
|
return false;
|
|
*this = dropFront(1);
|
|
return true;
|
|
}
|
|
|
|
bool consumeFront(StringView S) {
|
|
if (!startsWith(S))
|
|
return false;
|
|
*this = dropFront(S.size());
|
|
return true;
|
|
}
|
|
|
|
bool startsWith(char C) const { return !empty() && *begin() == C; }
|
|
|
|
bool startsWith(StringView Str) const {
|
|
if (Str.size() > size())
|
|
return false;
|
|
return std::equal(Str.begin(), Str.end(), begin());
|
|
}
|
|
|
|
const char &operator[](size_t Idx) const { return *(begin() + Idx); }
|
|
|
|
const char *begin() const { return First; }
|
|
const char *end() const { return Last; }
|
|
size_t size() const { return static_cast<size_t>(Last - First); }
|
|
bool empty() const { return First == Last; }
|
|
};
|
|
|
|
inline bool operator==(const StringView &LHS, const StringView &RHS) {
|
|
return LHS.size() == RHS.size() &&
|
|
std::equal(LHS.begin(), LHS.end(), RHS.begin());
|
|
}
|
|
|
|
#endif
|