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