[clang] 9c7aeae - Itanium Mangling: Mangle `__alignof__` differently than `alignof`.
James Y Knight via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 27 14:02:49 PST 2021
Author: James Y Knight
Date: 2021-01-27T16:46:51-05:00
New Revision: 9c7aeaebb3ac1b94200b59b111742cb6b8f090c2
URL: https://github.com/llvm/llvm-project/commit/9c7aeaebb3ac1b94200b59b111742cb6b8f090c2
DIFF: https://github.com/llvm/llvm-project/commit/9c7aeaebb3ac1b94200b59b111742cb6b8f090c2.diff
LOG: Itanium Mangling: Mangle `__alignof__` differently than `alignof`.
The two operations have acted differently since Clang 8, but were
unfortunately mangled the same. The new mangling uses new "vendor
extended expression" syntax proposed in
https://github.com/itanium-cxx-abi/cxx-abi/issues/112
GCC had the same mangling problem, https://gcc.gnu.org/PR88115, and
will hopefully be switching to the same mangling as implemented here.
Additionally, fix the mangling of `__uuidof` to use the new extension
syntax, instead of its previous nonstandard special-case.
Adjusts the demangler accordingly.
Differential Revision: https://reviews.llvm.org/D93922
Added:
clang/test/CodeGenCXX/mangle-alignof.cpp
Modified:
clang/lib/AST/ItaniumMangle.cpp
clang/test/CodeGenCXX/microsoft-uuidof-mangling.cpp
libcxxabi/src/demangle/ItaniumDemangle.h
libcxxabi/test/test_demangle.pass.cpp
llvm/include/llvm/Demangle/ItaniumDemangle.h
Removed:
################################################################################
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 6c8d5687c64a..668733a4be34 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -558,6 +558,7 @@ class CXXNameMangler {
unsigned NumTemplateArgs);
void mangleTemplateArgs(TemplateName TN, const TemplateArgumentList &AL);
void mangleTemplateArg(TemplateArgument A, bool NeedExactType);
+ void mangleTemplateArgExpr(const Expr *E);
void mangleValueInTemplateArg(QualType T, const APValue &V, bool TopLevel,
bool NeedExactType = false);
@@ -3528,8 +3529,8 @@ void CXXNameMangler::mangleType(const DependentSizedMatrixType *T) {
Out << "u" << VendorQualifier.size() << VendorQualifier;
Out << "I";
- mangleTemplateArg(T->getRowExpr(), false);
- mangleTemplateArg(T->getColumnExpr(), false);
+ mangleTemplateArgExpr(T->getRowExpr());
+ mangleTemplateArgExpr(T->getColumnExpr());
mangleType(T->getElementType());
Out << "E";
}
@@ -3916,6 +3917,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
// ::= ds <expression> <expression> # expr.*expr
// ::= sZ <template-param> # size of a parameter pack
// ::= sZ <function-param> # size of a function parameter pack
+ // ::= u <source-name> <template-arg>* E # vendor extended expression
// ::= <expr-primary>
// <expr-primary> ::= L <type> <value number> E # integer literal
// ::= L <type <value float> E # floating literal
@@ -4007,14 +4009,26 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
case Expr::CXXUuidofExprClass: {
const CXXUuidofExpr *UE = cast<CXXUuidofExpr>(E);
- if (UE->isTypeOperand()) {
- QualType UuidT = UE->getTypeOperand(Context.getASTContext());
- Out << "u8__uuidoft";
- mangleType(UuidT);
+ // As of clang 12, uuidof uses the vendor extended expression
+ // mangling. Previously, it used a special-cased nonstandard extension.
+ if (Context.getASTContext().getLangOpts().getClangABICompat() >
+ LangOptions::ClangABI::Ver11) {
+ Out << "u8__uuidof";
+ if (UE->isTypeOperand())
+ mangleType(UE->getTypeOperand(Context.getASTContext()));
+ else
+ mangleTemplateArgExpr(UE->getExprOperand());
+ Out << 'E';
} else {
- Expr *UuidExp = UE->getExprOperand();
- Out << "u8__uuidofz";
- mangleExpression(UuidExp, Arity);
+ if (UE->isTypeOperand()) {
+ QualType UuidT = UE->getTypeOperand(Context.getASTContext());
+ Out << "u8__uuidoft";
+ mangleType(UuidT);
+ } else {
+ Expr *UuidExp = UE->getExprOperand();
+ Out << "u8__uuidofz";
+ mangleExpression(UuidExp, Arity);
+ }
}
break;
}
@@ -4312,13 +4326,39 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
break;
}
+ auto MangleAlignofSizeofArg = [&] {
+ if (SAE->isArgumentType()) {
+ Out << 't';
+ mangleType(SAE->getArgumentType());
+ } else {
+ Out << 'z';
+ mangleExpression(SAE->getArgumentExpr());
+ }
+ };
+
switch(SAE->getKind()) {
case UETT_SizeOf:
Out << 's';
+ MangleAlignofSizeofArg();
break;
case UETT_PreferredAlignOf:
+ // As of clang 12, we mangle __alignof__
diff erently than alignof. (They
+ // have acted
diff erently since Clang 8, but were previously mangled the
+ // same.)
+ if (Context.getASTContext().getLangOpts().getClangABICompat() >
+ LangOptions::ClangABI::Ver11) {
+ Out << "u11__alignof__";
+ if (SAE->isArgumentType())
+ mangleType(SAE->getArgumentType());
+ else
+ mangleTemplateArgExpr(SAE->getArgumentExpr());
+ Out << 'E';
+ break;
+ }
+ LLVM_FALLTHROUGH;
case UETT_AlignOf:
Out << 'a';
+ MangleAlignofSizeofArg();
break;
case UETT_VecStep: {
DiagnosticsEngine &Diags = Context.getDiags();
@@ -4336,13 +4376,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
return;
}
}
- if (SAE->isArgumentType()) {
- Out << 't';
- mangleType(SAE->getArgumentType());
- } else {
- Out << 'z';
- mangleExpression(SAE->getArgumentExpr());
- }
break;
}
@@ -4971,23 +5004,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A, bool NeedExactType) {
mangleType(A.getAsTemplateOrTemplatePattern());
break;
case TemplateArgument::Expression: {
- // It's possible to end up with a DeclRefExpr here in certain
- // dependent cases, in which case we should mangle as a
- // declaration.
- const Expr *E = A.getAsExpr()->IgnoreParenImpCasts();
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
- const ValueDecl *D = DRE->getDecl();
- if (isa<VarDecl>(D) || isa<FunctionDecl>(D)) {
- Out << 'L';
- mangle(D);
- Out << 'E';
- break;
- }
- }
-
- Out << 'X';
- mangleExpression(E);
- Out << 'E';
+ mangleTemplateArgExpr(A.getAsExpr());
break;
}
case TemplateArgument::Integral:
@@ -5044,6 +5061,26 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A, bool NeedExactType) {
}
}
+void CXXNameMangler::mangleTemplateArgExpr(const Expr *E) {
+ // It's possible to end up with a DeclRefExpr here in certain
+ // dependent cases, in which case we should mangle as a
+ // declaration.
+ E = E->IgnoreParenImpCasts();
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+ const ValueDecl *D = DRE->getDecl();
+ if (isa<VarDecl>(D) || isa<FunctionDecl>(D)) {
+ Out << 'L';
+ mangle(D);
+ Out << 'E';
+ return;
+ }
+ }
+
+ Out << 'X';
+ mangleExpression(E);
+ Out << 'E';
+}
+
/// Determine whether a given value is equivalent to zero-initialization for
/// the purpose of discarding a trailing portion of a 'tl' mangling.
///
diff --git a/clang/test/CodeGenCXX/mangle-alignof.cpp b/clang/test/CodeGenCXX/mangle-alignof.cpp
new file mode 100644
index 000000000000..0a65c7e87a2d
--- /dev/null
+++ b/clang/test/CodeGenCXX/mangle-alignof.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++11 -Wno-gnu-alignof-expression -emit-llvm %s -o - -triple=%itanium_abi_triple | FileCheck %s --check-prefix=CHECK-NEW
+// RUN: %clang_cc1 -std=c++11 -Wno-gnu-alignof-expression -emit-llvm %s -o - -triple=%itanium_abi_triple -fclang-abi-compat=11 | FileCheck %s --check-prefix=CHECK-OLD
+
+// Verify the
diff erence in mangling for alignof and __alignof__ in a new ABI
+// compat mode.
+
+template <class T> void f1(decltype(alignof(T))) {}
+template void f1<int>(__SIZE_TYPE__);
+// CHECK-OLD: void @_Z2f1IiEvDTatT_E
+// CHECK-NEW: void @_Z2f1IiEvDTatT_E
+
+template <class T> void f2(decltype(__alignof__(T))) {}
+template void f2<int>(__SIZE_TYPE__);
+// CHECK-OLD: void @_Z2f2IiEvDTatT_E
+// CHECK-NEW: void @_Z2f2IiEvDTu11__alignof__T_E
+
+template <class T> void f3(decltype(alignof(T(0)))) {}
+template void f3<int>(__SIZE_TYPE__);
+// CHECK-OLD: void @_Z2f3IiEvDTazcvT_Li0EE
+// CHECK-NEW: void @_Z2f3IiEvDTazcvT_Li0EE
+
+template <class T> void f4(decltype(__alignof__(T(0)))) {}
+template void f4<int>(__SIZE_TYPE__);
+// CHECK-OLD: void @_Z2f4IiEvDTazcvT_Li0EE
+// CHECK-NEW: void @_Z2f4IiEvDTu11__alignof__XcvT_Li0EEEE
diff --git a/clang/test/CodeGenCXX/microsoft-uuidof-mangling.cpp b/clang/test/CodeGenCXX/microsoft-uuidof-mangling.cpp
index ec26be292acc..321f65cacc71 100644
--- a/clang/test/CodeGenCXX/microsoft-uuidof-mangling.cpp
+++ b/clang/test/CodeGenCXX/microsoft-uuidof-mangling.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-unknown-unknown -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-unknown-unknown -fms-extensions | FileCheck %s --check-prefixes=CHECK,CHECK-V12
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-unknown-unknown -fms-extensions -fclang-abi-compat=11 | FileCheck %s --check-prefixes=CHECK,CHECK-V11
// rdar://17784718
typedef struct _GUID
@@ -24,11 +25,16 @@ struct __declspec(uuid("EAFA1952-66F8-438B-8FBA-AF1BBAE42191")) TestStruct
struct __declspec(uuid("EAFA1952-66F8-438B-8FBA-AF1BBAE42191")) OtherStruct {};
-template <class T> void test_uuidofType(void *arg[sizeof(__uuidof(T))] = 0) {}
+template <class T> void test_uuidofType(decltype(__uuidof(T)) arg) {}
-template <class T> void test_uuidofExpr(void *arg[sizeof(__uuidof(typename T::member))] = 0) {}
+template <class T> void test_uuidofExpr(decltype(__uuidof(T::member)) arg) {}
-struct HasMember { typedef TestStruct member; };
+struct HasMember {
+ TestStruct member;
+};
+
+// Ensure that mangling an "expr-primary" argument is handled properly.
+template <class T> void test_uuidofExpr2(decltype(T{}, __uuidof(HasMember::member)) arg) {}
template<const GUID&> struct UUIDTestTwo { UUIDTestTwo(); };
@@ -39,19 +45,29 @@ int main(int argc, const char * argv[])
// type had better not mention TestStruct or OtherStruct!
UUIDTestTwo<__uuidof(TestStruct)> uuidof_test2;
UUIDTestTwo<__uuidof(OtherStruct)> uuidof_test3;
- test_uuidofType<TestStruct>();
- test_uuidofExpr<HasMember>();
+ test_uuidofType<TestStruct>(GUID{});
+ test_uuidofExpr<HasMember>(GUID{});
+ test_uuidofExpr2<TestStruct>(GUID{});
return 0;
}
// CHECK: define{{.*}} i32 @main
-// CHECK: call void @_ZN8UUIDTestI10TestStructL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC1Ev
-// CHECK: call void @_ZN11UUIDTestTwoIL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC1Ev
-// CHECK: call void @_ZN11UUIDTestTwoIL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC1Ev
-// CHECK: call void @_Z15test_uuidofTypeI10TestStructEvPPv(i8** null)
-// CHECK: call void @_Z15test_uuidofExprI9HasMemberEvPPv(i8** null)
-
+// CHECK: call void @_ZN8UUIDTestI10TestStructL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC1Ev(
+// CHECK: call void @_ZN11UUIDTestTwoIL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC1Ev(
+// CHECK: call void @_ZN11UUIDTestTwoIL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC1Ev(
+// CHECK-V11: call void @_Z15test_uuidofTypeI10TestStructEvDTu8__uuidoftT_E(
+// CHECK-V12: call void @_Z15test_uuidofTypeI10TestStructEvDTu8__uuidofT_EE(
+// CHECK-V11: call void @_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofzsrT_6memberE(
+// CHECK-V12: call void @_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofXsrT_6memberEEE(
+// CHECK-V11: call void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofzL_ZN9HasMember6memberEEE(
+// CHECK-V12: call void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofXL_ZN9HasMember6memberEEEEE(
+// TODO: the above mangling is wrong -- the X/E shouldn't be emitted: ^ ^
// CHECK: define linkonce_odr void @_ZN8UUIDTestI10TestStructL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC1Ev
-// CHECK: define linkonce_odr void @_Z15test_uuidofTypeI10TestStructEvPPv
-// CHECK: define linkonce_odr void @_Z15test_uuidofExprI9HasMemberEvPPv
+// CHECK-V11: define linkonce_odr void @_Z15test_uuidofTypeI10TestStructEvDTu8__uuidoftT_E(
+// CHECK-V12: define linkonce_odr void @_Z15test_uuidofTypeI10TestStructEvDTu8__uuidofT_EE(
+// CHECK-V11: define linkonce_odr void @_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofzsrT_6memberE(
+// CHECK-V12: define linkonce_odr void @_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofXsrT_6memberEEE(
+// CHECK-V11: define linkonce_odr void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofzL_ZN9HasMember6memberEEE(
+// CHECK-V12: define linkonce_odr void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofXL_ZN9HasMember6memberEEEEE(
+// TODO: the above mangling is wrong -- the X/E shouldn't be emitted: ^ ^
// CHECK: define linkonce_odr void @_ZN8UUIDTestI10TestStructL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC2Ev
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 6bfc02d15379..e5fca98f9271 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -96,7 +96,6 @@
X(InitListExpr) \
X(FoldExpr) \
X(ThrowExpr) \
- X(UUIDOfExpr) \
X(BoolExpr) \
X(StringLiteral) \
X(LambdaExpr) \
@@ -2035,21 +2034,6 @@ class ThrowExpr : public Node {
}
};
-// 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;
@@ -5013,6 +4997,43 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
}
}
return nullptr;
+ case 'u': {
+ ++First;
+ Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
+ if (!Name)
+ return nullptr;
+ // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
+ // standard encoding expects a <template-arg>, and would be otherwise be
+ // interpreted as <type> node 'short' or 'ellipsis'. However, neither
+ // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
+ // actual conflict here.
+ if (Name->getBaseName() == "__uuidof") {
+ if (numLeft() < 2)
+ return nullptr;
+ if (*First == 't') {
+ ++First;
+ Node *Ty = getDerived().parseType();
+ if (!Ty)
+ return nullptr;
+ return make<CallExpr>(Name, makeNodeArray(&Ty, &Ty + 1));
+ }
+ if (*First == 'z') {
+ ++First;
+ Node *Ex = getDerived().parseExpr();
+ if (!Ex)
+ return nullptr;
+ return make<CallExpr>(Name, makeNodeArray(&Ex, &Ex + 1));
+ }
+ }
+ size_t ExprsBegin = Names.size();
+ while (!consumeIf('E')) {
+ Node *E = getDerived().parseTemplateArg();
+ if (E == nullptr)
+ return E;
+ Names.push_back(E);
+ }
+ return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin));
+ }
case '1':
case '2':
case '3':
@@ -5024,21 +5045,6 @@ 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;
}
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 3954fdba048e..512cc3928fdd 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -29776,8 +29776,18 @@ const char* cases[][2] =
// Vendor extension types are substitution candidates.
{"_Z1fu3fooS_", "f(foo, foo)"},
- {"_ZN3FooIXu8__uuidofzdeL_Z3sucEEEC1Ev", "Foo<__uuidof(*(suc))>::Foo()"},
- {"_ZN3FooIXu8__uuidoft13SomeUUIDClassEEC1Ev", "Foo<__uuidof(SomeUUIDClass)>::Foo()"},
+ // alignof with type and expression, and __alignof__ with the same.
+ {"_Z2f1IiEvDTatT_E", "void f1<int>(decltype(alignof (int)))"},
+ {"_Z2f3IiEvDTazcvT_Li0EE", "void f3<int>(decltype(alignof ((int)(0))))"},
+ {"_Z2f2IiEvDTu11__alignof__T_EE", "void f2<int>(decltype(__alignof__(int)))"},
+ {"_Z2f4IiEvDTu11__alignof__XcvT_Li0EEEE", "void f4<int>(decltype(__alignof__((int)(0))))"},
+
+ // Legacy nonstandard mangling for __uuidof.
+ {"_Z15test_uuidofTypeI10TestStructEvDTu8__uuidoftT_E", "void test_uuidofType<TestStruct>(decltype(__uuidof(TestStruct)))"},
+ {"_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofXsrT_6memberEEE", "void test_uuidofExpr<HasMember>(decltype(__uuidof(HasMember::member)))"},
+ // Current __uuidof mangling using vendor extended expression.
+ {"_Z15test_uuidofTypeI10TestStructEvDTu8__uuidofT_EE", "void test_uuidofType<TestStruct>(decltype(__uuidof(TestStruct)))"},
+ {"_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofXsrT_6memberEEE", "void test_uuidofExpr<HasMember>(decltype(__uuidof(HasMember::member)))"},
// C++2a char8_t:
{"_ZTSPDu", "typeinfo name for char8_t*"},
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 6bfc02d15379..e5fca98f9271 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -96,7 +96,6 @@
X(InitListExpr) \
X(FoldExpr) \
X(ThrowExpr) \
- X(UUIDOfExpr) \
X(BoolExpr) \
X(StringLiteral) \
X(LambdaExpr) \
@@ -2035,21 +2034,6 @@ class ThrowExpr : public Node {
}
};
-// 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;
@@ -5013,6 +4997,43 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
}
}
return nullptr;
+ case 'u': {
+ ++First;
+ Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
+ if (!Name)
+ return nullptr;
+ // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
+ // standard encoding expects a <template-arg>, and would be otherwise be
+ // interpreted as <type> node 'short' or 'ellipsis'. However, neither
+ // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
+ // actual conflict here.
+ if (Name->getBaseName() == "__uuidof") {
+ if (numLeft() < 2)
+ return nullptr;
+ if (*First == 't') {
+ ++First;
+ Node *Ty = getDerived().parseType();
+ if (!Ty)
+ return nullptr;
+ return make<CallExpr>(Name, makeNodeArray(&Ty, &Ty + 1));
+ }
+ if (*First == 'z') {
+ ++First;
+ Node *Ex = getDerived().parseExpr();
+ if (!Ex)
+ return nullptr;
+ return make<CallExpr>(Name, makeNodeArray(&Ex, &Ex + 1));
+ }
+ }
+ size_t ExprsBegin = Names.size();
+ while (!consumeIf('E')) {
+ Node *E = getDerived().parseTemplateArg();
+ if (E == nullptr)
+ return E;
+ Names.push_back(E);
+ }
+ return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin));
+ }
case '1':
case '2':
case '3':
@@ -5024,21 +5045,6 @@ 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;
}
More information about the cfe-commits
mailing list