summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Demangle
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2018-08-10 14:31:04 +0000
committerZachary Turner <zturner@google.com>2018-08-10 14:31:04 +0000
commitdbefc6cd4ee559e2788ed9d1799b8c1b3da812cc (patch)
tree9b9894b7c74e95a9dc34f8faa424bd69f6712b5f /llvm/lib/Demangle
parentf337f5b7a579cf84a9243b9a96d294228ca63f75 (diff)
downloadbcm5719-llvm-dbefc6cd4ee559e2788ed9d1799b8c1b3da812cc.tar.gz
bcm5719-llvm-dbefc6cd4ee559e2788ed9d1799b8c1b3da812cc.zip
[MS Demangler] Fix several issues related to templates.
These were uncovered when porting the mangling tests in ms-templates.cpp from clang/CodeGenCXX over to demangling tests. The main issues fixed here are surrounding integer literal signed and unsignedness, empty array dimensions, and pointer and reference non-type template parameters. Differential Revision: https://reviews.llvm.org/D50512 llvm-svn: 339434
Diffstat (limited to 'llvm/lib/Demangle')
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangle.cpp124
1 files changed, 90 insertions, 34 deletions
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index 5aa90395c7d..fd64edbb9e0 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -234,6 +234,15 @@ struct FunctionParams {
struct TemplateParams {
bool IsTemplateTemplate = false;
bool IsAliasTemplate = false;
+ bool IsIntegerLiteral = false;
+ bool IntegerLiteralIsNegative = false;
+ bool IsEmptyParameterPack = false;
+ bool PointerToSymbol = false;
+ bool ReferenceToSymbol = false;
+
+ // If IsIntegerLiteral is true, this is a non-type template parameter
+ // whose value is contained in this field.
+ uint64_t IntegralValue = 0;
// Type can be null if this is a template template parameter. In that case
// only Name will be valid.
@@ -340,14 +349,18 @@ struct UdtType : public Type {
Name *UdtName = nullptr;
};
+struct ArrayDimension {
+ uint64_t Dim = 0;
+ ArrayDimension *Next = nullptr;
+};
+
struct ArrayType : public Type {
Type *clone(ArenaAllocator &Arena) const override;
void outputPre(OutputStream &OS, NameResolver &Resolver) override;
void outputPost(OutputStream &OS, NameResolver &Resolver) override;
// Either NextDimension or ElementType will be valid.
- ArrayType *NextDimension = nullptr;
- uint32_t ArrayDimension = 0;
+ ArrayDimension *Dims = nullptr;
Type *ElementType = nullptr;
};
@@ -510,7 +523,7 @@ static void outputName(OutputStream &OS, const Name *TheName,
static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
NameResolver &Resolver) {
- if (!Params.ParamType && !Params.ParamName) {
+ if (Params.IsEmptyParameterPack) {
OS << "<>";
return;
}
@@ -521,9 +534,13 @@ static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
// Type can be null if this is a template template parameter,
// and Name can be null if this is a simple type.
- if (Head->ParamType && Head->ParamName) {
- // Function pointer.
- OS << "&";
+ if (Head->IsIntegerLiteral) {
+ if (Head->IntegerLiteralIsNegative)
+ OS << '-';
+ OS << Head->IntegralValue;
+ } else if (Head->PointerToSymbol || Head->ReferenceToSymbol) {
+ if (Head->PointerToSymbol)
+ OS << "&";
Type::outputPre(OS, *Head->ParamType, Resolver);
outputName(OS, Head->ParamName, Resolver);
Type::outputPost(OS, *Head->ParamType, Resolver);
@@ -867,12 +884,16 @@ void ArrayType::outputPre(OutputStream &OS, NameResolver &Resolver) {
}
void ArrayType::outputPost(OutputStream &OS, NameResolver &Resolver) {
- if (ArrayDimension > 0)
- OS << "[" << ArrayDimension << "]";
- if (NextDimension)
- Type::outputPost(OS, *NextDimension, Resolver);
- else if (ElementType)
- Type::outputPost(OS, *ElementType, Resolver);
+ ArrayDimension *D = Dims;
+ while (D) {
+ OS << "[";
+ if (D->Dim > 0)
+ OS << D->Dim;
+ OS << "]";
+ D = D->Next;
+ }
+
+ Type::outputPost(OS, *ElementType, Resolver);
}
struct Symbol {
@@ -938,7 +959,7 @@ private:
TemplateParams *demangleTemplateParameterList(StringView &MangledName);
FunctionParams demangleFunctionParameterList(StringView &MangledName);
- int demangleNumber(StringView &MangledName);
+ std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
void memorizeString(StringView s);
@@ -1091,21 +1112,21 @@ Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
//
// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
-int Demangler::demangleNumber(StringView &MangledName) {
- bool neg = MangledName.consumeFront("?");
+std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
+ bool IsNegative = MangledName.consumeFront('?');
if (startsWithDigit(MangledName)) {
- int32_t Ret = MangledName[0] - '0' + 1;
+ uint64_t Ret = MangledName[0] - '0' + 1;
MangledName = MangledName.dropFront(1);
- return neg ? -Ret : Ret;
+ return {Ret, IsNegative};
}
- int Ret = 0;
+ uint64_t Ret = 0;
for (size_t i = 0; i < MangledName.size(); ++i) {
char C = MangledName[i];
if (C == '@') {
MangledName = MangledName.dropFront(i + 1);
- return neg ? -Ret : Ret;
+ return {Ret, IsNegative};
}
if ('A' <= C && C <= 'P') {
Ret = (Ret << 4) + (C - 'A');
@@ -1115,7 +1136,7 @@ int Demangler::demangleNumber(StringView &MangledName) {
}
Error = true;
- return 0;
+ return {0ULL, false};
}
// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
@@ -1346,7 +1367,8 @@ Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
Name *Node = Arena.alloc<Name>();
MangledName.consumeFront('?');
- int ScopeIdentifier = demangleNumber(MangledName);
+ auto Number = demangleNumber(MangledName);
+ assert(!Number.second);
// One ? to terminate the number
MangledName.consumeFront('?');
@@ -1361,7 +1383,7 @@ Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
OS << '`';
output(Scope, OS);
OS << '\'';
- OS << "::`" << ScopeIdentifier << "'";
+ OS << "::`" << Number.first << "'";
OS << '\0';
char *Result = OS.getBuffer();
Node->Str = copyString(Result);
@@ -1933,19 +1955,28 @@ ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
assert(MangledName.front() == 'Y');
MangledName.popFront();
- int Dimension = demangleNumber(MangledName);
- if (Dimension <= 0) {
+ uint64_t Rank = 0;
+ bool IsNegative = false;
+ std::tie(Rank, IsNegative) = demangleNumber(MangledName);
+ if (IsNegative || Rank == 0) {
Error = true;
return nullptr;
}
ArrayType *ATy = Arena.alloc<ArrayType>();
- ArrayType *Dim = ATy;
- for (int I = 0; I < Dimension; ++I) {
- Dim->Prim = PrimTy::Array;
- Dim->ArrayDimension = demangleNumber(MangledName);
- Dim->NextDimension = Arena.alloc<ArrayType>();
- Dim = Dim->NextDimension;
+ ATy->Prim = PrimTy::Array;
+ ATy->Dims = Arena.alloc<ArrayDimension>();
+ ArrayDimension *Dim = ATy->Dims;
+ for (uint64_t I = 0; I < Rank; ++I) {
+ std::tie(Dim->Dim, IsNegative) = demangleNumber(MangledName);
+ if (IsNegative) {
+ Error = true;
+ return nullptr;
+ }
+ if (I + 1 < Rank) {
+ Dim->Next = Arena.alloc<ArrayDimension>();
+ Dim = Dim->Next;
+ }
}
if (MangledName.consumeFront("$$C")) {
@@ -1958,7 +1989,6 @@ ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
}
ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
- Dim->ElementType = ATy->ElementType;
return ATy;
}
@@ -2034,16 +2064,42 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) {
// Empty parameter pack.
if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
MangledName.consumeFront("$$$V")) {
+ (*Current)->IsEmptyParameterPack = true;
break;
}
if (MangledName.consumeFront("$$Y")) {
+ // Template alias
(*Current)->IsTemplateTemplate = true;
(*Current)->IsAliasTemplate = true;
(*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
- } else if (MangledName.consumeFront("$1?")) {
- (*Current)->ParamName = demangleFullyQualifiedSymbolName(MangledName);
- (*Current)->ParamType = demangleFunctionEncoding(MangledName);
+ } else if (MangledName.consumeFront("$$B")) {
+ // Array
+ (*Current)->ParamType =
+ demangleType(MangledName, QualifierMangleMode::Drop);
+ } else if (MangledName.startsWith("$1?")) {
+ MangledName.consumeFront("$1");
+ // Pointer to symbol
+ Symbol *S = parse(MangledName);
+ (*Current)->ParamName = S->SymbolName;
+ (*Current)->ParamType = S->SymbolType;
+ (*Current)->PointerToSymbol = true;
+ } else if (MangledName.startsWith("$E?")) {
+ MangledName.consumeFront("$E");
+ // Reference to symbol
+ Symbol *S = parse(MangledName);
+ (*Current)->ParamName = S->SymbolName;
+ (*Current)->ParamType = S->SymbolType;
+ (*Current)->ReferenceToSymbol = true;
+ } else if (MangledName.consumeFront("$0")) {
+ // Integral non-type template parameter
+ bool IsNegative = false;
+ uint64_t Value = 0;
+ std::tie(Value, IsNegative) = demangleNumber(MangledName);
+
+ (*Current)->IsIntegerLiteral = true;
+ (*Current)->IntegerLiteralIsNegative = IsNegative;
+ (*Current)->IntegralValue = Value;
} else {
(*Current)->ParamType =
demangleType(MangledName, QualifierMangleMode::Drop);
OpenPOWER on IntegriCloud