[demangle] NFC: get rid of NodeOrString

This class was a bit overengineered, and was triggering some PVS warnings.
Instead, put strings into a NameType and let clients unconditionally treat it
as a Node.
This commit is contained in:
Erik Pilkington 2019-11-04 10:47:44 -08:00
parent efad56b2be
commit af11f417fc
5 changed files with 38 additions and 137 deletions

View File

@ -86,14 +86,6 @@ struct DumpVisitor {
else else
printStr("<null>"); printStr("<null>");
} }
void print(NodeOrString NS) {
if (NS.isNode())
print(NS.asNode());
else if (NS.isString())
print(NS.asString());
else
printStr("NodeOrString()");
}
void print(NodeArray A) { void print(NodeArray A) {
++Depth; ++Depth;
printStr("{"); printStr("{");

View File

@ -607,48 +607,12 @@ public:
} }
}; };
class NodeOrString {
const void *First;
const void *Second;
public:
/* implicit */ NodeOrString(StringView Str) {
const char *FirstChar = Str.begin();
const char *SecondChar = Str.end();
if (SecondChar == nullptr) {
assert(FirstChar == SecondChar);
++FirstChar, ++SecondChar;
}
First = static_cast<const void *>(FirstChar);
Second = static_cast<const void *>(SecondChar);
}
/* implicit */ NodeOrString(Node *N)
: First(static_cast<const void *>(N)), Second(nullptr) {}
NodeOrString() : First(nullptr), Second(nullptr) {}
bool isString() const { return Second && First; }
bool isNode() const { return First && !Second; }
bool isEmpty() const { return !First && !Second; }
StringView asString() const {
assert(isString());
return StringView(static_cast<const char *>(First),
static_cast<const char *>(Second));
}
const Node *asNode() const {
assert(isNode());
return static_cast<const Node *>(First);
}
};
class ArrayType final : public Node { class ArrayType final : public Node {
const Node *Base; const Node *Base;
NodeOrString Dimension; Node *Dimension;
public: public:
ArrayType(const Node *Base_, NodeOrString Dimension_) ArrayType(const Node *Base_, Node *Dimension_)
: Node(KArrayType, : Node(KArrayType,
/*RHSComponentCache=*/Cache::Yes, /*RHSComponentCache=*/Cache::Yes,
/*ArrayCache=*/Cache::Yes), /*ArrayCache=*/Cache::Yes),
@ -665,10 +629,8 @@ public:
if (S.back() != ']') if (S.back() != ']')
S += " "; S += " ";
S += "["; S += "[";
if (Dimension.isString()) if (Dimension)
S += Dimension.asString(); Dimension->print(S);
else if (Dimension.isNode())
Dimension.asNode()->print(S);
S += "]"; S += "]";
Base->printRight(S); Base->printRight(S);
} }
@ -934,10 +896,10 @@ public:
class VectorType final : public Node { class VectorType final : public Node {
const Node *BaseType; const Node *BaseType;
const NodeOrString Dimension; const Node *Dimension;
public: public:
VectorType(const Node *BaseType_, NodeOrString Dimension_) VectorType(const Node *BaseType_, Node *Dimension_)
: Node(KVectorType), BaseType(BaseType_), : Node(KVectorType), BaseType(BaseType_),
Dimension(Dimension_) {} Dimension(Dimension_) {}
@ -946,19 +908,17 @@ public:
void printLeft(OutputStream &S) const override { void printLeft(OutputStream &S) const override {
BaseType->print(S); BaseType->print(S);
S += " vector["; S += " vector[";
if (Dimension.isNode()) if (Dimension)
Dimension.asNode()->print(S); Dimension->print(S);
else if (Dimension.isString())
S += Dimension.asString();
S += "]"; S += "]";
} }
}; };
class PixelVectorType final : public Node { class PixelVectorType final : public Node {
const NodeOrString Dimension; const Node *Dimension;
public: public:
PixelVectorType(NodeOrString Dimension_) PixelVectorType(const Node *Dimension_)
: Node(KPixelVectorType), Dimension(Dimension_) {} : Node(KPixelVectorType), Dimension(Dimension_) {}
template<typename Fn> void match(Fn F) const { F(Dimension); } template<typename Fn> void match(Fn F) const { F(Dimension); }
@ -966,7 +926,7 @@ public:
void printLeft(OutputStream &S) const override { void printLeft(OutputStream &S) const override {
// FIXME: This should demangle as "vector pixel". // FIXME: This should demangle as "vector pixel".
S += "pixel vector["; S += "pixel vector[";
S += Dimension.asString(); Dimension->print(S);
S += "]"; S += "]";
} }
}; };
@ -3548,7 +3508,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
if (!consumeIf("Dv")) if (!consumeIf("Dv"))
return nullptr; return nullptr;
if (look() >= '1' && look() <= '9') { if (look() >= '1' && look() <= '9') {
StringView DimensionNumber = parseNumber(); Node *DimensionNumber = make<NameType>(parseNumber());
if (!DimensionNumber)
return nullptr;
if (!consumeIf('_')) if (!consumeIf('_'))
return nullptr; return nullptr;
if (consumeIf('p')) if (consumeIf('p'))
@ -3573,7 +3535,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
Node *ElemType = getDerived().parseType(); Node *ElemType = getDerived().parseType();
if (!ElemType) if (!ElemType)
return nullptr; return nullptr;
return make<VectorType>(ElemType, StringView()); return make<VectorType>(ElemType, /*Dimension=*/nullptr);
} }
// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x) // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
@ -3599,10 +3561,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
if (!consumeIf('A')) if (!consumeIf('A'))
return nullptr; return nullptr;
NodeOrString Dimension; Node *Dimension = nullptr;
if (std::isdigit(look())) { if (std::isdigit(look())) {
Dimension = parseNumber(); Dimension = make<NameType>(parseNumber());
if (!Dimension)
return nullptr;
if (!consumeIf('_')) if (!consumeIf('_'))
return nullptr; return nullptr;
} else if (!consumeIf('_')) { } else if (!consumeIf('_')) {

View File

@ -607,48 +607,12 @@ public:
} }
}; };
class NodeOrString {
const void *First;
const void *Second;
public:
/* implicit */ NodeOrString(StringView Str) {
const char *FirstChar = Str.begin();
const char *SecondChar = Str.end();
if (SecondChar == nullptr) {
assert(FirstChar == SecondChar);
++FirstChar, ++SecondChar;
}
First = static_cast<const void *>(FirstChar);
Second = static_cast<const void *>(SecondChar);
}
/* implicit */ NodeOrString(Node *N)
: First(static_cast<const void *>(N)), Second(nullptr) {}
NodeOrString() : First(nullptr), Second(nullptr) {}
bool isString() const { return Second && First; }
bool isNode() const { return First && !Second; }
bool isEmpty() const { return !First && !Second; }
StringView asString() const {
assert(isString());
return StringView(static_cast<const char *>(First),
static_cast<const char *>(Second));
}
const Node *asNode() const {
assert(isNode());
return static_cast<const Node *>(First);
}
};
class ArrayType final : public Node { class ArrayType final : public Node {
const Node *Base; const Node *Base;
NodeOrString Dimension; Node *Dimension;
public: public:
ArrayType(const Node *Base_, NodeOrString Dimension_) ArrayType(const Node *Base_, Node *Dimension_)
: Node(KArrayType, : Node(KArrayType,
/*RHSComponentCache=*/Cache::Yes, /*RHSComponentCache=*/Cache::Yes,
/*ArrayCache=*/Cache::Yes), /*ArrayCache=*/Cache::Yes),
@ -665,10 +629,8 @@ public:
if (S.back() != ']') if (S.back() != ']')
S += " "; S += " ";
S += "["; S += "[";
if (Dimension.isString()) if (Dimension)
S += Dimension.asString(); Dimension->print(S);
else if (Dimension.isNode())
Dimension.asNode()->print(S);
S += "]"; S += "]";
Base->printRight(S); Base->printRight(S);
} }
@ -934,10 +896,10 @@ public:
class VectorType final : public Node { class VectorType final : public Node {
const Node *BaseType; const Node *BaseType;
const NodeOrString Dimension; const Node *Dimension;
public: public:
VectorType(const Node *BaseType_, NodeOrString Dimension_) VectorType(const Node *BaseType_, Node *Dimension_)
: Node(KVectorType), BaseType(BaseType_), : Node(KVectorType), BaseType(BaseType_),
Dimension(Dimension_) {} Dimension(Dimension_) {}
@ -946,19 +908,17 @@ public:
void printLeft(OutputStream &S) const override { void printLeft(OutputStream &S) const override {
BaseType->print(S); BaseType->print(S);
S += " vector["; S += " vector[";
if (Dimension.isNode()) if (Dimension)
Dimension.asNode()->print(S); Dimension->print(S);
else if (Dimension.isString())
S += Dimension.asString();
S += "]"; S += "]";
} }
}; };
class PixelVectorType final : public Node { class PixelVectorType final : public Node {
const NodeOrString Dimension; const Node *Dimension;
public: public:
PixelVectorType(NodeOrString Dimension_) PixelVectorType(const Node *Dimension_)
: Node(KPixelVectorType), Dimension(Dimension_) {} : Node(KPixelVectorType), Dimension(Dimension_) {}
template<typename Fn> void match(Fn F) const { F(Dimension); } template<typename Fn> void match(Fn F) const { F(Dimension); }
@ -966,7 +926,7 @@ public:
void printLeft(OutputStream &S) const override { void printLeft(OutputStream &S) const override {
// FIXME: This should demangle as "vector pixel". // FIXME: This should demangle as "vector pixel".
S += "pixel vector["; S += "pixel vector[";
S += Dimension.asString(); Dimension->print(S);
S += "]"; S += "]";
} }
}; };
@ -3548,7 +3508,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
if (!consumeIf("Dv")) if (!consumeIf("Dv"))
return nullptr; return nullptr;
if (look() >= '1' && look() <= '9') { if (look() >= '1' && look() <= '9') {
StringView DimensionNumber = parseNumber(); Node *DimensionNumber = make<NameType>(parseNumber());
if (!DimensionNumber)
return nullptr;
if (!consumeIf('_')) if (!consumeIf('_'))
return nullptr; return nullptr;
if (consumeIf('p')) if (consumeIf('p'))
@ -3573,7 +3535,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
Node *ElemType = getDerived().parseType(); Node *ElemType = getDerived().parseType();
if (!ElemType) if (!ElemType)
return nullptr; return nullptr;
return make<VectorType>(ElemType, StringView()); return make<VectorType>(ElemType, /*Dimension=*/nullptr);
} }
// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x) // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
@ -3599,10 +3561,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
if (!consumeIf('A')) if (!consumeIf('A'))
return nullptr; return nullptr;
NodeOrString Dimension; Node *Dimension = nullptr;
if (std::isdigit(look())) { if (std::isdigit(look())) {
Dimension = parseNumber(); Dimension = make<NameType>(parseNumber());
if (!Dimension)
return nullptr;
if (!consumeIf('_')) if (!consumeIf('_'))
return nullptr; return nullptr;
} else if (!consumeIf('_')) { } else if (!consumeIf('_')) {

View File

@ -89,14 +89,6 @@ struct DumpVisitor {
else else
printStr("<null>"); printStr("<null>");
} }
void print(NodeOrString NS) {
if (NS.isNode())
print(NS.asNode());
else if (NS.isString())
print(NS.asString());
else
printStr("NodeOrString()");
}
void print(NodeArray A) { void print(NodeArray A) {
++Depth; ++Depth;
printStr("{"); printStr("{");

View File

@ -36,17 +36,6 @@ struct FoldingSetNodeIDBuilder {
operator()(T V) { operator()(T V) {
ID.AddInteger((unsigned long long)V); ID.AddInteger((unsigned long long)V);
} }
void operator()(itanium_demangle::NodeOrString NS) {
if (NS.isNode()) {
ID.AddInteger(0);
(*this)(NS.asNode());
} else if (NS.isString()) {
ID.AddInteger(1);
(*this)(NS.asString());
} else {
ID.AddInteger(2);
}
}
void operator()(itanium_demangle::NodeArray A) { void operator()(itanium_demangle::NodeArray A) {
ID.AddInteger(A.size()); ID.AddInteger(A.size());
for (const Node *N : A) for (const Node *N : A)