forked from OSchip/llvm-project
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. llvm-svn: 331692
This commit is contained in:
parent
37444285f1
commit
a6cede6d8e
|
@ -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 *findAnonymousUnionVarDeclName(const VarDecl& VD) {
|
|||
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];
|
||||
|
|
|
@ -76,4 +76,9 @@ template <class T> void dependent_foreach(T t) {
|
|||
a,b,c;
|
||||
}
|
||||
|
||||
struct PR37352 {
|
||||
int n;
|
||||
void f() { static auto [a] = *this; } // expected-error {{cannot be declared 'static'}}
|
||||
};
|
||||
|
||||
// FIXME: by-value array copies
|
||||
|
|
Loading…
Reference in New Issue