From 486754660bb926339aefcf012a3f848592babb8b Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 28 Jul 2018 11:06:01 +0000 Subject: Vendor import of clang trunk r338150: https://llvm.org/svn/llvm-project/cfe/trunk@338150 --- lib/AST/ItaniumCXXABI.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) (limited to 'lib/AST/ItaniumCXXABI.cpp') diff --git a/lib/AST/ItaniumCXXABI.cpp b/lib/AST/ItaniumCXXABI.cpp index d6bc16b6350f..a75ae14f9015 100644 --- a/lib/AST/ItaniumCXXABI.cpp +++ b/lib/AST/ItaniumCXXABI.cpp @@ -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; } -/// \brief Keeps track of the mangled names of lambda expressions and block +/// The name of a decomposition declaration. +struct DecompositionDeclName { + using BindingArray = ArrayRef; + + /// 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 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 { + using ArrayInfo = llvm::DenseMapInfo>; + using IdentInfo = llvm::DenseMapInfo; + 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 { + +/// Keeps track of the mangled names of lambda expressions and block /// literals within a particular context. class ItaniumNumberingContext : public MangleNumberingContext { llvm::DenseMap ManglingNumbers; llvm::DenseMap VarManglingNumbers; llvm::DenseMap TagManglingNumbers; + llvm::DenseMap + DecompsitionDeclManglingNumbers; public: unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { @@ -82,9 +135,15 @@ public: /// Variable decls are numbered by identifier. unsigned getManglingNumber(const VarDecl *VD, unsigned) override { + if (auto *DD = dyn_cast(VD)) { + DecompositionDeclName Name{DD->bindings()}; + return ++DecompsitionDeclManglingNumbers[Name]; + } + 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]; -- cgit v1.2.3