summaryrefslogtreecommitdiff
path: root/absl
diff options
context:
space:
mode:
Diffstat (limited to 'absl')
-rw-r--r--absl/debugging/internal/demangle.cc16
-rw-r--r--absl/debugging/internal/demangle_test.cc10
2 files changed, 23 insertions, 3 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index d32d5980..8bff73bb 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -621,6 +621,7 @@ static bool ParseExprPrimary(State *state);
static bool ParseExprCastValueAndTrailingE(State *state);
static bool ParseQRequiresClauseExpr(State *state);
static bool ParseRequirement(State *state);
+static bool ParseTypeConstraint(State *state);
static bool ParseLocalName(State *state);
static bool ParseLocalNameSuffix(State *state);
static bool ParseDiscriminator(State *state);
@@ -1274,6 +1275,7 @@ static bool ParseDecltype(State *state) {
// ::= <substitution>
// ::= Dp <type> # pack expansion of (C++0x)
// ::= Dv <num-elems> _ # GNU vector extension
+// ::= Dk <type-constraint> # constrained auto
//
static bool ParseType(State *state) {
ComplexityGuard guard(state);
@@ -1346,6 +1348,11 @@ static bool ParseType(State *state) {
}
state->parse_state = copy;
+ if (ParseTwoCharToken(state, "Dk") && ParseTypeConstraint(state)) {
+ return true;
+ }
+ state->parse_state = copy;
+
// For this notation see CXXNameMangler::mangleType in Clang's source code.
// The relevant logic and its comment "not clear how to mangle this!" date
// from 2011, so it may be with us awhile.
@@ -2292,8 +2299,6 @@ static bool ParseQRequiresClauseExpr(State *state) {
// <requirement> ::= T <type>
// <requirement> ::= Q <constraint-expression>
//
-// <type-constraint> ::= <name>
-//
// <constraint-expression> ::= <expression>
//
// https://github.com/itanium-cxx-abi/cxx-abi/issues/24
@@ -2307,7 +2312,7 @@ static bool ParseRequirement(State *state) {
Optional(ParseOneCharToken(state, 'N')) &&
// This logic backtracks cleanly if we eat an R but a valid type doesn't
// follow it.
- (!ParseOneCharToken(state, 'R') || ParseName(state))) {
+ (!ParseOneCharToken(state, 'R') || ParseTypeConstraint(state))) {
return true;
}
state->parse_state = copy;
@@ -2321,6 +2326,11 @@ static bool ParseRequirement(State *state) {
return false;
}
+// <type-constraint> ::= <name>
+static bool ParseTypeConstraint(State *state) {
+ return ParseName(state);
+}
+
// <local-name> ::= Z <(function) encoding> E <(entity) name> [<discriminator>]
// ::= Z <(function) encoding> E s [<discriminator>]
// ::= Z <(function) encoding> E d [<(parameter) number>] _ <name>
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 2895736c..de2d0979 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -150,6 +150,16 @@ TEST(Demangle, FunctionTemplateTemplateParamWithConstrainedArg) {
EXPECT_STREQ(tmp, "foo<>()");
}
+TEST(Demangle, ConstrainedAutoInFunctionTemplate) {
+ char tmp[100];
+
+ // template <typename T> concept C = true;
+ // template <C auto N> void f() {}
+ // template void f<0>();
+ ASSERT_TRUE(Demangle("_Z1fITnDk1CLi0EEvv", tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp, "f<>()");
+}
+
TEST(Demangle, NonTemplateBuiltinType) {
char tmp[100];