clang API Documentation
00001 //===------- ItaniumCXXABI.cpp - AST support for the Itanium C++ ABI ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This provides C++ AST support targeting the Itanium C++ ABI, which is 00011 // documented at: 00012 // http://www.codesourcery.com/public/cxx-abi/abi.html 00013 // http://www.codesourcery.com/public/cxx-abi/abi-eh.html 00014 // 00015 // It also supports the closely-related ARM C++ ABI, documented at: 00016 // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf 00017 // 00018 //===----------------------------------------------------------------------===// 00019 00020 #include "CXXABI.h" 00021 #include "clang/AST/ASTContext.h" 00022 #include "clang/AST/DeclCXX.h" 00023 #include "clang/AST/MangleNumberingContext.h" 00024 #include "clang/AST/RecordLayout.h" 00025 #include "clang/AST/Type.h" 00026 #include "clang/Basic/TargetInfo.h" 00027 00028 using namespace clang; 00029 00030 namespace { 00031 00032 /// \brief Keeps track of the mangled names of lambda expressions and block 00033 /// literals within a particular context. 00034 class ItaniumNumberingContext : public MangleNumberingContext { 00035 llvm::DenseMap<const Type *, unsigned> ManglingNumbers; 00036 llvm::DenseMap<IdentifierInfo *, unsigned> VarManglingNumbers; 00037 llvm::DenseMap<IdentifierInfo *, unsigned> TagManglingNumbers; 00038 00039 public: 00040 unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { 00041 const FunctionProtoType *Proto = 00042 CallOperator->getType()->getAs<FunctionProtoType>(); 00043 ASTContext &Context = CallOperator->getASTContext(); 00044 00045 QualType Key = 00046 Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(), 00047 FunctionProtoType::ExtProtoInfo()); 00048 Key = Context.getCanonicalType(Key); 00049 return ++ManglingNumbers[Key->castAs<FunctionProtoType>()]; 00050 } 00051 00052 unsigned getManglingNumber(const BlockDecl *BD) override { 00053 const Type *Ty = nullptr; 00054 return ++ManglingNumbers[Ty]; 00055 } 00056 00057 unsigned getStaticLocalNumber(const VarDecl *VD) override { 00058 return 0; 00059 } 00060 00061 /// Variable decls are numbered by identifier. 00062 unsigned getManglingNumber(const VarDecl *VD, unsigned) override { 00063 return ++VarManglingNumbers[VD->getIdentifier()]; 00064 } 00065 00066 unsigned getManglingNumber(const TagDecl *TD, unsigned) override { 00067 return ++TagManglingNumbers[TD->getIdentifier()]; 00068 } 00069 }; 00070 00071 class ItaniumCXXABI : public CXXABI { 00072 protected: 00073 ASTContext &Context; 00074 public: 00075 ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { } 00076 00077 std::pair<uint64_t, unsigned> 00078 getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override { 00079 const TargetInfo &Target = Context.getTargetInfo(); 00080 TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0); 00081 uint64_t Width = Target.getTypeWidth(PtrDiff); 00082 unsigned Align = Target.getTypeAlign(PtrDiff); 00083 if (MPT->getPointeeType()->isFunctionType()) 00084 Width = 2 * Width; 00085 return std::make_pair(Width, Align); 00086 } 00087 00088 CallingConv getDefaultMethodCallConv(bool isVariadic) const override { 00089 const llvm::Triple &T = Context.getTargetInfo().getTriple(); 00090 if (!isVariadic && T.isWindowsGNUEnvironment() && 00091 T.getArch() == llvm::Triple::x86) 00092 return CC_X86ThisCall; 00093 return CC_C; 00094 } 00095 00096 // We cheat and just check that the class has a vtable pointer, and that it's 00097 // only big enough to have a vtable pointer and nothing more (or less). 00098 bool isNearlyEmpty(const CXXRecordDecl *RD) const override { 00099 00100 // Check that the class has a vtable pointer. 00101 if (!RD->isDynamicClass()) 00102 return false; 00103 00104 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 00105 CharUnits PointerSize = 00106 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 00107 return Layout.getNonVirtualSize() == PointerSize; 00108 } 00109 00110 MangleNumberingContext *createMangleNumberingContext() const override { 00111 return new ItaniumNumberingContext(); 00112 } 00113 }; 00114 } 00115 00116 CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) { 00117 return new ItaniumCXXABI(Ctx); 00118 }