1*f4a2713aSLionel Sambuc //===------- ItaniumCXXABI.cpp - AST support for the Itanium C++ ABI ------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This provides C++ AST support targeting the Itanium C++ ABI, which is 11*f4a2713aSLionel Sambuc // documented at: 12*f4a2713aSLionel Sambuc // http://www.codesourcery.com/public/cxx-abi/abi.html 13*f4a2713aSLionel Sambuc // http://www.codesourcery.com/public/cxx-abi/abi-eh.html 14*f4a2713aSLionel Sambuc // 15*f4a2713aSLionel Sambuc // It also supports the closely-related ARM C++ ABI, documented at: 16*f4a2713aSLionel Sambuc // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf 17*f4a2713aSLionel Sambuc // 18*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 19*f4a2713aSLionel Sambuc 20*f4a2713aSLionel Sambuc #include "CXXABI.h" 21*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h" 22*f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h" 23*f4a2713aSLionel Sambuc #include "clang/AST/MangleNumberingContext.h" 24*f4a2713aSLionel Sambuc #include "clang/AST/RecordLayout.h" 25*f4a2713aSLionel Sambuc #include "clang/AST/Type.h" 26*f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h" 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc using namespace clang; 29*f4a2713aSLionel Sambuc 30*f4a2713aSLionel Sambuc namespace { 31*f4a2713aSLionel Sambuc 32*f4a2713aSLionel Sambuc /// \brief Keeps track of the mangled names of lambda expressions and block 33*f4a2713aSLionel Sambuc /// literals within a particular context. 34*f4a2713aSLionel Sambuc class ItaniumNumberingContext : public MangleNumberingContext { 35*f4a2713aSLionel Sambuc llvm::DenseMap<IdentifierInfo*, unsigned> VarManglingNumbers; 36*f4a2713aSLionel Sambuc 37*f4a2713aSLionel Sambuc public: 38*f4a2713aSLionel Sambuc /// Variable decls are numbered by identifier. 39*f4a2713aSLionel Sambuc virtual unsigned getManglingNumber(const VarDecl *VD) { 40*f4a2713aSLionel Sambuc return ++VarManglingNumbers[VD->getIdentifier()]; 41*f4a2713aSLionel Sambuc } 42*f4a2713aSLionel Sambuc }; 43*f4a2713aSLionel Sambuc 44*f4a2713aSLionel Sambuc class ItaniumCXXABI : public CXXABI { 45*f4a2713aSLionel Sambuc protected: 46*f4a2713aSLionel Sambuc ASTContext &Context; 47*f4a2713aSLionel Sambuc public: 48*f4a2713aSLionel Sambuc ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { } 49*f4a2713aSLionel Sambuc 50*f4a2713aSLionel Sambuc std::pair<uint64_t, unsigned> 51*f4a2713aSLionel Sambuc getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const { 52*f4a2713aSLionel Sambuc const TargetInfo &Target = Context.getTargetInfo(); 53*f4a2713aSLionel Sambuc TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0); 54*f4a2713aSLionel Sambuc uint64_t Width = Target.getTypeWidth(PtrDiff); 55*f4a2713aSLionel Sambuc unsigned Align = Target.getTypeAlign(PtrDiff); 56*f4a2713aSLionel Sambuc if (MPT->getPointeeType()->isFunctionType()) 57*f4a2713aSLionel Sambuc Width = 2 * Width; 58*f4a2713aSLionel Sambuc return std::make_pair(Width, Align); 59*f4a2713aSLionel Sambuc } 60*f4a2713aSLionel Sambuc 61*f4a2713aSLionel Sambuc CallingConv getDefaultMethodCallConv(bool isVariadic) const { 62*f4a2713aSLionel Sambuc return CC_C; 63*f4a2713aSLionel Sambuc } 64*f4a2713aSLionel Sambuc 65*f4a2713aSLionel Sambuc // We cheat and just check that the class has a vtable pointer, and that it's 66*f4a2713aSLionel Sambuc // only big enough to have a vtable pointer and nothing more (or less). 67*f4a2713aSLionel Sambuc bool isNearlyEmpty(const CXXRecordDecl *RD) const { 68*f4a2713aSLionel Sambuc 69*f4a2713aSLionel Sambuc // Check that the class has a vtable pointer. 70*f4a2713aSLionel Sambuc if (!RD->isDynamicClass()) 71*f4a2713aSLionel Sambuc return false; 72*f4a2713aSLionel Sambuc 73*f4a2713aSLionel Sambuc const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 74*f4a2713aSLionel Sambuc CharUnits PointerSize = 75*f4a2713aSLionel Sambuc Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 76*f4a2713aSLionel Sambuc return Layout.getNonVirtualSize() == PointerSize; 77*f4a2713aSLionel Sambuc } 78*f4a2713aSLionel Sambuc 79*f4a2713aSLionel Sambuc virtual MangleNumberingContext *createMangleNumberingContext() const { 80*f4a2713aSLionel Sambuc return new ItaniumNumberingContext(); 81*f4a2713aSLionel Sambuc } 82*f4a2713aSLionel Sambuc }; 83*f4a2713aSLionel Sambuc 84*f4a2713aSLionel Sambuc class ARMCXXABI : public ItaniumCXXABI { 85*f4a2713aSLionel Sambuc public: 86*f4a2713aSLionel Sambuc ARMCXXABI(ASTContext &Ctx) : ItaniumCXXABI(Ctx) { } 87*f4a2713aSLionel Sambuc }; 88*f4a2713aSLionel Sambuc } 89*f4a2713aSLionel Sambuc 90*f4a2713aSLionel Sambuc CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) { 91*f4a2713aSLionel Sambuc return new ItaniumCXXABI(Ctx); 92*f4a2713aSLionel Sambuc } 93*f4a2713aSLionel Sambuc 94*f4a2713aSLionel Sambuc CXXABI *clang::CreateARMCXXABI(ASTContext &Ctx) { 95*f4a2713aSLionel Sambuc return new ARMCXXABI(Ctx); 96*f4a2713aSLionel Sambuc } 97