P0217R3: Parsing support and framework for AST representation of C++1z
decomposition declarations.
There are a couple of things in the wording that seem strange here:
decomposition declarations are permitted at namespace scope (which we partially
support here) and they are permitted as the declaration in a template (which we
reject).
llvm-svn: 276492
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 51de561..5b27831 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -593,7 +593,7 @@
return false;
const VarDecl *VD = dyn_cast<VarDecl>(D);
- if (VD) {
+ if (VD && !isa<DecompositionDecl>(D)) {
// C variables are not mangled.
if (VD->isExternC())
return false;
@@ -1193,7 +1193,23 @@
// ::= <source-name>
switch (Name.getNameKind()) {
case DeclarationName::Identifier: {
- if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+ const IdentifierInfo *II = Name.getAsIdentifierInfo();
+
+ // We mangle decomposition declarations as the name of their first binding.
+ if (auto *DD = dyn_cast<DecompositionDecl>(ND)) {
+ auto B = DD->bindings();
+ if (B.begin() == B.end()) {
+ // FIXME: This is ill-formed but we accept it as an extension.
+ DiagnosticsEngine &Diags = Context.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "cannot mangle global empty decomposition decl");
+ Diags.Report(DD->getLocation(), DiagID);
+ break;
+ }
+ II = (*B.begin())->getIdentifier();
+ }
+
+ if (II) {
// We must avoid conflicts between internally- and externally-
// linked variable and function declaration names in the same TU:
// void test() { extern void foo(); }