summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-08-24 23:26:05 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-08-24 23:26:05 +0000
commit9c2e4f39bc6a2394747695bd013d4a2da844ea69 (patch)
tree34bef9c8610dc0f2cceb74250547c5f6021b4306 /llvm/lib
parent61b28ede75d9cbd2754a97364b7e99aa60e1b26c (diff)
downloadbcm5719-llvm-9c2e4f39bc6a2394747695bd013d4a2da844ea69.tar.gz
bcm5719-llvm-9c2e4f39bc6a2394747695bd013d4a2da844ea69.zip
Allow demangler's node allocator to fail, and bail out of the entire
demangling process when it does. Use this to support a "lookup" query for the mangling canonicalizer that does not create new nodes. This could also be used to implement demangling with a fixed-size temporary storage buffer. Reviewers: erik.pilkington Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D51003 llvm-svn: 340670
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Support/ItaniumManglingCanonicalizer.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp b/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp
index 9d78ddc0b8b..f7b8b98ed16 100644
--- a/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp
+++ b/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp
@@ -105,7 +105,7 @@ public:
void reset() {}
template<typename T, typename ...Args>
- std::pair<Node*, bool> getOrCreateNode(Args &&...As) {
+ std::pair<Node*, bool> getOrCreateNode(bool CreateNewNodes, Args &&...As) {
llvm::FoldingSetNodeID ID;
profileCtor(ID, NodeKind<T>::Kind, As...);
@@ -113,6 +113,9 @@ public:
if (NodeHeader *Existing = Nodes.FindNodeOrInsertPos(ID, InsertPos))
return {static_cast<T*>(Existing->getNode()), false};
+ if (!CreateNewNodes)
+ return {nullptr, true};
+
static_assert(alignof(T) <= alignof(NodeHeader),
"underaligned node header for specific node kind");
void *Storage =
@@ -125,7 +128,7 @@ public:
template<typename T, typename... Args>
Node *makeNode(Args &&...As) {
- return getOrCreateNode<T>(std::forward<Args>(As)...).first;
+ return getOrCreateNode<T>(true, std::forward<Args>(As)...).first;
}
void *allocateNodeArray(size_t sz) {
@@ -138,7 +141,8 @@ public:
// of creation.
template<>
std::pair<Node *, bool>
-FoldingNodeAllocator::getOrCreateNode<ForwardTemplateReference>(size_t &Index) {
+FoldingNodeAllocator::getOrCreateNode<ForwardTemplateReference>(bool,
+ size_t &Index) {
return {new (RawAlloc.Allocate(sizeof(ForwardTemplateReference),
alignof(ForwardTemplateReference)))
ForwardTemplateReference(Index),
@@ -149,15 +153,16 @@ class CanonicalizerAllocator : public FoldingNodeAllocator {
Node *MostRecentlyCreated = nullptr;
Node *TrackedNode = nullptr;
bool TrackedNodeIsUsed = false;
+ bool CreateNewNodes = true;
llvm::SmallDenseMap<Node*, Node*, 32> Remappings;
template<typename T, typename ...Args> Node *makeNodeSimple(Args &&...As) {
std::pair<Node *, bool> Result =
- getOrCreateNode<T>(std::forward<Args>(As)...);
+ getOrCreateNode<T>(CreateNewNodes, std::forward<Args>(As)...);
if (Result.second) {
// Node is new. Make a note of that.
MostRecentlyCreated = Result.first;
- } else {
+ } else if (Result.first) {
// Node is pre-existing; check if it's in our remapping table.
if (auto *N = Remappings.lookup(Result.first)) {
Result.first = N;
@@ -185,6 +190,8 @@ public:
void reset() { MostRecentlyCreated = nullptr; }
+ void setCreateNewNodes(bool CNN) { CreateNewNodes = CNN; }
+
void addRemapping(Node *A, Node *B) {
// Note, we don't need to check whether B is also remapped, because if it
// was we would have already remapped it when building it.
@@ -230,6 +237,7 @@ ItaniumManglingCanonicalizer::EquivalenceError
ItaniumManglingCanonicalizer::addEquivalence(FragmentKind Kind, StringRef First,
StringRef Second) {
auto &Alloc = P->Demangler.ASTAllocator;
+ Alloc.setCreateNewNodes(true);
auto Parse = [&](StringRef Str) {
P->Demangler.reset(Str.begin(), Str.end());
@@ -302,6 +310,14 @@ ItaniumManglingCanonicalizer::addEquivalence(FragmentKind Kind, StringRef First,
ItaniumManglingCanonicalizer::Key
ItaniumManglingCanonicalizer::canonicalize(StringRef Mangling) {
+ P->Demangler.ASTAllocator.setCreateNewNodes(true);
+ P->Demangler.reset(Mangling.begin(), Mangling.end());
+ return reinterpret_cast<Key>(P->Demangler.parse());
+}
+
+ItaniumManglingCanonicalizer::Key
+ItaniumManglingCanonicalizer::lookup(StringRef Mangling) {
+ P->Demangler.ASTAllocator.setCreateNewNodes(false);
P->Demangler.reset(Mangling.begin(), Mangling.end());
return reinterpret_cast<Key>(P->Demangler.parse());
}
OpenPOWER on IntegriCloud