xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/ItaniumCXXABI.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //===------- ItaniumCXXABI.cpp - AST support for the Itanium C++ ABI ------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This provides C++ AST support targeting the Itanium C++ ABI, which is
100b57cec5SDimitry Andric // documented at:
110b57cec5SDimitry Andric //  http://www.codesourcery.com/public/cxx-abi/abi.html
120b57cec5SDimitry Andric //  http://www.codesourcery.com/public/cxx-abi/abi-eh.html
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric // It also supports the closely-related ARM C++ ABI, documented at:
150b57cec5SDimitry Andric // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
160b57cec5SDimitry Andric //
170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include "CXXABI.h"
200b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
210b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
22a7dea167SDimitry Andric #include "clang/AST/Mangle.h"
230b57cec5SDimitry Andric #include "clang/AST/MangleNumberingContext.h"
240b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
250b57cec5SDimitry Andric #include "clang/AST/Type.h"
260b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
27a7dea167SDimitry Andric #include "llvm/ADT/FoldingSet.h"
280b57cec5SDimitry Andric #include "llvm/ADT/iterator.h"
29*bdd1243dSDimitry Andric #include <optional>
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric using namespace clang;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric namespace {
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric /// According to Itanium C++ ABI 5.1.2:
360b57cec5SDimitry Andric /// the name of an anonymous union is considered to be
370b57cec5SDimitry Andric /// the name of the first named data member found by a pre-order,
380b57cec5SDimitry Andric /// depth-first, declaration-order walk of the data members of
390b57cec5SDimitry Andric /// the anonymous union.
400b57cec5SDimitry Andric /// If there is no such data member (i.e., if all of the data members
410b57cec5SDimitry Andric /// in the union are unnamed), then there is no way for a program to
420b57cec5SDimitry Andric /// refer to the anonymous union, and there is therefore no need to mangle its name.
430b57cec5SDimitry Andric ///
440b57cec5SDimitry Andric /// Returns the name of anonymous union VarDecl or nullptr if it is not found.
findAnonymousUnionVarDeclName(const VarDecl & VD)450b57cec5SDimitry Andric static const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) {
460b57cec5SDimitry Andric   const RecordType *RT = VD.getType()->getAs<RecordType>();
470b57cec5SDimitry Andric   assert(RT && "type of VarDecl is expected to be RecordType.");
480b57cec5SDimitry Andric   assert(RT->getDecl()->isUnion() && "RecordType is expected to be a union.");
490b57cec5SDimitry Andric   if (const FieldDecl *FD = RT->getDecl()->findFirstNamedDataMember()) {
500b57cec5SDimitry Andric     return FD->getIdentifier();
510b57cec5SDimitry Andric   }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   return nullptr;
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric /// The name of a decomposition declaration.
570b57cec5SDimitry Andric struct DecompositionDeclName {
580b57cec5SDimitry Andric   using BindingArray = ArrayRef<const BindingDecl*>;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   /// Representative example of a set of bindings with these names.
610b57cec5SDimitry Andric   BindingArray Bindings;
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   /// Iterators over the sequence of identifiers in the name.
640b57cec5SDimitry Andric   struct Iterator
650b57cec5SDimitry Andric       : llvm::iterator_adaptor_base<Iterator, BindingArray::const_iterator,
660b57cec5SDimitry Andric                                     std::random_access_iterator_tag,
670b57cec5SDimitry Andric                                     const IdentifierInfo *> {
Iterator__anone02e58390111::DecompositionDeclName::Iterator680b57cec5SDimitry Andric     Iterator(BindingArray::const_iterator It) : iterator_adaptor_base(It) {}
operator *__anone02e58390111::DecompositionDeclName::Iterator690b57cec5SDimitry Andric     const IdentifierInfo *operator*() const {
700b57cec5SDimitry Andric       return (*this->I)->getIdentifier();
710b57cec5SDimitry Andric     }
720b57cec5SDimitry Andric   };
begin__anone02e58390111::DecompositionDeclName730b57cec5SDimitry Andric   Iterator begin() const { return Iterator(Bindings.begin()); }
end__anone02e58390111::DecompositionDeclName740b57cec5SDimitry Andric   Iterator end() const { return Iterator(Bindings.end()); }
750b57cec5SDimitry Andric };
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric namespace llvm {
isDenseMapKeyEmpty(T V)79a7dea167SDimitry Andric template<typename T> bool isDenseMapKeyEmpty(T V) {
80a7dea167SDimitry Andric   return llvm::DenseMapInfo<T>::isEqual(
81a7dea167SDimitry Andric       V, llvm::DenseMapInfo<T>::getEmptyKey());
82a7dea167SDimitry Andric }
isDenseMapKeyTombstone(T V)83a7dea167SDimitry Andric template<typename T> bool isDenseMapKeyTombstone(T V) {
84a7dea167SDimitry Andric   return llvm::DenseMapInfo<T>::isEqual(
85a7dea167SDimitry Andric       V, llvm::DenseMapInfo<T>::getTombstoneKey());
86a7dea167SDimitry Andric }
87a7dea167SDimitry Andric 
88a7dea167SDimitry Andric template <typename T>
areDenseMapKeysEqualSpecialValues(T LHS,T RHS)89*bdd1243dSDimitry Andric std::optional<bool> areDenseMapKeysEqualSpecialValues(T LHS, T RHS) {
90a7dea167SDimitry Andric   bool LHSEmpty = isDenseMapKeyEmpty(LHS);
91a7dea167SDimitry Andric   bool RHSEmpty = isDenseMapKeyEmpty(RHS);
92a7dea167SDimitry Andric   if (LHSEmpty || RHSEmpty)
93a7dea167SDimitry Andric     return LHSEmpty && RHSEmpty;
94a7dea167SDimitry Andric 
95a7dea167SDimitry Andric   bool LHSTombstone = isDenseMapKeyTombstone(LHS);
96a7dea167SDimitry Andric   bool RHSTombstone = isDenseMapKeyTombstone(RHS);
97a7dea167SDimitry Andric   if (LHSTombstone || RHSTombstone)
98a7dea167SDimitry Andric     return LHSTombstone && RHSTombstone;
99a7dea167SDimitry Andric 
100*bdd1243dSDimitry Andric   return std::nullopt;
101a7dea167SDimitry Andric }
102a7dea167SDimitry Andric 
1030b57cec5SDimitry Andric template<>
1040b57cec5SDimitry Andric struct DenseMapInfo<DecompositionDeclName> {
1050b57cec5SDimitry Andric   using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>;
getEmptyKeyllvm::DenseMapInfo1060b57cec5SDimitry Andric   static DecompositionDeclName getEmptyKey() {
1070b57cec5SDimitry Andric     return {ArrayInfo::getEmptyKey()};
1080b57cec5SDimitry Andric   }
getTombstoneKeyllvm::DenseMapInfo1090b57cec5SDimitry Andric   static DecompositionDeclName getTombstoneKey() {
1100b57cec5SDimitry Andric     return {ArrayInfo::getTombstoneKey()};
1110b57cec5SDimitry Andric   }
getHashValuellvm::DenseMapInfo1120b57cec5SDimitry Andric   static unsigned getHashValue(DecompositionDeclName Key) {
1130b57cec5SDimitry Andric     assert(!isEqual(Key, getEmptyKey()) && !isEqual(Key, getTombstoneKey()));
1140b57cec5SDimitry Andric     return llvm::hash_combine_range(Key.begin(), Key.end());
1150b57cec5SDimitry Andric   }
isEqualllvm::DenseMapInfo1160b57cec5SDimitry Andric   static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS) {
117*bdd1243dSDimitry Andric     if (std::optional<bool> Result =
118*bdd1243dSDimitry Andric             areDenseMapKeysEqualSpecialValues(LHS.Bindings, RHS.Bindings))
119a7dea167SDimitry Andric       return *Result;
120a7dea167SDimitry Andric 
1210b57cec5SDimitry Andric     return LHS.Bindings.size() == RHS.Bindings.size() &&
1220b57cec5SDimitry Andric            std::equal(LHS.begin(), LHS.end(), RHS.begin());
1230b57cec5SDimitry Andric   }
1240b57cec5SDimitry Andric };
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric namespace {
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric /// Keeps track of the mangled names of lambda expressions and block
1300b57cec5SDimitry Andric /// literals within a particular context.
1310b57cec5SDimitry Andric class ItaniumNumberingContext : public MangleNumberingContext {
132a7dea167SDimitry Andric   ItaniumMangleContext *Mangler;
133a7dea167SDimitry Andric   llvm::StringMap<unsigned> LambdaManglingNumbers;
134a7dea167SDimitry Andric   unsigned BlockManglingNumber = 0;
1350b57cec5SDimitry Andric   llvm::DenseMap<const IdentifierInfo *, unsigned> VarManglingNumbers;
1360b57cec5SDimitry Andric   llvm::DenseMap<const IdentifierInfo *, unsigned> TagManglingNumbers;
1370b57cec5SDimitry Andric   llvm::DenseMap<DecompositionDeclName, unsigned>
1380b57cec5SDimitry Andric       DecompsitionDeclManglingNumbers;
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric public:
ItaniumNumberingContext(ItaniumMangleContext * Mangler)141a7dea167SDimitry Andric   ItaniumNumberingContext(ItaniumMangleContext *Mangler) : Mangler(Mangler) {}
1420b57cec5SDimitry Andric 
getManglingNumber(const CXXMethodDecl * CallOperator)143a7dea167SDimitry Andric   unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
144a7dea167SDimitry Andric     const CXXRecordDecl *Lambda = CallOperator->getParent();
145a7dea167SDimitry Andric     assert(Lambda->isLambda());
146a7dea167SDimitry Andric 
147a7dea167SDimitry Andric     // Computation of the <lambda-sig> is non-trivial and subtle. Rather than
148a7dea167SDimitry Andric     // duplicating it here, just mangle the <lambda-sig> directly.
149a7dea167SDimitry Andric     llvm::SmallString<128> LambdaSig;
150a7dea167SDimitry Andric     llvm::raw_svector_ostream Out(LambdaSig);
151a7dea167SDimitry Andric     Mangler->mangleLambdaSig(Lambda, Out);
152a7dea167SDimitry Andric 
153a7dea167SDimitry Andric     return ++LambdaManglingNumbers[LambdaSig];
1540b57cec5SDimitry Andric   }
1550b57cec5SDimitry Andric 
getManglingNumber(const BlockDecl * BD)1560b57cec5SDimitry Andric   unsigned getManglingNumber(const BlockDecl *BD) override {
157a7dea167SDimitry Andric     return ++BlockManglingNumber;
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric 
getStaticLocalNumber(const VarDecl * VD)1600b57cec5SDimitry Andric   unsigned getStaticLocalNumber(const VarDecl *VD) override {
1610b57cec5SDimitry Andric     return 0;
1620b57cec5SDimitry Andric   }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   /// Variable decls are numbered by identifier.
getManglingNumber(const VarDecl * VD,unsigned)1650b57cec5SDimitry Andric   unsigned getManglingNumber(const VarDecl *VD, unsigned) override {
1660b57cec5SDimitry Andric     if (auto *DD = dyn_cast<DecompositionDecl>(VD)) {
1670b57cec5SDimitry Andric       DecompositionDeclName Name{DD->bindings()};
1680b57cec5SDimitry Andric       return ++DecompsitionDeclManglingNumbers[Name];
1690b57cec5SDimitry Andric     }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric     const IdentifierInfo *Identifier = VD->getIdentifier();
1720b57cec5SDimitry Andric     if (!Identifier) {
1730b57cec5SDimitry Andric       // VarDecl without an identifier represents an anonymous union
1740b57cec5SDimitry Andric       // declaration.
1750b57cec5SDimitry Andric       Identifier = findAnonymousUnionVarDeclName(*VD);
1760b57cec5SDimitry Andric     }
1770b57cec5SDimitry Andric     return ++VarManglingNumbers[Identifier];
1780b57cec5SDimitry Andric   }
1790b57cec5SDimitry Andric 
getManglingNumber(const TagDecl * TD,unsigned)1800b57cec5SDimitry Andric   unsigned getManglingNumber(const TagDecl *TD, unsigned) override {
1810b57cec5SDimitry Andric     return ++TagManglingNumbers[TD->getIdentifier()];
1820b57cec5SDimitry Andric   }
1830b57cec5SDimitry Andric };
1840b57cec5SDimitry Andric 
185349cc55cSDimitry Andric // A version of this for SYCL that makes sure that 'device' mangling context
186349cc55cSDimitry Andric // matches the lambda mangling number, so that __builtin_sycl_unique_stable_name
187349cc55cSDimitry Andric // can be consistently generated between a MS and Itanium host by just referring
188349cc55cSDimitry Andric // to the device mangling number.
189349cc55cSDimitry Andric class ItaniumSYCLNumberingContext : public ItaniumNumberingContext {
190349cc55cSDimitry Andric   llvm::DenseMap<const CXXMethodDecl *, unsigned> ManglingNumbers;
191349cc55cSDimitry Andric   using ManglingItr = decltype(ManglingNumbers)::iterator;
192349cc55cSDimitry Andric 
193349cc55cSDimitry Andric public:
ItaniumSYCLNumberingContext(ItaniumMangleContext * Mangler)194349cc55cSDimitry Andric   ItaniumSYCLNumberingContext(ItaniumMangleContext *Mangler)
195349cc55cSDimitry Andric       : ItaniumNumberingContext(Mangler) {}
196349cc55cSDimitry Andric 
getManglingNumber(const CXXMethodDecl * CallOperator)197349cc55cSDimitry Andric   unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
198349cc55cSDimitry Andric     unsigned Number = ItaniumNumberingContext::getManglingNumber(CallOperator);
199349cc55cSDimitry Andric     std::pair<ManglingItr, bool> emplace_result =
200349cc55cSDimitry Andric         ManglingNumbers.try_emplace(CallOperator, Number);
201349cc55cSDimitry Andric     (void)emplace_result;
202349cc55cSDimitry Andric     assert(emplace_result.second && "Lambda number set multiple times?");
203349cc55cSDimitry Andric     return Number;
204349cc55cSDimitry Andric   }
205349cc55cSDimitry Andric 
206349cc55cSDimitry Andric   using ItaniumNumberingContext::getManglingNumber;
207349cc55cSDimitry Andric 
getDeviceManglingNumber(const CXXMethodDecl * CallOperator)208349cc55cSDimitry Andric   unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
209349cc55cSDimitry Andric     ManglingItr Itr = ManglingNumbers.find(CallOperator);
210349cc55cSDimitry Andric     assert(Itr != ManglingNumbers.end() && "Lambda not yet mangled?");
211349cc55cSDimitry Andric 
212349cc55cSDimitry Andric     return Itr->second;
213349cc55cSDimitry Andric   }
214349cc55cSDimitry Andric };
215349cc55cSDimitry Andric 
2160b57cec5SDimitry Andric class ItaniumCXXABI : public CXXABI {
217a7dea167SDimitry Andric private:
218a7dea167SDimitry Andric   std::unique_ptr<MangleContext> Mangler;
2190b57cec5SDimitry Andric protected:
2200b57cec5SDimitry Andric   ASTContext &Context;
2210b57cec5SDimitry Andric public:
ItaniumCXXABI(ASTContext & Ctx)222a7dea167SDimitry Andric   ItaniumCXXABI(ASTContext &Ctx)
223a7dea167SDimitry Andric       : Mangler(Ctx.createMangleContext()), Context(Ctx) {}
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   MemberPointerInfo
getMemberPointerInfo(const MemberPointerType * MPT) const2260b57cec5SDimitry Andric   getMemberPointerInfo(const MemberPointerType *MPT) const override {
2270b57cec5SDimitry Andric     const TargetInfo &Target = Context.getTargetInfo();
228*bdd1243dSDimitry Andric     TargetInfo::IntType PtrDiff = Target.getPtrDiffType(LangAS::Default);
2290b57cec5SDimitry Andric     MemberPointerInfo MPI;
2300b57cec5SDimitry Andric     MPI.Width = Target.getTypeWidth(PtrDiff);
2310b57cec5SDimitry Andric     MPI.Align = Target.getTypeAlign(PtrDiff);
2320b57cec5SDimitry Andric     MPI.HasPadding = false;
2330b57cec5SDimitry Andric     if (MPT->isMemberFunctionPointer())
2340b57cec5SDimitry Andric       MPI.Width *= 2;
2350b57cec5SDimitry Andric     return MPI;
2360b57cec5SDimitry Andric   }
2370b57cec5SDimitry Andric 
getDefaultMethodCallConv(bool isVariadic) const2380b57cec5SDimitry Andric   CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
2390b57cec5SDimitry Andric     const llvm::Triple &T = Context.getTargetInfo().getTriple();
2400b57cec5SDimitry Andric     if (!isVariadic && T.isWindowsGNUEnvironment() &&
2410b57cec5SDimitry Andric         T.getArch() == llvm::Triple::x86)
2420b57cec5SDimitry Andric       return CC_X86ThisCall;
2430b57cec5SDimitry Andric     return Context.getTargetInfo().getDefaultCallingConv();
2440b57cec5SDimitry Andric   }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric   // We cheat and just check that the class has a vtable pointer, and that it's
2470b57cec5SDimitry Andric   // only big enough to have a vtable pointer and nothing more (or less).
isNearlyEmpty(const CXXRecordDecl * RD) const2480b57cec5SDimitry Andric   bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric     // Check that the class has a vtable pointer.
2510b57cec5SDimitry Andric     if (!RD->isDynamicClass())
2520b57cec5SDimitry Andric       return false;
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
255*bdd1243dSDimitry Andric     CharUnits PointerSize = Context.toCharUnitsFromBits(
256*bdd1243dSDimitry Andric         Context.getTargetInfo().getPointerWidth(LangAS::Default));
2570b57cec5SDimitry Andric     return Layout.getNonVirtualSize() == PointerSize;
2580b57cec5SDimitry Andric   }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   const CXXConstructorDecl *
getCopyConstructorForExceptionObject(CXXRecordDecl * RD)2610b57cec5SDimitry Andric   getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
2620b57cec5SDimitry Andric     return nullptr;
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
addCopyConstructorForExceptionObject(CXXRecordDecl * RD,CXXConstructorDecl * CD)2650b57cec5SDimitry Andric   void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
2660b57cec5SDimitry Andric                                             CXXConstructorDecl *CD) override {}
2670b57cec5SDimitry Andric 
addTypedefNameForUnnamedTagDecl(TagDecl * TD,TypedefNameDecl * DD)2680b57cec5SDimitry Andric   void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
2690b57cec5SDimitry Andric                                        TypedefNameDecl *DD) override {}
2700b57cec5SDimitry Andric 
getTypedefNameForUnnamedTagDecl(const TagDecl * TD)2710b57cec5SDimitry Andric   TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
2720b57cec5SDimitry Andric     return nullptr;
2730b57cec5SDimitry Andric   }
2740b57cec5SDimitry Andric 
addDeclaratorForUnnamedTagDecl(TagDecl * TD,DeclaratorDecl * DD)2750b57cec5SDimitry Andric   void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
2760b57cec5SDimitry Andric                                       DeclaratorDecl *DD) override {}
2770b57cec5SDimitry Andric 
getDeclaratorForUnnamedTagDecl(const TagDecl * TD)2780b57cec5SDimitry Andric   DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
2790b57cec5SDimitry Andric     return nullptr;
2800b57cec5SDimitry Andric   }
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   std::unique_ptr<MangleNumberingContext>
createMangleNumberingContext() const2830b57cec5SDimitry Andric   createMangleNumberingContext() const override {
284349cc55cSDimitry Andric     if (Context.getLangOpts().isSYCL())
285349cc55cSDimitry Andric       return std::make_unique<ItaniumSYCLNumberingContext>(
286349cc55cSDimitry Andric           cast<ItaniumMangleContext>(Mangler.get()));
287a7dea167SDimitry Andric     return std::make_unique<ItaniumNumberingContext>(
288a7dea167SDimitry Andric         cast<ItaniumMangleContext>(Mangler.get()));
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric };
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
CreateItaniumCXXABI(ASTContext & Ctx)2930b57cec5SDimitry Andric CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) {
2940b57cec5SDimitry Andric   return new ItaniumCXXABI(Ctx);
2950b57cec5SDimitry Andric }
296d409305fSDimitry Andric 
297d409305fSDimitry Andric std::unique_ptr<MangleNumberingContext>
createItaniumNumberingContext(MangleContext * Mangler)298d409305fSDimitry Andric clang::createItaniumNumberingContext(MangleContext *Mangler) {
299d409305fSDimitry Andric   return std::make_unique<ItaniumNumberingContext>(
300d409305fSDimitry Andric       cast<ItaniumMangleContext>(Mangler));
301d409305fSDimitry Andric }
302