[demangler] Support C23 _BitInt type

Reviewed By: #libc_abi, aaron.ballman, urnathan

Differential Revision: https://reviews.llvm.org/D122530
This commit is contained in:
Senran Zhang 2022-03-27 00:04:23 +08:00
parent 497f87bb7b
commit a23652f6f9
5 changed files with 78 additions and 0 deletions

View file

@ -482,6 +482,26 @@ public:
void printLeft(OutputBuffer &OB) const override { OB += Name; }
};
class BitIntType final : public Node {
const Node *Size;
bool Signed;
public:
BitIntType(const Node *Size_, bool Signed_)
: Node(KBitIntType), Size(Size_), Signed(Signed_) {}
template <typename Fn> void match(Fn F) const { F(Size, Signed); }
void printLeft(OutputBuffer &OB) const override {
if (!Signed)
OB += "unsigned ";
OB += "_BitInt";
OB.printOpen();
Size->printAsOperand(OB);
OB.printClose();
}
};
class ElaboratedTypeSpefType : public Node {
StringView Kind;
Node *Child;
@ -3924,6 +3944,22 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
return nullptr;
return make<BinaryFPType>(DimensionNumber);
}
// ::= DB <number> _ # C23 signed _BitInt(N)
// ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
// ::= DU <number> _ # C23 unsigned _BitInt(N)
// ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
case 'B':
case 'U': {
bool Signed = look(1) == 'B';
First += 2;
Node *Size = std::isdigit(look()) ? make<NameType>(parseNumber())
: getDerived().parseExpr();
if (!Size)
return nullptr;
if (!consumeIf('_'))
return nullptr;
return make<BitIntType>(Size, Signed);
}
// ::= Di # char32_t
case 'i':
First += 2;

View file

@ -42,6 +42,7 @@ NODE(ModuleEntity)
NODE(VectorType)
NODE(PixelVectorType)
NODE(BinaryFPType)
NODE(BitIntType)
NODE(SyntheticTemplateParamName)
NODE(TypeTemplateParamDecl)
NODE(NonTypeTemplateParamDecl)

View file

@ -32,6 +32,10 @@ const char* cases[][2] =
{"_Z1A", "A"},
{"_Z1Av", "A()"},
{"_Z1A1B1C", "A(B, C)"},
{"_Z1fDB3_", "f(_BitInt(3))"},
{"_Z1fDU10_", "f(unsigned _BitInt(10))"},
{"_Z1fIfEvDUstPT__", "void f<float>(unsigned _BitInt(sizeof (float*)))"},
{"_Z1fIiEvDBstPT__", "void f<int>(_BitInt(sizeof (int*)))"},
{"_Z4testI1A1BE1Cv", "C test<A, B>()"},
{"_Z4testI1A1BET0_T_S3_", "B test<A, B>(A, A)"},
{"_ZN1SgtEi", "S::operator>(int)"},

View file

@ -482,6 +482,26 @@ public:
void printLeft(OutputBuffer &OB) const override { OB += Name; }
};
class BitIntType final : public Node {
const Node *Size;
bool Signed;
public:
BitIntType(const Node *Size_, bool Signed_)
: Node(KBitIntType), Size(Size_), Signed(Signed_) {}
template <typename Fn> void match(Fn F) const { F(Size, Signed); }
void printLeft(OutputBuffer &OB) const override {
if (!Signed)
OB += "unsigned ";
OB += "_BitInt";
OB.printOpen();
Size->printAsOperand(OB);
OB.printClose();
}
};
class ElaboratedTypeSpefType : public Node {
StringView Kind;
Node *Child;
@ -3924,6 +3944,22 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
return nullptr;
return make<BinaryFPType>(DimensionNumber);
}
// ::= DB <number> _ # C23 signed _BitInt(N)
// ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
// ::= DU <number> _ # C23 unsigned _BitInt(N)
// ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
case 'B':
case 'U': {
bool Signed = look(1) == 'B';
First += 2;
Node *Size = std::isdigit(look()) ? make<NameType>(parseNumber())
: getDerived().parseExpr();
if (!Size)
return nullptr;
if (!consumeIf('_'))
return nullptr;
return make<BitIntType>(Size, Signed);
}
// ::= Di # char32_t
case 'i':
First += 2;

View file

@ -42,6 +42,7 @@ NODE(ModuleEntity)
NODE(VectorType)
NODE(PixelVectorType)
NODE(BinaryFPType)
NODE(BitIntType)
NODE(SyntheticTemplateParamName)
NODE(TypeTemplateParamDecl)
NODE(NonTypeTemplateParamDecl)