diff options
Diffstat (limited to 'lib/AST/ItaniumCXXABI.cpp')
| -rw-r--r-- | lib/AST/ItaniumCXXABI.cpp | 260 | 
1 files changed, 0 insertions, 260 deletions
diff --git a/lib/AST/ItaniumCXXABI.cpp b/lib/AST/ItaniumCXXABI.cpp deleted file mode 100644 index 069add8464ae8..0000000000000 --- a/lib/AST/ItaniumCXXABI.cpp +++ /dev/null @@ -1,260 +0,0 @@ -//===------- ItaniumCXXABI.cpp - AST support for the Itanium C++ ABI ------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This provides C++ AST support targeting the Itanium C++ ABI, which is -// documented at: -//  http://www.codesourcery.com/public/cxx-abi/abi.html -//  http://www.codesourcery.com/public/cxx-abi/abi-eh.html -// -// It also supports the closely-related ARM C++ ABI, documented at: -// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf -// -//===----------------------------------------------------------------------===// - -#include "CXXABI.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/Mangle.h" -#include "clang/AST/MangleNumberingContext.h" -#include "clang/AST/RecordLayout.h" -#include "clang/AST/Type.h" -#include "clang/Basic/TargetInfo.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/iterator.h" - -using namespace clang; - -namespace { - -/// According to Itanium C++ ABI 5.1.2: -/// the name of an anonymous union is considered to be -/// the name of the first named data member found by a pre-order, -/// depth-first, declaration-order walk of the data members of -/// the anonymous union. -/// If there is no such data member (i.e., if all of the data members -/// in the union are unnamed), then there is no way for a program to -/// refer to the anonymous union, and there is therefore no need to mangle its name. -/// -/// Returns the name of anonymous union VarDecl or nullptr if it is not found. -static const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) { -  const RecordType *RT = VD.getType()->getAs<RecordType>(); -  assert(RT && "type of VarDecl is expected to be RecordType."); -  assert(RT->getDecl()->isUnion() && "RecordType is expected to be a union."); -  if (const FieldDecl *FD = RT->getDecl()->findFirstNamedDataMember()) { -    return FD->getIdentifier(); -  } - -  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<typename T> bool isDenseMapKeyEmpty(T V) { -  return llvm::DenseMapInfo<T>::isEqual( -      V, llvm::DenseMapInfo<T>::getEmptyKey()); -} -template<typename T> bool isDenseMapKeyTombstone(T V) { -  return llvm::DenseMapInfo<T>::isEqual( -      V, llvm::DenseMapInfo<T>::getTombstoneKey()); -} - -template<typename T> -Optional<bool> areDenseMapKeysEqualSpecialValues(T LHS, T RHS) { -  bool LHSEmpty = isDenseMapKeyEmpty(LHS); -  bool RHSEmpty = isDenseMapKeyEmpty(RHS); -  if (LHSEmpty || RHSEmpty) -    return LHSEmpty && RHSEmpty; - -  bool LHSTombstone = isDenseMapKeyTombstone(LHS); -  bool RHSTombstone = isDenseMapKeyTombstone(RHS); -  if (LHSTombstone || RHSTombstone) -    return LHSTombstone && RHSTombstone; - -  return None; -} - -template<> -struct DenseMapInfo<DecompositionDeclName> { -  using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>; -  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 (Optional<bool> Result = areDenseMapKeysEqualSpecialValues( -            LHS.Bindings, RHS.Bindings)) -      return *Result; - -    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 { -  ItaniumMangleContext *Mangler; -  llvm::StringMap<unsigned> LambdaManglingNumbers; -  unsigned BlockManglingNumber = 0; -  llvm::DenseMap<const IdentifierInfo *, unsigned> VarManglingNumbers; -  llvm::DenseMap<const IdentifierInfo *, unsigned> TagManglingNumbers; -  llvm::DenseMap<DecompositionDeclName, unsigned> -      DecompsitionDeclManglingNumbers; - -public: -  ItaniumNumberingContext(ItaniumMangleContext *Mangler) : Mangler(Mangler) {} - -  unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { -    const CXXRecordDecl *Lambda = CallOperator->getParent(); -    assert(Lambda->isLambda()); - -    // Computation of the <lambda-sig> is non-trivial and subtle. Rather than -    // duplicating it here, just mangle the <lambda-sig> directly. -    llvm::SmallString<128> LambdaSig; -    llvm::raw_svector_ostream Out(LambdaSig); -    Mangler->mangleLambdaSig(Lambda, Out); - -    return ++LambdaManglingNumbers[LambdaSig]; -  } - -  unsigned getManglingNumber(const BlockDecl *BD) override { -    return ++BlockManglingNumber; -  } - -  unsigned getStaticLocalNumber(const VarDecl *VD) override { -    return 0; -  } - -  /// Variable decls are numbered by identifier. -  unsigned getManglingNumber(const VarDecl *VD, unsigned) override { -    if (auto *DD = dyn_cast<DecompositionDecl>(VD)) { -      DecompositionDeclName Name{DD->bindings()}; -      return ++DecompsitionDeclManglingNumbers[Name]; -    } - -    const IdentifierInfo *Identifier = VD->getIdentifier(); -    if (!Identifier) { -      // VarDecl without an identifier represents an anonymous union -      // declaration. -      Identifier = findAnonymousUnionVarDeclName(*VD); -    } -    return ++VarManglingNumbers[Identifier]; -  } - -  unsigned getManglingNumber(const TagDecl *TD, unsigned) override { -    return ++TagManglingNumbers[TD->getIdentifier()]; -  } -}; - -class ItaniumCXXABI : public CXXABI { -private: -  std::unique_ptr<MangleContext> Mangler; -protected: -  ASTContext &Context; -public: -  ItaniumCXXABI(ASTContext &Ctx) -      : Mangler(Ctx.createMangleContext()), Context(Ctx) {} - -  MemberPointerInfo -  getMemberPointerInfo(const MemberPointerType *MPT) const override { -    const TargetInfo &Target = Context.getTargetInfo(); -    TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0); -    MemberPointerInfo MPI; -    MPI.Width = Target.getTypeWidth(PtrDiff); -    MPI.Align = Target.getTypeAlign(PtrDiff); -    MPI.HasPadding = false; -    if (MPT->isMemberFunctionPointer()) -      MPI.Width *= 2; -    return MPI; -  } - -  CallingConv getDefaultMethodCallConv(bool isVariadic) const override { -    const llvm::Triple &T = Context.getTargetInfo().getTriple(); -    if (!isVariadic && T.isWindowsGNUEnvironment() && -        T.getArch() == llvm::Triple::x86) -      return CC_X86ThisCall; -    return Context.getTargetInfo().getDefaultCallingConv(); -  } - -  // We cheat and just check that the class has a vtable pointer, and that it's -  // only big enough to have a vtable pointer and nothing more (or less). -  bool isNearlyEmpty(const CXXRecordDecl *RD) const override { - -    // Check that the class has a vtable pointer. -    if (!RD->isDynamicClass()) -      return false; - -    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); -    CharUnits PointerSize = -      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); -    return Layout.getNonVirtualSize() == PointerSize; -  } - -  const CXXConstructorDecl * -  getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override { -    return nullptr; -  } - -  void addCopyConstructorForExceptionObject(CXXRecordDecl *RD, -                                            CXXConstructorDecl *CD) override {} - -  void addTypedefNameForUnnamedTagDecl(TagDecl *TD, -                                       TypedefNameDecl *DD) override {} - -  TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override { -    return nullptr; -  } - -  void addDeclaratorForUnnamedTagDecl(TagDecl *TD, -                                      DeclaratorDecl *DD) override {} - -  DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override { -    return nullptr; -  } - -  std::unique_ptr<MangleNumberingContext> -  createMangleNumberingContext() const override { -    return std::make_unique<ItaniumNumberingContext>( -        cast<ItaniumMangleContext>(Mangler.get())); -  } -}; -} - -CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) { -  return new ItaniumCXXABI(Ctx); -}  | 
