1071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===------- ItaniumCXXABI.cpp - AST support for the Itanium C++ ABI ------===// 2071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 3071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// The LLVM Compiler Infrastructure 4071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 5071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// This file is distributed under the University of Illinois Open Source 6071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// License. See LICENSE.TXT for details. 7071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 8071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===----------------------------------------------------------------------===// 9071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner// This provides C++ AST support targeting the Itanium C++ ABI, which is 11071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// documented at: 12071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// http://www.codesourcery.com/public/cxx-abi/abi.html 13071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// http://www.codesourcery.com/public/cxx-abi/abi-eh.html 14ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall// 15ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall// It also supports the closely-related ARM C++ ABI, documented at: 16ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf 17ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall// 18071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===----------------------------------------------------------------------===// 19071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 20071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "CXXABI.h" 21071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "clang/AST/ASTContext.h" 22dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/AST/DeclCXX.h" 23942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner#include "clang/AST/MangleNumberingContext.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/RecordLayout.h" 25071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "clang/AST/Type.h" 26dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/Basic/TargetInfo.h" 27071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 28071cc7deffad608165b1ddd5263e8bf181861520Charles Davisusing namespace clang; 29071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 30071cc7deffad608165b1ddd5263e8bf181861520Charles Davisnamespace { 31942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// According to Itanium C++ ABI 5.1.2: 330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// the name of an anonymous union is considered to be 340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// the name of the first named data member found by a pre-order, 350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// depth-first, declaration-order walk of the data members of 360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// the anonymous union. 370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// If there is no such data member (i.e., if all of the data members 380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// in the union are unnamed), then there is no way for a program to 390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// refer to the anonymous union, and there is therefore no need to mangle its name. 400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// 410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines/// Returns the name of anonymous union VarDecl or nullptr if it is not found. 420e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstatic const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) { 430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines const RecordType *RT = VD.getType()->getAs<RecordType>(); 440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines assert(RT && "type of VarDecl is expected to be RecordType."); 450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines assert(RT->getDecl()->isUnion() && "RecordType is expected to be a union."); 460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (const FieldDecl *FD = RT->getDecl()->findFirstNamedDataMember()) { 470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return FD->getIdentifier(); 480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return nullptr; 510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 53942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner/// \brief Keeps track of the mangled names of lambda expressions and block 54942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner/// literals within a particular context. 55942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Klecknerclass ItaniumNumberingContext : public MangleNumberingContext { 56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::DenseMap<const Type *, unsigned> ManglingNumbers; 570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::DenseMap<const IdentifierInfo *, unsigned> VarManglingNumbers; 580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::DenseMap<const IdentifierInfo *, unsigned> TagManglingNumbers; 59942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 60942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Klecknerpublic: 61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { 62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const FunctionProtoType *Proto = 63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CallOperator->getType()->getAs<FunctionProtoType>(); 64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ASTContext &Context = CallOperator->getASTContext(); 65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 66176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines QualType Key = 67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(), 68176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines FunctionProtoType::ExtProtoInfo()); 69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Key = Context.getCanonicalType(Key); 70176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ++ManglingNumbers[Key->castAs<FunctionProtoType>()]; 71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned getManglingNumber(const BlockDecl *BD) override { 74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const Type *Ty = nullptr; 75176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ++ManglingNumbers[Ty]; 76176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 77176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 78176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned getStaticLocalNumber(const VarDecl *VD) override { 79176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return 0; 80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 82942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner /// Variable decls are numbered by identifier. 83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getManglingNumber(const VarDecl *VD, unsigned) override { 840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines const IdentifierInfo *Identifier = VD->getIdentifier(); 850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!Identifier) { 860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // VarDecl without an identifier represents an anonymous union declaration. 870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Identifier = findAnonymousUnionVarDeclName(*VD); 880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return ++VarManglingNumbers[Identifier]; 90942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner } 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getManglingNumber(const TagDecl *TD, unsigned) override { 93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ++TagManglingNumbers[TD->getIdentifier()]; 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 95942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner}; 96942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 97071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass ItaniumCXXABI : public CXXABI { 98ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCallprotected: 99071cc7deffad608165b1ddd5263e8bf181861520Charles Davis ASTContext &Context; 100071cc7deffad608165b1ddd5263e8bf181861520Charles Davispublic: 101071cc7deffad608165b1ddd5263e8bf181861520Charles Davis ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { } 102071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 10384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner std::pair<uint64_t, unsigned> 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override { 10584e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner const TargetInfo &Target = Context.getTargetInfo(); 10684e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0); 10784e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner uint64_t Width = Target.getTypeWidth(PtrDiff); 10884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner unsigned Align = Target.getTypeAlign(PtrDiff); 109b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar if (MPT->isMemberFunctionPointer()) 11084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner Width = 2 * Width; 11184e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return std::make_pair(Width, Align); 112071cc7deffad608165b1ddd5263e8bf181861520Charles Davis } 113424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CallingConv getDefaultMethodCallConv(bool isVariadic) const override { 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const llvm::Triple &T = Context.getTargetInfo().getTriple(); 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isVariadic && T.isWindowsGNUEnvironment() && 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines T.getArch() == llvm::Triple::x86) 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return CC_X86ThisCall; 119424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis return CC_C; 120424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis } 121dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson 122dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson // We cheat and just check that the class has a vtable pointer, and that it's 123dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson // only big enough to have a vtable pointer and nothing more (or less). 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isNearlyEmpty(const CXXRecordDecl *RD) const override { 125dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson 126dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson // Check that the class has a vtable pointer. 127dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson if (!RD->isDynamicClass()) 128dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson return false; 129dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson 130dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1315c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck CharUnits PointerSize = 132bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 1335c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck return Layout.getNonVirtualSize() == PointerSize; 134dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson } 135942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 1363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const CXXConstructorDecl * 1373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override { 1383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return nullptr; 1393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 1403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar void addCopyConstructorForExceptionObject(CXXRecordDecl *RD, 1423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CXXConstructorDecl *CD) override {} 1433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD, 1453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar unsigned ParmIdx, Expr *DAE) override {} 1463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD, 1483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar unsigned ParmIdx) override { 1493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return nullptr; 1503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 1513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 15287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void addTypedefNameForUnnamedTagDecl(TagDecl *TD, 15387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypedefNameDecl *DD) override {} 15487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 15587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override { 15687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return nullptr; 15787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 15887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 15987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void addDeclaratorForUnnamedTagDecl(TagDecl *TD, 16087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DeclaratorDecl *DD) override {} 16187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 16287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override { 16387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return nullptr; 16487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 16587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MangleNumberingContext *createMangleNumberingContext() const override { 167942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner return new ItaniumNumberingContext(); 168942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner } 169071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}; 170071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 171071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 172071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) { 173071cc7deffad608165b1ddd5263e8bf181861520Charles Davis return new ItaniumCXXABI(Ctx); 174071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 175