aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Demangle/ItaniumDemangle.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Demangle/ItaniumDemangle.h')
-rw-r--r--include/llvm/Demangle/ItaniumDemangle.h108
1 files changed, 79 insertions, 29 deletions
diff --git a/include/llvm/Demangle/ItaniumDemangle.h b/include/llvm/Demangle/ItaniumDemangle.h
index 0b9187f30a5a..aaccb27e17a3 100644
--- a/include/llvm/Demangle/ItaniumDemangle.h
+++ b/include/llvm/Demangle/ItaniumDemangle.h
@@ -1,23 +1,26 @@
//===------------------------- ItaniumDemangle.h ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// Generic itanium demangler library. This file has two byte-per-byte identical
+// copies in the source tree, one in libcxxabi, and the other in llvm.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEMANGLE_ITANIUMDEMANGLE_H
-#define LLVM_DEMANGLE_ITANIUMDEMANGLE_H
+#ifndef DEMANGLE_ITANIUMDEMANGLE_H
+#define DEMANGLE_ITANIUMDEMANGLE_H
// FIXME: (possibly) incomplete list of features that clang mangles that this
// file does not yet support:
// - C++ modules TS
-#include "llvm/Demangle/Compiler.h"
-#include "llvm/Demangle/StringView.h"
-#include "llvm/Demangle/Utility.h"
-
+#include "DemangleConfig.h"
+#include "StringView.h"
+#include "Utility.h"
#include <cassert>
#include <cctype>
#include <cstdio>
@@ -86,6 +89,7 @@
X(InitListExpr) \
X(FoldExpr) \
X(ThrowExpr) \
+ X(UUIDOfExpr) \
X(BoolExpr) \
X(IntegerCastExpr) \
X(IntegerLiteral) \
@@ -95,8 +99,8 @@
X(BracedExpr) \
X(BracedRangeExpr)
-namespace llvm {
-namespace itanium_demangle {
+DEMANGLE_NAMESPACE_BEGIN
+
// Base class of all AST nodes. The AST is built by the parser, then is
// traversed by the printLeft/Right functions to produce a demangled string.
class Node {
@@ -194,7 +198,7 @@ public:
virtual ~Node() = default;
#ifndef NDEBUG
- LLVM_DUMP_METHOD void dump() const;
+ DEMANGLE_DUMP_METHOD void dump() const;
#endif
};
@@ -1278,7 +1282,7 @@ public:
case SpecialSubKind::iostream:
return StringView("basic_iostream");
}
- LLVM_BUILTIN_UNREACHABLE;
+ DEMANGLE_UNREACHABLE;
}
void printLeft(OutputStream &S) const override {
@@ -1330,7 +1334,7 @@ public:
case SpecialSubKind::iostream:
return StringView("iostream");
}
- LLVM_BUILTIN_UNREACHABLE;
+ DEMANGLE_UNREACHABLE;
}
void printLeft(OutputStream &S) const override {
@@ -1870,6 +1874,21 @@ public:
}
};
+// MSVC __uuidof extension, generated by clang in -fms-extensions mode.
+class UUIDOfExpr : public Node {
+ Node *Operand;
+public:
+ UUIDOfExpr(Node *Operand_) : Node(KUUIDOfExpr), Operand(Operand_) {}
+
+ template<typename Fn> void match(Fn F) const { F(Operand); }
+
+ void printLeft(OutputStream &S) const override {
+ S << "__uuidof(";
+ Operand->print(S);
+ S << ")";
+ }
+};
+
class BoolExpr : public Node {
bool Value;
@@ -2476,6 +2495,12 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *) {
return nullptr;
return make<ClosureTypeName>(Params, Count);
}
+ if (consumeIf("Ub")) {
+ (void)parseNumber();
+ if (!consumeIf('_'))
+ return nullptr;
+ return make<NameType>("'block-literal'");
+ }
return nullptr;
}
@@ -2785,11 +2810,13 @@ AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
// <ctor-dtor-name> ::= C1 # complete object constructor
// ::= C2 # base object constructor
// ::= C3 # complete object allocating constructor
-// extension ::= C5 # ?
+// extension ::= C4 # gcc old-style "[unified]" constructor
+// extension ::= C5 # the COMDAT used for ctors
// ::= D0 # deleting destructor
// ::= D1 # complete object destructor
// ::= D2 # base object destructor
-// extension ::= D5 # ?
+// extension ::= D4 # gcc old-style "[unified]" destructor
+// extension ::= D5 # the COMDAT used for dtors
template <typename Derived, typename Alloc>
Node *
AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
@@ -2812,7 +2839,8 @@ AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
if (consumeIf('C')) {
bool IsInherited = consumeIf('I');
- if (look() != '1' && look() != '2' && look() != '3' && look() != '5')
+ if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
+ look() != '5')
return nullptr;
int Variant = look() - '0';
++First;
@@ -2821,15 +2849,15 @@ AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
if (getDerived().parseName(State) == nullptr)
return nullptr;
}
- return make<CtorDtorName>(SoFar, false, Variant);
+ return make<CtorDtorName>(SoFar, /*IsDtor=*/false, Variant);
}
- if (look() == 'D' &&
- (look(1) == '0' || look(1) == '1' || look(1) == '2' || look(1) == '5')) {
+ if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' ||
+ look(1) == '4' || look(1) == '5')) {
int Variant = look(1) - '0';
First += 2;
if (State) State->CtorDtorConversion = true;
- return make<CtorDtorName>(SoFar, true, Variant);
+ return make<CtorDtorName>(SoFar, /*IsDtor=*/true, Variant);
}
return nullptr;
@@ -3467,7 +3495,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
Result = getDerived().parseFunctionType();
break;
}
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
}
case 'U': {
Result = getDerived().parseQualifiedType();
@@ -3564,7 +3592,11 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
StringView Res = parseBareSourceName();
if (Res.empty())
return nullptr;
- return make<NameType>(Res);
+ // Typically, <builtin-type>s are not considered substitution candidates,
+ // but the exception to that exception is vendor extended types (Itanium C++
+ // ABI 5.9.1).
+ Result = make<NameType>(Res);
+ break;
}
case 'D':
switch (look(1)) {
@@ -3592,6 +3624,10 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
case 's':
First += 2;
return make<NameType>("char16_t");
+ // ::= Du # char8_t (C++2a, not yet in the Itanium spec)
+ case 'u':
+ First += 2;
+ return make<NameType>("char8_t");
// ::= Da # auto (in dependent new-expressions)
case 'a':
First += 2;
@@ -3754,7 +3790,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
// substitution table.
return Sub;
}
- LLVM_FALLTHROUGH;
+ DEMANGLE_FALLTHROUGH;
}
// ::= <class-enum-type>
default: {
@@ -4633,6 +4669,21 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
case '9':
return getDerived().parseUnresolvedName();
}
+
+ if (consumeIf("u8__uuidoft")) {
+ Node *Ty = getDerived().parseType();
+ if (!Ty)
+ return nullptr;
+ return make<UUIDOfExpr>(Ty);
+ }
+
+ if (consumeIf("u8__uuidofz")) {
+ Node *Ex = getDerived().parseExpr();
+ if (!Ex)
+ return nullptr;
+ return make<UUIDOfExpr>(Ex);
+ }
+
return nullptr;
}
@@ -5139,7 +5190,7 @@ AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
// extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+
template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parse() {
- if (consumeIf("_Z")) {
+ if (consumeIf("_Z") || consumeIf("__Z")) {
Node *Encoding = getDerived().parseEncoding();
if (Encoding == nullptr)
return nullptr;
@@ -5152,7 +5203,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parse() {
return Encoding;
}
- if (consumeIf("___Z")) {
+ if (consumeIf("___Z") || consumeIf("____Z")) {
Node *Encoding = getDerived().parseEncoding();
if (Encoding == nullptr || !consumeIf("_block_invoke"))
return nullptr;
@@ -5178,7 +5229,6 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
Alloc>::AbstractManglingParser;
};
-} // namespace itanium_demangle
-} // namespace llvm
+DEMANGLE_NAMESPACE_END
-#endif // LLVM_DEMANGLE_ITANIUMDEMANGLE_H
+#endif // DEMANGLE_ITANIUMDEMANGLE_H