r331692 - PR37352: mangle numbering for decomposition declarations.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon May 7 15:23:38 PDT 2018


Author: rsmith
Date: Mon May  7 15:23:38 2018
New Revision: 331692

URL: http://llvm.org/viewvc/llvm-project?rev=331692&view=rev
Log:
PR37352: mangle numbering for decomposition declarations.

In order to match our mangling scheme, use a different set of numbers for
decomposition declarations, and consider all binding names when forming the
numbering. This does not yet affect any mangled names we produce, because
local decomposition declarations can't yet have linkage, but a C++ standard
proposal to change that is currently being processed.

Modified:
    cfe/trunk/lib/AST/ItaniumCXXABI.cpp
    cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp

Modified: cfe/trunk/lib/AST/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumCXXABI.cpp?rev=331692&r1=331691&r2=331692&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumCXXABI.cpp Mon May  7 15:23:38 2018
@@ -24,6 +24,7 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/iterator.h"
 
 using namespace clang;
 
@@ -50,12 +51,64 @@ static const IdentifierInfo *findAnonymo
   return nullptr;
 }
 
+/// The name of a decomposition declaration.
+struct DecompositionDeclName {
+  using BindingArray = ArrayRef<const BindingDecl*>;
+
+  /// Representative example of a set of bindings with these names.
+  BindingArray Bindings;
+
+  /// Iterators over the sequence of identifiers in the name.
+  struct Iterator
+      : llvm::iterator_adaptor_base<Iterator, BindingArray::const_iterator,
+                                    std::random_access_iterator_tag,
+                                    const IdentifierInfo *> {
+    Iterator(BindingArray::const_iterator It) : iterator_adaptor_base(It) {}
+    const IdentifierInfo *operator*() const {
+      return (*this->I)->getIdentifier();
+    }
+  };
+  Iterator begin() const { return Iterator(Bindings.begin()); }
+  Iterator end() const { return Iterator(Bindings.end()); }
+};
+}
+
+namespace llvm {
+template<>
+struct DenseMapInfo<DecompositionDeclName> {
+  using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>;
+  using IdentInfo = llvm::DenseMapInfo<const IdentifierInfo*>;
+  static DecompositionDeclName getEmptyKey() {
+    return {ArrayInfo::getEmptyKey()};
+  }
+  static DecompositionDeclName getTombstoneKey() {
+    return {ArrayInfo::getTombstoneKey()};
+  }
+  static unsigned getHashValue(DecompositionDeclName Key) {
+    assert(!isEqual(Key, getEmptyKey()) && !isEqual(Key, getTombstoneKey()));
+    return llvm::hash_combine_range(Key.begin(), Key.end());
+  }
+  static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS) {
+    if (ArrayInfo::isEqual(LHS.Bindings, ArrayInfo::getEmptyKey()))
+      return ArrayInfo::isEqual(RHS.Bindings, ArrayInfo::getEmptyKey());
+    if (ArrayInfo::isEqual(LHS.Bindings, ArrayInfo::getTombstoneKey()))
+      return ArrayInfo::isEqual(RHS.Bindings, ArrayInfo::getTombstoneKey());
+    return LHS.Bindings.size() == RHS.Bindings.size() &&
+           std::equal(LHS.begin(), LHS.end(), RHS.begin());
+  }
+};
+}
+
+namespace {
+
 /// \brief Keeps track of the mangled names of lambda expressions and block
 /// literals within a particular context.
 class ItaniumNumberingContext : public MangleNumberingContext {
   llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
   llvm::DenseMap<const IdentifierInfo *, unsigned> VarManglingNumbers;
   llvm::DenseMap<const IdentifierInfo *, unsigned> TagManglingNumbers;
+  llvm::DenseMap<DecompositionDeclName, unsigned>
+      DecompsitionDeclManglingNumbers;
 
 public:
   unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
@@ -82,9 +135,14 @@ public:
 
   /// Variable decls are numbered by identifier.
   unsigned getManglingNumber(const VarDecl *VD, unsigned) override {
+    if (auto *DD = dyn_cast<DecompositionDecl>(VD))
+      return ++DecompsitionDeclManglingNumbers[
+          DecompositionDeclName{DD->bindings()}];
+
     const IdentifierInfo *Identifier = VD->getIdentifier();
     if (!Identifier) {
-      // VarDecl without an identifier represents an anonymous union declaration.
+      // VarDecl without an identifier represents an anonymous union
+      // declaration.
       Identifier = findAnonymousUnionVarDeclName(*VD);
     }
     return ++VarManglingNumbers[Identifier];

Modified: cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp?rev=331692&r1=331691&r2=331692&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp Mon May  7 15:23:38 2018
@@ -76,4 +76,9 @@ template <class T> void dependent_foreac
     a,b,c;
 }
 
+struct PR37352 {
+  int n;
+  void f() { static auto [a] = *this; } // expected-error {{cannot be declared 'static'}}
+};
+
 // FIXME: by-value array copies




More information about the cfe-commits mailing list