xref: /minix3/external/bsd/llvm/dist/clang/lib/CodeGen/ItaniumCXXABI.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This provides C++ code generation targeting the Itanium C++ ABI.  The class
11f4a2713aSLionel Sambuc // in this file generates structures that follow the Itanium C++ ABI, which is
12f4a2713aSLionel Sambuc // documented at:
13f4a2713aSLionel Sambuc //  http://www.codesourcery.com/public/cxx-abi/abi.html
14f4a2713aSLionel Sambuc //  http://www.codesourcery.com/public/cxx-abi/abi-eh.html
15f4a2713aSLionel Sambuc //
16f4a2713aSLionel Sambuc // It also supports the closely-related ARM ABI, documented at:
17f4a2713aSLionel Sambuc // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
18f4a2713aSLionel Sambuc //
19f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
20f4a2713aSLionel Sambuc 
21f4a2713aSLionel Sambuc #include "CGCXXABI.h"
22f4a2713aSLionel Sambuc #include "CGRecordLayout.h"
23f4a2713aSLionel Sambuc #include "CGVTables.h"
24f4a2713aSLionel Sambuc #include "CodeGenFunction.h"
25f4a2713aSLionel Sambuc #include "CodeGenModule.h"
26f4a2713aSLionel Sambuc #include "clang/AST/Mangle.h"
27f4a2713aSLionel Sambuc #include "clang/AST/Type.h"
28*0a6a1f1dSLionel Sambuc #include "llvm/IR/CallSite.h"
29f4a2713aSLionel Sambuc #include "llvm/IR/DataLayout.h"
30f4a2713aSLionel Sambuc #include "llvm/IR/Intrinsics.h"
31f4a2713aSLionel Sambuc #include "llvm/IR/Value.h"
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc using namespace clang;
34f4a2713aSLionel Sambuc using namespace CodeGen;
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc namespace {
37f4a2713aSLionel Sambuc class ItaniumCXXABI : public CodeGen::CGCXXABI {
38f4a2713aSLionel Sambuc   /// VTables - All the vtables which have been defined.
39f4a2713aSLionel Sambuc   llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
40f4a2713aSLionel Sambuc 
41f4a2713aSLionel Sambuc protected:
42f4a2713aSLionel Sambuc   bool UseARMMethodPtrABI;
43f4a2713aSLionel Sambuc   bool UseARMGuardVarABI;
44f4a2713aSLionel Sambuc 
getMangleContext()45f4a2713aSLionel Sambuc   ItaniumMangleContext &getMangleContext() {
46f4a2713aSLionel Sambuc     return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext());
47f4a2713aSLionel Sambuc   }
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc public:
ItaniumCXXABI(CodeGen::CodeGenModule & CGM,bool UseARMMethodPtrABI=false,bool UseARMGuardVarABI=false)50f4a2713aSLionel Sambuc   ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
51f4a2713aSLionel Sambuc                 bool UseARMMethodPtrABI = false,
52f4a2713aSLionel Sambuc                 bool UseARMGuardVarABI = false) :
53f4a2713aSLionel Sambuc     CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
54f4a2713aSLionel Sambuc     UseARMGuardVarABI(UseARMGuardVarABI) { }
55f4a2713aSLionel Sambuc 
56*0a6a1f1dSLionel Sambuc   bool classifyReturnType(CGFunctionInfo &FI) const override;
57f4a2713aSLionel Sambuc 
getRecordArgABI(const CXXRecordDecl * RD) const58*0a6a1f1dSLionel Sambuc   RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
59f4a2713aSLionel Sambuc     // Structures with either a non-trivial destructor or a non-trivial
60f4a2713aSLionel Sambuc     // copy constructor are always indirect.
61*0a6a1f1dSLionel Sambuc     // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
62*0a6a1f1dSLionel Sambuc     // special members.
63*0a6a1f1dSLionel Sambuc     if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
64f4a2713aSLionel Sambuc       return RAA_Indirect;
65f4a2713aSLionel Sambuc     return RAA_Default;
66f4a2713aSLionel Sambuc   }
67f4a2713aSLionel Sambuc 
68*0a6a1f1dSLionel Sambuc   bool isZeroInitializable(const MemberPointerType *MPT) override;
69f4a2713aSLionel Sambuc 
70*0a6a1f1dSLionel Sambuc   llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
71f4a2713aSLionel Sambuc 
72*0a6a1f1dSLionel Sambuc   llvm::Value *
73*0a6a1f1dSLionel Sambuc     EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
74*0a6a1f1dSLionel Sambuc                                     const Expr *E,
75f4a2713aSLionel Sambuc                                     llvm::Value *&This,
76f4a2713aSLionel Sambuc                                     llvm::Value *MemFnPtr,
77*0a6a1f1dSLionel Sambuc                                     const MemberPointerType *MPT) override;
78f4a2713aSLionel Sambuc 
79*0a6a1f1dSLionel Sambuc   llvm::Value *
80*0a6a1f1dSLionel Sambuc     EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
81f4a2713aSLionel Sambuc                                  llvm::Value *Base,
82f4a2713aSLionel Sambuc                                  llvm::Value *MemPtr,
83*0a6a1f1dSLionel Sambuc                                  const MemberPointerType *MPT) override;
84f4a2713aSLionel Sambuc 
85f4a2713aSLionel Sambuc   llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
86f4a2713aSLionel Sambuc                                            const CastExpr *E,
87*0a6a1f1dSLionel Sambuc                                            llvm::Value *Src) override;
88f4a2713aSLionel Sambuc   llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
89*0a6a1f1dSLionel Sambuc                                               llvm::Constant *Src) override;
90f4a2713aSLionel Sambuc 
91*0a6a1f1dSLionel Sambuc   llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;
92f4a2713aSLionel Sambuc 
93*0a6a1f1dSLionel Sambuc   llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD) override;
94f4a2713aSLionel Sambuc   llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
95*0a6a1f1dSLionel Sambuc                                         CharUnits offset) override;
96*0a6a1f1dSLionel Sambuc   llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override;
97f4a2713aSLionel Sambuc   llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD,
98f4a2713aSLionel Sambuc                                      CharUnits ThisAdjustment);
99f4a2713aSLionel Sambuc 
100f4a2713aSLionel Sambuc   llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
101*0a6a1f1dSLionel Sambuc                                            llvm::Value *L, llvm::Value *R,
102f4a2713aSLionel Sambuc                                            const MemberPointerType *MPT,
103*0a6a1f1dSLionel Sambuc                                            bool Inequality) override;
104f4a2713aSLionel Sambuc 
105f4a2713aSLionel Sambuc   llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
106f4a2713aSLionel Sambuc                                          llvm::Value *Addr,
107*0a6a1f1dSLionel Sambuc                                          const MemberPointerType *MPT) override;
108f4a2713aSLionel Sambuc 
109*0a6a1f1dSLionel Sambuc   void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE,
110*0a6a1f1dSLionel Sambuc                                llvm::Value *Ptr, QualType ElementType,
111*0a6a1f1dSLionel Sambuc                                const CXXDestructorDecl *Dtor) override;
112f4a2713aSLionel Sambuc 
113*0a6a1f1dSLionel Sambuc   void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
114*0a6a1f1dSLionel Sambuc 
115*0a6a1f1dSLionel Sambuc   void EmitFundamentalRTTIDescriptor(QualType Type);
116*0a6a1f1dSLionel Sambuc   void EmitFundamentalRTTIDescriptors();
117*0a6a1f1dSLionel Sambuc   llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
118*0a6a1f1dSLionel Sambuc 
119*0a6a1f1dSLionel Sambuc   bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
120*0a6a1f1dSLionel Sambuc   void EmitBadTypeidCall(CodeGenFunction &CGF) override;
121*0a6a1f1dSLionel Sambuc   llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
122*0a6a1f1dSLionel Sambuc                           llvm::Value *ThisPtr,
123*0a6a1f1dSLionel Sambuc                           llvm::Type *StdTypeInfoPtrTy) override;
124*0a6a1f1dSLionel Sambuc 
125*0a6a1f1dSLionel Sambuc   bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
126*0a6a1f1dSLionel Sambuc                                           QualType SrcRecordTy) override;
127*0a6a1f1dSLionel Sambuc 
128*0a6a1f1dSLionel Sambuc   llvm::Value *EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
129*0a6a1f1dSLionel Sambuc                                    QualType SrcRecordTy, QualType DestTy,
130*0a6a1f1dSLionel Sambuc                                    QualType DestRecordTy,
131*0a6a1f1dSLionel Sambuc                                    llvm::BasicBlock *CastEnd) override;
132*0a6a1f1dSLionel Sambuc 
133*0a6a1f1dSLionel Sambuc   llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF, llvm::Value *Value,
134*0a6a1f1dSLionel Sambuc                                      QualType SrcRecordTy,
135*0a6a1f1dSLionel Sambuc                                      QualType DestTy) override;
136*0a6a1f1dSLionel Sambuc 
137*0a6a1f1dSLionel Sambuc   bool EmitBadCastCall(CodeGenFunction &CGF) override;
138*0a6a1f1dSLionel Sambuc 
139*0a6a1f1dSLionel Sambuc   llvm::Value *
140*0a6a1f1dSLionel Sambuc     GetVirtualBaseClassOffset(CodeGenFunction &CGF, llvm::Value *This,
141f4a2713aSLionel Sambuc                               const CXXRecordDecl *ClassDecl,
142*0a6a1f1dSLionel Sambuc                               const CXXRecordDecl *BaseClassDecl) override;
143f4a2713aSLionel Sambuc 
144*0a6a1f1dSLionel Sambuc   void EmitCXXConstructors(const CXXConstructorDecl *D) override;
145f4a2713aSLionel Sambuc 
146*0a6a1f1dSLionel Sambuc   void buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
147*0a6a1f1dSLionel Sambuc                               SmallVectorImpl<CanQualType> &ArgTys) override;
148f4a2713aSLionel Sambuc 
useThunkForDtorVariant(const CXXDestructorDecl * Dtor,CXXDtorType DT) const149f4a2713aSLionel Sambuc   bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
150*0a6a1f1dSLionel Sambuc                               CXXDtorType DT) const override {
151f4a2713aSLionel Sambuc     // Itanium does not emit any destructor variant as an inline thunk.
152f4a2713aSLionel Sambuc     // Delegating may occur as an optimization, but all variants are either
153f4a2713aSLionel Sambuc     // emitted with external linkage or as linkonce if they are inline and used.
154f4a2713aSLionel Sambuc     return false;
155f4a2713aSLionel Sambuc   }
156f4a2713aSLionel Sambuc 
157*0a6a1f1dSLionel Sambuc   void EmitCXXDestructors(const CXXDestructorDecl *D) override;
158f4a2713aSLionel Sambuc 
159*0a6a1f1dSLionel Sambuc   void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
160*0a6a1f1dSLionel Sambuc                                  FunctionArgList &Params) override;
161f4a2713aSLionel Sambuc 
162*0a6a1f1dSLionel Sambuc   void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
163f4a2713aSLionel Sambuc 
164*0a6a1f1dSLionel Sambuc   unsigned addImplicitConstructorArgs(CodeGenFunction &CGF,
165*0a6a1f1dSLionel Sambuc                                       const CXXConstructorDecl *D,
166*0a6a1f1dSLionel Sambuc                                       CXXCtorType Type, bool ForVirtualBase,
167*0a6a1f1dSLionel Sambuc                                       bool Delegating,
168*0a6a1f1dSLionel Sambuc                                       CallArgList &Args) override;
169f4a2713aSLionel Sambuc 
170*0a6a1f1dSLionel Sambuc   void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
171*0a6a1f1dSLionel Sambuc                           CXXDtorType Type, bool ForVirtualBase,
172*0a6a1f1dSLionel Sambuc                           bool Delegating, llvm::Value *This) override;
173*0a6a1f1dSLionel Sambuc 
174*0a6a1f1dSLionel Sambuc   void emitVTableDefinitions(CodeGenVTables &CGVT,
175*0a6a1f1dSLionel Sambuc                              const CXXRecordDecl *RD) override;
176f4a2713aSLionel Sambuc 
177f4a2713aSLionel Sambuc   llvm::Value *getVTableAddressPointInStructor(
178f4a2713aSLionel Sambuc       CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
179f4a2713aSLionel Sambuc       BaseSubobject Base, const CXXRecordDecl *NearestVBase,
180*0a6a1f1dSLionel Sambuc       bool &NeedsVirtualOffset) override;
181f4a2713aSLionel Sambuc 
182f4a2713aSLionel Sambuc   llvm::Constant *
183f4a2713aSLionel Sambuc   getVTableAddressPointForConstExpr(BaseSubobject Base,
184*0a6a1f1dSLionel Sambuc                                     const CXXRecordDecl *VTableClass) override;
185f4a2713aSLionel Sambuc 
186f4a2713aSLionel Sambuc   llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
187*0a6a1f1dSLionel Sambuc                                         CharUnits VPtrOffset) override;
188f4a2713aSLionel Sambuc 
189f4a2713aSLionel Sambuc   llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
190*0a6a1f1dSLionel Sambuc                                          llvm::Value *This,
191*0a6a1f1dSLionel Sambuc                                          llvm::Type *Ty) override;
192f4a2713aSLionel Sambuc 
193*0a6a1f1dSLionel Sambuc   llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
194f4a2713aSLionel Sambuc                                          const CXXDestructorDecl *Dtor,
195*0a6a1f1dSLionel Sambuc                                          CXXDtorType DtorType,
196*0a6a1f1dSLionel Sambuc                                          llvm::Value *This,
197*0a6a1f1dSLionel Sambuc                                          const CXXMemberCallExpr *CE) override;
198f4a2713aSLionel Sambuc 
199*0a6a1f1dSLionel Sambuc   void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
200f4a2713aSLionel Sambuc 
setThunkLinkage(llvm::Function * Thunk,bool ForVTable,GlobalDecl GD,bool ReturnAdjustment)201*0a6a1f1dSLionel Sambuc   void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD,
202*0a6a1f1dSLionel Sambuc                        bool ReturnAdjustment) override {
203f4a2713aSLionel Sambuc     // Allow inlining of thunks by emitting them with available_externally
204f4a2713aSLionel Sambuc     // linkage together with vtables when needed.
205f4a2713aSLionel Sambuc     if (ForVTable)
206f4a2713aSLionel Sambuc       Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
207f4a2713aSLionel Sambuc   }
208f4a2713aSLionel Sambuc 
209f4a2713aSLionel Sambuc   llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This,
210*0a6a1f1dSLionel Sambuc                                      const ThisAdjustment &TA) override;
211f4a2713aSLionel Sambuc 
212f4a2713aSLionel Sambuc   llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret,
213*0a6a1f1dSLionel Sambuc                                        const ReturnAdjustment &RA) override;
214f4a2713aSLionel Sambuc 
getSrcArgforCopyCtor(const CXXConstructorDecl *,FunctionArgList & Args) const215*0a6a1f1dSLionel Sambuc   size_t getSrcArgforCopyCtor(const CXXConstructorDecl *,
216*0a6a1f1dSLionel Sambuc                               FunctionArgList &Args) const override {
217*0a6a1f1dSLionel Sambuc     assert(!Args.empty() && "expected the arglist to not be empty!");
218*0a6a1f1dSLionel Sambuc     return Args.size() - 1;
219*0a6a1f1dSLionel Sambuc   }
220f4a2713aSLionel Sambuc 
GetPureVirtualCallName()221*0a6a1f1dSLionel Sambuc   StringRef GetPureVirtualCallName() override { return "__cxa_pure_virtual"; }
GetDeletedVirtualCallName()222*0a6a1f1dSLionel Sambuc   StringRef GetDeletedVirtualCallName() override
223*0a6a1f1dSLionel Sambuc     { return "__cxa_deleted_virtual"; }
224*0a6a1f1dSLionel Sambuc 
225*0a6a1f1dSLionel Sambuc   CharUnits getArrayCookieSizeImpl(QualType elementType) override;
226f4a2713aSLionel Sambuc   llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
227f4a2713aSLionel Sambuc                                      llvm::Value *NewPtr,
228f4a2713aSLionel Sambuc                                      llvm::Value *NumElements,
229f4a2713aSLionel Sambuc                                      const CXXNewExpr *expr,
230*0a6a1f1dSLionel Sambuc                                      QualType ElementType) override;
231f4a2713aSLionel Sambuc   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
232f4a2713aSLionel Sambuc                                    llvm::Value *allocPtr,
233*0a6a1f1dSLionel Sambuc                                    CharUnits cookieSize) override;
234f4a2713aSLionel Sambuc 
235f4a2713aSLionel Sambuc   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
236*0a6a1f1dSLionel Sambuc                        llvm::GlobalVariable *DeclPtr,
237*0a6a1f1dSLionel Sambuc                        bool PerformInit) override;
238f4a2713aSLionel Sambuc   void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
239*0a6a1f1dSLionel Sambuc                           llvm::Constant *dtor, llvm::Constant *addr) override;
240f4a2713aSLionel Sambuc 
241f4a2713aSLionel Sambuc   llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD,
242*0a6a1f1dSLionel Sambuc                                                 llvm::Value *Val);
243f4a2713aSLionel Sambuc   void EmitThreadLocalInitFuncs(
244*0a6a1f1dSLionel Sambuc       CodeGenModule &CGM,
245*0a6a1f1dSLionel Sambuc       ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *>>
246*0a6a1f1dSLionel Sambuc           CXXThreadLocals,
247*0a6a1f1dSLionel Sambuc       ArrayRef<llvm::Function *> CXXThreadLocalInits,
248*0a6a1f1dSLionel Sambuc       ArrayRef<llvm::GlobalVariable *> CXXThreadLocalInitVars) override;
249f4a2713aSLionel Sambuc 
usesThreadWrapperFunction() const250*0a6a1f1dSLionel Sambuc   bool usesThreadWrapperFunction() const override { return true; }
251*0a6a1f1dSLionel Sambuc   LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,
252*0a6a1f1dSLionel Sambuc                                       QualType LValType) override;
253*0a6a1f1dSLionel Sambuc 
254*0a6a1f1dSLionel Sambuc   bool NeedsVTTParameter(GlobalDecl GD) override;
255*0a6a1f1dSLionel Sambuc 
256*0a6a1f1dSLionel Sambuc   /**************************** RTTI Uniqueness ******************************/
257*0a6a1f1dSLionel Sambuc 
258*0a6a1f1dSLionel Sambuc protected:
259*0a6a1f1dSLionel Sambuc   /// Returns true if the ABI requires RTTI type_info objects to be unique
260*0a6a1f1dSLionel Sambuc   /// across a program.
shouldRTTIBeUnique() const261*0a6a1f1dSLionel Sambuc   virtual bool shouldRTTIBeUnique() const { return true; }
262*0a6a1f1dSLionel Sambuc 
263*0a6a1f1dSLionel Sambuc public:
264*0a6a1f1dSLionel Sambuc   /// What sort of unique-RTTI behavior should we use?
265*0a6a1f1dSLionel Sambuc   enum RTTIUniquenessKind {
266*0a6a1f1dSLionel Sambuc     /// We are guaranteeing, or need to guarantee, that the RTTI string
267*0a6a1f1dSLionel Sambuc     /// is unique.
268*0a6a1f1dSLionel Sambuc     RUK_Unique,
269*0a6a1f1dSLionel Sambuc 
270*0a6a1f1dSLionel Sambuc     /// We are not guaranteeing uniqueness for the RTTI string, so we
271*0a6a1f1dSLionel Sambuc     /// can demote to hidden visibility but must use string comparisons.
272*0a6a1f1dSLionel Sambuc     RUK_NonUniqueHidden,
273*0a6a1f1dSLionel Sambuc 
274*0a6a1f1dSLionel Sambuc     /// We are not guaranteeing uniqueness for the RTTI string, so we
275*0a6a1f1dSLionel Sambuc     /// have to use string comparisons, but we also have to emit it with
276*0a6a1f1dSLionel Sambuc     /// non-hidden visibility.
277*0a6a1f1dSLionel Sambuc     RUK_NonUniqueVisible
278*0a6a1f1dSLionel Sambuc   };
279*0a6a1f1dSLionel Sambuc 
280*0a6a1f1dSLionel Sambuc   /// Return the required visibility status for the given type and linkage in
281*0a6a1f1dSLionel Sambuc   /// the current ABI.
282*0a6a1f1dSLionel Sambuc   RTTIUniquenessKind
283*0a6a1f1dSLionel Sambuc   classifyRTTIUniqueness(QualType CanTy,
284*0a6a1f1dSLionel Sambuc                          llvm::GlobalValue::LinkageTypes Linkage) const;
285*0a6a1f1dSLionel Sambuc   friend class ItaniumRTTIBuilder;
286*0a6a1f1dSLionel Sambuc 
287*0a6a1f1dSLionel Sambuc   void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
288f4a2713aSLionel Sambuc };
289f4a2713aSLionel Sambuc 
290f4a2713aSLionel Sambuc class ARMCXXABI : public ItaniumCXXABI {
291f4a2713aSLionel Sambuc public:
ARMCXXABI(CodeGen::CodeGenModule & CGM)292f4a2713aSLionel Sambuc   ARMCXXABI(CodeGen::CodeGenModule &CGM) :
293f4a2713aSLionel Sambuc     ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true,
294f4a2713aSLionel Sambuc                   /* UseARMGuardVarABI = */ true) {}
295f4a2713aSLionel Sambuc 
HasThisReturn(GlobalDecl GD) const296*0a6a1f1dSLionel Sambuc   bool HasThisReturn(GlobalDecl GD) const override {
297f4a2713aSLionel Sambuc     return (isa<CXXConstructorDecl>(GD.getDecl()) || (
298f4a2713aSLionel Sambuc               isa<CXXDestructorDecl>(GD.getDecl()) &&
299f4a2713aSLionel Sambuc               GD.getDtorType() != Dtor_Deleting));
300f4a2713aSLionel Sambuc   }
301f4a2713aSLionel Sambuc 
302*0a6a1f1dSLionel Sambuc   void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
303*0a6a1f1dSLionel Sambuc                            QualType ResTy) override;
304f4a2713aSLionel Sambuc 
305*0a6a1f1dSLionel Sambuc   CharUnits getArrayCookieSizeImpl(QualType elementType) override;
306f4a2713aSLionel Sambuc   llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
307f4a2713aSLionel Sambuc                                      llvm::Value *NewPtr,
308f4a2713aSLionel Sambuc                                      llvm::Value *NumElements,
309f4a2713aSLionel Sambuc                                      const CXXNewExpr *expr,
310*0a6a1f1dSLionel Sambuc                                      QualType ElementType) override;
311f4a2713aSLionel Sambuc   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, llvm::Value *allocPtr,
312*0a6a1f1dSLionel Sambuc                                    CharUnits cookieSize) override;
313*0a6a1f1dSLionel Sambuc };
314*0a6a1f1dSLionel Sambuc 
315*0a6a1f1dSLionel Sambuc class iOS64CXXABI : public ARMCXXABI {
316*0a6a1f1dSLionel Sambuc public:
iOS64CXXABI(CodeGen::CodeGenModule & CGM)317*0a6a1f1dSLionel Sambuc   iOS64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {}
318*0a6a1f1dSLionel Sambuc 
319*0a6a1f1dSLionel Sambuc   // ARM64 libraries are prepared for non-unique RTTI.
shouldRTTIBeUnique() const320*0a6a1f1dSLionel Sambuc   bool shouldRTTIBeUnique() const override { return false; }
321f4a2713aSLionel Sambuc };
322f4a2713aSLionel Sambuc }
323f4a2713aSLionel Sambuc 
CreateItaniumCXXABI(CodeGenModule & CGM)324f4a2713aSLionel Sambuc CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
325f4a2713aSLionel Sambuc   switch (CGM.getTarget().getCXXABI().getKind()) {
326f4a2713aSLionel Sambuc   // For IR-generation purposes, there's no significant difference
327f4a2713aSLionel Sambuc   // between the ARM and iOS ABIs.
328f4a2713aSLionel Sambuc   case TargetCXXABI::GenericARM:
329f4a2713aSLionel Sambuc   case TargetCXXABI::iOS:
330f4a2713aSLionel Sambuc     return new ARMCXXABI(CGM);
331f4a2713aSLionel Sambuc 
332*0a6a1f1dSLionel Sambuc   case TargetCXXABI::iOS64:
333*0a6a1f1dSLionel Sambuc     return new iOS64CXXABI(CGM);
334*0a6a1f1dSLionel Sambuc 
335f4a2713aSLionel Sambuc   // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't
336f4a2713aSLionel Sambuc   // include the other 32-bit ARM oddities: constructor/destructor return values
337f4a2713aSLionel Sambuc   // and array cookies.
338f4a2713aSLionel Sambuc   case TargetCXXABI::GenericAArch64:
339f4a2713aSLionel Sambuc     return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true,
340f4a2713aSLionel Sambuc                              /* UseARMGuardVarABI = */ true);
341f4a2713aSLionel Sambuc 
342*0a6a1f1dSLionel Sambuc   case TargetCXXABI::GenericMIPS:
343*0a6a1f1dSLionel Sambuc     return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true);
344*0a6a1f1dSLionel Sambuc 
345f4a2713aSLionel Sambuc   case TargetCXXABI::GenericItanium:
346f4a2713aSLionel Sambuc     if (CGM.getContext().getTargetInfo().getTriple().getArch()
347f4a2713aSLionel Sambuc         == llvm::Triple::le32) {
348f4a2713aSLionel Sambuc       // For PNaCl, use ARM-style method pointers so that PNaCl code
349f4a2713aSLionel Sambuc       // does not assume anything about the alignment of function
350f4a2713aSLionel Sambuc       // pointers.
351f4a2713aSLionel Sambuc       return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true,
352f4a2713aSLionel Sambuc                                /* UseARMGuardVarABI = */ false);
353f4a2713aSLionel Sambuc     }
354f4a2713aSLionel Sambuc     return new ItaniumCXXABI(CGM);
355f4a2713aSLionel Sambuc 
356f4a2713aSLionel Sambuc   case TargetCXXABI::Microsoft:
357f4a2713aSLionel Sambuc     llvm_unreachable("Microsoft ABI is not Itanium-based");
358f4a2713aSLionel Sambuc   }
359f4a2713aSLionel Sambuc   llvm_unreachable("bad ABI kind");
360f4a2713aSLionel Sambuc }
361f4a2713aSLionel Sambuc 
362f4a2713aSLionel Sambuc llvm::Type *
ConvertMemberPointerType(const MemberPointerType * MPT)363f4a2713aSLionel Sambuc ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
364f4a2713aSLionel Sambuc   if (MPT->isMemberDataPointer())
365f4a2713aSLionel Sambuc     return CGM.PtrDiffTy;
366*0a6a1f1dSLionel Sambuc   return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy, nullptr);
367f4a2713aSLionel Sambuc }
368f4a2713aSLionel Sambuc 
369f4a2713aSLionel Sambuc /// In the Itanium and ARM ABIs, method pointers have the form:
370f4a2713aSLionel Sambuc ///   struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
371f4a2713aSLionel Sambuc ///
372f4a2713aSLionel Sambuc /// In the Itanium ABI:
373f4a2713aSLionel Sambuc ///  - method pointers are virtual if (memptr.ptr & 1) is nonzero
374f4a2713aSLionel Sambuc ///  - the this-adjustment is (memptr.adj)
375f4a2713aSLionel Sambuc ///  - the virtual offset is (memptr.ptr - 1)
376f4a2713aSLionel Sambuc ///
377f4a2713aSLionel Sambuc /// In the ARM ABI:
378f4a2713aSLionel Sambuc ///  - method pointers are virtual if (memptr.adj & 1) is nonzero
379f4a2713aSLionel Sambuc ///  - the this-adjustment is (memptr.adj >> 1)
380f4a2713aSLionel Sambuc ///  - the virtual offset is (memptr.ptr)
381f4a2713aSLionel Sambuc /// ARM uses 'adj' for the virtual flag because Thumb functions
382f4a2713aSLionel Sambuc /// may be only single-byte aligned.
383f4a2713aSLionel Sambuc ///
384f4a2713aSLionel Sambuc /// If the member is virtual, the adjusted 'this' pointer points
385f4a2713aSLionel Sambuc /// to a vtable pointer from which the virtual offset is applied.
386f4a2713aSLionel Sambuc ///
387f4a2713aSLionel Sambuc /// If the member is non-virtual, memptr.ptr is the address of
388f4a2713aSLionel Sambuc /// the function to call.
EmitLoadOfMemberFunctionPointer(CodeGenFunction & CGF,const Expr * E,llvm::Value * & This,llvm::Value * MemFnPtr,const MemberPointerType * MPT)389*0a6a1f1dSLionel Sambuc llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
390*0a6a1f1dSLionel Sambuc     CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
391*0a6a1f1dSLionel Sambuc     llvm::Value *MemFnPtr, const MemberPointerType *MPT) {
392f4a2713aSLionel Sambuc   CGBuilderTy &Builder = CGF.Builder;
393f4a2713aSLionel Sambuc 
394f4a2713aSLionel Sambuc   const FunctionProtoType *FPT =
395f4a2713aSLionel Sambuc     MPT->getPointeeType()->getAs<FunctionProtoType>();
396f4a2713aSLionel Sambuc   const CXXRecordDecl *RD =
397f4a2713aSLionel Sambuc     cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
398f4a2713aSLionel Sambuc 
399f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
400f4a2713aSLionel Sambuc     CGM.getTypes().GetFunctionType(
401f4a2713aSLionel Sambuc       CGM.getTypes().arrangeCXXMethodType(RD, FPT));
402f4a2713aSLionel Sambuc 
403f4a2713aSLionel Sambuc   llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
404f4a2713aSLionel Sambuc 
405f4a2713aSLionel Sambuc   llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
406f4a2713aSLionel Sambuc   llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
407f4a2713aSLionel Sambuc   llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
408f4a2713aSLionel Sambuc 
409f4a2713aSLionel Sambuc   // Extract memptr.adj, which is in the second field.
410f4a2713aSLionel Sambuc   llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
411f4a2713aSLionel Sambuc 
412f4a2713aSLionel Sambuc   // Compute the true adjustment.
413f4a2713aSLionel Sambuc   llvm::Value *Adj = RawAdj;
414f4a2713aSLionel Sambuc   if (UseARMMethodPtrABI)
415f4a2713aSLionel Sambuc     Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
416f4a2713aSLionel Sambuc 
417f4a2713aSLionel Sambuc   // Apply the adjustment and cast back to the original struct type
418f4a2713aSLionel Sambuc   // for consistency.
419f4a2713aSLionel Sambuc   llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
420f4a2713aSLionel Sambuc   Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
421f4a2713aSLionel Sambuc   This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
422f4a2713aSLionel Sambuc 
423f4a2713aSLionel Sambuc   // Load the function pointer.
424f4a2713aSLionel Sambuc   llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
425f4a2713aSLionel Sambuc 
426f4a2713aSLionel Sambuc   // If the LSB in the function pointer is 1, the function pointer points to
427f4a2713aSLionel Sambuc   // a virtual function.
428f4a2713aSLionel Sambuc   llvm::Value *IsVirtual;
429f4a2713aSLionel Sambuc   if (UseARMMethodPtrABI)
430f4a2713aSLionel Sambuc     IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
431f4a2713aSLionel Sambuc   else
432f4a2713aSLionel Sambuc     IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
433f4a2713aSLionel Sambuc   IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
434f4a2713aSLionel Sambuc   Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
435f4a2713aSLionel Sambuc 
436f4a2713aSLionel Sambuc   // In the virtual path, the adjustment left 'This' pointing to the
437f4a2713aSLionel Sambuc   // vtable of the correct base subobject.  The "function pointer" is an
438f4a2713aSLionel Sambuc   // offset within the vtable (+1 for the virtual flag on non-ARM).
439f4a2713aSLionel Sambuc   CGF.EmitBlock(FnVirtual);
440f4a2713aSLionel Sambuc 
441f4a2713aSLionel Sambuc   // Cast the adjusted this to a pointer to vtable pointer and load.
442f4a2713aSLionel Sambuc   llvm::Type *VTableTy = Builder.getInt8PtrTy();
443*0a6a1f1dSLionel Sambuc   llvm::Value *VTable = CGF.GetVTablePtr(This, VTableTy);
444f4a2713aSLionel Sambuc 
445f4a2713aSLionel Sambuc   // Apply the offset.
446f4a2713aSLionel Sambuc   llvm::Value *VTableOffset = FnAsInt;
447f4a2713aSLionel Sambuc   if (!UseARMMethodPtrABI)
448f4a2713aSLionel Sambuc     VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
449f4a2713aSLionel Sambuc   VTable = Builder.CreateGEP(VTable, VTableOffset);
450f4a2713aSLionel Sambuc 
451f4a2713aSLionel Sambuc   // Load the virtual function to call.
452f4a2713aSLionel Sambuc   VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
453f4a2713aSLionel Sambuc   llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
454f4a2713aSLionel Sambuc   CGF.EmitBranch(FnEnd);
455f4a2713aSLionel Sambuc 
456f4a2713aSLionel Sambuc   // In the non-virtual path, the function pointer is actually a
457f4a2713aSLionel Sambuc   // function pointer.
458f4a2713aSLionel Sambuc   CGF.EmitBlock(FnNonVirtual);
459f4a2713aSLionel Sambuc   llvm::Value *NonVirtualFn =
460f4a2713aSLionel Sambuc     Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
461f4a2713aSLionel Sambuc 
462f4a2713aSLionel Sambuc   // We're done.
463f4a2713aSLionel Sambuc   CGF.EmitBlock(FnEnd);
464f4a2713aSLionel Sambuc   llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
465f4a2713aSLionel Sambuc   Callee->addIncoming(VirtualFn, FnVirtual);
466f4a2713aSLionel Sambuc   Callee->addIncoming(NonVirtualFn, FnNonVirtual);
467f4a2713aSLionel Sambuc   return Callee;
468f4a2713aSLionel Sambuc }
469f4a2713aSLionel Sambuc 
470f4a2713aSLionel Sambuc /// Compute an l-value by applying the given pointer-to-member to a
471f4a2713aSLionel Sambuc /// base object.
EmitMemberDataPointerAddress(CodeGenFunction & CGF,const Expr * E,llvm::Value * Base,llvm::Value * MemPtr,const MemberPointerType * MPT)472*0a6a1f1dSLionel Sambuc llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
473*0a6a1f1dSLionel Sambuc     CodeGenFunction &CGF, const Expr *E, llvm::Value *Base, llvm::Value *MemPtr,
474f4a2713aSLionel Sambuc     const MemberPointerType *MPT) {
475f4a2713aSLionel Sambuc   assert(MemPtr->getType() == CGM.PtrDiffTy);
476f4a2713aSLionel Sambuc 
477f4a2713aSLionel Sambuc   CGBuilderTy &Builder = CGF.Builder;
478f4a2713aSLionel Sambuc 
479f4a2713aSLionel Sambuc   unsigned AS = Base->getType()->getPointerAddressSpace();
480f4a2713aSLionel Sambuc 
481f4a2713aSLionel Sambuc   // Cast to char*.
482f4a2713aSLionel Sambuc   Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
483f4a2713aSLionel Sambuc 
484f4a2713aSLionel Sambuc   // Apply the offset, which we assume is non-null.
485f4a2713aSLionel Sambuc   llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
486f4a2713aSLionel Sambuc 
487f4a2713aSLionel Sambuc   // Cast the address to the appropriate pointer type, adopting the
488f4a2713aSLionel Sambuc   // address space of the base pointer.
489f4a2713aSLionel Sambuc   llvm::Type *PType
490f4a2713aSLionel Sambuc     = CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
491f4a2713aSLionel Sambuc   return Builder.CreateBitCast(Addr, PType);
492f4a2713aSLionel Sambuc }
493f4a2713aSLionel Sambuc 
494f4a2713aSLionel Sambuc /// Perform a bitcast, derived-to-base, or base-to-derived member pointer
495f4a2713aSLionel Sambuc /// conversion.
496f4a2713aSLionel Sambuc ///
497f4a2713aSLionel Sambuc /// Bitcast conversions are always a no-op under Itanium.
498f4a2713aSLionel Sambuc ///
499f4a2713aSLionel Sambuc /// Obligatory offset/adjustment diagram:
500f4a2713aSLionel Sambuc ///         <-- offset -->          <-- adjustment -->
501f4a2713aSLionel Sambuc ///   |--------------------------|----------------------|--------------------|
502f4a2713aSLionel Sambuc ///   ^Derived address point     ^Base address point    ^Member address point
503f4a2713aSLionel Sambuc ///
504f4a2713aSLionel Sambuc /// So when converting a base member pointer to a derived member pointer,
505f4a2713aSLionel Sambuc /// we add the offset to the adjustment because the address point has
506f4a2713aSLionel Sambuc /// decreased;  and conversely, when converting a derived MP to a base MP
507f4a2713aSLionel Sambuc /// we subtract the offset from the adjustment because the address point
508f4a2713aSLionel Sambuc /// has increased.
509f4a2713aSLionel Sambuc ///
510f4a2713aSLionel Sambuc /// The standard forbids (at compile time) conversion to and from
511f4a2713aSLionel Sambuc /// virtual bases, which is why we don't have to consider them here.
512f4a2713aSLionel Sambuc ///
513f4a2713aSLionel Sambuc /// The standard forbids (at run time) casting a derived MP to a base
514f4a2713aSLionel Sambuc /// MP when the derived MP does not point to a member of the base.
515f4a2713aSLionel Sambuc /// This is why -1 is a reasonable choice for null data member
516f4a2713aSLionel Sambuc /// pointers.
517f4a2713aSLionel Sambuc llvm::Value *
EmitMemberPointerConversion(CodeGenFunction & CGF,const CastExpr * E,llvm::Value * src)518f4a2713aSLionel Sambuc ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
519f4a2713aSLionel Sambuc                                            const CastExpr *E,
520f4a2713aSLionel Sambuc                                            llvm::Value *src) {
521f4a2713aSLionel Sambuc   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
522f4a2713aSLionel Sambuc          E->getCastKind() == CK_BaseToDerivedMemberPointer ||
523f4a2713aSLionel Sambuc          E->getCastKind() == CK_ReinterpretMemberPointer);
524f4a2713aSLionel Sambuc 
525f4a2713aSLionel Sambuc   // Under Itanium, reinterprets don't require any additional processing.
526f4a2713aSLionel Sambuc   if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
527f4a2713aSLionel Sambuc 
528f4a2713aSLionel Sambuc   // Use constant emission if we can.
529f4a2713aSLionel Sambuc   if (isa<llvm::Constant>(src))
530f4a2713aSLionel Sambuc     return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
531f4a2713aSLionel Sambuc 
532f4a2713aSLionel Sambuc   llvm::Constant *adj = getMemberPointerAdjustment(E);
533f4a2713aSLionel Sambuc   if (!adj) return src;
534f4a2713aSLionel Sambuc 
535f4a2713aSLionel Sambuc   CGBuilderTy &Builder = CGF.Builder;
536f4a2713aSLionel Sambuc   bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
537f4a2713aSLionel Sambuc 
538f4a2713aSLionel Sambuc   const MemberPointerType *destTy =
539f4a2713aSLionel Sambuc     E->getType()->castAs<MemberPointerType>();
540f4a2713aSLionel Sambuc 
541f4a2713aSLionel Sambuc   // For member data pointers, this is just a matter of adding the
542f4a2713aSLionel Sambuc   // offset if the source is non-null.
543f4a2713aSLionel Sambuc   if (destTy->isMemberDataPointer()) {
544f4a2713aSLionel Sambuc     llvm::Value *dst;
545f4a2713aSLionel Sambuc     if (isDerivedToBase)
546f4a2713aSLionel Sambuc       dst = Builder.CreateNSWSub(src, adj, "adj");
547f4a2713aSLionel Sambuc     else
548f4a2713aSLionel Sambuc       dst = Builder.CreateNSWAdd(src, adj, "adj");
549f4a2713aSLionel Sambuc 
550f4a2713aSLionel Sambuc     // Null check.
551f4a2713aSLionel Sambuc     llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
552f4a2713aSLionel Sambuc     llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull");
553f4a2713aSLionel Sambuc     return Builder.CreateSelect(isNull, src, dst);
554f4a2713aSLionel Sambuc   }
555f4a2713aSLionel Sambuc 
556f4a2713aSLionel Sambuc   // The this-adjustment is left-shifted by 1 on ARM.
557f4a2713aSLionel Sambuc   if (UseARMMethodPtrABI) {
558f4a2713aSLionel Sambuc     uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
559f4a2713aSLionel Sambuc     offset <<= 1;
560f4a2713aSLionel Sambuc     adj = llvm::ConstantInt::get(adj->getType(), offset);
561f4a2713aSLionel Sambuc   }
562f4a2713aSLionel Sambuc 
563f4a2713aSLionel Sambuc   llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj");
564f4a2713aSLionel Sambuc   llvm::Value *dstAdj;
565f4a2713aSLionel Sambuc   if (isDerivedToBase)
566f4a2713aSLionel Sambuc     dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj");
567f4a2713aSLionel Sambuc   else
568f4a2713aSLionel Sambuc     dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj");
569f4a2713aSLionel Sambuc 
570f4a2713aSLionel Sambuc   return Builder.CreateInsertValue(src, dstAdj, 1);
571f4a2713aSLionel Sambuc }
572f4a2713aSLionel Sambuc 
573f4a2713aSLionel Sambuc llvm::Constant *
EmitMemberPointerConversion(const CastExpr * E,llvm::Constant * src)574f4a2713aSLionel Sambuc ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
575f4a2713aSLionel Sambuc                                            llvm::Constant *src) {
576f4a2713aSLionel Sambuc   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
577f4a2713aSLionel Sambuc          E->getCastKind() == CK_BaseToDerivedMemberPointer ||
578f4a2713aSLionel Sambuc          E->getCastKind() == CK_ReinterpretMemberPointer);
579f4a2713aSLionel Sambuc 
580f4a2713aSLionel Sambuc   // Under Itanium, reinterprets don't require any additional processing.
581f4a2713aSLionel Sambuc   if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
582f4a2713aSLionel Sambuc 
583f4a2713aSLionel Sambuc   // If the adjustment is trivial, we don't need to do anything.
584f4a2713aSLionel Sambuc   llvm::Constant *adj = getMemberPointerAdjustment(E);
585f4a2713aSLionel Sambuc   if (!adj) return src;
586f4a2713aSLionel Sambuc 
587f4a2713aSLionel Sambuc   bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
588f4a2713aSLionel Sambuc 
589f4a2713aSLionel Sambuc   const MemberPointerType *destTy =
590f4a2713aSLionel Sambuc     E->getType()->castAs<MemberPointerType>();
591f4a2713aSLionel Sambuc 
592f4a2713aSLionel Sambuc   // For member data pointers, this is just a matter of adding the
593f4a2713aSLionel Sambuc   // offset if the source is non-null.
594f4a2713aSLionel Sambuc   if (destTy->isMemberDataPointer()) {
595f4a2713aSLionel Sambuc     // null maps to null.
596f4a2713aSLionel Sambuc     if (src->isAllOnesValue()) return src;
597f4a2713aSLionel Sambuc 
598f4a2713aSLionel Sambuc     if (isDerivedToBase)
599f4a2713aSLionel Sambuc       return llvm::ConstantExpr::getNSWSub(src, adj);
600f4a2713aSLionel Sambuc     else
601f4a2713aSLionel Sambuc       return llvm::ConstantExpr::getNSWAdd(src, adj);
602f4a2713aSLionel Sambuc   }
603f4a2713aSLionel Sambuc 
604f4a2713aSLionel Sambuc   // The this-adjustment is left-shifted by 1 on ARM.
605f4a2713aSLionel Sambuc   if (UseARMMethodPtrABI) {
606f4a2713aSLionel Sambuc     uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
607f4a2713aSLionel Sambuc     offset <<= 1;
608f4a2713aSLionel Sambuc     adj = llvm::ConstantInt::get(adj->getType(), offset);
609f4a2713aSLionel Sambuc   }
610f4a2713aSLionel Sambuc 
611f4a2713aSLionel Sambuc   llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
612f4a2713aSLionel Sambuc   llvm::Constant *dstAdj;
613f4a2713aSLionel Sambuc   if (isDerivedToBase)
614f4a2713aSLionel Sambuc     dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
615f4a2713aSLionel Sambuc   else
616f4a2713aSLionel Sambuc     dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
617f4a2713aSLionel Sambuc 
618f4a2713aSLionel Sambuc   return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
619f4a2713aSLionel Sambuc }
620f4a2713aSLionel Sambuc 
621f4a2713aSLionel Sambuc llvm::Constant *
EmitNullMemberPointer(const MemberPointerType * MPT)622f4a2713aSLionel Sambuc ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
623f4a2713aSLionel Sambuc   // Itanium C++ ABI 2.3:
624f4a2713aSLionel Sambuc   //   A NULL pointer is represented as -1.
625f4a2713aSLionel Sambuc   if (MPT->isMemberDataPointer())
626f4a2713aSLionel Sambuc     return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true);
627f4a2713aSLionel Sambuc 
628f4a2713aSLionel Sambuc   llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
629f4a2713aSLionel Sambuc   llvm::Constant *Values[2] = { Zero, Zero };
630f4a2713aSLionel Sambuc   return llvm::ConstantStruct::getAnon(Values);
631f4a2713aSLionel Sambuc }
632f4a2713aSLionel Sambuc 
633f4a2713aSLionel Sambuc llvm::Constant *
EmitMemberDataPointer(const MemberPointerType * MPT,CharUnits offset)634f4a2713aSLionel Sambuc ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
635f4a2713aSLionel Sambuc                                      CharUnits offset) {
636f4a2713aSLionel Sambuc   // Itanium C++ ABI 2.3:
637f4a2713aSLionel Sambuc   //   A pointer to data member is an offset from the base address of
638f4a2713aSLionel Sambuc   //   the class object containing it, represented as a ptrdiff_t
639f4a2713aSLionel Sambuc   return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity());
640f4a2713aSLionel Sambuc }
641f4a2713aSLionel Sambuc 
EmitMemberPointer(const CXXMethodDecl * MD)642f4a2713aSLionel Sambuc llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
643f4a2713aSLionel Sambuc   return BuildMemberPointer(MD, CharUnits::Zero());
644f4a2713aSLionel Sambuc }
645f4a2713aSLionel Sambuc 
BuildMemberPointer(const CXXMethodDecl * MD,CharUnits ThisAdjustment)646f4a2713aSLionel Sambuc llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,
647f4a2713aSLionel Sambuc                                                   CharUnits ThisAdjustment) {
648f4a2713aSLionel Sambuc   assert(MD->isInstance() && "Member function must not be static!");
649f4a2713aSLionel Sambuc   MD = MD->getCanonicalDecl();
650f4a2713aSLionel Sambuc 
651f4a2713aSLionel Sambuc   CodeGenTypes &Types = CGM.getTypes();
652f4a2713aSLionel Sambuc 
653f4a2713aSLionel Sambuc   // Get the function pointer (or index if this is a virtual function).
654f4a2713aSLionel Sambuc   llvm::Constant *MemPtr[2];
655f4a2713aSLionel Sambuc   if (MD->isVirtual()) {
656f4a2713aSLionel Sambuc     uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
657f4a2713aSLionel Sambuc 
658f4a2713aSLionel Sambuc     const ASTContext &Context = getContext();
659f4a2713aSLionel Sambuc     CharUnits PointerWidth =
660f4a2713aSLionel Sambuc       Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
661f4a2713aSLionel Sambuc     uint64_t VTableOffset = (Index * PointerWidth.getQuantity());
662f4a2713aSLionel Sambuc 
663f4a2713aSLionel Sambuc     if (UseARMMethodPtrABI) {
664f4a2713aSLionel Sambuc       // ARM C++ ABI 3.2.1:
665f4a2713aSLionel Sambuc       //   This ABI specifies that adj contains twice the this
666f4a2713aSLionel Sambuc       //   adjustment, plus 1 if the member function is virtual. The
667f4a2713aSLionel Sambuc       //   least significant bit of adj then makes exactly the same
668f4a2713aSLionel Sambuc       //   discrimination as the least significant bit of ptr does for
669f4a2713aSLionel Sambuc       //   Itanium.
670f4a2713aSLionel Sambuc       MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
671f4a2713aSLionel Sambuc       MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
672f4a2713aSLionel Sambuc                                          2 * ThisAdjustment.getQuantity() + 1);
673f4a2713aSLionel Sambuc     } else {
674f4a2713aSLionel Sambuc       // Itanium C++ ABI 2.3:
675f4a2713aSLionel Sambuc       //   For a virtual function, [the pointer field] is 1 plus the
676f4a2713aSLionel Sambuc       //   virtual table offset (in bytes) of the function,
677f4a2713aSLionel Sambuc       //   represented as a ptrdiff_t.
678f4a2713aSLionel Sambuc       MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
679f4a2713aSLionel Sambuc       MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
680f4a2713aSLionel Sambuc                                          ThisAdjustment.getQuantity());
681f4a2713aSLionel Sambuc     }
682f4a2713aSLionel Sambuc   } else {
683f4a2713aSLionel Sambuc     const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
684f4a2713aSLionel Sambuc     llvm::Type *Ty;
685f4a2713aSLionel Sambuc     // Check whether the function has a computable LLVM signature.
686f4a2713aSLionel Sambuc     if (Types.isFuncTypeConvertible(FPT)) {
687f4a2713aSLionel Sambuc       // The function has a computable LLVM signature; use the correct type.
688f4a2713aSLionel Sambuc       Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
689f4a2713aSLionel Sambuc     } else {
690f4a2713aSLionel Sambuc       // Use an arbitrary non-function type to tell GetAddrOfFunction that the
691f4a2713aSLionel Sambuc       // function type is incomplete.
692f4a2713aSLionel Sambuc       Ty = CGM.PtrDiffTy;
693f4a2713aSLionel Sambuc     }
694f4a2713aSLionel Sambuc     llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
695f4a2713aSLionel Sambuc 
696f4a2713aSLionel Sambuc     MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
697f4a2713aSLionel Sambuc     MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
698f4a2713aSLionel Sambuc                                        (UseARMMethodPtrABI ? 2 : 1) *
699f4a2713aSLionel Sambuc                                        ThisAdjustment.getQuantity());
700f4a2713aSLionel Sambuc   }
701f4a2713aSLionel Sambuc 
702f4a2713aSLionel Sambuc   return llvm::ConstantStruct::getAnon(MemPtr);
703f4a2713aSLionel Sambuc }
704f4a2713aSLionel Sambuc 
EmitMemberPointer(const APValue & MP,QualType MPType)705f4a2713aSLionel Sambuc llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,
706f4a2713aSLionel Sambuc                                                  QualType MPType) {
707f4a2713aSLionel Sambuc   const MemberPointerType *MPT = MPType->castAs<MemberPointerType>();
708f4a2713aSLionel Sambuc   const ValueDecl *MPD = MP.getMemberPointerDecl();
709f4a2713aSLionel Sambuc   if (!MPD)
710f4a2713aSLionel Sambuc     return EmitNullMemberPointer(MPT);
711f4a2713aSLionel Sambuc 
712f4a2713aSLionel Sambuc   CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
713f4a2713aSLionel Sambuc 
714f4a2713aSLionel Sambuc   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))
715f4a2713aSLionel Sambuc     return BuildMemberPointer(MD, ThisAdjustment);
716f4a2713aSLionel Sambuc 
717f4a2713aSLionel Sambuc   CharUnits FieldOffset =
718f4a2713aSLionel Sambuc     getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD));
719f4a2713aSLionel Sambuc   return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
720f4a2713aSLionel Sambuc }
721f4a2713aSLionel Sambuc 
722f4a2713aSLionel Sambuc /// The comparison algorithm is pretty easy: the member pointers are
723f4a2713aSLionel Sambuc /// the same if they're either bitwise identical *or* both null.
724f4a2713aSLionel Sambuc ///
725f4a2713aSLionel Sambuc /// ARM is different here only because null-ness is more complicated.
726f4a2713aSLionel Sambuc llvm::Value *
EmitMemberPointerComparison(CodeGenFunction & CGF,llvm::Value * L,llvm::Value * R,const MemberPointerType * MPT,bool Inequality)727f4a2713aSLionel Sambuc ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
728f4a2713aSLionel Sambuc                                            llvm::Value *L,
729f4a2713aSLionel Sambuc                                            llvm::Value *R,
730f4a2713aSLionel Sambuc                                            const MemberPointerType *MPT,
731f4a2713aSLionel Sambuc                                            bool Inequality) {
732f4a2713aSLionel Sambuc   CGBuilderTy &Builder = CGF.Builder;
733f4a2713aSLionel Sambuc 
734f4a2713aSLionel Sambuc   llvm::ICmpInst::Predicate Eq;
735f4a2713aSLionel Sambuc   llvm::Instruction::BinaryOps And, Or;
736f4a2713aSLionel Sambuc   if (Inequality) {
737f4a2713aSLionel Sambuc     Eq = llvm::ICmpInst::ICMP_NE;
738f4a2713aSLionel Sambuc     And = llvm::Instruction::Or;
739f4a2713aSLionel Sambuc     Or = llvm::Instruction::And;
740f4a2713aSLionel Sambuc   } else {
741f4a2713aSLionel Sambuc     Eq = llvm::ICmpInst::ICMP_EQ;
742f4a2713aSLionel Sambuc     And = llvm::Instruction::And;
743f4a2713aSLionel Sambuc     Or = llvm::Instruction::Or;
744f4a2713aSLionel Sambuc   }
745f4a2713aSLionel Sambuc 
746f4a2713aSLionel Sambuc   // Member data pointers are easy because there's a unique null
747f4a2713aSLionel Sambuc   // value, so it just comes down to bitwise equality.
748f4a2713aSLionel Sambuc   if (MPT->isMemberDataPointer())
749f4a2713aSLionel Sambuc     return Builder.CreateICmp(Eq, L, R);
750f4a2713aSLionel Sambuc 
751f4a2713aSLionel Sambuc   // For member function pointers, the tautologies are more complex.
752f4a2713aSLionel Sambuc   // The Itanium tautology is:
753f4a2713aSLionel Sambuc   //   (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
754f4a2713aSLionel Sambuc   // The ARM tautology is:
755f4a2713aSLionel Sambuc   //   (L == R) <==> (L.ptr == R.ptr &&
756f4a2713aSLionel Sambuc   //                  (L.adj == R.adj ||
757f4a2713aSLionel Sambuc   //                   (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
758f4a2713aSLionel Sambuc   // The inequality tautologies have exactly the same structure, except
759f4a2713aSLionel Sambuc   // applying De Morgan's laws.
760f4a2713aSLionel Sambuc 
761f4a2713aSLionel Sambuc   llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
762f4a2713aSLionel Sambuc   llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
763f4a2713aSLionel Sambuc 
764f4a2713aSLionel Sambuc   // This condition tests whether L.ptr == R.ptr.  This must always be
765f4a2713aSLionel Sambuc   // true for equality to hold.
766f4a2713aSLionel Sambuc   llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
767f4a2713aSLionel Sambuc 
768f4a2713aSLionel Sambuc   // This condition, together with the assumption that L.ptr == R.ptr,
769f4a2713aSLionel Sambuc   // tests whether the pointers are both null.  ARM imposes an extra
770f4a2713aSLionel Sambuc   // condition.
771f4a2713aSLionel Sambuc   llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
772f4a2713aSLionel Sambuc   llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
773f4a2713aSLionel Sambuc 
774f4a2713aSLionel Sambuc   // This condition tests whether L.adj == R.adj.  If this isn't
775f4a2713aSLionel Sambuc   // true, the pointers are unequal unless they're both null.
776f4a2713aSLionel Sambuc   llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
777f4a2713aSLionel Sambuc   llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
778f4a2713aSLionel Sambuc   llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
779f4a2713aSLionel Sambuc 
780f4a2713aSLionel Sambuc   // Null member function pointers on ARM clear the low bit of Adj,
781f4a2713aSLionel Sambuc   // so the zero condition has to check that neither low bit is set.
782f4a2713aSLionel Sambuc   if (UseARMMethodPtrABI) {
783f4a2713aSLionel Sambuc     llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
784f4a2713aSLionel Sambuc 
785f4a2713aSLionel Sambuc     // Compute (l.adj | r.adj) & 1 and test it against zero.
786f4a2713aSLionel Sambuc     llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
787f4a2713aSLionel Sambuc     llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
788f4a2713aSLionel Sambuc     llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
789f4a2713aSLionel Sambuc                                                       "cmp.or.adj");
790f4a2713aSLionel Sambuc     EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
791f4a2713aSLionel Sambuc   }
792f4a2713aSLionel Sambuc 
793f4a2713aSLionel Sambuc   // Tie together all our conditions.
794f4a2713aSLionel Sambuc   llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
795f4a2713aSLionel Sambuc   Result = Builder.CreateBinOp(And, PtrEq, Result,
796f4a2713aSLionel Sambuc                                Inequality ? "memptr.ne" : "memptr.eq");
797f4a2713aSLionel Sambuc   return Result;
798f4a2713aSLionel Sambuc }
799f4a2713aSLionel Sambuc 
800f4a2713aSLionel Sambuc llvm::Value *
EmitMemberPointerIsNotNull(CodeGenFunction & CGF,llvm::Value * MemPtr,const MemberPointerType * MPT)801f4a2713aSLionel Sambuc ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
802f4a2713aSLionel Sambuc                                           llvm::Value *MemPtr,
803f4a2713aSLionel Sambuc                                           const MemberPointerType *MPT) {
804f4a2713aSLionel Sambuc   CGBuilderTy &Builder = CGF.Builder;
805f4a2713aSLionel Sambuc 
806f4a2713aSLionel Sambuc   /// For member data pointers, this is just a check against -1.
807f4a2713aSLionel Sambuc   if (MPT->isMemberDataPointer()) {
808f4a2713aSLionel Sambuc     assert(MemPtr->getType() == CGM.PtrDiffTy);
809f4a2713aSLionel Sambuc     llvm::Value *NegativeOne =
810f4a2713aSLionel Sambuc       llvm::Constant::getAllOnesValue(MemPtr->getType());
811f4a2713aSLionel Sambuc     return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
812f4a2713aSLionel Sambuc   }
813f4a2713aSLionel Sambuc 
814f4a2713aSLionel Sambuc   // In Itanium, a member function pointer is not null if 'ptr' is not null.
815f4a2713aSLionel Sambuc   llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
816f4a2713aSLionel Sambuc 
817f4a2713aSLionel Sambuc   llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
818f4a2713aSLionel Sambuc   llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
819f4a2713aSLionel Sambuc 
820f4a2713aSLionel Sambuc   // On ARM, a member function pointer is also non-null if the low bit of 'adj'
821f4a2713aSLionel Sambuc   // (the virtual bit) is set.
822f4a2713aSLionel Sambuc   if (UseARMMethodPtrABI) {
823f4a2713aSLionel Sambuc     llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
824f4a2713aSLionel Sambuc     llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
825f4a2713aSLionel Sambuc     llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
826f4a2713aSLionel Sambuc     llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
827f4a2713aSLionel Sambuc                                                   "memptr.isvirtual");
828f4a2713aSLionel Sambuc     Result = Builder.CreateOr(Result, IsVirtual);
829f4a2713aSLionel Sambuc   }
830f4a2713aSLionel Sambuc 
831f4a2713aSLionel Sambuc   return Result;
832f4a2713aSLionel Sambuc }
833f4a2713aSLionel Sambuc 
classifyReturnType(CGFunctionInfo & FI) const834*0a6a1f1dSLionel Sambuc bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
835*0a6a1f1dSLionel Sambuc   const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
836*0a6a1f1dSLionel Sambuc   if (!RD)
837*0a6a1f1dSLionel Sambuc     return false;
838*0a6a1f1dSLionel Sambuc 
839*0a6a1f1dSLionel Sambuc   // Return indirectly if we have a non-trivial copy ctor or non-trivial dtor.
840*0a6a1f1dSLionel Sambuc   // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
841*0a6a1f1dSLionel Sambuc   // special members.
842*0a6a1f1dSLionel Sambuc   if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) {
843*0a6a1f1dSLionel Sambuc     FI.getReturnInfo() = ABIArgInfo::getIndirect(0, /*ByVal=*/false);
844*0a6a1f1dSLionel Sambuc     return true;
845*0a6a1f1dSLionel Sambuc   }
846*0a6a1f1dSLionel Sambuc   return false;
847*0a6a1f1dSLionel Sambuc }
848*0a6a1f1dSLionel Sambuc 
849f4a2713aSLionel Sambuc /// The Itanium ABI requires non-zero initialization only for data
850f4a2713aSLionel Sambuc /// member pointers, for which '0' is a valid offset.
isZeroInitializable(const MemberPointerType * MPT)851f4a2713aSLionel Sambuc bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
852f4a2713aSLionel Sambuc   return MPT->getPointeeType()->isFunctionType();
853f4a2713aSLionel Sambuc }
854f4a2713aSLionel Sambuc 
855f4a2713aSLionel Sambuc /// The Itanium ABI always places an offset to the complete object
856f4a2713aSLionel Sambuc /// at entry -2 in the vtable.
emitVirtualObjectDelete(CodeGenFunction & CGF,const CXXDeleteExpr * DE,llvm::Value * Ptr,QualType ElementType,const CXXDestructorDecl * Dtor)857*0a6a1f1dSLionel Sambuc void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
858*0a6a1f1dSLionel Sambuc                                             const CXXDeleteExpr *DE,
859*0a6a1f1dSLionel Sambuc                                             llvm::Value *Ptr,
860*0a6a1f1dSLionel Sambuc                                             QualType ElementType,
861*0a6a1f1dSLionel Sambuc                                             const CXXDestructorDecl *Dtor) {
862*0a6a1f1dSLionel Sambuc   bool UseGlobalDelete = DE->isGlobalDelete();
863*0a6a1f1dSLionel Sambuc   if (UseGlobalDelete) {
864*0a6a1f1dSLionel Sambuc     // Derive the complete-object pointer, which is what we need
865*0a6a1f1dSLionel Sambuc     // to pass to the deallocation function.
866*0a6a1f1dSLionel Sambuc 
867f4a2713aSLionel Sambuc     // Grab the vtable pointer as an intptr_t*.
868*0a6a1f1dSLionel Sambuc     llvm::Value *VTable = CGF.GetVTablePtr(Ptr, CGF.IntPtrTy->getPointerTo());
869f4a2713aSLionel Sambuc 
870f4a2713aSLionel Sambuc     // Track back to entry -2 and pull out the offset there.
871*0a6a1f1dSLionel Sambuc     llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
872*0a6a1f1dSLionel Sambuc         VTable, -2, "complete-offset.ptr");
873*0a6a1f1dSLionel Sambuc     llvm::LoadInst *Offset = CGF.Builder.CreateLoad(OffsetPtr);
874*0a6a1f1dSLionel Sambuc     Offset->setAlignment(CGF.PointerAlignInBytes);
875f4a2713aSLionel Sambuc 
876f4a2713aSLionel Sambuc     // Apply the offset.
877*0a6a1f1dSLionel Sambuc     llvm::Value *CompletePtr = CGF.Builder.CreateBitCast(Ptr, CGF.Int8PtrTy);
878*0a6a1f1dSLionel Sambuc     CompletePtr = CGF.Builder.CreateInBoundsGEP(CompletePtr, Offset);
879*0a6a1f1dSLionel Sambuc 
880*0a6a1f1dSLionel Sambuc     // If we're supposed to call the global delete, make sure we do so
881*0a6a1f1dSLionel Sambuc     // even if the destructor throws.
882*0a6a1f1dSLionel Sambuc     CGF.pushCallObjectDeleteCleanup(DE->getOperatorDelete(), CompletePtr,
883*0a6a1f1dSLionel Sambuc                                     ElementType);
884*0a6a1f1dSLionel Sambuc   }
885*0a6a1f1dSLionel Sambuc 
886*0a6a1f1dSLionel Sambuc   // FIXME: Provide a source location here even though there's no
887*0a6a1f1dSLionel Sambuc   // CXXMemberCallExpr for dtor call.
888*0a6a1f1dSLionel Sambuc   CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
889*0a6a1f1dSLionel Sambuc   EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, /*CE=*/nullptr);
890*0a6a1f1dSLionel Sambuc 
891*0a6a1f1dSLionel Sambuc   if (UseGlobalDelete)
892*0a6a1f1dSLionel Sambuc     CGF.PopCleanupBlock();
893*0a6a1f1dSLionel Sambuc }
894*0a6a1f1dSLionel Sambuc 
emitRethrow(CodeGenFunction & CGF,bool isNoReturn)895*0a6a1f1dSLionel Sambuc void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
896*0a6a1f1dSLionel Sambuc   // void __cxa_rethrow();
897*0a6a1f1dSLionel Sambuc 
898*0a6a1f1dSLionel Sambuc   llvm::FunctionType *FTy =
899*0a6a1f1dSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);
900*0a6a1f1dSLionel Sambuc 
901*0a6a1f1dSLionel Sambuc   llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
902*0a6a1f1dSLionel Sambuc 
903*0a6a1f1dSLionel Sambuc   if (isNoReturn)
904*0a6a1f1dSLionel Sambuc     CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, None);
905*0a6a1f1dSLionel Sambuc   else
906*0a6a1f1dSLionel Sambuc     CGF.EmitRuntimeCallOrInvoke(Fn);
907*0a6a1f1dSLionel Sambuc }
908*0a6a1f1dSLionel Sambuc 
getItaniumDynamicCastFn(CodeGenFunction & CGF)909*0a6a1f1dSLionel Sambuc static llvm::Constant *getItaniumDynamicCastFn(CodeGenFunction &CGF) {
910*0a6a1f1dSLionel Sambuc   // void *__dynamic_cast(const void *sub,
911*0a6a1f1dSLionel Sambuc   //                      const abi::__class_type_info *src,
912*0a6a1f1dSLionel Sambuc   //                      const abi::__class_type_info *dst,
913*0a6a1f1dSLionel Sambuc   //                      std::ptrdiff_t src2dst_offset);
914*0a6a1f1dSLionel Sambuc 
915*0a6a1f1dSLionel Sambuc   llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
916*0a6a1f1dSLionel Sambuc   llvm::Type *PtrDiffTy =
917*0a6a1f1dSLionel Sambuc     CGF.ConvertType(CGF.getContext().getPointerDiffType());
918*0a6a1f1dSLionel Sambuc 
919*0a6a1f1dSLionel Sambuc   llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
920*0a6a1f1dSLionel Sambuc 
921*0a6a1f1dSLionel Sambuc   llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
922*0a6a1f1dSLionel Sambuc 
923*0a6a1f1dSLionel Sambuc   // Mark the function as nounwind readonly.
924*0a6a1f1dSLionel Sambuc   llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
925*0a6a1f1dSLionel Sambuc                                             llvm::Attribute::ReadOnly };
926*0a6a1f1dSLionel Sambuc   llvm::AttributeSet Attrs = llvm::AttributeSet::get(
927*0a6a1f1dSLionel Sambuc       CGF.getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
928*0a6a1f1dSLionel Sambuc 
929*0a6a1f1dSLionel Sambuc   return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs);
930*0a6a1f1dSLionel Sambuc }
931*0a6a1f1dSLionel Sambuc 
getBadCastFn(CodeGenFunction & CGF)932*0a6a1f1dSLionel Sambuc static llvm::Constant *getBadCastFn(CodeGenFunction &CGF) {
933*0a6a1f1dSLionel Sambuc   // void __cxa_bad_cast();
934*0a6a1f1dSLionel Sambuc   llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
935*0a6a1f1dSLionel Sambuc   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast");
936*0a6a1f1dSLionel Sambuc }
937*0a6a1f1dSLionel Sambuc 
938*0a6a1f1dSLionel Sambuc /// \brief Compute the src2dst_offset hint as described in the
939*0a6a1f1dSLionel Sambuc /// Itanium C++ ABI [2.9.7]
computeOffsetHint(ASTContext & Context,const CXXRecordDecl * Src,const CXXRecordDecl * Dst)940*0a6a1f1dSLionel Sambuc static CharUnits computeOffsetHint(ASTContext &Context,
941*0a6a1f1dSLionel Sambuc                                    const CXXRecordDecl *Src,
942*0a6a1f1dSLionel Sambuc                                    const CXXRecordDecl *Dst) {
943*0a6a1f1dSLionel Sambuc   CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
944*0a6a1f1dSLionel Sambuc                      /*DetectVirtual=*/false);
945*0a6a1f1dSLionel Sambuc 
946*0a6a1f1dSLionel Sambuc   // If Dst is not derived from Src we can skip the whole computation below and
947*0a6a1f1dSLionel Sambuc   // return that Src is not a public base of Dst.  Record all inheritance paths.
948*0a6a1f1dSLionel Sambuc   if (!Dst->isDerivedFrom(Src, Paths))
949*0a6a1f1dSLionel Sambuc     return CharUnits::fromQuantity(-2ULL);
950*0a6a1f1dSLionel Sambuc 
951*0a6a1f1dSLionel Sambuc   unsigned NumPublicPaths = 0;
952*0a6a1f1dSLionel Sambuc   CharUnits Offset;
953*0a6a1f1dSLionel Sambuc 
954*0a6a1f1dSLionel Sambuc   // Now walk all possible inheritance paths.
955*0a6a1f1dSLionel Sambuc   for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end(); I != E;
956*0a6a1f1dSLionel Sambuc        ++I) {
957*0a6a1f1dSLionel Sambuc     if (I->Access != AS_public) // Ignore non-public inheritance.
958*0a6a1f1dSLionel Sambuc       continue;
959*0a6a1f1dSLionel Sambuc 
960*0a6a1f1dSLionel Sambuc     ++NumPublicPaths;
961*0a6a1f1dSLionel Sambuc 
962*0a6a1f1dSLionel Sambuc     for (CXXBasePath::iterator J = I->begin(), JE = I->end(); J != JE; ++J) {
963*0a6a1f1dSLionel Sambuc       // If the path contains a virtual base class we can't give any hint.
964*0a6a1f1dSLionel Sambuc       // -1: no hint.
965*0a6a1f1dSLionel Sambuc       if (J->Base->isVirtual())
966*0a6a1f1dSLionel Sambuc         return CharUnits::fromQuantity(-1ULL);
967*0a6a1f1dSLionel Sambuc 
968*0a6a1f1dSLionel Sambuc       if (NumPublicPaths > 1) // Won't use offsets, skip computation.
969*0a6a1f1dSLionel Sambuc         continue;
970*0a6a1f1dSLionel Sambuc 
971*0a6a1f1dSLionel Sambuc       // Accumulate the base class offsets.
972*0a6a1f1dSLionel Sambuc       const ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
973*0a6a1f1dSLionel Sambuc       Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
974*0a6a1f1dSLionel Sambuc     }
975*0a6a1f1dSLionel Sambuc   }
976*0a6a1f1dSLionel Sambuc 
977*0a6a1f1dSLionel Sambuc   // -2: Src is not a public base of Dst.
978*0a6a1f1dSLionel Sambuc   if (NumPublicPaths == 0)
979*0a6a1f1dSLionel Sambuc     return CharUnits::fromQuantity(-2ULL);
980*0a6a1f1dSLionel Sambuc 
981*0a6a1f1dSLionel Sambuc   // -3: Src is a multiple public base type but never a virtual base type.
982*0a6a1f1dSLionel Sambuc   if (NumPublicPaths > 1)
983*0a6a1f1dSLionel Sambuc     return CharUnits::fromQuantity(-3ULL);
984*0a6a1f1dSLionel Sambuc 
985*0a6a1f1dSLionel Sambuc   // Otherwise, the Src type is a unique public nonvirtual base type of Dst.
986*0a6a1f1dSLionel Sambuc   // Return the offset of Src from the origin of Dst.
987*0a6a1f1dSLionel Sambuc   return Offset;
988*0a6a1f1dSLionel Sambuc }
989*0a6a1f1dSLionel Sambuc 
getBadTypeidFn(CodeGenFunction & CGF)990*0a6a1f1dSLionel Sambuc static llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) {
991*0a6a1f1dSLionel Sambuc   // void __cxa_bad_typeid();
992*0a6a1f1dSLionel Sambuc   llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
993*0a6a1f1dSLionel Sambuc 
994*0a6a1f1dSLionel Sambuc   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
995*0a6a1f1dSLionel Sambuc }
996*0a6a1f1dSLionel Sambuc 
shouldTypeidBeNullChecked(bool IsDeref,QualType SrcRecordTy)997*0a6a1f1dSLionel Sambuc bool ItaniumCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
998*0a6a1f1dSLionel Sambuc                                               QualType SrcRecordTy) {
999*0a6a1f1dSLionel Sambuc   return IsDeref;
1000*0a6a1f1dSLionel Sambuc }
1001*0a6a1f1dSLionel Sambuc 
EmitBadTypeidCall(CodeGenFunction & CGF)1002*0a6a1f1dSLionel Sambuc void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1003*0a6a1f1dSLionel Sambuc   llvm::Value *Fn = getBadTypeidFn(CGF);
1004*0a6a1f1dSLionel Sambuc   CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
1005*0a6a1f1dSLionel Sambuc   CGF.Builder.CreateUnreachable();
1006*0a6a1f1dSLionel Sambuc }
1007*0a6a1f1dSLionel Sambuc 
EmitTypeid(CodeGenFunction & CGF,QualType SrcRecordTy,llvm::Value * ThisPtr,llvm::Type * StdTypeInfoPtrTy)1008*0a6a1f1dSLionel Sambuc llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
1009*0a6a1f1dSLionel Sambuc                                        QualType SrcRecordTy,
1010*0a6a1f1dSLionel Sambuc                                        llvm::Value *ThisPtr,
1011*0a6a1f1dSLionel Sambuc                                        llvm::Type *StdTypeInfoPtrTy) {
1012*0a6a1f1dSLionel Sambuc   llvm::Value *Value =
1013*0a6a1f1dSLionel Sambuc       CGF.GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo());
1014*0a6a1f1dSLionel Sambuc 
1015*0a6a1f1dSLionel Sambuc   // Load the type info.
1016*0a6a1f1dSLionel Sambuc   Value = CGF.Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
1017*0a6a1f1dSLionel Sambuc   return CGF.Builder.CreateLoad(Value);
1018*0a6a1f1dSLionel Sambuc }
1019*0a6a1f1dSLionel Sambuc 
shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,QualType SrcRecordTy)1020*0a6a1f1dSLionel Sambuc bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
1021*0a6a1f1dSLionel Sambuc                                                        QualType SrcRecordTy) {
1022*0a6a1f1dSLionel Sambuc   return SrcIsPtr;
1023*0a6a1f1dSLionel Sambuc }
1024*0a6a1f1dSLionel Sambuc 
EmitDynamicCastCall(CodeGenFunction & CGF,llvm::Value * Value,QualType SrcRecordTy,QualType DestTy,QualType DestRecordTy,llvm::BasicBlock * CastEnd)1025*0a6a1f1dSLionel Sambuc llvm::Value *ItaniumCXXABI::EmitDynamicCastCall(
1026*0a6a1f1dSLionel Sambuc     CodeGenFunction &CGF, llvm::Value *Value, QualType SrcRecordTy,
1027*0a6a1f1dSLionel Sambuc     QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1028*0a6a1f1dSLionel Sambuc   llvm::Type *PtrDiffLTy =
1029*0a6a1f1dSLionel Sambuc       CGF.ConvertType(CGF.getContext().getPointerDiffType());
1030*0a6a1f1dSLionel Sambuc   llvm::Type *DestLTy = CGF.ConvertType(DestTy);
1031*0a6a1f1dSLionel Sambuc 
1032*0a6a1f1dSLionel Sambuc   llvm::Value *SrcRTTI =
1033*0a6a1f1dSLionel Sambuc       CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
1034*0a6a1f1dSLionel Sambuc   llvm::Value *DestRTTI =
1035*0a6a1f1dSLionel Sambuc       CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
1036*0a6a1f1dSLionel Sambuc 
1037*0a6a1f1dSLionel Sambuc   // Compute the offset hint.
1038*0a6a1f1dSLionel Sambuc   const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
1039*0a6a1f1dSLionel Sambuc   const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();
1040*0a6a1f1dSLionel Sambuc   llvm::Value *OffsetHint = llvm::ConstantInt::get(
1041*0a6a1f1dSLionel Sambuc       PtrDiffLTy,
1042*0a6a1f1dSLionel Sambuc       computeOffsetHint(CGF.getContext(), SrcDecl, DestDecl).getQuantity());
1043*0a6a1f1dSLionel Sambuc 
1044*0a6a1f1dSLionel Sambuc   // Emit the call to __dynamic_cast.
1045*0a6a1f1dSLionel Sambuc   Value = CGF.EmitCastToVoidPtr(Value);
1046*0a6a1f1dSLionel Sambuc 
1047*0a6a1f1dSLionel Sambuc   llvm::Value *args[] = {Value, SrcRTTI, DestRTTI, OffsetHint};
1048*0a6a1f1dSLionel Sambuc   Value = CGF.EmitNounwindRuntimeCall(getItaniumDynamicCastFn(CGF), args);
1049*0a6a1f1dSLionel Sambuc   Value = CGF.Builder.CreateBitCast(Value, DestLTy);
1050*0a6a1f1dSLionel Sambuc 
1051*0a6a1f1dSLionel Sambuc   /// C++ [expr.dynamic.cast]p9:
1052*0a6a1f1dSLionel Sambuc   ///   A failed cast to reference type throws std::bad_cast
1053*0a6a1f1dSLionel Sambuc   if (DestTy->isReferenceType()) {
1054*0a6a1f1dSLionel Sambuc     llvm::BasicBlock *BadCastBlock =
1055*0a6a1f1dSLionel Sambuc         CGF.createBasicBlock("dynamic_cast.bad_cast");
1056*0a6a1f1dSLionel Sambuc 
1057*0a6a1f1dSLionel Sambuc     llvm::Value *IsNull = CGF.Builder.CreateIsNull(Value);
1058*0a6a1f1dSLionel Sambuc     CGF.Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1059*0a6a1f1dSLionel Sambuc 
1060*0a6a1f1dSLionel Sambuc     CGF.EmitBlock(BadCastBlock);
1061*0a6a1f1dSLionel Sambuc     EmitBadCastCall(CGF);
1062*0a6a1f1dSLionel Sambuc   }
1063*0a6a1f1dSLionel Sambuc 
1064*0a6a1f1dSLionel Sambuc   return Value;
1065*0a6a1f1dSLionel Sambuc }
1066*0a6a1f1dSLionel Sambuc 
EmitDynamicCastToVoid(CodeGenFunction & CGF,llvm::Value * Value,QualType SrcRecordTy,QualType DestTy)1067*0a6a1f1dSLionel Sambuc llvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF,
1068*0a6a1f1dSLionel Sambuc                                                   llvm::Value *Value,
1069*0a6a1f1dSLionel Sambuc                                                   QualType SrcRecordTy,
1070*0a6a1f1dSLionel Sambuc                                                   QualType DestTy) {
1071*0a6a1f1dSLionel Sambuc   llvm::Type *PtrDiffLTy =
1072*0a6a1f1dSLionel Sambuc       CGF.ConvertType(CGF.getContext().getPointerDiffType());
1073*0a6a1f1dSLionel Sambuc   llvm::Type *DestLTy = CGF.ConvertType(DestTy);
1074*0a6a1f1dSLionel Sambuc 
1075*0a6a1f1dSLionel Sambuc   // Get the vtable pointer.
1076*0a6a1f1dSLionel Sambuc   llvm::Value *VTable = CGF.GetVTablePtr(Value, PtrDiffLTy->getPointerTo());
1077*0a6a1f1dSLionel Sambuc 
1078*0a6a1f1dSLionel Sambuc   // Get the offset-to-top from the vtable.
1079*0a6a1f1dSLionel Sambuc   llvm::Value *OffsetToTop =
1080*0a6a1f1dSLionel Sambuc       CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
1081*0a6a1f1dSLionel Sambuc   OffsetToTop = CGF.Builder.CreateLoad(OffsetToTop, "offset.to.top");
1082*0a6a1f1dSLionel Sambuc 
1083*0a6a1f1dSLionel Sambuc   // Finally, add the offset to the pointer.
1084*0a6a1f1dSLionel Sambuc   Value = CGF.EmitCastToVoidPtr(Value);
1085*0a6a1f1dSLionel Sambuc   Value = CGF.Builder.CreateInBoundsGEP(Value, OffsetToTop);
1086*0a6a1f1dSLionel Sambuc 
1087*0a6a1f1dSLionel Sambuc   return CGF.Builder.CreateBitCast(Value, DestLTy);
1088*0a6a1f1dSLionel Sambuc }
1089*0a6a1f1dSLionel Sambuc 
EmitBadCastCall(CodeGenFunction & CGF)1090*0a6a1f1dSLionel Sambuc bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1091*0a6a1f1dSLionel Sambuc   llvm::Value *Fn = getBadCastFn(CGF);
1092*0a6a1f1dSLionel Sambuc   CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
1093*0a6a1f1dSLionel Sambuc   CGF.Builder.CreateUnreachable();
1094*0a6a1f1dSLionel Sambuc   return true;
1095f4a2713aSLionel Sambuc }
1096f4a2713aSLionel Sambuc 
1097f4a2713aSLionel Sambuc llvm::Value *
GetVirtualBaseClassOffset(CodeGenFunction & CGF,llvm::Value * This,const CXXRecordDecl * ClassDecl,const CXXRecordDecl * BaseClassDecl)1098f4a2713aSLionel Sambuc ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
1099f4a2713aSLionel Sambuc                                          llvm::Value *This,
1100f4a2713aSLionel Sambuc                                          const CXXRecordDecl *ClassDecl,
1101f4a2713aSLionel Sambuc                                          const CXXRecordDecl *BaseClassDecl) {
1102f4a2713aSLionel Sambuc   llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy);
1103f4a2713aSLionel Sambuc   CharUnits VBaseOffsetOffset =
1104f4a2713aSLionel Sambuc       CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1105f4a2713aSLionel Sambuc                                                                BaseClassDecl);
1106f4a2713aSLionel Sambuc 
1107f4a2713aSLionel Sambuc   llvm::Value *VBaseOffsetPtr =
1108f4a2713aSLionel Sambuc     CGF.Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(),
1109f4a2713aSLionel Sambuc                                    "vbase.offset.ptr");
1110f4a2713aSLionel Sambuc   VBaseOffsetPtr = CGF.Builder.CreateBitCast(VBaseOffsetPtr,
1111f4a2713aSLionel Sambuc                                              CGM.PtrDiffTy->getPointerTo());
1112f4a2713aSLionel Sambuc 
1113f4a2713aSLionel Sambuc   llvm::Value *VBaseOffset =
1114f4a2713aSLionel Sambuc     CGF.Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset");
1115f4a2713aSLionel Sambuc 
1116f4a2713aSLionel Sambuc   return VBaseOffset;
1117f4a2713aSLionel Sambuc }
1118f4a2713aSLionel Sambuc 
EmitCXXConstructors(const CXXConstructorDecl * D)1119f4a2713aSLionel Sambuc void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
1120f4a2713aSLionel Sambuc   // Just make sure we're in sync with TargetCXXABI.
1121f4a2713aSLionel Sambuc   assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1122f4a2713aSLionel Sambuc 
1123*0a6a1f1dSLionel Sambuc   // The constructor used for constructing this as a base class;
1124*0a6a1f1dSLionel Sambuc   // ignores virtual bases.
1125*0a6a1f1dSLionel Sambuc   CGM.EmitGlobal(GlobalDecl(D, Ctor_Base));
1126*0a6a1f1dSLionel Sambuc 
1127f4a2713aSLionel Sambuc   // The constructor used for constructing this as a complete class;
1128*0a6a1f1dSLionel Sambuc   // constructs the virtual bases, then calls the base constructor.
1129f4a2713aSLionel Sambuc   if (!D->getParent()->isAbstract()) {
1130f4a2713aSLionel Sambuc     // We don't need to emit the complete ctor if the class is abstract.
1131f4a2713aSLionel Sambuc     CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete));
1132f4a2713aSLionel Sambuc   }
1133f4a2713aSLionel Sambuc }
1134f4a2713aSLionel Sambuc 
1135*0a6a1f1dSLionel Sambuc void
buildStructorSignature(const CXXMethodDecl * MD,StructorType T,SmallVectorImpl<CanQualType> & ArgTys)1136*0a6a1f1dSLionel Sambuc ItaniumCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
1137f4a2713aSLionel Sambuc                                       SmallVectorImpl<CanQualType> &ArgTys) {
1138f4a2713aSLionel Sambuc   ASTContext &Context = getContext();
1139f4a2713aSLionel Sambuc 
1140*0a6a1f1dSLionel Sambuc   // All parameters are already in place except VTT, which goes after 'this'.
1141*0a6a1f1dSLionel Sambuc   // These are Clang types, so we don't need to worry about sret yet.
1142f4a2713aSLionel Sambuc 
1143f4a2713aSLionel Sambuc   // Check if we need to add a VTT parameter (which has type void **).
1144*0a6a1f1dSLionel Sambuc   if (T == StructorType::Base && MD->getParent()->getNumVBases() != 0)
1145*0a6a1f1dSLionel Sambuc     ArgTys.insert(ArgTys.begin() + 1,
1146*0a6a1f1dSLionel Sambuc                   Context.getPointerType(Context.VoidPtrTy));
1147f4a2713aSLionel Sambuc }
1148f4a2713aSLionel Sambuc 
EmitCXXDestructors(const CXXDestructorDecl * D)1149f4a2713aSLionel Sambuc void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
1150*0a6a1f1dSLionel Sambuc   // The destructor used for destructing this as a base class; ignores
1151*0a6a1f1dSLionel Sambuc   // virtual bases.
1152*0a6a1f1dSLionel Sambuc   CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
1153f4a2713aSLionel Sambuc 
1154f4a2713aSLionel Sambuc   // The destructor used for destructing this as a most-derived class;
1155f4a2713aSLionel Sambuc   // call the base destructor and then destructs any virtual bases.
1156f4a2713aSLionel Sambuc   CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete));
1157f4a2713aSLionel Sambuc 
1158*0a6a1f1dSLionel Sambuc   // The destructor in a virtual table is always a 'deleting'
1159*0a6a1f1dSLionel Sambuc   // destructor, which calls the complete destructor and then uses the
1160*0a6a1f1dSLionel Sambuc   // appropriate operator delete.
1161*0a6a1f1dSLionel Sambuc   if (D->isVirtual())
1162*0a6a1f1dSLionel Sambuc     CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting));
1163f4a2713aSLionel Sambuc }
1164f4a2713aSLionel Sambuc 
addImplicitStructorParams(CodeGenFunction & CGF,QualType & ResTy,FunctionArgList & Params)1165*0a6a1f1dSLionel Sambuc void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1166f4a2713aSLionel Sambuc                                               QualType &ResTy,
1167f4a2713aSLionel Sambuc                                               FunctionArgList &Params) {
1168f4a2713aSLionel Sambuc   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
1169*0a6a1f1dSLionel Sambuc   assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1170f4a2713aSLionel Sambuc 
1171f4a2713aSLionel Sambuc   // Check if we need a VTT parameter as well.
1172f4a2713aSLionel Sambuc   if (NeedsVTTParameter(CGF.CurGD)) {
1173f4a2713aSLionel Sambuc     ASTContext &Context = getContext();
1174f4a2713aSLionel Sambuc 
1175f4a2713aSLionel Sambuc     // FIXME: avoid the fake decl
1176f4a2713aSLionel Sambuc     QualType T = Context.getPointerType(Context.VoidPtrTy);
1177f4a2713aSLionel Sambuc     ImplicitParamDecl *VTTDecl
1178*0a6a1f1dSLionel Sambuc       = ImplicitParamDecl::Create(Context, nullptr, MD->getLocation(),
1179f4a2713aSLionel Sambuc                                   &Context.Idents.get("vtt"), T);
1180*0a6a1f1dSLionel Sambuc     Params.insert(Params.begin() + 1, VTTDecl);
1181*0a6a1f1dSLionel Sambuc     getStructorImplicitParamDecl(CGF) = VTTDecl;
1182f4a2713aSLionel Sambuc   }
1183f4a2713aSLionel Sambuc }
1184f4a2713aSLionel Sambuc 
EmitInstanceFunctionProlog(CodeGenFunction & CGF)1185f4a2713aSLionel Sambuc void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1186f4a2713aSLionel Sambuc   /// Initialize the 'this' slot.
1187f4a2713aSLionel Sambuc   EmitThisParam(CGF);
1188f4a2713aSLionel Sambuc 
1189f4a2713aSLionel Sambuc   /// Initialize the 'vtt' slot if needed.
1190*0a6a1f1dSLionel Sambuc   if (getStructorImplicitParamDecl(CGF)) {
1191*0a6a1f1dSLionel Sambuc     getStructorImplicitParamValue(CGF) = CGF.Builder.CreateLoad(
1192*0a6a1f1dSLionel Sambuc         CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), "vtt");
1193f4a2713aSLionel Sambuc   }
1194f4a2713aSLionel Sambuc 
1195f4a2713aSLionel Sambuc   /// If this is a function that the ABI specifies returns 'this', initialize
1196f4a2713aSLionel Sambuc   /// the return slot to 'this' at the start of the function.
1197f4a2713aSLionel Sambuc   ///
1198f4a2713aSLionel Sambuc   /// Unlike the setting of return types, this is done within the ABI
1199f4a2713aSLionel Sambuc   /// implementation instead of by clients of CGCXXABI because:
1200f4a2713aSLionel Sambuc   /// 1) getThisValue is currently protected
1201f4a2713aSLionel Sambuc   /// 2) in theory, an ABI could implement 'this' returns some other way;
1202f4a2713aSLionel Sambuc   ///    HasThisReturn only specifies a contract, not the implementation
1203f4a2713aSLionel Sambuc   if (HasThisReturn(CGF.CurGD))
1204f4a2713aSLionel Sambuc     CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
1205f4a2713aSLionel Sambuc }
1206f4a2713aSLionel Sambuc 
addImplicitConstructorArgs(CodeGenFunction & CGF,const CXXConstructorDecl * D,CXXCtorType Type,bool ForVirtualBase,bool Delegating,CallArgList & Args)1207*0a6a1f1dSLionel Sambuc unsigned ItaniumCXXABI::addImplicitConstructorArgs(
1208*0a6a1f1dSLionel Sambuc     CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
1209*0a6a1f1dSLionel Sambuc     bool ForVirtualBase, bool Delegating, CallArgList &Args) {
1210*0a6a1f1dSLionel Sambuc   if (!NeedsVTTParameter(GlobalDecl(D, Type)))
1211*0a6a1f1dSLionel Sambuc     return 0;
1212f4a2713aSLionel Sambuc 
1213*0a6a1f1dSLionel Sambuc   // Insert the implicit 'vtt' argument as the second argument.
1214*0a6a1f1dSLionel Sambuc   llvm::Value *VTT =
1215*0a6a1f1dSLionel Sambuc       CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, Delegating);
1216*0a6a1f1dSLionel Sambuc   QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1217*0a6a1f1dSLionel Sambuc   Args.insert(Args.begin() + 1,
1218*0a6a1f1dSLionel Sambuc               CallArg(RValue::get(VTT), VTTTy, /*needscopy=*/false));
1219*0a6a1f1dSLionel Sambuc   return 1;  // Added one arg.
1220*0a6a1f1dSLionel Sambuc }
1221*0a6a1f1dSLionel Sambuc 
EmitDestructorCall(CodeGenFunction & CGF,const CXXDestructorDecl * DD,CXXDtorType Type,bool ForVirtualBase,bool Delegating,llvm::Value * This)1222*0a6a1f1dSLionel Sambuc void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
1223*0a6a1f1dSLionel Sambuc                                        const CXXDestructorDecl *DD,
1224*0a6a1f1dSLionel Sambuc                                        CXXDtorType Type, bool ForVirtualBase,
1225*0a6a1f1dSLionel Sambuc                                        bool Delegating, llvm::Value *This) {
1226*0a6a1f1dSLionel Sambuc   GlobalDecl GD(DD, Type);
1227*0a6a1f1dSLionel Sambuc   llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating);
1228*0a6a1f1dSLionel Sambuc   QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1229*0a6a1f1dSLionel Sambuc 
1230*0a6a1f1dSLionel Sambuc   llvm::Value *Callee = nullptr;
1231*0a6a1f1dSLionel Sambuc   if (getContext().getLangOpts().AppleKext)
1232*0a6a1f1dSLionel Sambuc     Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent());
1233*0a6a1f1dSLionel Sambuc 
1234*0a6a1f1dSLionel Sambuc   if (!Callee)
1235*0a6a1f1dSLionel Sambuc     Callee = CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type));
1236*0a6a1f1dSLionel Sambuc 
1237*0a6a1f1dSLionel Sambuc   CGF.EmitCXXMemberOrOperatorCall(DD, Callee, ReturnValueSlot(), This, VTT,
1238*0a6a1f1dSLionel Sambuc                                   VTTTy, nullptr);
1239f4a2713aSLionel Sambuc }
1240f4a2713aSLionel Sambuc 
emitVTableDefinitions(CodeGenVTables & CGVT,const CXXRecordDecl * RD)1241f4a2713aSLionel Sambuc void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
1242f4a2713aSLionel Sambuc                                           const CXXRecordDecl *RD) {
1243f4a2713aSLionel Sambuc   llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());
1244f4a2713aSLionel Sambuc   if (VTable->hasInitializer())
1245f4a2713aSLionel Sambuc     return;
1246f4a2713aSLionel Sambuc 
1247f4a2713aSLionel Sambuc   ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
1248f4a2713aSLionel Sambuc   const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);
1249f4a2713aSLionel Sambuc   llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1250*0a6a1f1dSLionel Sambuc   llvm::Constant *RTTI =
1251*0a6a1f1dSLionel Sambuc       CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1252f4a2713aSLionel Sambuc 
1253f4a2713aSLionel Sambuc   // Create and set the initializer.
1254f4a2713aSLionel Sambuc   llvm::Constant *Init = CGVT.CreateVTableInitializer(
1255f4a2713aSLionel Sambuc       RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(),
1256*0a6a1f1dSLionel Sambuc       VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks(), RTTI);
1257f4a2713aSLionel Sambuc   VTable->setInitializer(Init);
1258f4a2713aSLionel Sambuc 
1259f4a2713aSLionel Sambuc   // Set the correct linkage.
1260f4a2713aSLionel Sambuc   VTable->setLinkage(Linkage);
1261f4a2713aSLionel Sambuc 
1262f4a2713aSLionel Sambuc   // Set the right visibility.
1263*0a6a1f1dSLionel Sambuc   CGM.setGlobalVisibility(VTable, RD);
1264*0a6a1f1dSLionel Sambuc 
1265*0a6a1f1dSLionel Sambuc   // Use pointer alignment for the vtable. Otherwise we would align them based
1266*0a6a1f1dSLionel Sambuc   // on the size of the initializer which doesn't make sense as only single
1267*0a6a1f1dSLionel Sambuc   // values are read.
1268*0a6a1f1dSLionel Sambuc   unsigned PAlign = CGM.getTarget().getPointerAlign(0);
1269*0a6a1f1dSLionel Sambuc   VTable->setAlignment(getContext().toCharUnitsFromBits(PAlign).getQuantity());
1270f4a2713aSLionel Sambuc 
1271f4a2713aSLionel Sambuc   // If this is the magic class __cxxabiv1::__fundamental_type_info,
1272f4a2713aSLionel Sambuc   // we will emit the typeinfo for the fundamental types. This is the
1273f4a2713aSLionel Sambuc   // same behaviour as GCC.
1274f4a2713aSLionel Sambuc   const DeclContext *DC = RD->getDeclContext();
1275f4a2713aSLionel Sambuc   if (RD->getIdentifier() &&
1276f4a2713aSLionel Sambuc       RD->getIdentifier()->isStr("__fundamental_type_info") &&
1277f4a2713aSLionel Sambuc       isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1278f4a2713aSLionel Sambuc       cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&
1279f4a2713aSLionel Sambuc       DC->getParent()->isTranslationUnit())
1280*0a6a1f1dSLionel Sambuc     EmitFundamentalRTTIDescriptors();
1281f4a2713aSLionel Sambuc }
1282f4a2713aSLionel Sambuc 
getVTableAddressPointInStructor(CodeGenFunction & CGF,const CXXRecordDecl * VTableClass,BaseSubobject Base,const CXXRecordDecl * NearestVBase,bool & NeedsVirtualOffset)1283f4a2713aSLionel Sambuc llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1284f4a2713aSLionel Sambuc     CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
1285f4a2713aSLionel Sambuc     const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {
1286f4a2713aSLionel Sambuc   bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CGF.CurGD);
1287f4a2713aSLionel Sambuc   NeedsVirtualOffset = (NeedsVTTParam && NearestVBase);
1288f4a2713aSLionel Sambuc 
1289f4a2713aSLionel Sambuc   llvm::Value *VTableAddressPoint;
1290f4a2713aSLionel Sambuc   if (NeedsVTTParam && (Base.getBase()->getNumVBases() || NearestVBase)) {
1291f4a2713aSLionel Sambuc     // Get the secondary vpointer index.
1292f4a2713aSLionel Sambuc     uint64_t VirtualPointerIndex =
1293f4a2713aSLionel Sambuc         CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1294f4a2713aSLionel Sambuc 
1295f4a2713aSLionel Sambuc     /// Load the VTT.
1296f4a2713aSLionel Sambuc     llvm::Value *VTT = CGF.LoadCXXVTT();
1297f4a2713aSLionel Sambuc     if (VirtualPointerIndex)
1298f4a2713aSLionel Sambuc       VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
1299f4a2713aSLionel Sambuc 
1300f4a2713aSLionel Sambuc     // And load the address point from the VTT.
1301f4a2713aSLionel Sambuc     VTableAddressPoint = CGF.Builder.CreateLoad(VTT);
1302f4a2713aSLionel Sambuc   } else {
1303f4a2713aSLionel Sambuc     llvm::Constant *VTable =
1304f4a2713aSLionel Sambuc         CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits());
1305f4a2713aSLionel Sambuc     uint64_t AddressPoint = CGM.getItaniumVTableContext()
1306f4a2713aSLionel Sambuc                                 .getVTableLayout(VTableClass)
1307f4a2713aSLionel Sambuc                                 .getAddressPoint(Base);
1308f4a2713aSLionel Sambuc     VTableAddressPoint =
1309f4a2713aSLionel Sambuc         CGF.Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);
1310f4a2713aSLionel Sambuc   }
1311f4a2713aSLionel Sambuc 
1312f4a2713aSLionel Sambuc   return VTableAddressPoint;
1313f4a2713aSLionel Sambuc }
1314f4a2713aSLionel Sambuc 
getVTableAddressPointForConstExpr(BaseSubobject Base,const CXXRecordDecl * VTableClass)1315f4a2713aSLionel Sambuc llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1316f4a2713aSLionel Sambuc     BaseSubobject Base, const CXXRecordDecl *VTableClass) {
1317f4a2713aSLionel Sambuc   llvm::Constant *VTable = getAddrOfVTable(VTableClass, CharUnits());
1318f4a2713aSLionel Sambuc 
1319f4a2713aSLionel Sambuc   // Find the appropriate vtable within the vtable group.
1320f4a2713aSLionel Sambuc   uint64_t AddressPoint = CGM.getItaniumVTableContext()
1321f4a2713aSLionel Sambuc                               .getVTableLayout(VTableClass)
1322f4a2713aSLionel Sambuc                               .getAddressPoint(Base);
1323f4a2713aSLionel Sambuc   llvm::Value *Indices[] = {
1324f4a2713aSLionel Sambuc     llvm::ConstantInt::get(CGM.Int64Ty, 0),
1325f4a2713aSLionel Sambuc     llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint)
1326f4a2713aSLionel Sambuc   };
1327f4a2713aSLionel Sambuc 
1328f4a2713aSLionel Sambuc   return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices);
1329f4a2713aSLionel Sambuc }
1330f4a2713aSLionel Sambuc 
getAddrOfVTable(const CXXRecordDecl * RD,CharUnits VPtrOffset)1331f4a2713aSLionel Sambuc llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
1332f4a2713aSLionel Sambuc                                                      CharUnits VPtrOffset) {
1333f4a2713aSLionel Sambuc   assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets");
1334f4a2713aSLionel Sambuc 
1335f4a2713aSLionel Sambuc   llvm::GlobalVariable *&VTable = VTables[RD];
1336f4a2713aSLionel Sambuc   if (VTable)
1337f4a2713aSLionel Sambuc     return VTable;
1338f4a2713aSLionel Sambuc 
1339f4a2713aSLionel Sambuc   // Queue up this v-table for possible deferred emission.
1340f4a2713aSLionel Sambuc   CGM.addDeferredVTable(RD);
1341f4a2713aSLionel Sambuc 
1342f4a2713aSLionel Sambuc   SmallString<256> OutName;
1343f4a2713aSLionel Sambuc   llvm::raw_svector_ostream Out(OutName);
1344f4a2713aSLionel Sambuc   getMangleContext().mangleCXXVTable(RD, Out);
1345f4a2713aSLionel Sambuc   Out.flush();
1346f4a2713aSLionel Sambuc   StringRef Name = OutName.str();
1347f4a2713aSLionel Sambuc 
1348f4a2713aSLionel Sambuc   ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
1349f4a2713aSLionel Sambuc   llvm::ArrayType *ArrayType = llvm::ArrayType::get(
1350f4a2713aSLionel Sambuc       CGM.Int8PtrTy, VTContext.getVTableLayout(RD).getNumVTableComponents());
1351f4a2713aSLionel Sambuc 
1352f4a2713aSLionel Sambuc   VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1353f4a2713aSLionel Sambuc       Name, ArrayType, llvm::GlobalValue::ExternalLinkage);
1354f4a2713aSLionel Sambuc   VTable->setUnnamedAddr(true);
1355*0a6a1f1dSLionel Sambuc 
1356*0a6a1f1dSLionel Sambuc   if (RD->hasAttr<DLLImportAttr>())
1357*0a6a1f1dSLionel Sambuc     VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1358*0a6a1f1dSLionel Sambuc   else if (RD->hasAttr<DLLExportAttr>())
1359*0a6a1f1dSLionel Sambuc     VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1360*0a6a1f1dSLionel Sambuc 
1361f4a2713aSLionel Sambuc   return VTable;
1362f4a2713aSLionel Sambuc }
1363f4a2713aSLionel Sambuc 
getVirtualFunctionPointer(CodeGenFunction & CGF,GlobalDecl GD,llvm::Value * This,llvm::Type * Ty)1364f4a2713aSLionel Sambuc llvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
1365f4a2713aSLionel Sambuc                                                       GlobalDecl GD,
1366f4a2713aSLionel Sambuc                                                       llvm::Value *This,
1367f4a2713aSLionel Sambuc                                                       llvm::Type *Ty) {
1368f4a2713aSLionel Sambuc   GD = GD.getCanonicalDecl();
1369f4a2713aSLionel Sambuc   Ty = Ty->getPointerTo()->getPointerTo();
1370f4a2713aSLionel Sambuc   llvm::Value *VTable = CGF.GetVTablePtr(This, Ty);
1371f4a2713aSLionel Sambuc 
1372f4a2713aSLionel Sambuc   uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1373f4a2713aSLionel Sambuc   llvm::Value *VFuncPtr =
1374f4a2713aSLionel Sambuc       CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn");
1375f4a2713aSLionel Sambuc   return CGF.Builder.CreateLoad(VFuncPtr);
1376f4a2713aSLionel Sambuc }
1377f4a2713aSLionel Sambuc 
EmitVirtualDestructorCall(CodeGenFunction & CGF,const CXXDestructorDecl * Dtor,CXXDtorType DtorType,llvm::Value * This,const CXXMemberCallExpr * CE)1378*0a6a1f1dSLionel Sambuc llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1379*0a6a1f1dSLionel Sambuc     CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
1380*0a6a1f1dSLionel Sambuc     llvm::Value *This, const CXXMemberCallExpr *CE) {
1381*0a6a1f1dSLionel Sambuc   assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
1382f4a2713aSLionel Sambuc   assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
1383f4a2713aSLionel Sambuc 
1384*0a6a1f1dSLionel Sambuc   const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1385*0a6a1f1dSLionel Sambuc       Dtor, getFromDtorType(DtorType));
1386f4a2713aSLionel Sambuc   llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
1387f4a2713aSLionel Sambuc   llvm::Value *Callee =
1388f4a2713aSLionel Sambuc       getVirtualFunctionPointer(CGF, GlobalDecl(Dtor, DtorType), This, Ty);
1389f4a2713aSLionel Sambuc 
1390*0a6a1f1dSLionel Sambuc   CGF.EmitCXXMemberOrOperatorCall(Dtor, Callee, ReturnValueSlot(), This,
1391*0a6a1f1dSLionel Sambuc                                   /*ImplicitParam=*/nullptr, QualType(), CE);
1392*0a6a1f1dSLionel Sambuc   return nullptr;
1393f4a2713aSLionel Sambuc }
1394f4a2713aSLionel Sambuc 
emitVirtualInheritanceTables(const CXXRecordDecl * RD)1395f4a2713aSLionel Sambuc void ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {
1396f4a2713aSLionel Sambuc   CodeGenVTables &VTables = CGM.getVTables();
1397f4a2713aSLionel Sambuc   llvm::GlobalVariable *VTT = VTables.GetAddrOfVTT(RD);
1398f4a2713aSLionel Sambuc   VTables.EmitVTTDefinition(VTT, CGM.getVTableLinkage(RD), RD);
1399f4a2713aSLionel Sambuc }
1400f4a2713aSLionel Sambuc 
performTypeAdjustment(CodeGenFunction & CGF,llvm::Value * Ptr,int64_t NonVirtualAdjustment,int64_t VirtualAdjustment,bool IsReturnAdjustment)1401f4a2713aSLionel Sambuc static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,
1402f4a2713aSLionel Sambuc                                           llvm::Value *Ptr,
1403f4a2713aSLionel Sambuc                                           int64_t NonVirtualAdjustment,
1404f4a2713aSLionel Sambuc                                           int64_t VirtualAdjustment,
1405f4a2713aSLionel Sambuc                                           bool IsReturnAdjustment) {
1406f4a2713aSLionel Sambuc   if (!NonVirtualAdjustment && !VirtualAdjustment)
1407f4a2713aSLionel Sambuc     return Ptr;
1408f4a2713aSLionel Sambuc 
1409f4a2713aSLionel Sambuc   llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
1410f4a2713aSLionel Sambuc   llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy);
1411f4a2713aSLionel Sambuc 
1412f4a2713aSLionel Sambuc   if (NonVirtualAdjustment && !IsReturnAdjustment) {
1413f4a2713aSLionel Sambuc     // Perform the non-virtual adjustment for a base-to-derived cast.
1414f4a2713aSLionel Sambuc     V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment);
1415f4a2713aSLionel Sambuc   }
1416f4a2713aSLionel Sambuc 
1417f4a2713aSLionel Sambuc   if (VirtualAdjustment) {
1418f4a2713aSLionel Sambuc     llvm::Type *PtrDiffTy =
1419f4a2713aSLionel Sambuc         CGF.ConvertType(CGF.getContext().getPointerDiffType());
1420f4a2713aSLionel Sambuc 
1421f4a2713aSLionel Sambuc     // Perform the virtual adjustment.
1422f4a2713aSLionel Sambuc     llvm::Value *VTablePtrPtr =
1423f4a2713aSLionel Sambuc         CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo());
1424f4a2713aSLionel Sambuc 
1425f4a2713aSLionel Sambuc     llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr);
1426f4a2713aSLionel Sambuc 
1427f4a2713aSLionel Sambuc     llvm::Value *OffsetPtr =
1428f4a2713aSLionel Sambuc         CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
1429f4a2713aSLionel Sambuc 
1430f4a2713aSLionel Sambuc     OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo());
1431f4a2713aSLionel Sambuc 
1432f4a2713aSLionel Sambuc     // Load the adjustment offset from the vtable.
1433f4a2713aSLionel Sambuc     llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr);
1434f4a2713aSLionel Sambuc 
1435f4a2713aSLionel Sambuc     // Adjust our pointer.
1436f4a2713aSLionel Sambuc     V = CGF.Builder.CreateInBoundsGEP(V, Offset);
1437f4a2713aSLionel Sambuc   }
1438f4a2713aSLionel Sambuc 
1439f4a2713aSLionel Sambuc   if (NonVirtualAdjustment && IsReturnAdjustment) {
1440f4a2713aSLionel Sambuc     // Perform the non-virtual adjustment for a derived-to-base cast.
1441f4a2713aSLionel Sambuc     V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment);
1442f4a2713aSLionel Sambuc   }
1443f4a2713aSLionel Sambuc 
1444f4a2713aSLionel Sambuc   // Cast back to the original type.
1445f4a2713aSLionel Sambuc   return CGF.Builder.CreateBitCast(V, Ptr->getType());
1446f4a2713aSLionel Sambuc }
1447f4a2713aSLionel Sambuc 
performThisAdjustment(CodeGenFunction & CGF,llvm::Value * This,const ThisAdjustment & TA)1448f4a2713aSLionel Sambuc llvm::Value *ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF,
1449f4a2713aSLionel Sambuc                                                   llvm::Value *This,
1450f4a2713aSLionel Sambuc                                                   const ThisAdjustment &TA) {
1451f4a2713aSLionel Sambuc   return performTypeAdjustment(CGF, This, TA.NonVirtual,
1452f4a2713aSLionel Sambuc                                TA.Virtual.Itanium.VCallOffsetOffset,
1453f4a2713aSLionel Sambuc                                /*IsReturnAdjustment=*/false);
1454f4a2713aSLionel Sambuc }
1455f4a2713aSLionel Sambuc 
1456f4a2713aSLionel Sambuc llvm::Value *
performReturnAdjustment(CodeGenFunction & CGF,llvm::Value * Ret,const ReturnAdjustment & RA)1457f4a2713aSLionel Sambuc ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret,
1458f4a2713aSLionel Sambuc                                        const ReturnAdjustment &RA) {
1459f4a2713aSLionel Sambuc   return performTypeAdjustment(CGF, Ret, RA.NonVirtual,
1460f4a2713aSLionel Sambuc                                RA.Virtual.Itanium.VBaseOffsetOffset,
1461f4a2713aSLionel Sambuc                                /*IsReturnAdjustment=*/true);
1462f4a2713aSLionel Sambuc }
1463f4a2713aSLionel Sambuc 
EmitReturnFromThunk(CodeGenFunction & CGF,RValue RV,QualType ResultType)1464f4a2713aSLionel Sambuc void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
1465f4a2713aSLionel Sambuc                                     RValue RV, QualType ResultType) {
1466f4a2713aSLionel Sambuc   if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
1467f4a2713aSLionel Sambuc     return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
1468f4a2713aSLionel Sambuc 
1469f4a2713aSLionel Sambuc   // Destructor thunks in the ARM ABI have indeterminate results.
1470f4a2713aSLionel Sambuc   llvm::Type *T =
1471f4a2713aSLionel Sambuc     cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType();
1472f4a2713aSLionel Sambuc   RValue Undef = RValue::get(llvm::UndefValue::get(T));
1473f4a2713aSLionel Sambuc   return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
1474f4a2713aSLionel Sambuc }
1475f4a2713aSLionel Sambuc 
1476f4a2713aSLionel Sambuc /************************** Array allocation cookies **************************/
1477f4a2713aSLionel Sambuc 
getArrayCookieSizeImpl(QualType elementType)1478f4a2713aSLionel Sambuc CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
1479f4a2713aSLionel Sambuc   // The array cookie is a size_t; pad that up to the element alignment.
1480f4a2713aSLionel Sambuc   // The cookie is actually right-justified in that space.
1481f4a2713aSLionel Sambuc   return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes),
1482f4a2713aSLionel Sambuc                   CGM.getContext().getTypeAlignInChars(elementType));
1483f4a2713aSLionel Sambuc }
1484f4a2713aSLionel Sambuc 
InitializeArrayCookie(CodeGenFunction & CGF,llvm::Value * NewPtr,llvm::Value * NumElements,const CXXNewExpr * expr,QualType ElementType)1485f4a2713aSLionel Sambuc llvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
1486f4a2713aSLionel Sambuc                                                   llvm::Value *NewPtr,
1487f4a2713aSLionel Sambuc                                                   llvm::Value *NumElements,
1488f4a2713aSLionel Sambuc                                                   const CXXNewExpr *expr,
1489f4a2713aSLionel Sambuc                                                   QualType ElementType) {
1490f4a2713aSLionel Sambuc   assert(requiresArrayCookie(expr));
1491f4a2713aSLionel Sambuc 
1492f4a2713aSLionel Sambuc   unsigned AS = NewPtr->getType()->getPointerAddressSpace();
1493f4a2713aSLionel Sambuc 
1494f4a2713aSLionel Sambuc   ASTContext &Ctx = getContext();
1495f4a2713aSLionel Sambuc   QualType SizeTy = Ctx.getSizeType();
1496f4a2713aSLionel Sambuc   CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy);
1497f4a2713aSLionel Sambuc 
1498f4a2713aSLionel Sambuc   // The size of the cookie.
1499f4a2713aSLionel Sambuc   CharUnits CookieSize =
1500f4a2713aSLionel Sambuc     std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
1501f4a2713aSLionel Sambuc   assert(CookieSize == getArrayCookieSizeImpl(ElementType));
1502f4a2713aSLionel Sambuc 
1503f4a2713aSLionel Sambuc   // Compute an offset to the cookie.
1504f4a2713aSLionel Sambuc   llvm::Value *CookiePtr = NewPtr;
1505f4a2713aSLionel Sambuc   CharUnits CookieOffset = CookieSize - SizeSize;
1506f4a2713aSLionel Sambuc   if (!CookieOffset.isZero())
1507f4a2713aSLionel Sambuc     CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr,
1508f4a2713aSLionel Sambuc                                                  CookieOffset.getQuantity());
1509f4a2713aSLionel Sambuc 
1510f4a2713aSLionel Sambuc   // Write the number of elements into the appropriate slot.
1511*0a6a1f1dSLionel Sambuc   llvm::Type *NumElementsTy = CGF.ConvertType(SizeTy)->getPointerTo(AS);
1512*0a6a1f1dSLionel Sambuc   llvm::Value *NumElementsPtr =
1513*0a6a1f1dSLionel Sambuc       CGF.Builder.CreateBitCast(CookiePtr, NumElementsTy);
1514*0a6a1f1dSLionel Sambuc   llvm::Instruction *SI = CGF.Builder.CreateStore(NumElements, NumElementsPtr);
1515*0a6a1f1dSLionel Sambuc   if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
1516*0a6a1f1dSLionel Sambuc       expr->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
1517*0a6a1f1dSLionel Sambuc     // The store to the CookiePtr does not need to be instrumented.
1518*0a6a1f1dSLionel Sambuc     CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
1519*0a6a1f1dSLionel Sambuc     llvm::FunctionType *FTy =
1520*0a6a1f1dSLionel Sambuc         llvm::FunctionType::get(CGM.VoidTy, NumElementsTy, false);
1521*0a6a1f1dSLionel Sambuc     llvm::Constant *F =
1522*0a6a1f1dSLionel Sambuc         CGM.CreateRuntimeFunction(FTy, "__asan_poison_cxx_array_cookie");
1523*0a6a1f1dSLionel Sambuc     CGF.Builder.CreateCall(F, NumElementsPtr);
1524*0a6a1f1dSLionel Sambuc   }
1525f4a2713aSLionel Sambuc 
1526f4a2713aSLionel Sambuc   // Finally, compute a pointer to the actual data buffer by skipping
1527f4a2713aSLionel Sambuc   // over the cookie completely.
1528f4a2713aSLionel Sambuc   return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
1529f4a2713aSLionel Sambuc                                                 CookieSize.getQuantity());
1530f4a2713aSLionel Sambuc }
1531f4a2713aSLionel Sambuc 
readArrayCookieImpl(CodeGenFunction & CGF,llvm::Value * allocPtr,CharUnits cookieSize)1532f4a2713aSLionel Sambuc llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
1533f4a2713aSLionel Sambuc                                                 llvm::Value *allocPtr,
1534f4a2713aSLionel Sambuc                                                 CharUnits cookieSize) {
1535f4a2713aSLionel Sambuc   // The element size is right-justified in the cookie.
1536f4a2713aSLionel Sambuc   llvm::Value *numElementsPtr = allocPtr;
1537f4a2713aSLionel Sambuc   CharUnits numElementsOffset =
1538f4a2713aSLionel Sambuc     cookieSize - CharUnits::fromQuantity(CGF.SizeSizeInBytes);
1539f4a2713aSLionel Sambuc   if (!numElementsOffset.isZero())
1540f4a2713aSLionel Sambuc     numElementsPtr =
1541f4a2713aSLionel Sambuc       CGF.Builder.CreateConstInBoundsGEP1_64(numElementsPtr,
1542f4a2713aSLionel Sambuc                                              numElementsOffset.getQuantity());
1543f4a2713aSLionel Sambuc 
1544f4a2713aSLionel Sambuc   unsigned AS = allocPtr->getType()->getPointerAddressSpace();
1545f4a2713aSLionel Sambuc   numElementsPtr =
1546f4a2713aSLionel Sambuc     CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
1547*0a6a1f1dSLionel Sambuc   if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
1548f4a2713aSLionel Sambuc     return CGF.Builder.CreateLoad(numElementsPtr);
1549*0a6a1f1dSLionel Sambuc   // In asan mode emit a function call instead of a regular load and let the
1550*0a6a1f1dSLionel Sambuc   // run-time deal with it: if the shadow is properly poisoned return the
1551*0a6a1f1dSLionel Sambuc   // cookie, otherwise return 0 to avoid an infinite loop calling DTORs.
1552*0a6a1f1dSLionel Sambuc   // We can't simply ignore this load using nosanitize metadata because
1553*0a6a1f1dSLionel Sambuc   // the metadata may be lost.
1554*0a6a1f1dSLionel Sambuc   llvm::FunctionType *FTy =
1555*0a6a1f1dSLionel Sambuc       llvm::FunctionType::get(CGF.SizeTy, CGF.SizeTy->getPointerTo(0), false);
1556*0a6a1f1dSLionel Sambuc   llvm::Constant *F =
1557*0a6a1f1dSLionel Sambuc       CGM.CreateRuntimeFunction(FTy, "__asan_load_cxx_array_cookie");
1558*0a6a1f1dSLionel Sambuc   return CGF.Builder.CreateCall(F, numElementsPtr);
1559f4a2713aSLionel Sambuc }
1560f4a2713aSLionel Sambuc 
getArrayCookieSizeImpl(QualType elementType)1561f4a2713aSLionel Sambuc CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
1562f4a2713aSLionel Sambuc   // ARM says that the cookie is always:
1563f4a2713aSLionel Sambuc   //   struct array_cookie {
1564f4a2713aSLionel Sambuc   //     std::size_t element_size; // element_size != 0
1565f4a2713aSLionel Sambuc   //     std::size_t element_count;
1566f4a2713aSLionel Sambuc   //   };
1567f4a2713aSLionel Sambuc   // But the base ABI doesn't give anything an alignment greater than
1568f4a2713aSLionel Sambuc   // 8, so we can dismiss this as typical ABI-author blindness to
1569f4a2713aSLionel Sambuc   // actual language complexity and round up to the element alignment.
1570f4a2713aSLionel Sambuc   return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes),
1571f4a2713aSLionel Sambuc                   CGM.getContext().getTypeAlignInChars(elementType));
1572f4a2713aSLionel Sambuc }
1573f4a2713aSLionel Sambuc 
InitializeArrayCookie(CodeGenFunction & CGF,llvm::Value * newPtr,llvm::Value * numElements,const CXXNewExpr * expr,QualType elementType)1574f4a2713aSLionel Sambuc llvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
1575f4a2713aSLionel Sambuc                                               llvm::Value *newPtr,
1576f4a2713aSLionel Sambuc                                               llvm::Value *numElements,
1577f4a2713aSLionel Sambuc                                               const CXXNewExpr *expr,
1578f4a2713aSLionel Sambuc                                               QualType elementType) {
1579f4a2713aSLionel Sambuc   assert(requiresArrayCookie(expr));
1580f4a2713aSLionel Sambuc 
1581f4a2713aSLionel Sambuc   // NewPtr is a char*, but we generalize to arbitrary addrspaces.
1582f4a2713aSLionel Sambuc   unsigned AS = newPtr->getType()->getPointerAddressSpace();
1583f4a2713aSLionel Sambuc 
1584f4a2713aSLionel Sambuc   // The cookie is always at the start of the buffer.
1585f4a2713aSLionel Sambuc   llvm::Value *cookie = newPtr;
1586f4a2713aSLionel Sambuc 
1587f4a2713aSLionel Sambuc   // The first element is the element size.
1588f4a2713aSLionel Sambuc   cookie = CGF.Builder.CreateBitCast(cookie, CGF.SizeTy->getPointerTo(AS));
1589f4a2713aSLionel Sambuc   llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy,
1590f4a2713aSLionel Sambuc                  getContext().getTypeSizeInChars(elementType).getQuantity());
1591f4a2713aSLionel Sambuc   CGF.Builder.CreateStore(elementSize, cookie);
1592f4a2713aSLionel Sambuc 
1593f4a2713aSLionel Sambuc   // The second element is the element count.
1594f4a2713aSLionel Sambuc   cookie = CGF.Builder.CreateConstInBoundsGEP1_32(cookie, 1);
1595f4a2713aSLionel Sambuc   CGF.Builder.CreateStore(numElements, cookie);
1596f4a2713aSLionel Sambuc 
1597f4a2713aSLionel Sambuc   // Finally, compute a pointer to the actual data buffer by skipping
1598f4a2713aSLionel Sambuc   // over the cookie completely.
1599f4a2713aSLionel Sambuc   CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
1600f4a2713aSLionel Sambuc   return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
1601f4a2713aSLionel Sambuc                                                 cookieSize.getQuantity());
1602f4a2713aSLionel Sambuc }
1603f4a2713aSLionel Sambuc 
readArrayCookieImpl(CodeGenFunction & CGF,llvm::Value * allocPtr,CharUnits cookieSize)1604f4a2713aSLionel Sambuc llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
1605f4a2713aSLionel Sambuc                                             llvm::Value *allocPtr,
1606f4a2713aSLionel Sambuc                                             CharUnits cookieSize) {
1607f4a2713aSLionel Sambuc   // The number of elements is at offset sizeof(size_t) relative to
1608f4a2713aSLionel Sambuc   // the allocated pointer.
1609f4a2713aSLionel Sambuc   llvm::Value *numElementsPtr
1610f4a2713aSLionel Sambuc     = CGF.Builder.CreateConstInBoundsGEP1_64(allocPtr, CGF.SizeSizeInBytes);
1611f4a2713aSLionel Sambuc 
1612f4a2713aSLionel Sambuc   unsigned AS = allocPtr->getType()->getPointerAddressSpace();
1613f4a2713aSLionel Sambuc   numElementsPtr =
1614f4a2713aSLionel Sambuc     CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
1615f4a2713aSLionel Sambuc   return CGF.Builder.CreateLoad(numElementsPtr);
1616f4a2713aSLionel Sambuc }
1617f4a2713aSLionel Sambuc 
1618f4a2713aSLionel Sambuc /*********************** Static local initialization **************************/
1619f4a2713aSLionel Sambuc 
getGuardAcquireFn(CodeGenModule & CGM,llvm::PointerType * GuardPtrTy)1620f4a2713aSLionel Sambuc static llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM,
1621f4a2713aSLionel Sambuc                                          llvm::PointerType *GuardPtrTy) {
1622f4a2713aSLionel Sambuc   // int __cxa_guard_acquire(__guard *guard_object);
1623f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
1624f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
1625f4a2713aSLionel Sambuc                             GuardPtrTy, /*isVarArg=*/false);
1626f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire",
1627f4a2713aSLionel Sambuc                                    llvm::AttributeSet::get(CGM.getLLVMContext(),
1628f4a2713aSLionel Sambuc                                               llvm::AttributeSet::FunctionIndex,
1629f4a2713aSLionel Sambuc                                                  llvm::Attribute::NoUnwind));
1630f4a2713aSLionel Sambuc }
1631f4a2713aSLionel Sambuc 
getGuardReleaseFn(CodeGenModule & CGM,llvm::PointerType * GuardPtrTy)1632f4a2713aSLionel Sambuc static llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
1633f4a2713aSLionel Sambuc                                          llvm::PointerType *GuardPtrTy) {
1634f4a2713aSLionel Sambuc   // void __cxa_guard_release(__guard *guard_object);
1635f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
1636f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
1637f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release",
1638f4a2713aSLionel Sambuc                                    llvm::AttributeSet::get(CGM.getLLVMContext(),
1639f4a2713aSLionel Sambuc                                               llvm::AttributeSet::FunctionIndex,
1640f4a2713aSLionel Sambuc                                                  llvm::Attribute::NoUnwind));
1641f4a2713aSLionel Sambuc }
1642f4a2713aSLionel Sambuc 
getGuardAbortFn(CodeGenModule & CGM,llvm::PointerType * GuardPtrTy)1643f4a2713aSLionel Sambuc static llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
1644f4a2713aSLionel Sambuc                                        llvm::PointerType *GuardPtrTy) {
1645f4a2713aSLionel Sambuc   // void __cxa_guard_abort(__guard *guard_object);
1646f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
1647f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
1648f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort",
1649f4a2713aSLionel Sambuc                                    llvm::AttributeSet::get(CGM.getLLVMContext(),
1650f4a2713aSLionel Sambuc                                               llvm::AttributeSet::FunctionIndex,
1651f4a2713aSLionel Sambuc                                                  llvm::Attribute::NoUnwind));
1652f4a2713aSLionel Sambuc }
1653f4a2713aSLionel Sambuc 
1654f4a2713aSLionel Sambuc namespace {
1655f4a2713aSLionel Sambuc   struct CallGuardAbort : EHScopeStack::Cleanup {
1656f4a2713aSLionel Sambuc     llvm::GlobalVariable *Guard;
CallGuardAbort__anone546df870211::CallGuardAbort1657f4a2713aSLionel Sambuc     CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
1658f4a2713aSLionel Sambuc 
Emit__anone546df870211::CallGuardAbort1659*0a6a1f1dSLionel Sambuc     void Emit(CodeGenFunction &CGF, Flags flags) override {
1660f4a2713aSLionel Sambuc       CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()),
1661f4a2713aSLionel Sambuc                                   Guard);
1662f4a2713aSLionel Sambuc     }
1663f4a2713aSLionel Sambuc   };
1664f4a2713aSLionel Sambuc }
1665f4a2713aSLionel Sambuc 
1666f4a2713aSLionel Sambuc /// The ARM code here follows the Itanium code closely enough that we
1667f4a2713aSLionel Sambuc /// just special-case it at particular places.
EmitGuardedInit(CodeGenFunction & CGF,const VarDecl & D,llvm::GlobalVariable * var,bool shouldPerformInit)1668f4a2713aSLionel Sambuc void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
1669f4a2713aSLionel Sambuc                                     const VarDecl &D,
1670f4a2713aSLionel Sambuc                                     llvm::GlobalVariable *var,
1671f4a2713aSLionel Sambuc                                     bool shouldPerformInit) {
1672f4a2713aSLionel Sambuc   CGBuilderTy &Builder = CGF.Builder;
1673f4a2713aSLionel Sambuc 
1674f4a2713aSLionel Sambuc   // We only need to use thread-safe statics for local non-TLS variables;
1675f4a2713aSLionel Sambuc   // global initialization is always single-threaded.
1676f4a2713aSLionel Sambuc   bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
1677f4a2713aSLionel Sambuc                     D.isLocalVarDecl() && !D.getTLSKind();
1678f4a2713aSLionel Sambuc 
1679f4a2713aSLionel Sambuc   // If we have a global variable with internal linkage and thread-safe statics
1680f4a2713aSLionel Sambuc   // are disabled, we can just let the guard variable be of type i8.
1681f4a2713aSLionel Sambuc   bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
1682f4a2713aSLionel Sambuc 
1683f4a2713aSLionel Sambuc   llvm::IntegerType *guardTy;
1684f4a2713aSLionel Sambuc   if (useInt8GuardVariable) {
1685f4a2713aSLionel Sambuc     guardTy = CGF.Int8Ty;
1686f4a2713aSLionel Sambuc   } else {
1687f4a2713aSLionel Sambuc     // Guard variables are 64 bits in the generic ABI and size width on ARM
1688f4a2713aSLionel Sambuc     // (i.e. 32-bit on AArch32, 64-bit on AArch64).
1689f4a2713aSLionel Sambuc     guardTy = (UseARMGuardVarABI ? CGF.SizeTy : CGF.Int64Ty);
1690f4a2713aSLionel Sambuc   }
1691f4a2713aSLionel Sambuc   llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
1692f4a2713aSLionel Sambuc 
1693f4a2713aSLionel Sambuc   // Create the guard variable if we don't already have it (as we
1694f4a2713aSLionel Sambuc   // might if we're double-emitting this function body).
1695f4a2713aSLionel Sambuc   llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
1696f4a2713aSLionel Sambuc   if (!guard) {
1697f4a2713aSLionel Sambuc     // Mangle the name for the guard.
1698f4a2713aSLionel Sambuc     SmallString<256> guardName;
1699f4a2713aSLionel Sambuc     {
1700f4a2713aSLionel Sambuc       llvm::raw_svector_ostream out(guardName);
1701f4a2713aSLionel Sambuc       getMangleContext().mangleStaticGuardVariable(&D, out);
1702f4a2713aSLionel Sambuc       out.flush();
1703f4a2713aSLionel Sambuc     }
1704f4a2713aSLionel Sambuc 
1705f4a2713aSLionel Sambuc     // Create the guard variable with a zero-initializer.
1706f4a2713aSLionel Sambuc     // Just absorb linkage and visibility from the guarded variable.
1707f4a2713aSLionel Sambuc     guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
1708f4a2713aSLionel Sambuc                                      false, var->getLinkage(),
1709f4a2713aSLionel Sambuc                                      llvm::ConstantInt::get(guardTy, 0),
1710f4a2713aSLionel Sambuc                                      guardName.str());
1711f4a2713aSLionel Sambuc     guard->setVisibility(var->getVisibility());
1712f4a2713aSLionel Sambuc     // If the variable is thread-local, so is its guard variable.
1713f4a2713aSLionel Sambuc     guard->setThreadLocalMode(var->getThreadLocalMode());
1714f4a2713aSLionel Sambuc 
1715*0a6a1f1dSLionel Sambuc     // The ABI says: It is suggested that it be emitted in the same COMDAT group
1716*0a6a1f1dSLionel Sambuc     // as the associated data object
1717*0a6a1f1dSLionel Sambuc     if (!D.isLocalVarDecl() && var->isWeakForLinker() && CGM.supportsCOMDAT()) {
1718*0a6a1f1dSLionel Sambuc       llvm::Comdat *C = CGM.getModule().getOrInsertComdat(var->getName());
1719*0a6a1f1dSLionel Sambuc       guard->setComdat(C);
1720*0a6a1f1dSLionel Sambuc       var->setComdat(C);
1721*0a6a1f1dSLionel Sambuc       CGF.CurFn->setComdat(C);
1722*0a6a1f1dSLionel Sambuc     }
1723*0a6a1f1dSLionel Sambuc 
1724f4a2713aSLionel Sambuc     CGM.setStaticLocalDeclGuardAddress(&D, guard);
1725f4a2713aSLionel Sambuc   }
1726f4a2713aSLionel Sambuc 
1727f4a2713aSLionel Sambuc   // Test whether the variable has completed initialization.
1728*0a6a1f1dSLionel Sambuc   //
1729f4a2713aSLionel Sambuc   // Itanium C++ ABI 3.3.2:
1730f4a2713aSLionel Sambuc   //   The following is pseudo-code showing how these functions can be used:
1731f4a2713aSLionel Sambuc   //     if (obj_guard.first_byte == 0) {
1732f4a2713aSLionel Sambuc   //       if ( __cxa_guard_acquire (&obj_guard) ) {
1733f4a2713aSLionel Sambuc   //         try {
1734f4a2713aSLionel Sambuc   //           ... initialize the object ...;
1735f4a2713aSLionel Sambuc   //         } catch (...) {
1736f4a2713aSLionel Sambuc   //            __cxa_guard_abort (&obj_guard);
1737f4a2713aSLionel Sambuc   //            throw;
1738f4a2713aSLionel Sambuc   //         }
1739f4a2713aSLionel Sambuc   //         ... queue object destructor with __cxa_atexit() ...;
1740f4a2713aSLionel Sambuc   //         __cxa_guard_release (&obj_guard);
1741f4a2713aSLionel Sambuc   //       }
1742f4a2713aSLionel Sambuc   //     }
1743*0a6a1f1dSLionel Sambuc 
1744f4a2713aSLionel Sambuc   // Load the first byte of the guard variable.
1745f4a2713aSLionel Sambuc   llvm::LoadInst *LI =
1746f4a2713aSLionel Sambuc       Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
1747f4a2713aSLionel Sambuc   LI->setAlignment(1);
1748f4a2713aSLionel Sambuc 
1749f4a2713aSLionel Sambuc   // Itanium ABI:
1750f4a2713aSLionel Sambuc   //   An implementation supporting thread-safety on multiprocessor
1751f4a2713aSLionel Sambuc   //   systems must also guarantee that references to the initialized
1752f4a2713aSLionel Sambuc   //   object do not occur before the load of the initialization flag.
1753f4a2713aSLionel Sambuc   //
1754f4a2713aSLionel Sambuc   // In LLVM, we do this by marking the load Acquire.
1755f4a2713aSLionel Sambuc   if (threadsafe)
1756f4a2713aSLionel Sambuc     LI->setAtomic(llvm::Acquire);
1757f4a2713aSLionel Sambuc 
1758*0a6a1f1dSLionel Sambuc   // For ARM, we should only check the first bit, rather than the entire byte:
1759*0a6a1f1dSLionel Sambuc   //
1760*0a6a1f1dSLionel Sambuc   // ARM C++ ABI 3.2.3.1:
1761*0a6a1f1dSLionel Sambuc   //   To support the potential use of initialization guard variables
1762*0a6a1f1dSLionel Sambuc   //   as semaphores that are the target of ARM SWP and LDREX/STREX
1763*0a6a1f1dSLionel Sambuc   //   synchronizing instructions we define a static initialization
1764*0a6a1f1dSLionel Sambuc   //   guard variable to be a 4-byte aligned, 4-byte word with the
1765*0a6a1f1dSLionel Sambuc   //   following inline access protocol.
1766*0a6a1f1dSLionel Sambuc   //     #define INITIALIZED 1
1767*0a6a1f1dSLionel Sambuc   //     if ((obj_guard & INITIALIZED) != INITIALIZED) {
1768*0a6a1f1dSLionel Sambuc   //       if (__cxa_guard_acquire(&obj_guard))
1769*0a6a1f1dSLionel Sambuc   //         ...
1770*0a6a1f1dSLionel Sambuc   //     }
1771*0a6a1f1dSLionel Sambuc   //
1772*0a6a1f1dSLionel Sambuc   // and similarly for ARM64:
1773*0a6a1f1dSLionel Sambuc   //
1774*0a6a1f1dSLionel Sambuc   // ARM64 C++ ABI 3.2.2:
1775*0a6a1f1dSLionel Sambuc   //   This ABI instead only specifies the value bit 0 of the static guard
1776*0a6a1f1dSLionel Sambuc   //   variable; all other bits are platform defined. Bit 0 shall be 0 when the
1777*0a6a1f1dSLionel Sambuc   //   variable is not initialized and 1 when it is.
1778*0a6a1f1dSLionel Sambuc   llvm::Value *V =
1779*0a6a1f1dSLionel Sambuc       (UseARMGuardVarABI && !useInt8GuardVariable)
1780*0a6a1f1dSLionel Sambuc           ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
1781*0a6a1f1dSLionel Sambuc           : LI;
1782*0a6a1f1dSLionel Sambuc   llvm::Value *isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
1783f4a2713aSLionel Sambuc 
1784f4a2713aSLionel Sambuc   llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
1785f4a2713aSLionel Sambuc   llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
1786f4a2713aSLionel Sambuc 
1787f4a2713aSLionel Sambuc   // Check if the first byte of the guard variable is zero.
1788f4a2713aSLionel Sambuc   Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
1789f4a2713aSLionel Sambuc 
1790f4a2713aSLionel Sambuc   CGF.EmitBlock(InitCheckBlock);
1791f4a2713aSLionel Sambuc 
1792f4a2713aSLionel Sambuc   // Variables used when coping with thread-safe statics and exceptions.
1793f4a2713aSLionel Sambuc   if (threadsafe) {
1794f4a2713aSLionel Sambuc     // Call __cxa_guard_acquire.
1795f4a2713aSLionel Sambuc     llvm::Value *V
1796f4a2713aSLionel Sambuc       = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
1797f4a2713aSLionel Sambuc 
1798f4a2713aSLionel Sambuc     llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
1799f4a2713aSLionel Sambuc 
1800f4a2713aSLionel Sambuc     Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
1801f4a2713aSLionel Sambuc                          InitBlock, EndBlock);
1802f4a2713aSLionel Sambuc 
1803f4a2713aSLionel Sambuc     // Call __cxa_guard_abort along the exceptional edge.
1804f4a2713aSLionel Sambuc     CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);
1805f4a2713aSLionel Sambuc 
1806f4a2713aSLionel Sambuc     CGF.EmitBlock(InitBlock);
1807f4a2713aSLionel Sambuc   }
1808f4a2713aSLionel Sambuc 
1809f4a2713aSLionel Sambuc   // Emit the initializer and add a global destructor if appropriate.
1810f4a2713aSLionel Sambuc   CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit);
1811f4a2713aSLionel Sambuc 
1812f4a2713aSLionel Sambuc   if (threadsafe) {
1813f4a2713aSLionel Sambuc     // Pop the guard-abort cleanup if we pushed one.
1814f4a2713aSLionel Sambuc     CGF.PopCleanupBlock();
1815f4a2713aSLionel Sambuc 
1816f4a2713aSLionel Sambuc     // Call __cxa_guard_release.  This cannot throw.
1817f4a2713aSLionel Sambuc     CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
1818f4a2713aSLionel Sambuc   } else {
1819f4a2713aSLionel Sambuc     Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
1820f4a2713aSLionel Sambuc   }
1821f4a2713aSLionel Sambuc 
1822f4a2713aSLionel Sambuc   CGF.EmitBlock(EndBlock);
1823f4a2713aSLionel Sambuc }
1824f4a2713aSLionel Sambuc 
1825f4a2713aSLionel Sambuc /// Register a global destructor using __cxa_atexit.
emitGlobalDtorWithCXAAtExit(CodeGenFunction & CGF,llvm::Constant * dtor,llvm::Constant * addr,bool TLS)1826f4a2713aSLionel Sambuc static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
1827f4a2713aSLionel Sambuc                                         llvm::Constant *dtor,
1828f4a2713aSLionel Sambuc                                         llvm::Constant *addr,
1829f4a2713aSLionel Sambuc                                         bool TLS) {
1830f4a2713aSLionel Sambuc   const char *Name = "__cxa_atexit";
1831f4a2713aSLionel Sambuc   if (TLS) {
1832f4a2713aSLionel Sambuc     const llvm::Triple &T = CGF.getTarget().getTriple();
1833f4a2713aSLionel Sambuc     Name = T.isMacOSX() ?  "_tlv_atexit" : "__cxa_thread_atexit";
1834f4a2713aSLionel Sambuc   }
1835f4a2713aSLionel Sambuc 
1836f4a2713aSLionel Sambuc   // We're assuming that the destructor function is something we can
1837f4a2713aSLionel Sambuc   // reasonably call with the default CC.  Go ahead and cast it to the
1838f4a2713aSLionel Sambuc   // right prototype.
1839f4a2713aSLionel Sambuc   llvm::Type *dtorTy =
1840f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo();
1841f4a2713aSLionel Sambuc 
1842f4a2713aSLionel Sambuc   // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);
1843f4a2713aSLionel Sambuc   llvm::Type *paramTys[] = { dtorTy, CGF.Int8PtrTy, CGF.Int8PtrTy };
1844f4a2713aSLionel Sambuc   llvm::FunctionType *atexitTy =
1845f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGF.IntTy, paramTys, false);
1846f4a2713aSLionel Sambuc 
1847f4a2713aSLionel Sambuc   // Fetch the actual function.
1848f4a2713aSLionel Sambuc   llvm::Constant *atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name);
1849f4a2713aSLionel Sambuc   if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
1850f4a2713aSLionel Sambuc     fn->setDoesNotThrow();
1851f4a2713aSLionel Sambuc 
1852f4a2713aSLionel Sambuc   // Create a variable that binds the atexit to this shared object.
1853f4a2713aSLionel Sambuc   llvm::Constant *handle =
1854f4a2713aSLionel Sambuc     CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
1855f4a2713aSLionel Sambuc 
1856f4a2713aSLionel Sambuc   llvm::Value *args[] = {
1857f4a2713aSLionel Sambuc     llvm::ConstantExpr::getBitCast(dtor, dtorTy),
1858f4a2713aSLionel Sambuc     llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
1859f4a2713aSLionel Sambuc     handle
1860f4a2713aSLionel Sambuc   };
1861f4a2713aSLionel Sambuc   CGF.EmitNounwindRuntimeCall(atexit, args);
1862f4a2713aSLionel Sambuc }
1863f4a2713aSLionel Sambuc 
1864f4a2713aSLionel Sambuc /// Register a global destructor as best as we know how.
registerGlobalDtor(CodeGenFunction & CGF,const VarDecl & D,llvm::Constant * dtor,llvm::Constant * addr)1865f4a2713aSLionel Sambuc void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
1866f4a2713aSLionel Sambuc                                        const VarDecl &D,
1867f4a2713aSLionel Sambuc                                        llvm::Constant *dtor,
1868f4a2713aSLionel Sambuc                                        llvm::Constant *addr) {
1869f4a2713aSLionel Sambuc   // Use __cxa_atexit if available.
1870f4a2713aSLionel Sambuc   if (CGM.getCodeGenOpts().CXAAtExit)
1871f4a2713aSLionel Sambuc     return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr, D.getTLSKind());
1872f4a2713aSLionel Sambuc 
1873f4a2713aSLionel Sambuc   if (D.getTLSKind())
1874f4a2713aSLionel Sambuc     CGM.ErrorUnsupported(&D, "non-trivial TLS destruction");
1875f4a2713aSLionel Sambuc 
1876f4a2713aSLionel Sambuc   // In Apple kexts, we want to add a global destructor entry.
1877f4a2713aSLionel Sambuc   // FIXME: shouldn't this be guarded by some variable?
1878f4a2713aSLionel Sambuc   if (CGM.getLangOpts().AppleKext) {
1879f4a2713aSLionel Sambuc     // Generate a global destructor entry.
1880f4a2713aSLionel Sambuc     return CGM.AddCXXDtorEntry(dtor, addr);
1881f4a2713aSLionel Sambuc   }
1882f4a2713aSLionel Sambuc 
1883f4a2713aSLionel Sambuc   CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
1884f4a2713aSLionel Sambuc }
1885f4a2713aSLionel Sambuc 
isThreadWrapperReplaceable(const VarDecl * VD,CodeGen::CodeGenModule & CGM)1886*0a6a1f1dSLionel Sambuc static bool isThreadWrapperReplaceable(const VarDecl *VD,
1887*0a6a1f1dSLionel Sambuc                                        CodeGen::CodeGenModule &CGM) {
1888*0a6a1f1dSLionel Sambuc   assert(!VD->isStaticLocal() && "static local VarDecls don't need wrappers!");
1889*0a6a1f1dSLionel Sambuc   // OS X prefers to have references to thread local variables to go through
1890*0a6a1f1dSLionel Sambuc   // the thread wrapper instead of directly referencing the backing variable.
1891*0a6a1f1dSLionel Sambuc   return VD->getTLSKind() == VarDecl::TLS_Dynamic &&
1892*0a6a1f1dSLionel Sambuc          CGM.getTarget().getTriple().isMacOSX();
1893*0a6a1f1dSLionel Sambuc }
1894*0a6a1f1dSLionel Sambuc 
1895f4a2713aSLionel Sambuc /// Get the appropriate linkage for the wrapper function. This is essentially
1896*0a6a1f1dSLionel Sambuc /// the weak form of the variable's linkage; every translation unit which needs
1897f4a2713aSLionel Sambuc /// the wrapper emits a copy, and we want the linker to merge them.
1898*0a6a1f1dSLionel Sambuc static llvm::GlobalValue::LinkageTypes
getThreadLocalWrapperLinkage(const VarDecl * VD,CodeGen::CodeGenModule & CGM)1899*0a6a1f1dSLionel Sambuc getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {
1900*0a6a1f1dSLionel Sambuc   llvm::GlobalValue::LinkageTypes VarLinkage =
1901*0a6a1f1dSLionel Sambuc       CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false);
1902*0a6a1f1dSLionel Sambuc 
1903f4a2713aSLionel Sambuc   // For internal linkage variables, we don't need an external or weak wrapper.
1904f4a2713aSLionel Sambuc   if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
1905f4a2713aSLionel Sambuc     return VarLinkage;
1906*0a6a1f1dSLionel Sambuc 
1907*0a6a1f1dSLionel Sambuc   // If the thread wrapper is replaceable, give it appropriate linkage.
1908*0a6a1f1dSLionel Sambuc   if (isThreadWrapperReplaceable(VD, CGM)) {
1909*0a6a1f1dSLionel Sambuc     if (llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) ||
1910*0a6a1f1dSLionel Sambuc         llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
1911*0a6a1f1dSLionel Sambuc       return llvm::GlobalVariable::WeakAnyLinkage;
1912*0a6a1f1dSLionel Sambuc     return VarLinkage;
1913*0a6a1f1dSLionel Sambuc   }
1914f4a2713aSLionel Sambuc   return llvm::GlobalValue::WeakODRLinkage;
1915f4a2713aSLionel Sambuc }
1916f4a2713aSLionel Sambuc 
1917f4a2713aSLionel Sambuc llvm::Function *
getOrCreateThreadLocalWrapper(const VarDecl * VD,llvm::Value * Val)1918f4a2713aSLionel Sambuc ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,
1919*0a6a1f1dSLionel Sambuc                                              llvm::Value *Val) {
1920f4a2713aSLionel Sambuc   // Mangle the name for the thread_local wrapper function.
1921f4a2713aSLionel Sambuc   SmallString<256> WrapperName;
1922f4a2713aSLionel Sambuc   {
1923f4a2713aSLionel Sambuc     llvm::raw_svector_ostream Out(WrapperName);
1924f4a2713aSLionel Sambuc     getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
1925f4a2713aSLionel Sambuc     Out.flush();
1926f4a2713aSLionel Sambuc   }
1927f4a2713aSLionel Sambuc 
1928*0a6a1f1dSLionel Sambuc   if (llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))
1929f4a2713aSLionel Sambuc     return cast<llvm::Function>(V);
1930f4a2713aSLionel Sambuc 
1931*0a6a1f1dSLionel Sambuc   llvm::Type *RetTy = Val->getType();
1932f4a2713aSLionel Sambuc   if (VD->getType()->isReferenceType())
1933f4a2713aSLionel Sambuc     RetTy = RetTy->getPointerElementType();
1934f4a2713aSLionel Sambuc 
1935f4a2713aSLionel Sambuc   llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false);
1936*0a6a1f1dSLionel Sambuc   llvm::Function *Wrapper =
1937*0a6a1f1dSLionel Sambuc       llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM),
1938*0a6a1f1dSLionel Sambuc                              WrapperName.str(), &CGM.getModule());
1939f4a2713aSLionel Sambuc   // Always resolve references to the wrapper at link time.
1940*0a6a1f1dSLionel Sambuc   if (!Wrapper->hasLocalLinkage() && !isThreadWrapperReplaceable(VD, CGM))
1941f4a2713aSLionel Sambuc     Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
1942f4a2713aSLionel Sambuc   return Wrapper;
1943f4a2713aSLionel Sambuc }
1944f4a2713aSLionel Sambuc 
EmitThreadLocalInitFuncs(CodeGenModule & CGM,ArrayRef<std::pair<const VarDecl *,llvm::GlobalVariable * >> CXXThreadLocals,ArrayRef<llvm::Function * > CXXThreadLocalInits,ArrayRef<llvm::GlobalVariable * > CXXThreadLocalInitVars)1945f4a2713aSLionel Sambuc void ItaniumCXXABI::EmitThreadLocalInitFuncs(
1946*0a6a1f1dSLionel Sambuc     CodeGenModule &CGM,
1947*0a6a1f1dSLionel Sambuc     ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *>>
1948*0a6a1f1dSLionel Sambuc         CXXThreadLocals, ArrayRef<llvm::Function *> CXXThreadLocalInits,
1949*0a6a1f1dSLionel Sambuc     ArrayRef<llvm::GlobalVariable *> CXXThreadLocalInitVars) {
1950*0a6a1f1dSLionel Sambuc   llvm::Function *InitFunc = nullptr;
1951*0a6a1f1dSLionel Sambuc   if (!CXXThreadLocalInits.empty()) {
1952*0a6a1f1dSLionel Sambuc     // Generate a guarded initialization function.
1953*0a6a1f1dSLionel Sambuc     llvm::FunctionType *FTy =
1954*0a6a1f1dSLionel Sambuc         llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
1955*0a6a1f1dSLionel Sambuc     InitFunc = CGM.CreateGlobalInitOrDestructFunction(FTy, "__tls_init",
1956*0a6a1f1dSLionel Sambuc                                                       SourceLocation(),
1957*0a6a1f1dSLionel Sambuc                                                       /*TLS=*/true);
1958*0a6a1f1dSLionel Sambuc     llvm::GlobalVariable *Guard = new llvm::GlobalVariable(
1959*0a6a1f1dSLionel Sambuc         CGM.getModule(), CGM.Int8Ty, /*isConstant=*/false,
1960*0a6a1f1dSLionel Sambuc         llvm::GlobalVariable::InternalLinkage,
1961*0a6a1f1dSLionel Sambuc         llvm::ConstantInt::get(CGM.Int8Ty, 0), "__tls_guard");
1962*0a6a1f1dSLionel Sambuc     Guard->setThreadLocal(true);
1963*0a6a1f1dSLionel Sambuc     CodeGenFunction(CGM)
1964*0a6a1f1dSLionel Sambuc         .GenerateCXXGlobalInitFunc(InitFunc, CXXThreadLocalInits, Guard);
1965*0a6a1f1dSLionel Sambuc   }
1966*0a6a1f1dSLionel Sambuc   for (unsigned I = 0, N = CXXThreadLocals.size(); I != N; ++I) {
1967*0a6a1f1dSLionel Sambuc     const VarDecl *VD = CXXThreadLocals[I].first;
1968*0a6a1f1dSLionel Sambuc     llvm::GlobalVariable *Var = CXXThreadLocals[I].second;
1969*0a6a1f1dSLionel Sambuc 
1970*0a6a1f1dSLionel Sambuc     // Some targets require that all access to thread local variables go through
1971*0a6a1f1dSLionel Sambuc     // the thread wrapper.  This means that we cannot attempt to create a thread
1972*0a6a1f1dSLionel Sambuc     // wrapper or a thread helper.
1973*0a6a1f1dSLionel Sambuc     if (isThreadWrapperReplaceable(VD, CGM) && !VD->hasDefinition())
1974*0a6a1f1dSLionel Sambuc       continue;
1975f4a2713aSLionel Sambuc 
1976f4a2713aSLionel Sambuc     // Mangle the name for the thread_local initialization function.
1977f4a2713aSLionel Sambuc     SmallString<256> InitFnName;
1978f4a2713aSLionel Sambuc     {
1979f4a2713aSLionel Sambuc       llvm::raw_svector_ostream Out(InitFnName);
1980f4a2713aSLionel Sambuc       getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
1981f4a2713aSLionel Sambuc       Out.flush();
1982f4a2713aSLionel Sambuc     }
1983f4a2713aSLionel Sambuc 
1984f4a2713aSLionel Sambuc     // If we have a definition for the variable, emit the initialization
1985f4a2713aSLionel Sambuc     // function as an alias to the global Init function (if any). Otherwise,
1986f4a2713aSLionel Sambuc     // produce a declaration of the initialization function.
1987*0a6a1f1dSLionel Sambuc     llvm::GlobalValue *Init = nullptr;
1988f4a2713aSLionel Sambuc     bool InitIsInitFunc = false;
1989f4a2713aSLionel Sambuc     if (VD->hasDefinition()) {
1990f4a2713aSLionel Sambuc       InitIsInitFunc = true;
1991f4a2713aSLionel Sambuc       if (InitFunc)
1992*0a6a1f1dSLionel Sambuc         Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
1993*0a6a1f1dSLionel Sambuc                                          InitFunc);
1994f4a2713aSLionel Sambuc     } else {
1995f4a2713aSLionel Sambuc       // Emit a weak global function referring to the initialization function.
1996f4a2713aSLionel Sambuc       // This function will not exist if the TU defining the thread_local
1997f4a2713aSLionel Sambuc       // variable in question does not need any dynamic initialization for
1998f4a2713aSLionel Sambuc       // its thread_local variables.
1999f4a2713aSLionel Sambuc       llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, false);
2000f4a2713aSLionel Sambuc       Init = llvm::Function::Create(
2001f4a2713aSLionel Sambuc           FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(),
2002f4a2713aSLionel Sambuc           &CGM.getModule());
2003f4a2713aSLionel Sambuc     }
2004f4a2713aSLionel Sambuc 
2005f4a2713aSLionel Sambuc     if (Init)
2006f4a2713aSLionel Sambuc       Init->setVisibility(Var->getVisibility());
2007f4a2713aSLionel Sambuc 
2008f4a2713aSLionel Sambuc     llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
2009f4a2713aSLionel Sambuc     llvm::LLVMContext &Context = CGM.getModule().getContext();
2010f4a2713aSLionel Sambuc     llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper);
2011f4a2713aSLionel Sambuc     CGBuilderTy Builder(Entry);
2012f4a2713aSLionel Sambuc     if (InitIsInitFunc) {
2013f4a2713aSLionel Sambuc       if (Init)
2014f4a2713aSLionel Sambuc         Builder.CreateCall(Init);
2015f4a2713aSLionel Sambuc     } else {
2016f4a2713aSLionel Sambuc       // Don't know whether we have an init function. Call it if it exists.
2017f4a2713aSLionel Sambuc       llvm::Value *Have = Builder.CreateIsNotNull(Init);
2018f4a2713aSLionel Sambuc       llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context, "", Wrapper);
2019f4a2713aSLionel Sambuc       llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context, "", Wrapper);
2020f4a2713aSLionel Sambuc       Builder.CreateCondBr(Have, InitBB, ExitBB);
2021f4a2713aSLionel Sambuc 
2022f4a2713aSLionel Sambuc       Builder.SetInsertPoint(InitBB);
2023f4a2713aSLionel Sambuc       Builder.CreateCall(Init);
2024f4a2713aSLionel Sambuc       Builder.CreateBr(ExitBB);
2025f4a2713aSLionel Sambuc 
2026f4a2713aSLionel Sambuc       Builder.SetInsertPoint(ExitBB);
2027f4a2713aSLionel Sambuc     }
2028f4a2713aSLionel Sambuc 
2029f4a2713aSLionel Sambuc     // For a reference, the result of the wrapper function is a pointer to
2030f4a2713aSLionel Sambuc     // the referenced object.
2031f4a2713aSLionel Sambuc     llvm::Value *Val = Var;
2032f4a2713aSLionel Sambuc     if (VD->getType()->isReferenceType()) {
2033f4a2713aSLionel Sambuc       llvm::LoadInst *LI = Builder.CreateLoad(Val);
2034f4a2713aSLionel Sambuc       LI->setAlignment(CGM.getContext().getDeclAlign(VD).getQuantity());
2035f4a2713aSLionel Sambuc       Val = LI;
2036f4a2713aSLionel Sambuc     }
2037*0a6a1f1dSLionel Sambuc     if (Val->getType() != Wrapper->getReturnType())
2038*0a6a1f1dSLionel Sambuc       Val = Builder.CreatePointerBitCastOrAddrSpaceCast(
2039*0a6a1f1dSLionel Sambuc           Val, Wrapper->getReturnType(), "");
2040f4a2713aSLionel Sambuc     Builder.CreateRet(Val);
2041f4a2713aSLionel Sambuc   }
2042f4a2713aSLionel Sambuc }
2043f4a2713aSLionel Sambuc 
EmitThreadLocalVarDeclLValue(CodeGenFunction & CGF,const VarDecl * VD,QualType LValType)2044*0a6a1f1dSLionel Sambuc LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
2045*0a6a1f1dSLionel Sambuc                                                    const VarDecl *VD,
2046*0a6a1f1dSLionel Sambuc                                                    QualType LValType) {
2047f4a2713aSLionel Sambuc   QualType T = VD->getType();
2048f4a2713aSLionel Sambuc   llvm::Type *Ty = CGF.getTypes().ConvertTypeForMem(T);
2049f4a2713aSLionel Sambuc   llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD, Ty);
2050*0a6a1f1dSLionel Sambuc   llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
2051f4a2713aSLionel Sambuc 
2052f4a2713aSLionel Sambuc   Val = CGF.Builder.CreateCall(Wrapper);
2053f4a2713aSLionel Sambuc 
2054f4a2713aSLionel Sambuc   LValue LV;
2055f4a2713aSLionel Sambuc   if (VD->getType()->isReferenceType())
2056*0a6a1f1dSLionel Sambuc     LV = CGF.MakeNaturalAlignAddrLValue(Val, LValType);
2057f4a2713aSLionel Sambuc   else
2058*0a6a1f1dSLionel Sambuc     LV = CGF.MakeAddrLValue(Val, LValType, CGF.getContext().getDeclAlign(VD));
2059f4a2713aSLionel Sambuc   // FIXME: need setObjCGCLValueClass?
2060f4a2713aSLionel Sambuc   return LV;
2061f4a2713aSLionel Sambuc }
2062f4a2713aSLionel Sambuc 
2063f4a2713aSLionel Sambuc /// Return whether the given global decl needs a VTT parameter, which it does
2064f4a2713aSLionel Sambuc /// if it's a base constructor or destructor with virtual bases.
NeedsVTTParameter(GlobalDecl GD)2065f4a2713aSLionel Sambuc bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
2066f4a2713aSLionel Sambuc   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
2067f4a2713aSLionel Sambuc 
2068f4a2713aSLionel Sambuc   // We don't have any virtual bases, just return early.
2069f4a2713aSLionel Sambuc   if (!MD->getParent()->getNumVBases())
2070f4a2713aSLionel Sambuc     return false;
2071f4a2713aSLionel Sambuc 
2072f4a2713aSLionel Sambuc   // Check if we have a base constructor.
2073f4a2713aSLionel Sambuc   if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
2074f4a2713aSLionel Sambuc     return true;
2075f4a2713aSLionel Sambuc 
2076f4a2713aSLionel Sambuc   // Check if we have a base destructor.
2077f4a2713aSLionel Sambuc   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
2078f4a2713aSLionel Sambuc     return true;
2079f4a2713aSLionel Sambuc 
2080f4a2713aSLionel Sambuc   return false;
2081f4a2713aSLionel Sambuc }
2082*0a6a1f1dSLionel Sambuc 
2083*0a6a1f1dSLionel Sambuc namespace {
2084*0a6a1f1dSLionel Sambuc class ItaniumRTTIBuilder {
2085*0a6a1f1dSLionel Sambuc   CodeGenModule &CGM;  // Per-module state.
2086*0a6a1f1dSLionel Sambuc   llvm::LLVMContext &VMContext;
2087*0a6a1f1dSLionel Sambuc   const ItaniumCXXABI &CXXABI;  // Per-module state.
2088*0a6a1f1dSLionel Sambuc 
2089*0a6a1f1dSLionel Sambuc   /// Fields - The fields of the RTTI descriptor currently being built.
2090*0a6a1f1dSLionel Sambuc   SmallVector<llvm::Constant *, 16> Fields;
2091*0a6a1f1dSLionel Sambuc 
2092*0a6a1f1dSLionel Sambuc   /// GetAddrOfTypeName - Returns the mangled type name of the given type.
2093*0a6a1f1dSLionel Sambuc   llvm::GlobalVariable *
2094*0a6a1f1dSLionel Sambuc   GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
2095*0a6a1f1dSLionel Sambuc 
2096*0a6a1f1dSLionel Sambuc   /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI
2097*0a6a1f1dSLionel Sambuc   /// descriptor of the given type.
2098*0a6a1f1dSLionel Sambuc   llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
2099*0a6a1f1dSLionel Sambuc 
2100*0a6a1f1dSLionel Sambuc   /// BuildVTablePointer - Build the vtable pointer for the given type.
2101*0a6a1f1dSLionel Sambuc   void BuildVTablePointer(const Type *Ty);
2102*0a6a1f1dSLionel Sambuc 
2103*0a6a1f1dSLionel Sambuc   /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
2104*0a6a1f1dSLionel Sambuc   /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
2105*0a6a1f1dSLionel Sambuc   void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
2106*0a6a1f1dSLionel Sambuc 
2107*0a6a1f1dSLionel Sambuc   /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
2108*0a6a1f1dSLionel Sambuc   /// classes with bases that do not satisfy the abi::__si_class_type_info
2109*0a6a1f1dSLionel Sambuc   /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
2110*0a6a1f1dSLionel Sambuc   void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
2111*0a6a1f1dSLionel Sambuc 
2112*0a6a1f1dSLionel Sambuc   /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
2113*0a6a1f1dSLionel Sambuc   /// for pointer types.
2114*0a6a1f1dSLionel Sambuc   void BuildPointerTypeInfo(QualType PointeeTy);
2115*0a6a1f1dSLionel Sambuc 
2116*0a6a1f1dSLionel Sambuc   /// BuildObjCObjectTypeInfo - Build the appropriate kind of
2117*0a6a1f1dSLionel Sambuc   /// type_info for an object type.
2118*0a6a1f1dSLionel Sambuc   void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
2119*0a6a1f1dSLionel Sambuc 
2120*0a6a1f1dSLionel Sambuc   /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
2121*0a6a1f1dSLionel Sambuc   /// struct, used for member pointer types.
2122*0a6a1f1dSLionel Sambuc   void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
2123*0a6a1f1dSLionel Sambuc 
2124*0a6a1f1dSLionel Sambuc public:
ItaniumRTTIBuilder(const ItaniumCXXABI & ABI)2125*0a6a1f1dSLionel Sambuc   ItaniumRTTIBuilder(const ItaniumCXXABI &ABI)
2126*0a6a1f1dSLionel Sambuc       : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {}
2127*0a6a1f1dSLionel Sambuc 
2128*0a6a1f1dSLionel Sambuc   // Pointer type info flags.
2129*0a6a1f1dSLionel Sambuc   enum {
2130*0a6a1f1dSLionel Sambuc     /// PTI_Const - Type has const qualifier.
2131*0a6a1f1dSLionel Sambuc     PTI_Const = 0x1,
2132*0a6a1f1dSLionel Sambuc 
2133*0a6a1f1dSLionel Sambuc     /// PTI_Volatile - Type has volatile qualifier.
2134*0a6a1f1dSLionel Sambuc     PTI_Volatile = 0x2,
2135*0a6a1f1dSLionel Sambuc 
2136*0a6a1f1dSLionel Sambuc     /// PTI_Restrict - Type has restrict qualifier.
2137*0a6a1f1dSLionel Sambuc     PTI_Restrict = 0x4,
2138*0a6a1f1dSLionel Sambuc 
2139*0a6a1f1dSLionel Sambuc     /// PTI_Incomplete - Type is incomplete.
2140*0a6a1f1dSLionel Sambuc     PTI_Incomplete = 0x8,
2141*0a6a1f1dSLionel Sambuc 
2142*0a6a1f1dSLionel Sambuc     /// PTI_ContainingClassIncomplete - Containing class is incomplete.
2143*0a6a1f1dSLionel Sambuc     /// (in pointer to member).
2144*0a6a1f1dSLionel Sambuc     PTI_ContainingClassIncomplete = 0x10
2145*0a6a1f1dSLionel Sambuc   };
2146*0a6a1f1dSLionel Sambuc 
2147*0a6a1f1dSLionel Sambuc   // VMI type info flags.
2148*0a6a1f1dSLionel Sambuc   enum {
2149*0a6a1f1dSLionel Sambuc     /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
2150*0a6a1f1dSLionel Sambuc     VMI_NonDiamondRepeat = 0x1,
2151*0a6a1f1dSLionel Sambuc 
2152*0a6a1f1dSLionel Sambuc     /// VMI_DiamondShaped - Class is diamond shaped.
2153*0a6a1f1dSLionel Sambuc     VMI_DiamondShaped = 0x2
2154*0a6a1f1dSLionel Sambuc   };
2155*0a6a1f1dSLionel Sambuc 
2156*0a6a1f1dSLionel Sambuc   // Base class type info flags.
2157*0a6a1f1dSLionel Sambuc   enum {
2158*0a6a1f1dSLionel Sambuc     /// BCTI_Virtual - Base class is virtual.
2159*0a6a1f1dSLionel Sambuc     BCTI_Virtual = 0x1,
2160*0a6a1f1dSLionel Sambuc 
2161*0a6a1f1dSLionel Sambuc     /// BCTI_Public - Base class is public.
2162*0a6a1f1dSLionel Sambuc     BCTI_Public = 0x2
2163*0a6a1f1dSLionel Sambuc   };
2164*0a6a1f1dSLionel Sambuc 
2165*0a6a1f1dSLionel Sambuc   /// BuildTypeInfo - Build the RTTI type info struct for the given type.
2166*0a6a1f1dSLionel Sambuc   ///
2167*0a6a1f1dSLionel Sambuc   /// \param Force - true to force the creation of this RTTI value
2168*0a6a1f1dSLionel Sambuc   llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
2169*0a6a1f1dSLionel Sambuc };
2170*0a6a1f1dSLionel Sambuc }
2171*0a6a1f1dSLionel Sambuc 
GetAddrOfTypeName(QualType Ty,llvm::GlobalVariable::LinkageTypes Linkage)2172*0a6a1f1dSLionel Sambuc llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
2173*0a6a1f1dSLionel Sambuc     QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {
2174*0a6a1f1dSLionel Sambuc   SmallString<256> OutName;
2175*0a6a1f1dSLionel Sambuc   llvm::raw_svector_ostream Out(OutName);
2176*0a6a1f1dSLionel Sambuc   CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
2177*0a6a1f1dSLionel Sambuc   Out.flush();
2178*0a6a1f1dSLionel Sambuc   StringRef Name = OutName.str();
2179*0a6a1f1dSLionel Sambuc 
2180*0a6a1f1dSLionel Sambuc   // We know that the mangled name of the type starts at index 4 of the
2181*0a6a1f1dSLionel Sambuc   // mangled name of the typename, so we can just index into it in order to
2182*0a6a1f1dSLionel Sambuc   // get the mangled name of the type.
2183*0a6a1f1dSLionel Sambuc   llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
2184*0a6a1f1dSLionel Sambuc                                                             Name.substr(4));
2185*0a6a1f1dSLionel Sambuc 
2186*0a6a1f1dSLionel Sambuc   llvm::GlobalVariable *GV =
2187*0a6a1f1dSLionel Sambuc     CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);
2188*0a6a1f1dSLionel Sambuc 
2189*0a6a1f1dSLionel Sambuc   GV->setInitializer(Init);
2190*0a6a1f1dSLionel Sambuc 
2191*0a6a1f1dSLionel Sambuc   return GV;
2192*0a6a1f1dSLionel Sambuc }
2193*0a6a1f1dSLionel Sambuc 
2194*0a6a1f1dSLionel Sambuc llvm::Constant *
GetAddrOfExternalRTTIDescriptor(QualType Ty)2195*0a6a1f1dSLionel Sambuc ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
2196*0a6a1f1dSLionel Sambuc   // Mangle the RTTI name.
2197*0a6a1f1dSLionel Sambuc   SmallString<256> OutName;
2198*0a6a1f1dSLionel Sambuc   llvm::raw_svector_ostream Out(OutName);
2199*0a6a1f1dSLionel Sambuc   CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
2200*0a6a1f1dSLionel Sambuc   Out.flush();
2201*0a6a1f1dSLionel Sambuc   StringRef Name = OutName.str();
2202*0a6a1f1dSLionel Sambuc 
2203*0a6a1f1dSLionel Sambuc   // Look for an existing global.
2204*0a6a1f1dSLionel Sambuc   llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
2205*0a6a1f1dSLionel Sambuc 
2206*0a6a1f1dSLionel Sambuc   if (!GV) {
2207*0a6a1f1dSLionel Sambuc     // Create a new global variable.
2208*0a6a1f1dSLionel Sambuc     GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
2209*0a6a1f1dSLionel Sambuc                                   /*Constant=*/true,
2210*0a6a1f1dSLionel Sambuc                                   llvm::GlobalValue::ExternalLinkage, nullptr,
2211*0a6a1f1dSLionel Sambuc                                   Name);
2212*0a6a1f1dSLionel Sambuc     if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2213*0a6a1f1dSLionel Sambuc       const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2214*0a6a1f1dSLionel Sambuc       if (RD->hasAttr<DLLImportAttr>())
2215*0a6a1f1dSLionel Sambuc         GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
2216*0a6a1f1dSLionel Sambuc     }
2217*0a6a1f1dSLionel Sambuc   }
2218*0a6a1f1dSLionel Sambuc 
2219*0a6a1f1dSLionel Sambuc   return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
2220*0a6a1f1dSLionel Sambuc }
2221*0a6a1f1dSLionel Sambuc 
2222*0a6a1f1dSLionel Sambuc /// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
2223*0a6a1f1dSLionel Sambuc /// info for that type is defined in the standard library.
TypeInfoIsInStandardLibrary(const BuiltinType * Ty)2224*0a6a1f1dSLionel Sambuc static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
2225*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.2:
2226*0a6a1f1dSLionel Sambuc   //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
2227*0a6a1f1dSLionel Sambuc   //   the run-time support library. Specifically, the run-time support
2228*0a6a1f1dSLionel Sambuc   //   library should contain type_info objects for the types X, X* and
2229*0a6a1f1dSLionel Sambuc   //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
2230*0a6a1f1dSLionel Sambuc   //   unsigned char, signed char, short, unsigned short, int, unsigned int,
2231*0a6a1f1dSLionel Sambuc   //   long, unsigned long, long long, unsigned long long, float, double,
2232*0a6a1f1dSLionel Sambuc   //   long double, char16_t, char32_t, and the IEEE 754r decimal and
2233*0a6a1f1dSLionel Sambuc   //   half-precision floating point types.
2234*0a6a1f1dSLionel Sambuc   switch (Ty->getKind()) {
2235*0a6a1f1dSLionel Sambuc     case BuiltinType::Void:
2236*0a6a1f1dSLionel Sambuc     case BuiltinType::NullPtr:
2237*0a6a1f1dSLionel Sambuc     case BuiltinType::Bool:
2238*0a6a1f1dSLionel Sambuc     case BuiltinType::WChar_S:
2239*0a6a1f1dSLionel Sambuc     case BuiltinType::WChar_U:
2240*0a6a1f1dSLionel Sambuc     case BuiltinType::Char_U:
2241*0a6a1f1dSLionel Sambuc     case BuiltinType::Char_S:
2242*0a6a1f1dSLionel Sambuc     case BuiltinType::UChar:
2243*0a6a1f1dSLionel Sambuc     case BuiltinType::SChar:
2244*0a6a1f1dSLionel Sambuc     case BuiltinType::Short:
2245*0a6a1f1dSLionel Sambuc     case BuiltinType::UShort:
2246*0a6a1f1dSLionel Sambuc     case BuiltinType::Int:
2247*0a6a1f1dSLionel Sambuc     case BuiltinType::UInt:
2248*0a6a1f1dSLionel Sambuc     case BuiltinType::Long:
2249*0a6a1f1dSLionel Sambuc     case BuiltinType::ULong:
2250*0a6a1f1dSLionel Sambuc     case BuiltinType::LongLong:
2251*0a6a1f1dSLionel Sambuc     case BuiltinType::ULongLong:
2252*0a6a1f1dSLionel Sambuc     case BuiltinType::Half:
2253*0a6a1f1dSLionel Sambuc     case BuiltinType::Float:
2254*0a6a1f1dSLionel Sambuc     case BuiltinType::Double:
2255*0a6a1f1dSLionel Sambuc     case BuiltinType::LongDouble:
2256*0a6a1f1dSLionel Sambuc     case BuiltinType::Char16:
2257*0a6a1f1dSLionel Sambuc     case BuiltinType::Char32:
2258*0a6a1f1dSLionel Sambuc     case BuiltinType::Int128:
2259*0a6a1f1dSLionel Sambuc     case BuiltinType::UInt128:
2260*0a6a1f1dSLionel Sambuc     case BuiltinType::OCLImage1d:
2261*0a6a1f1dSLionel Sambuc     case BuiltinType::OCLImage1dArray:
2262*0a6a1f1dSLionel Sambuc     case BuiltinType::OCLImage1dBuffer:
2263*0a6a1f1dSLionel Sambuc     case BuiltinType::OCLImage2d:
2264*0a6a1f1dSLionel Sambuc     case BuiltinType::OCLImage2dArray:
2265*0a6a1f1dSLionel Sambuc     case BuiltinType::OCLImage3d:
2266*0a6a1f1dSLionel Sambuc     case BuiltinType::OCLSampler:
2267*0a6a1f1dSLionel Sambuc     case BuiltinType::OCLEvent:
2268*0a6a1f1dSLionel Sambuc       return true;
2269*0a6a1f1dSLionel Sambuc 
2270*0a6a1f1dSLionel Sambuc     case BuiltinType::Dependent:
2271*0a6a1f1dSLionel Sambuc #define BUILTIN_TYPE(Id, SingletonId)
2272*0a6a1f1dSLionel Sambuc #define PLACEHOLDER_TYPE(Id, SingletonId) \
2273*0a6a1f1dSLionel Sambuc     case BuiltinType::Id:
2274*0a6a1f1dSLionel Sambuc #include "clang/AST/BuiltinTypes.def"
2275*0a6a1f1dSLionel Sambuc       llvm_unreachable("asking for RRTI for a placeholder type!");
2276*0a6a1f1dSLionel Sambuc 
2277*0a6a1f1dSLionel Sambuc     case BuiltinType::ObjCId:
2278*0a6a1f1dSLionel Sambuc     case BuiltinType::ObjCClass:
2279*0a6a1f1dSLionel Sambuc     case BuiltinType::ObjCSel:
2280*0a6a1f1dSLionel Sambuc       llvm_unreachable("FIXME: Objective-C types are unsupported!");
2281*0a6a1f1dSLionel Sambuc   }
2282*0a6a1f1dSLionel Sambuc 
2283*0a6a1f1dSLionel Sambuc   llvm_unreachable("Invalid BuiltinType Kind!");
2284*0a6a1f1dSLionel Sambuc }
2285*0a6a1f1dSLionel Sambuc 
TypeInfoIsInStandardLibrary(const PointerType * PointerTy)2286*0a6a1f1dSLionel Sambuc static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
2287*0a6a1f1dSLionel Sambuc   QualType PointeeTy = PointerTy->getPointeeType();
2288*0a6a1f1dSLionel Sambuc   const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
2289*0a6a1f1dSLionel Sambuc   if (!BuiltinTy)
2290*0a6a1f1dSLionel Sambuc     return false;
2291*0a6a1f1dSLionel Sambuc 
2292*0a6a1f1dSLionel Sambuc   // Check the qualifiers.
2293*0a6a1f1dSLionel Sambuc   Qualifiers Quals = PointeeTy.getQualifiers();
2294*0a6a1f1dSLionel Sambuc   Quals.removeConst();
2295*0a6a1f1dSLionel Sambuc 
2296*0a6a1f1dSLionel Sambuc   if (!Quals.empty())
2297*0a6a1f1dSLionel Sambuc     return false;
2298*0a6a1f1dSLionel Sambuc 
2299*0a6a1f1dSLionel Sambuc   return TypeInfoIsInStandardLibrary(BuiltinTy);
2300*0a6a1f1dSLionel Sambuc }
2301*0a6a1f1dSLionel Sambuc 
2302*0a6a1f1dSLionel Sambuc /// IsStandardLibraryRTTIDescriptor - Returns whether the type
2303*0a6a1f1dSLionel Sambuc /// information for the given type exists in the standard library.
IsStandardLibraryRTTIDescriptor(QualType Ty)2304*0a6a1f1dSLionel Sambuc static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
2305*0a6a1f1dSLionel Sambuc   // Type info for builtin types is defined in the standard library.
2306*0a6a1f1dSLionel Sambuc   if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
2307*0a6a1f1dSLionel Sambuc     return TypeInfoIsInStandardLibrary(BuiltinTy);
2308*0a6a1f1dSLionel Sambuc 
2309*0a6a1f1dSLionel Sambuc   // Type info for some pointer types to builtin types is defined in the
2310*0a6a1f1dSLionel Sambuc   // standard library.
2311*0a6a1f1dSLionel Sambuc   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2312*0a6a1f1dSLionel Sambuc     return TypeInfoIsInStandardLibrary(PointerTy);
2313*0a6a1f1dSLionel Sambuc 
2314*0a6a1f1dSLionel Sambuc   return false;
2315*0a6a1f1dSLionel Sambuc }
2316*0a6a1f1dSLionel Sambuc 
2317*0a6a1f1dSLionel Sambuc /// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
2318*0a6a1f1dSLionel Sambuc /// the given type exists somewhere else, and that we should not emit the type
2319*0a6a1f1dSLionel Sambuc /// information in this translation unit.  Assumes that it is not a
2320*0a6a1f1dSLionel Sambuc /// standard-library type.
ShouldUseExternalRTTIDescriptor(CodeGenModule & CGM,QualType Ty)2321*0a6a1f1dSLionel Sambuc static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
2322*0a6a1f1dSLionel Sambuc                                             QualType Ty) {
2323*0a6a1f1dSLionel Sambuc   ASTContext &Context = CGM.getContext();
2324*0a6a1f1dSLionel Sambuc 
2325*0a6a1f1dSLionel Sambuc   // If RTTI is disabled, assume it might be disabled in the
2326*0a6a1f1dSLionel Sambuc   // translation unit that defines any potential key function, too.
2327*0a6a1f1dSLionel Sambuc   if (!Context.getLangOpts().RTTI) return false;
2328*0a6a1f1dSLionel Sambuc 
2329*0a6a1f1dSLionel Sambuc   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2330*0a6a1f1dSLionel Sambuc     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2331*0a6a1f1dSLionel Sambuc     if (!RD->hasDefinition())
2332*0a6a1f1dSLionel Sambuc       return false;
2333*0a6a1f1dSLionel Sambuc 
2334*0a6a1f1dSLionel Sambuc     if (!RD->isDynamicClass())
2335*0a6a1f1dSLionel Sambuc       return false;
2336*0a6a1f1dSLionel Sambuc 
2337*0a6a1f1dSLionel Sambuc     // FIXME: this may need to be reconsidered if the key function
2338*0a6a1f1dSLionel Sambuc     // changes.
2339*0a6a1f1dSLionel Sambuc     if (CGM.getVTables().isVTableExternal(RD))
2340*0a6a1f1dSLionel Sambuc       return true;
2341*0a6a1f1dSLionel Sambuc 
2342*0a6a1f1dSLionel Sambuc     if (RD->hasAttr<DLLImportAttr>())
2343*0a6a1f1dSLionel Sambuc       return true;
2344*0a6a1f1dSLionel Sambuc   }
2345*0a6a1f1dSLionel Sambuc 
2346*0a6a1f1dSLionel Sambuc   return false;
2347*0a6a1f1dSLionel Sambuc }
2348*0a6a1f1dSLionel Sambuc 
2349*0a6a1f1dSLionel Sambuc /// IsIncompleteClassType - Returns whether the given record type is incomplete.
IsIncompleteClassType(const RecordType * RecordTy)2350*0a6a1f1dSLionel Sambuc static bool IsIncompleteClassType(const RecordType *RecordTy) {
2351*0a6a1f1dSLionel Sambuc   return !RecordTy->getDecl()->isCompleteDefinition();
2352*0a6a1f1dSLionel Sambuc }
2353*0a6a1f1dSLionel Sambuc 
2354*0a6a1f1dSLionel Sambuc /// ContainsIncompleteClassType - Returns whether the given type contains an
2355*0a6a1f1dSLionel Sambuc /// incomplete class type. This is true if
2356*0a6a1f1dSLionel Sambuc ///
2357*0a6a1f1dSLionel Sambuc ///   * The given type is an incomplete class type.
2358*0a6a1f1dSLionel Sambuc ///   * The given type is a pointer type whose pointee type contains an
2359*0a6a1f1dSLionel Sambuc ///     incomplete class type.
2360*0a6a1f1dSLionel Sambuc ///   * The given type is a member pointer type whose class is an incomplete
2361*0a6a1f1dSLionel Sambuc ///     class type.
2362*0a6a1f1dSLionel Sambuc ///   * The given type is a member pointer type whoise pointee type contains an
2363*0a6a1f1dSLionel Sambuc ///     incomplete class type.
2364*0a6a1f1dSLionel Sambuc /// is an indirect or direct pointer to an incomplete class type.
ContainsIncompleteClassType(QualType Ty)2365*0a6a1f1dSLionel Sambuc static bool ContainsIncompleteClassType(QualType Ty) {
2366*0a6a1f1dSLionel Sambuc   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2367*0a6a1f1dSLionel Sambuc     if (IsIncompleteClassType(RecordTy))
2368*0a6a1f1dSLionel Sambuc       return true;
2369*0a6a1f1dSLionel Sambuc   }
2370*0a6a1f1dSLionel Sambuc 
2371*0a6a1f1dSLionel Sambuc   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2372*0a6a1f1dSLionel Sambuc     return ContainsIncompleteClassType(PointerTy->getPointeeType());
2373*0a6a1f1dSLionel Sambuc 
2374*0a6a1f1dSLionel Sambuc   if (const MemberPointerType *MemberPointerTy =
2375*0a6a1f1dSLionel Sambuc       dyn_cast<MemberPointerType>(Ty)) {
2376*0a6a1f1dSLionel Sambuc     // Check if the class type is incomplete.
2377*0a6a1f1dSLionel Sambuc     const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
2378*0a6a1f1dSLionel Sambuc     if (IsIncompleteClassType(ClassType))
2379*0a6a1f1dSLionel Sambuc       return true;
2380*0a6a1f1dSLionel Sambuc 
2381*0a6a1f1dSLionel Sambuc     return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
2382*0a6a1f1dSLionel Sambuc   }
2383*0a6a1f1dSLionel Sambuc 
2384*0a6a1f1dSLionel Sambuc   return false;
2385*0a6a1f1dSLionel Sambuc }
2386*0a6a1f1dSLionel Sambuc 
2387*0a6a1f1dSLionel Sambuc // CanUseSingleInheritance - Return whether the given record decl has a "single,
2388*0a6a1f1dSLionel Sambuc // public, non-virtual base at offset zero (i.e. the derived class is dynamic
2389*0a6a1f1dSLionel Sambuc // iff the base is)", according to Itanium C++ ABI, 2.95p6b.
CanUseSingleInheritance(const CXXRecordDecl * RD)2390*0a6a1f1dSLionel Sambuc static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
2391*0a6a1f1dSLionel Sambuc   // Check the number of bases.
2392*0a6a1f1dSLionel Sambuc   if (RD->getNumBases() != 1)
2393*0a6a1f1dSLionel Sambuc     return false;
2394*0a6a1f1dSLionel Sambuc 
2395*0a6a1f1dSLionel Sambuc   // Get the base.
2396*0a6a1f1dSLionel Sambuc   CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
2397*0a6a1f1dSLionel Sambuc 
2398*0a6a1f1dSLionel Sambuc   // Check that the base is not virtual.
2399*0a6a1f1dSLionel Sambuc   if (Base->isVirtual())
2400*0a6a1f1dSLionel Sambuc     return false;
2401*0a6a1f1dSLionel Sambuc 
2402*0a6a1f1dSLionel Sambuc   // Check that the base is public.
2403*0a6a1f1dSLionel Sambuc   if (Base->getAccessSpecifier() != AS_public)
2404*0a6a1f1dSLionel Sambuc     return false;
2405*0a6a1f1dSLionel Sambuc 
2406*0a6a1f1dSLionel Sambuc   // Check that the class is dynamic iff the base is.
2407*0a6a1f1dSLionel Sambuc   const CXXRecordDecl *BaseDecl =
2408*0a6a1f1dSLionel Sambuc     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
2409*0a6a1f1dSLionel Sambuc   if (!BaseDecl->isEmpty() &&
2410*0a6a1f1dSLionel Sambuc       BaseDecl->isDynamicClass() != RD->isDynamicClass())
2411*0a6a1f1dSLionel Sambuc     return false;
2412*0a6a1f1dSLionel Sambuc 
2413*0a6a1f1dSLionel Sambuc   return true;
2414*0a6a1f1dSLionel Sambuc }
2415*0a6a1f1dSLionel Sambuc 
BuildVTablePointer(const Type * Ty)2416*0a6a1f1dSLionel Sambuc void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
2417*0a6a1f1dSLionel Sambuc   // abi::__class_type_info.
2418*0a6a1f1dSLionel Sambuc   static const char * const ClassTypeInfo =
2419*0a6a1f1dSLionel Sambuc     "_ZTVN10__cxxabiv117__class_type_infoE";
2420*0a6a1f1dSLionel Sambuc   // abi::__si_class_type_info.
2421*0a6a1f1dSLionel Sambuc   static const char * const SIClassTypeInfo =
2422*0a6a1f1dSLionel Sambuc     "_ZTVN10__cxxabiv120__si_class_type_infoE";
2423*0a6a1f1dSLionel Sambuc   // abi::__vmi_class_type_info.
2424*0a6a1f1dSLionel Sambuc   static const char * const VMIClassTypeInfo =
2425*0a6a1f1dSLionel Sambuc     "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
2426*0a6a1f1dSLionel Sambuc 
2427*0a6a1f1dSLionel Sambuc   const char *VTableName = nullptr;
2428*0a6a1f1dSLionel Sambuc 
2429*0a6a1f1dSLionel Sambuc   switch (Ty->getTypeClass()) {
2430*0a6a1f1dSLionel Sambuc #define TYPE(Class, Base)
2431*0a6a1f1dSLionel Sambuc #define ABSTRACT_TYPE(Class, Base)
2432*0a6a1f1dSLionel Sambuc #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
2433*0a6a1f1dSLionel Sambuc #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
2434*0a6a1f1dSLionel Sambuc #define DEPENDENT_TYPE(Class, Base) case Type::Class:
2435*0a6a1f1dSLionel Sambuc #include "clang/AST/TypeNodes.def"
2436*0a6a1f1dSLionel Sambuc     llvm_unreachable("Non-canonical and dependent types shouldn't get here");
2437*0a6a1f1dSLionel Sambuc 
2438*0a6a1f1dSLionel Sambuc   case Type::LValueReference:
2439*0a6a1f1dSLionel Sambuc   case Type::RValueReference:
2440*0a6a1f1dSLionel Sambuc     llvm_unreachable("References shouldn't get here");
2441*0a6a1f1dSLionel Sambuc 
2442*0a6a1f1dSLionel Sambuc   case Type::Auto:
2443*0a6a1f1dSLionel Sambuc     llvm_unreachable("Undeduced auto type shouldn't get here");
2444*0a6a1f1dSLionel Sambuc 
2445*0a6a1f1dSLionel Sambuc   case Type::Builtin:
2446*0a6a1f1dSLionel Sambuc   // GCC treats vector and complex types as fundamental types.
2447*0a6a1f1dSLionel Sambuc   case Type::Vector:
2448*0a6a1f1dSLionel Sambuc   case Type::ExtVector:
2449*0a6a1f1dSLionel Sambuc   case Type::Complex:
2450*0a6a1f1dSLionel Sambuc   case Type::Atomic:
2451*0a6a1f1dSLionel Sambuc   // FIXME: GCC treats block pointers as fundamental types?!
2452*0a6a1f1dSLionel Sambuc   case Type::BlockPointer:
2453*0a6a1f1dSLionel Sambuc     // abi::__fundamental_type_info.
2454*0a6a1f1dSLionel Sambuc     VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
2455*0a6a1f1dSLionel Sambuc     break;
2456*0a6a1f1dSLionel Sambuc 
2457*0a6a1f1dSLionel Sambuc   case Type::ConstantArray:
2458*0a6a1f1dSLionel Sambuc   case Type::IncompleteArray:
2459*0a6a1f1dSLionel Sambuc   case Type::VariableArray:
2460*0a6a1f1dSLionel Sambuc     // abi::__array_type_info.
2461*0a6a1f1dSLionel Sambuc     VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
2462*0a6a1f1dSLionel Sambuc     break;
2463*0a6a1f1dSLionel Sambuc 
2464*0a6a1f1dSLionel Sambuc   case Type::FunctionNoProto:
2465*0a6a1f1dSLionel Sambuc   case Type::FunctionProto:
2466*0a6a1f1dSLionel Sambuc     // abi::__function_type_info.
2467*0a6a1f1dSLionel Sambuc     VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
2468*0a6a1f1dSLionel Sambuc     break;
2469*0a6a1f1dSLionel Sambuc 
2470*0a6a1f1dSLionel Sambuc   case Type::Enum:
2471*0a6a1f1dSLionel Sambuc     // abi::__enum_type_info.
2472*0a6a1f1dSLionel Sambuc     VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
2473*0a6a1f1dSLionel Sambuc     break;
2474*0a6a1f1dSLionel Sambuc 
2475*0a6a1f1dSLionel Sambuc   case Type::Record: {
2476*0a6a1f1dSLionel Sambuc     const CXXRecordDecl *RD =
2477*0a6a1f1dSLionel Sambuc       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
2478*0a6a1f1dSLionel Sambuc 
2479*0a6a1f1dSLionel Sambuc     if (!RD->hasDefinition() || !RD->getNumBases()) {
2480*0a6a1f1dSLionel Sambuc       VTableName = ClassTypeInfo;
2481*0a6a1f1dSLionel Sambuc     } else if (CanUseSingleInheritance(RD)) {
2482*0a6a1f1dSLionel Sambuc       VTableName = SIClassTypeInfo;
2483*0a6a1f1dSLionel Sambuc     } else {
2484*0a6a1f1dSLionel Sambuc       VTableName = VMIClassTypeInfo;
2485*0a6a1f1dSLionel Sambuc     }
2486*0a6a1f1dSLionel Sambuc 
2487*0a6a1f1dSLionel Sambuc     break;
2488*0a6a1f1dSLionel Sambuc   }
2489*0a6a1f1dSLionel Sambuc 
2490*0a6a1f1dSLionel Sambuc   case Type::ObjCObject:
2491*0a6a1f1dSLionel Sambuc     // Ignore protocol qualifiers.
2492*0a6a1f1dSLionel Sambuc     Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
2493*0a6a1f1dSLionel Sambuc 
2494*0a6a1f1dSLionel Sambuc     // Handle id and Class.
2495*0a6a1f1dSLionel Sambuc     if (isa<BuiltinType>(Ty)) {
2496*0a6a1f1dSLionel Sambuc       VTableName = ClassTypeInfo;
2497*0a6a1f1dSLionel Sambuc       break;
2498*0a6a1f1dSLionel Sambuc     }
2499*0a6a1f1dSLionel Sambuc 
2500*0a6a1f1dSLionel Sambuc     assert(isa<ObjCInterfaceType>(Ty));
2501*0a6a1f1dSLionel Sambuc     // Fall through.
2502*0a6a1f1dSLionel Sambuc 
2503*0a6a1f1dSLionel Sambuc   case Type::ObjCInterface:
2504*0a6a1f1dSLionel Sambuc     if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
2505*0a6a1f1dSLionel Sambuc       VTableName = SIClassTypeInfo;
2506*0a6a1f1dSLionel Sambuc     } else {
2507*0a6a1f1dSLionel Sambuc       VTableName = ClassTypeInfo;
2508*0a6a1f1dSLionel Sambuc     }
2509*0a6a1f1dSLionel Sambuc     break;
2510*0a6a1f1dSLionel Sambuc 
2511*0a6a1f1dSLionel Sambuc   case Type::ObjCObjectPointer:
2512*0a6a1f1dSLionel Sambuc   case Type::Pointer:
2513*0a6a1f1dSLionel Sambuc     // abi::__pointer_type_info.
2514*0a6a1f1dSLionel Sambuc     VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
2515*0a6a1f1dSLionel Sambuc     break;
2516*0a6a1f1dSLionel Sambuc 
2517*0a6a1f1dSLionel Sambuc   case Type::MemberPointer:
2518*0a6a1f1dSLionel Sambuc     // abi::__pointer_to_member_type_info.
2519*0a6a1f1dSLionel Sambuc     VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
2520*0a6a1f1dSLionel Sambuc     break;
2521*0a6a1f1dSLionel Sambuc   }
2522*0a6a1f1dSLionel Sambuc 
2523*0a6a1f1dSLionel Sambuc   llvm::Constant *VTable =
2524*0a6a1f1dSLionel Sambuc     CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
2525*0a6a1f1dSLionel Sambuc 
2526*0a6a1f1dSLionel Sambuc   llvm::Type *PtrDiffTy =
2527*0a6a1f1dSLionel Sambuc     CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
2528*0a6a1f1dSLionel Sambuc 
2529*0a6a1f1dSLionel Sambuc   // The vtable address point is 2.
2530*0a6a1f1dSLionel Sambuc   llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
2531*0a6a1f1dSLionel Sambuc   VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
2532*0a6a1f1dSLionel Sambuc   VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
2533*0a6a1f1dSLionel Sambuc 
2534*0a6a1f1dSLionel Sambuc   Fields.push_back(VTable);
2535*0a6a1f1dSLionel Sambuc }
2536*0a6a1f1dSLionel Sambuc 
2537*0a6a1f1dSLionel Sambuc /// \brief Return the linkage that the type info and type info name constants
2538*0a6a1f1dSLionel Sambuc /// should have for the given type.
getTypeInfoLinkage(CodeGenModule & CGM,QualType Ty)2539*0a6a1f1dSLionel Sambuc static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
2540*0a6a1f1dSLionel Sambuc                                                              QualType Ty) {
2541*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p7:
2542*0a6a1f1dSLionel Sambuc   //   In addition, it and all of the intermediate abi::__pointer_type_info
2543*0a6a1f1dSLionel Sambuc   //   structs in the chain down to the abi::__class_type_info for the
2544*0a6a1f1dSLionel Sambuc   //   incomplete class type must be prevented from resolving to the
2545*0a6a1f1dSLionel Sambuc   //   corresponding type_info structs for the complete class type, possibly
2546*0a6a1f1dSLionel Sambuc   //   by making them local static objects. Finally, a dummy class RTTI is
2547*0a6a1f1dSLionel Sambuc   //   generated for the incomplete type that will not resolve to the final
2548*0a6a1f1dSLionel Sambuc   //   complete class RTTI (because the latter need not exist), possibly by
2549*0a6a1f1dSLionel Sambuc   //   making it a local static object.
2550*0a6a1f1dSLionel Sambuc   if (ContainsIncompleteClassType(Ty))
2551*0a6a1f1dSLionel Sambuc     return llvm::GlobalValue::InternalLinkage;
2552*0a6a1f1dSLionel Sambuc 
2553*0a6a1f1dSLionel Sambuc   switch (Ty->getLinkage()) {
2554*0a6a1f1dSLionel Sambuc   case NoLinkage:
2555*0a6a1f1dSLionel Sambuc   case InternalLinkage:
2556*0a6a1f1dSLionel Sambuc   case UniqueExternalLinkage:
2557*0a6a1f1dSLionel Sambuc     return llvm::GlobalValue::InternalLinkage;
2558*0a6a1f1dSLionel Sambuc 
2559*0a6a1f1dSLionel Sambuc   case VisibleNoLinkage:
2560*0a6a1f1dSLionel Sambuc   case ExternalLinkage:
2561*0a6a1f1dSLionel Sambuc     if (!CGM.getLangOpts().RTTI) {
2562*0a6a1f1dSLionel Sambuc       // RTTI is not enabled, which means that this type info struct is going
2563*0a6a1f1dSLionel Sambuc       // to be used for exception handling. Give it linkonce_odr linkage.
2564*0a6a1f1dSLionel Sambuc       return llvm::GlobalValue::LinkOnceODRLinkage;
2565*0a6a1f1dSLionel Sambuc     }
2566*0a6a1f1dSLionel Sambuc 
2567*0a6a1f1dSLionel Sambuc     if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
2568*0a6a1f1dSLionel Sambuc       const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
2569*0a6a1f1dSLionel Sambuc       if (RD->hasAttr<WeakAttr>())
2570*0a6a1f1dSLionel Sambuc         return llvm::GlobalValue::WeakODRLinkage;
2571*0a6a1f1dSLionel Sambuc       if (RD->isDynamicClass())
2572*0a6a1f1dSLionel Sambuc         return CGM.getVTableLinkage(RD);
2573*0a6a1f1dSLionel Sambuc     }
2574*0a6a1f1dSLionel Sambuc 
2575*0a6a1f1dSLionel Sambuc     return llvm::GlobalValue::LinkOnceODRLinkage;
2576*0a6a1f1dSLionel Sambuc   }
2577*0a6a1f1dSLionel Sambuc 
2578*0a6a1f1dSLionel Sambuc   llvm_unreachable("Invalid linkage!");
2579*0a6a1f1dSLionel Sambuc }
2580*0a6a1f1dSLionel Sambuc 
BuildTypeInfo(QualType Ty,bool Force)2581*0a6a1f1dSLionel Sambuc llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
2582*0a6a1f1dSLionel Sambuc   // We want to operate on the canonical type.
2583*0a6a1f1dSLionel Sambuc   Ty = CGM.getContext().getCanonicalType(Ty);
2584*0a6a1f1dSLionel Sambuc 
2585*0a6a1f1dSLionel Sambuc   // Check if we've already emitted an RTTI descriptor for this type.
2586*0a6a1f1dSLionel Sambuc   SmallString<256> OutName;
2587*0a6a1f1dSLionel Sambuc   llvm::raw_svector_ostream Out(OutName);
2588*0a6a1f1dSLionel Sambuc   CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
2589*0a6a1f1dSLionel Sambuc   Out.flush();
2590*0a6a1f1dSLionel Sambuc   StringRef Name = OutName.str();
2591*0a6a1f1dSLionel Sambuc 
2592*0a6a1f1dSLionel Sambuc   llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
2593*0a6a1f1dSLionel Sambuc   if (OldGV && !OldGV->isDeclaration()) {
2594*0a6a1f1dSLionel Sambuc     assert(!OldGV->hasAvailableExternallyLinkage() &&
2595*0a6a1f1dSLionel Sambuc            "available_externally typeinfos not yet implemented");
2596*0a6a1f1dSLionel Sambuc 
2597*0a6a1f1dSLionel Sambuc     return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
2598*0a6a1f1dSLionel Sambuc   }
2599*0a6a1f1dSLionel Sambuc 
2600*0a6a1f1dSLionel Sambuc   // Check if there is already an external RTTI descriptor for this type.
2601*0a6a1f1dSLionel Sambuc   bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
2602*0a6a1f1dSLionel Sambuc   if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
2603*0a6a1f1dSLionel Sambuc     return GetAddrOfExternalRTTIDescriptor(Ty);
2604*0a6a1f1dSLionel Sambuc 
2605*0a6a1f1dSLionel Sambuc   // Emit the standard library with external linkage.
2606*0a6a1f1dSLionel Sambuc   llvm::GlobalVariable::LinkageTypes Linkage;
2607*0a6a1f1dSLionel Sambuc   if (IsStdLib)
2608*0a6a1f1dSLionel Sambuc     Linkage = llvm::GlobalValue::ExternalLinkage;
2609*0a6a1f1dSLionel Sambuc   else
2610*0a6a1f1dSLionel Sambuc     Linkage = getTypeInfoLinkage(CGM, Ty);
2611*0a6a1f1dSLionel Sambuc 
2612*0a6a1f1dSLionel Sambuc   // Add the vtable pointer.
2613*0a6a1f1dSLionel Sambuc   BuildVTablePointer(cast<Type>(Ty));
2614*0a6a1f1dSLionel Sambuc 
2615*0a6a1f1dSLionel Sambuc   // And the name.
2616*0a6a1f1dSLionel Sambuc   llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
2617*0a6a1f1dSLionel Sambuc   llvm::Constant *TypeNameField;
2618*0a6a1f1dSLionel Sambuc 
2619*0a6a1f1dSLionel Sambuc   // If we're supposed to demote the visibility, be sure to set a flag
2620*0a6a1f1dSLionel Sambuc   // to use a string comparison for type_info comparisons.
2621*0a6a1f1dSLionel Sambuc   ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
2622*0a6a1f1dSLionel Sambuc       CXXABI.classifyRTTIUniqueness(Ty, Linkage);
2623*0a6a1f1dSLionel Sambuc   if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
2624*0a6a1f1dSLionel Sambuc     // The flag is the sign bit, which on ARM64 is defined to be clear
2625*0a6a1f1dSLionel Sambuc     // for global pointers.  This is very ARM64-specific.
2626*0a6a1f1dSLionel Sambuc     TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
2627*0a6a1f1dSLionel Sambuc     llvm::Constant *flag =
2628*0a6a1f1dSLionel Sambuc         llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);
2629*0a6a1f1dSLionel Sambuc     TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
2630*0a6a1f1dSLionel Sambuc     TypeNameField =
2631*0a6a1f1dSLionel Sambuc         llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy);
2632*0a6a1f1dSLionel Sambuc   } else {
2633*0a6a1f1dSLionel Sambuc     TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
2634*0a6a1f1dSLionel Sambuc   }
2635*0a6a1f1dSLionel Sambuc   Fields.push_back(TypeNameField);
2636*0a6a1f1dSLionel Sambuc 
2637*0a6a1f1dSLionel Sambuc   switch (Ty->getTypeClass()) {
2638*0a6a1f1dSLionel Sambuc #define TYPE(Class, Base)
2639*0a6a1f1dSLionel Sambuc #define ABSTRACT_TYPE(Class, Base)
2640*0a6a1f1dSLionel Sambuc #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
2641*0a6a1f1dSLionel Sambuc #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
2642*0a6a1f1dSLionel Sambuc #define DEPENDENT_TYPE(Class, Base) case Type::Class:
2643*0a6a1f1dSLionel Sambuc #include "clang/AST/TypeNodes.def"
2644*0a6a1f1dSLionel Sambuc     llvm_unreachable("Non-canonical and dependent types shouldn't get here");
2645*0a6a1f1dSLionel Sambuc 
2646*0a6a1f1dSLionel Sambuc   // GCC treats vector types as fundamental types.
2647*0a6a1f1dSLionel Sambuc   case Type::Builtin:
2648*0a6a1f1dSLionel Sambuc   case Type::Vector:
2649*0a6a1f1dSLionel Sambuc   case Type::ExtVector:
2650*0a6a1f1dSLionel Sambuc   case Type::Complex:
2651*0a6a1f1dSLionel Sambuc   case Type::BlockPointer:
2652*0a6a1f1dSLionel Sambuc     // Itanium C++ ABI 2.9.5p4:
2653*0a6a1f1dSLionel Sambuc     // abi::__fundamental_type_info adds no data members to std::type_info.
2654*0a6a1f1dSLionel Sambuc     break;
2655*0a6a1f1dSLionel Sambuc 
2656*0a6a1f1dSLionel Sambuc   case Type::LValueReference:
2657*0a6a1f1dSLionel Sambuc   case Type::RValueReference:
2658*0a6a1f1dSLionel Sambuc     llvm_unreachable("References shouldn't get here");
2659*0a6a1f1dSLionel Sambuc 
2660*0a6a1f1dSLionel Sambuc   case Type::Auto:
2661*0a6a1f1dSLionel Sambuc     llvm_unreachable("Undeduced auto type shouldn't get here");
2662*0a6a1f1dSLionel Sambuc 
2663*0a6a1f1dSLionel Sambuc   case Type::ConstantArray:
2664*0a6a1f1dSLionel Sambuc   case Type::IncompleteArray:
2665*0a6a1f1dSLionel Sambuc   case Type::VariableArray:
2666*0a6a1f1dSLionel Sambuc     // Itanium C++ ABI 2.9.5p5:
2667*0a6a1f1dSLionel Sambuc     // abi::__array_type_info adds no data members to std::type_info.
2668*0a6a1f1dSLionel Sambuc     break;
2669*0a6a1f1dSLionel Sambuc 
2670*0a6a1f1dSLionel Sambuc   case Type::FunctionNoProto:
2671*0a6a1f1dSLionel Sambuc   case Type::FunctionProto:
2672*0a6a1f1dSLionel Sambuc     // Itanium C++ ABI 2.9.5p5:
2673*0a6a1f1dSLionel Sambuc     // abi::__function_type_info adds no data members to std::type_info.
2674*0a6a1f1dSLionel Sambuc     break;
2675*0a6a1f1dSLionel Sambuc 
2676*0a6a1f1dSLionel Sambuc   case Type::Enum:
2677*0a6a1f1dSLionel Sambuc     // Itanium C++ ABI 2.9.5p5:
2678*0a6a1f1dSLionel Sambuc     // abi::__enum_type_info adds no data members to std::type_info.
2679*0a6a1f1dSLionel Sambuc     break;
2680*0a6a1f1dSLionel Sambuc 
2681*0a6a1f1dSLionel Sambuc   case Type::Record: {
2682*0a6a1f1dSLionel Sambuc     const CXXRecordDecl *RD =
2683*0a6a1f1dSLionel Sambuc       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
2684*0a6a1f1dSLionel Sambuc     if (!RD->hasDefinition() || !RD->getNumBases()) {
2685*0a6a1f1dSLionel Sambuc       // We don't need to emit any fields.
2686*0a6a1f1dSLionel Sambuc       break;
2687*0a6a1f1dSLionel Sambuc     }
2688*0a6a1f1dSLionel Sambuc 
2689*0a6a1f1dSLionel Sambuc     if (CanUseSingleInheritance(RD))
2690*0a6a1f1dSLionel Sambuc       BuildSIClassTypeInfo(RD);
2691*0a6a1f1dSLionel Sambuc     else
2692*0a6a1f1dSLionel Sambuc       BuildVMIClassTypeInfo(RD);
2693*0a6a1f1dSLionel Sambuc 
2694*0a6a1f1dSLionel Sambuc     break;
2695*0a6a1f1dSLionel Sambuc   }
2696*0a6a1f1dSLionel Sambuc 
2697*0a6a1f1dSLionel Sambuc   case Type::ObjCObject:
2698*0a6a1f1dSLionel Sambuc   case Type::ObjCInterface:
2699*0a6a1f1dSLionel Sambuc     BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
2700*0a6a1f1dSLionel Sambuc     break;
2701*0a6a1f1dSLionel Sambuc 
2702*0a6a1f1dSLionel Sambuc   case Type::ObjCObjectPointer:
2703*0a6a1f1dSLionel Sambuc     BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
2704*0a6a1f1dSLionel Sambuc     break;
2705*0a6a1f1dSLionel Sambuc 
2706*0a6a1f1dSLionel Sambuc   case Type::Pointer:
2707*0a6a1f1dSLionel Sambuc     BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
2708*0a6a1f1dSLionel Sambuc     break;
2709*0a6a1f1dSLionel Sambuc 
2710*0a6a1f1dSLionel Sambuc   case Type::MemberPointer:
2711*0a6a1f1dSLionel Sambuc     BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
2712*0a6a1f1dSLionel Sambuc     break;
2713*0a6a1f1dSLionel Sambuc 
2714*0a6a1f1dSLionel Sambuc   case Type::Atomic:
2715*0a6a1f1dSLionel Sambuc     // No fields, at least for the moment.
2716*0a6a1f1dSLionel Sambuc     break;
2717*0a6a1f1dSLionel Sambuc   }
2718*0a6a1f1dSLionel Sambuc 
2719*0a6a1f1dSLionel Sambuc   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
2720*0a6a1f1dSLionel Sambuc 
2721*0a6a1f1dSLionel Sambuc   llvm::GlobalVariable *GV =
2722*0a6a1f1dSLionel Sambuc     new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
2723*0a6a1f1dSLionel Sambuc                              /*Constant=*/true, Linkage, Init, Name);
2724*0a6a1f1dSLionel Sambuc 
2725*0a6a1f1dSLionel Sambuc   // If there's already an old global variable, replace it with the new one.
2726*0a6a1f1dSLionel Sambuc   if (OldGV) {
2727*0a6a1f1dSLionel Sambuc     GV->takeName(OldGV);
2728*0a6a1f1dSLionel Sambuc     llvm::Constant *NewPtr =
2729*0a6a1f1dSLionel Sambuc       llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
2730*0a6a1f1dSLionel Sambuc     OldGV->replaceAllUsesWith(NewPtr);
2731*0a6a1f1dSLionel Sambuc     OldGV->eraseFromParent();
2732*0a6a1f1dSLionel Sambuc   }
2733*0a6a1f1dSLionel Sambuc 
2734*0a6a1f1dSLionel Sambuc   // The Itanium ABI specifies that type_info objects must be globally
2735*0a6a1f1dSLionel Sambuc   // unique, with one exception: if the type is an incomplete class
2736*0a6a1f1dSLionel Sambuc   // type or a (possibly indirect) pointer to one.  That exception
2737*0a6a1f1dSLionel Sambuc   // affects the general case of comparing type_info objects produced
2738*0a6a1f1dSLionel Sambuc   // by the typeid operator, which is why the comparison operators on
2739*0a6a1f1dSLionel Sambuc   // std::type_info generally use the type_info name pointers instead
2740*0a6a1f1dSLionel Sambuc   // of the object addresses.  However, the language's built-in uses
2741*0a6a1f1dSLionel Sambuc   // of RTTI generally require class types to be complete, even when
2742*0a6a1f1dSLionel Sambuc   // manipulating pointers to those class types.  This allows the
2743*0a6a1f1dSLionel Sambuc   // implementation of dynamic_cast to rely on address equality tests,
2744*0a6a1f1dSLionel Sambuc   // which is much faster.
2745*0a6a1f1dSLionel Sambuc 
2746*0a6a1f1dSLionel Sambuc   // All of this is to say that it's important that both the type_info
2747*0a6a1f1dSLionel Sambuc   // object and the type_info name be uniqued when weakly emitted.
2748*0a6a1f1dSLionel Sambuc 
2749*0a6a1f1dSLionel Sambuc   // Give the type_info object and name the formal visibility of the
2750*0a6a1f1dSLionel Sambuc   // type itself.
2751*0a6a1f1dSLionel Sambuc   llvm::GlobalValue::VisibilityTypes llvmVisibility;
2752*0a6a1f1dSLionel Sambuc   if (llvm::GlobalValue::isLocalLinkage(Linkage))
2753*0a6a1f1dSLionel Sambuc     // If the linkage is local, only default visibility makes sense.
2754*0a6a1f1dSLionel Sambuc     llvmVisibility = llvm::GlobalValue::DefaultVisibility;
2755*0a6a1f1dSLionel Sambuc   else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
2756*0a6a1f1dSLionel Sambuc     llvmVisibility = llvm::GlobalValue::HiddenVisibility;
2757*0a6a1f1dSLionel Sambuc   else
2758*0a6a1f1dSLionel Sambuc     llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
2759*0a6a1f1dSLionel Sambuc   TypeName->setVisibility(llvmVisibility);
2760*0a6a1f1dSLionel Sambuc   GV->setVisibility(llvmVisibility);
2761*0a6a1f1dSLionel Sambuc 
2762*0a6a1f1dSLionel Sambuc   return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
2763*0a6a1f1dSLionel Sambuc }
2764*0a6a1f1dSLionel Sambuc 
2765*0a6a1f1dSLionel Sambuc /// ComputeQualifierFlags - Compute the pointer type info flags from the
2766*0a6a1f1dSLionel Sambuc /// given qualifier.
ComputeQualifierFlags(Qualifiers Quals)2767*0a6a1f1dSLionel Sambuc static unsigned ComputeQualifierFlags(Qualifiers Quals) {
2768*0a6a1f1dSLionel Sambuc   unsigned Flags = 0;
2769*0a6a1f1dSLionel Sambuc 
2770*0a6a1f1dSLionel Sambuc   if (Quals.hasConst())
2771*0a6a1f1dSLionel Sambuc     Flags |= ItaniumRTTIBuilder::PTI_Const;
2772*0a6a1f1dSLionel Sambuc   if (Quals.hasVolatile())
2773*0a6a1f1dSLionel Sambuc     Flags |= ItaniumRTTIBuilder::PTI_Volatile;
2774*0a6a1f1dSLionel Sambuc   if (Quals.hasRestrict())
2775*0a6a1f1dSLionel Sambuc     Flags |= ItaniumRTTIBuilder::PTI_Restrict;
2776*0a6a1f1dSLionel Sambuc 
2777*0a6a1f1dSLionel Sambuc   return Flags;
2778*0a6a1f1dSLionel Sambuc }
2779*0a6a1f1dSLionel Sambuc 
2780*0a6a1f1dSLionel Sambuc /// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
2781*0a6a1f1dSLionel Sambuc /// for the given Objective-C object type.
BuildObjCObjectTypeInfo(const ObjCObjectType * OT)2782*0a6a1f1dSLionel Sambuc void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
2783*0a6a1f1dSLionel Sambuc   // Drop qualifiers.
2784*0a6a1f1dSLionel Sambuc   const Type *T = OT->getBaseType().getTypePtr();
2785*0a6a1f1dSLionel Sambuc   assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
2786*0a6a1f1dSLionel Sambuc 
2787*0a6a1f1dSLionel Sambuc   // The builtin types are abi::__class_type_infos and don't require
2788*0a6a1f1dSLionel Sambuc   // extra fields.
2789*0a6a1f1dSLionel Sambuc   if (isa<BuiltinType>(T)) return;
2790*0a6a1f1dSLionel Sambuc 
2791*0a6a1f1dSLionel Sambuc   ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
2792*0a6a1f1dSLionel Sambuc   ObjCInterfaceDecl *Super = Class->getSuperClass();
2793*0a6a1f1dSLionel Sambuc 
2794*0a6a1f1dSLionel Sambuc   // Root classes are also __class_type_info.
2795*0a6a1f1dSLionel Sambuc   if (!Super) return;
2796*0a6a1f1dSLionel Sambuc 
2797*0a6a1f1dSLionel Sambuc   QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
2798*0a6a1f1dSLionel Sambuc 
2799*0a6a1f1dSLionel Sambuc   // Everything else is single inheritance.
2800*0a6a1f1dSLionel Sambuc   llvm::Constant *BaseTypeInfo =
2801*0a6a1f1dSLionel Sambuc       ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(SuperTy);
2802*0a6a1f1dSLionel Sambuc   Fields.push_back(BaseTypeInfo);
2803*0a6a1f1dSLionel Sambuc }
2804*0a6a1f1dSLionel Sambuc 
2805*0a6a1f1dSLionel Sambuc /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
2806*0a6a1f1dSLionel Sambuc /// inheritance, according to the Itanium C++ ABI, 2.95p6b.
BuildSIClassTypeInfo(const CXXRecordDecl * RD)2807*0a6a1f1dSLionel Sambuc void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
2808*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p6b:
2809*0a6a1f1dSLionel Sambuc   // It adds to abi::__class_type_info a single member pointing to the
2810*0a6a1f1dSLionel Sambuc   // type_info structure for the base type,
2811*0a6a1f1dSLionel Sambuc   llvm::Constant *BaseTypeInfo =
2812*0a6a1f1dSLionel Sambuc     ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType());
2813*0a6a1f1dSLionel Sambuc   Fields.push_back(BaseTypeInfo);
2814*0a6a1f1dSLionel Sambuc }
2815*0a6a1f1dSLionel Sambuc 
2816*0a6a1f1dSLionel Sambuc namespace {
2817*0a6a1f1dSLionel Sambuc   /// SeenBases - Contains virtual and non-virtual bases seen when traversing
2818*0a6a1f1dSLionel Sambuc   /// a class hierarchy.
2819*0a6a1f1dSLionel Sambuc   struct SeenBases {
2820*0a6a1f1dSLionel Sambuc     llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
2821*0a6a1f1dSLionel Sambuc     llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
2822*0a6a1f1dSLionel Sambuc   };
2823*0a6a1f1dSLionel Sambuc }
2824*0a6a1f1dSLionel Sambuc 
2825*0a6a1f1dSLionel Sambuc /// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
2826*0a6a1f1dSLionel Sambuc /// abi::__vmi_class_type_info.
2827*0a6a1f1dSLionel Sambuc ///
ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier * Base,SeenBases & Bases)2828*0a6a1f1dSLionel Sambuc static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base,
2829*0a6a1f1dSLionel Sambuc                                              SeenBases &Bases) {
2830*0a6a1f1dSLionel Sambuc 
2831*0a6a1f1dSLionel Sambuc   unsigned Flags = 0;
2832*0a6a1f1dSLionel Sambuc 
2833*0a6a1f1dSLionel Sambuc   const CXXRecordDecl *BaseDecl =
2834*0a6a1f1dSLionel Sambuc     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
2835*0a6a1f1dSLionel Sambuc 
2836*0a6a1f1dSLionel Sambuc   if (Base->isVirtual()) {
2837*0a6a1f1dSLionel Sambuc     // Mark the virtual base as seen.
2838*0a6a1f1dSLionel Sambuc     if (!Bases.VirtualBases.insert(BaseDecl).second) {
2839*0a6a1f1dSLionel Sambuc       // If this virtual base has been seen before, then the class is diamond
2840*0a6a1f1dSLionel Sambuc       // shaped.
2841*0a6a1f1dSLionel Sambuc       Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
2842*0a6a1f1dSLionel Sambuc     } else {
2843*0a6a1f1dSLionel Sambuc       if (Bases.NonVirtualBases.count(BaseDecl))
2844*0a6a1f1dSLionel Sambuc         Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
2845*0a6a1f1dSLionel Sambuc     }
2846*0a6a1f1dSLionel Sambuc   } else {
2847*0a6a1f1dSLionel Sambuc     // Mark the non-virtual base as seen.
2848*0a6a1f1dSLionel Sambuc     if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
2849*0a6a1f1dSLionel Sambuc       // If this non-virtual base has been seen before, then the class has non-
2850*0a6a1f1dSLionel Sambuc       // diamond shaped repeated inheritance.
2851*0a6a1f1dSLionel Sambuc       Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
2852*0a6a1f1dSLionel Sambuc     } else {
2853*0a6a1f1dSLionel Sambuc       if (Bases.VirtualBases.count(BaseDecl))
2854*0a6a1f1dSLionel Sambuc         Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
2855*0a6a1f1dSLionel Sambuc     }
2856*0a6a1f1dSLionel Sambuc   }
2857*0a6a1f1dSLionel Sambuc 
2858*0a6a1f1dSLionel Sambuc   // Walk all bases.
2859*0a6a1f1dSLionel Sambuc   for (const auto &I : BaseDecl->bases())
2860*0a6a1f1dSLionel Sambuc     Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
2861*0a6a1f1dSLionel Sambuc 
2862*0a6a1f1dSLionel Sambuc   return Flags;
2863*0a6a1f1dSLionel Sambuc }
2864*0a6a1f1dSLionel Sambuc 
ComputeVMIClassTypeInfoFlags(const CXXRecordDecl * RD)2865*0a6a1f1dSLionel Sambuc static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
2866*0a6a1f1dSLionel Sambuc   unsigned Flags = 0;
2867*0a6a1f1dSLionel Sambuc   SeenBases Bases;
2868*0a6a1f1dSLionel Sambuc 
2869*0a6a1f1dSLionel Sambuc   // Walk all bases.
2870*0a6a1f1dSLionel Sambuc   for (const auto &I : RD->bases())
2871*0a6a1f1dSLionel Sambuc     Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
2872*0a6a1f1dSLionel Sambuc 
2873*0a6a1f1dSLionel Sambuc   return Flags;
2874*0a6a1f1dSLionel Sambuc }
2875*0a6a1f1dSLionel Sambuc 
2876*0a6a1f1dSLionel Sambuc /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
2877*0a6a1f1dSLionel Sambuc /// classes with bases that do not satisfy the abi::__si_class_type_info
2878*0a6a1f1dSLionel Sambuc /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
BuildVMIClassTypeInfo(const CXXRecordDecl * RD)2879*0a6a1f1dSLionel Sambuc void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
2880*0a6a1f1dSLionel Sambuc   llvm::Type *UnsignedIntLTy =
2881*0a6a1f1dSLionel Sambuc     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
2882*0a6a1f1dSLionel Sambuc 
2883*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p6c:
2884*0a6a1f1dSLionel Sambuc   //   __flags is a word with flags describing details about the class
2885*0a6a1f1dSLionel Sambuc   //   structure, which may be referenced by using the __flags_masks
2886*0a6a1f1dSLionel Sambuc   //   enumeration. These flags refer to both direct and indirect bases.
2887*0a6a1f1dSLionel Sambuc   unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
2888*0a6a1f1dSLionel Sambuc   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
2889*0a6a1f1dSLionel Sambuc 
2890*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p6c:
2891*0a6a1f1dSLionel Sambuc   //   __base_count is a word with the number of direct proper base class
2892*0a6a1f1dSLionel Sambuc   //   descriptions that follow.
2893*0a6a1f1dSLionel Sambuc   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
2894*0a6a1f1dSLionel Sambuc 
2895*0a6a1f1dSLionel Sambuc   if (!RD->getNumBases())
2896*0a6a1f1dSLionel Sambuc     return;
2897*0a6a1f1dSLionel Sambuc 
2898*0a6a1f1dSLionel Sambuc   llvm::Type *LongLTy =
2899*0a6a1f1dSLionel Sambuc     CGM.getTypes().ConvertType(CGM.getContext().LongTy);
2900*0a6a1f1dSLionel Sambuc 
2901*0a6a1f1dSLionel Sambuc   // Now add the base class descriptions.
2902*0a6a1f1dSLionel Sambuc 
2903*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p6c:
2904*0a6a1f1dSLionel Sambuc   //   __base_info[] is an array of base class descriptions -- one for every
2905*0a6a1f1dSLionel Sambuc   //   direct proper base. Each description is of the type:
2906*0a6a1f1dSLionel Sambuc   //
2907*0a6a1f1dSLionel Sambuc   //   struct abi::__base_class_type_info {
2908*0a6a1f1dSLionel Sambuc   //   public:
2909*0a6a1f1dSLionel Sambuc   //     const __class_type_info *__base_type;
2910*0a6a1f1dSLionel Sambuc   //     long __offset_flags;
2911*0a6a1f1dSLionel Sambuc   //
2912*0a6a1f1dSLionel Sambuc   //     enum __offset_flags_masks {
2913*0a6a1f1dSLionel Sambuc   //       __virtual_mask = 0x1,
2914*0a6a1f1dSLionel Sambuc   //       __public_mask = 0x2,
2915*0a6a1f1dSLionel Sambuc   //       __offset_shift = 8
2916*0a6a1f1dSLionel Sambuc   //     };
2917*0a6a1f1dSLionel Sambuc   //   };
2918*0a6a1f1dSLionel Sambuc   for (const auto &Base : RD->bases()) {
2919*0a6a1f1dSLionel Sambuc     // The __base_type member points to the RTTI for the base type.
2920*0a6a1f1dSLionel Sambuc     Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()));
2921*0a6a1f1dSLionel Sambuc 
2922*0a6a1f1dSLionel Sambuc     const CXXRecordDecl *BaseDecl =
2923*0a6a1f1dSLionel Sambuc       cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
2924*0a6a1f1dSLionel Sambuc 
2925*0a6a1f1dSLionel Sambuc     int64_t OffsetFlags = 0;
2926*0a6a1f1dSLionel Sambuc 
2927*0a6a1f1dSLionel Sambuc     // All but the lower 8 bits of __offset_flags are a signed offset.
2928*0a6a1f1dSLionel Sambuc     // For a non-virtual base, this is the offset in the object of the base
2929*0a6a1f1dSLionel Sambuc     // subobject. For a virtual base, this is the offset in the virtual table of
2930*0a6a1f1dSLionel Sambuc     // the virtual base offset for the virtual base referenced (negative).
2931*0a6a1f1dSLionel Sambuc     CharUnits Offset;
2932*0a6a1f1dSLionel Sambuc     if (Base.isVirtual())
2933*0a6a1f1dSLionel Sambuc       Offset =
2934*0a6a1f1dSLionel Sambuc         CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
2935*0a6a1f1dSLionel Sambuc     else {
2936*0a6a1f1dSLionel Sambuc       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
2937*0a6a1f1dSLionel Sambuc       Offset = Layout.getBaseClassOffset(BaseDecl);
2938*0a6a1f1dSLionel Sambuc     };
2939*0a6a1f1dSLionel Sambuc 
2940*0a6a1f1dSLionel Sambuc     OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
2941*0a6a1f1dSLionel Sambuc 
2942*0a6a1f1dSLionel Sambuc     // The low-order byte of __offset_flags contains flags, as given by the
2943*0a6a1f1dSLionel Sambuc     // masks from the enumeration __offset_flags_masks.
2944*0a6a1f1dSLionel Sambuc     if (Base.isVirtual())
2945*0a6a1f1dSLionel Sambuc       OffsetFlags |= BCTI_Virtual;
2946*0a6a1f1dSLionel Sambuc     if (Base.getAccessSpecifier() == AS_public)
2947*0a6a1f1dSLionel Sambuc       OffsetFlags |= BCTI_Public;
2948*0a6a1f1dSLionel Sambuc 
2949*0a6a1f1dSLionel Sambuc     Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
2950*0a6a1f1dSLionel Sambuc   }
2951*0a6a1f1dSLionel Sambuc }
2952*0a6a1f1dSLionel Sambuc 
2953*0a6a1f1dSLionel Sambuc /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
2954*0a6a1f1dSLionel Sambuc /// used for pointer types.
BuildPointerTypeInfo(QualType PointeeTy)2955*0a6a1f1dSLionel Sambuc void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
2956*0a6a1f1dSLionel Sambuc   Qualifiers Quals;
2957*0a6a1f1dSLionel Sambuc   QualType UnqualifiedPointeeTy =
2958*0a6a1f1dSLionel Sambuc     CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
2959*0a6a1f1dSLionel Sambuc 
2960*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p7:
2961*0a6a1f1dSLionel Sambuc   //   __flags is a flag word describing the cv-qualification and other
2962*0a6a1f1dSLionel Sambuc   //   attributes of the type pointed to
2963*0a6a1f1dSLionel Sambuc   unsigned Flags = ComputeQualifierFlags(Quals);
2964*0a6a1f1dSLionel Sambuc 
2965*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p7:
2966*0a6a1f1dSLionel Sambuc   //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
2967*0a6a1f1dSLionel Sambuc   //   incomplete class type, the incomplete target type flag is set.
2968*0a6a1f1dSLionel Sambuc   if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
2969*0a6a1f1dSLionel Sambuc     Flags |= PTI_Incomplete;
2970*0a6a1f1dSLionel Sambuc 
2971*0a6a1f1dSLionel Sambuc   llvm::Type *UnsignedIntLTy =
2972*0a6a1f1dSLionel Sambuc     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
2973*0a6a1f1dSLionel Sambuc   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
2974*0a6a1f1dSLionel Sambuc 
2975*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p7:
2976*0a6a1f1dSLionel Sambuc   //  __pointee is a pointer to the std::type_info derivation for the
2977*0a6a1f1dSLionel Sambuc   //  unqualified type being pointed to.
2978*0a6a1f1dSLionel Sambuc   llvm::Constant *PointeeTypeInfo =
2979*0a6a1f1dSLionel Sambuc     ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
2980*0a6a1f1dSLionel Sambuc   Fields.push_back(PointeeTypeInfo);
2981*0a6a1f1dSLionel Sambuc }
2982*0a6a1f1dSLionel Sambuc 
2983*0a6a1f1dSLionel Sambuc /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
2984*0a6a1f1dSLionel Sambuc /// struct, used for member pointer types.
2985*0a6a1f1dSLionel Sambuc void
BuildPointerToMemberTypeInfo(const MemberPointerType * Ty)2986*0a6a1f1dSLionel Sambuc ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
2987*0a6a1f1dSLionel Sambuc   QualType PointeeTy = Ty->getPointeeType();
2988*0a6a1f1dSLionel Sambuc 
2989*0a6a1f1dSLionel Sambuc   Qualifiers Quals;
2990*0a6a1f1dSLionel Sambuc   QualType UnqualifiedPointeeTy =
2991*0a6a1f1dSLionel Sambuc     CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
2992*0a6a1f1dSLionel Sambuc 
2993*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p7:
2994*0a6a1f1dSLionel Sambuc   //   __flags is a flag word describing the cv-qualification and other
2995*0a6a1f1dSLionel Sambuc   //   attributes of the type pointed to.
2996*0a6a1f1dSLionel Sambuc   unsigned Flags = ComputeQualifierFlags(Quals);
2997*0a6a1f1dSLionel Sambuc 
2998*0a6a1f1dSLionel Sambuc   const RecordType *ClassType = cast<RecordType>(Ty->getClass());
2999*0a6a1f1dSLionel Sambuc 
3000*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p7:
3001*0a6a1f1dSLionel Sambuc   //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
3002*0a6a1f1dSLionel Sambuc   //   incomplete class type, the incomplete target type flag is set.
3003*0a6a1f1dSLionel Sambuc   if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
3004*0a6a1f1dSLionel Sambuc     Flags |= PTI_Incomplete;
3005*0a6a1f1dSLionel Sambuc 
3006*0a6a1f1dSLionel Sambuc   if (IsIncompleteClassType(ClassType))
3007*0a6a1f1dSLionel Sambuc     Flags |= PTI_ContainingClassIncomplete;
3008*0a6a1f1dSLionel Sambuc 
3009*0a6a1f1dSLionel Sambuc   llvm::Type *UnsignedIntLTy =
3010*0a6a1f1dSLionel Sambuc     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
3011*0a6a1f1dSLionel Sambuc   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3012*0a6a1f1dSLionel Sambuc 
3013*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p7:
3014*0a6a1f1dSLionel Sambuc   //   __pointee is a pointer to the std::type_info derivation for the
3015*0a6a1f1dSLionel Sambuc   //   unqualified type being pointed to.
3016*0a6a1f1dSLionel Sambuc   llvm::Constant *PointeeTypeInfo =
3017*0a6a1f1dSLionel Sambuc     ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
3018*0a6a1f1dSLionel Sambuc   Fields.push_back(PointeeTypeInfo);
3019*0a6a1f1dSLionel Sambuc 
3020*0a6a1f1dSLionel Sambuc   // Itanium C++ ABI 2.9.5p9:
3021*0a6a1f1dSLionel Sambuc   //   __context is a pointer to an abi::__class_type_info corresponding to the
3022*0a6a1f1dSLionel Sambuc   //   class type containing the member pointed to
3023*0a6a1f1dSLionel Sambuc   //   (e.g., the "A" in "int A::*").
3024*0a6a1f1dSLionel Sambuc   Fields.push_back(
3025*0a6a1f1dSLionel Sambuc       ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(QualType(ClassType, 0)));
3026*0a6a1f1dSLionel Sambuc }
3027*0a6a1f1dSLionel Sambuc 
getAddrOfRTTIDescriptor(QualType Ty)3028*0a6a1f1dSLionel Sambuc llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
3029*0a6a1f1dSLionel Sambuc   return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
3030*0a6a1f1dSLionel Sambuc }
3031*0a6a1f1dSLionel Sambuc 
EmitFundamentalRTTIDescriptor(QualType Type)3032*0a6a1f1dSLionel Sambuc void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(QualType Type) {
3033*0a6a1f1dSLionel Sambuc   QualType PointerType = getContext().getPointerType(Type);
3034*0a6a1f1dSLionel Sambuc   QualType PointerTypeConst = getContext().getPointerType(Type.withConst());
3035*0a6a1f1dSLionel Sambuc   ItaniumRTTIBuilder(*this).BuildTypeInfo(Type, true);
3036*0a6a1f1dSLionel Sambuc   ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, true);
3037*0a6a1f1dSLionel Sambuc   ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
3038*0a6a1f1dSLionel Sambuc }
3039*0a6a1f1dSLionel Sambuc 
EmitFundamentalRTTIDescriptors()3040*0a6a1f1dSLionel Sambuc void ItaniumCXXABI::EmitFundamentalRTTIDescriptors() {
3041*0a6a1f1dSLionel Sambuc   QualType FundamentalTypes[] = {
3042*0a6a1f1dSLionel Sambuc       getContext().VoidTy,             getContext().NullPtrTy,
3043*0a6a1f1dSLionel Sambuc       getContext().BoolTy,             getContext().WCharTy,
3044*0a6a1f1dSLionel Sambuc       getContext().CharTy,             getContext().UnsignedCharTy,
3045*0a6a1f1dSLionel Sambuc       getContext().SignedCharTy,       getContext().ShortTy,
3046*0a6a1f1dSLionel Sambuc       getContext().UnsignedShortTy,    getContext().IntTy,
3047*0a6a1f1dSLionel Sambuc       getContext().UnsignedIntTy,      getContext().LongTy,
3048*0a6a1f1dSLionel Sambuc       getContext().UnsignedLongTy,     getContext().LongLongTy,
3049*0a6a1f1dSLionel Sambuc       getContext().UnsignedLongLongTy, getContext().HalfTy,
3050*0a6a1f1dSLionel Sambuc       getContext().FloatTy,            getContext().DoubleTy,
3051*0a6a1f1dSLionel Sambuc       getContext().LongDoubleTy,       getContext().Char16Ty,
3052*0a6a1f1dSLionel Sambuc       getContext().Char32Ty,
3053*0a6a1f1dSLionel Sambuc   };
3054*0a6a1f1dSLionel Sambuc   for (const QualType &FundamentalType : FundamentalTypes)
3055*0a6a1f1dSLionel Sambuc     EmitFundamentalRTTIDescriptor(FundamentalType);
3056*0a6a1f1dSLionel Sambuc }
3057*0a6a1f1dSLionel Sambuc 
3058*0a6a1f1dSLionel Sambuc /// What sort of uniqueness rules should we use for the RTTI for the
3059*0a6a1f1dSLionel Sambuc /// given type?
classifyRTTIUniqueness(QualType CanTy,llvm::GlobalValue::LinkageTypes Linkage) const3060*0a6a1f1dSLionel Sambuc ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
3061*0a6a1f1dSLionel Sambuc     QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const {
3062*0a6a1f1dSLionel Sambuc   if (shouldRTTIBeUnique())
3063*0a6a1f1dSLionel Sambuc     return RUK_Unique;
3064*0a6a1f1dSLionel Sambuc 
3065*0a6a1f1dSLionel Sambuc   // It's only necessary for linkonce_odr or weak_odr linkage.
3066*0a6a1f1dSLionel Sambuc   if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
3067*0a6a1f1dSLionel Sambuc       Linkage != llvm::GlobalValue::WeakODRLinkage)
3068*0a6a1f1dSLionel Sambuc     return RUK_Unique;
3069*0a6a1f1dSLionel Sambuc 
3070*0a6a1f1dSLionel Sambuc   // It's only necessary with default visibility.
3071*0a6a1f1dSLionel Sambuc   if (CanTy->getVisibility() != DefaultVisibility)
3072*0a6a1f1dSLionel Sambuc     return RUK_Unique;
3073*0a6a1f1dSLionel Sambuc 
3074*0a6a1f1dSLionel Sambuc   // If we're not required to publish this symbol, hide it.
3075*0a6a1f1dSLionel Sambuc   if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3076*0a6a1f1dSLionel Sambuc     return RUK_NonUniqueHidden;
3077*0a6a1f1dSLionel Sambuc 
3078*0a6a1f1dSLionel Sambuc   // If we're required to publish this symbol, as we might be under an
3079*0a6a1f1dSLionel Sambuc   // explicit instantiation, leave it with default visibility but
3080*0a6a1f1dSLionel Sambuc   // enable string-comparisons.
3081*0a6a1f1dSLionel Sambuc   assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
3082*0a6a1f1dSLionel Sambuc   return RUK_NonUniqueVisible;
3083*0a6a1f1dSLionel Sambuc }
3084*0a6a1f1dSLionel Sambuc 
3085*0a6a1f1dSLionel Sambuc // Find out how to codegen the complete destructor and constructor
3086*0a6a1f1dSLionel Sambuc namespace {
3087*0a6a1f1dSLionel Sambuc enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
3088*0a6a1f1dSLionel Sambuc }
getCodegenToUse(CodeGenModule & CGM,const CXXMethodDecl * MD)3089*0a6a1f1dSLionel Sambuc static StructorCodegen getCodegenToUse(CodeGenModule &CGM,
3090*0a6a1f1dSLionel Sambuc                                        const CXXMethodDecl *MD) {
3091*0a6a1f1dSLionel Sambuc   if (!CGM.getCodeGenOpts().CXXCtorDtorAliases)
3092*0a6a1f1dSLionel Sambuc     return StructorCodegen::Emit;
3093*0a6a1f1dSLionel Sambuc 
3094*0a6a1f1dSLionel Sambuc   // The complete and base structors are not equivalent if there are any virtual
3095*0a6a1f1dSLionel Sambuc   // bases, so emit separate functions.
3096*0a6a1f1dSLionel Sambuc   if (MD->getParent()->getNumVBases())
3097*0a6a1f1dSLionel Sambuc     return StructorCodegen::Emit;
3098*0a6a1f1dSLionel Sambuc 
3099*0a6a1f1dSLionel Sambuc   GlobalDecl AliasDecl;
3100*0a6a1f1dSLionel Sambuc   if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
3101*0a6a1f1dSLionel Sambuc     AliasDecl = GlobalDecl(DD, Dtor_Complete);
3102*0a6a1f1dSLionel Sambuc   } else {
3103*0a6a1f1dSLionel Sambuc     const auto *CD = cast<CXXConstructorDecl>(MD);
3104*0a6a1f1dSLionel Sambuc     AliasDecl = GlobalDecl(CD, Ctor_Complete);
3105*0a6a1f1dSLionel Sambuc   }
3106*0a6a1f1dSLionel Sambuc   llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl);
3107*0a6a1f1dSLionel Sambuc 
3108*0a6a1f1dSLionel Sambuc   if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
3109*0a6a1f1dSLionel Sambuc     return StructorCodegen::RAUW;
3110*0a6a1f1dSLionel Sambuc 
3111*0a6a1f1dSLionel Sambuc   // FIXME: Should we allow available_externally aliases?
3112*0a6a1f1dSLionel Sambuc   if (!llvm::GlobalAlias::isValidLinkage(Linkage))
3113*0a6a1f1dSLionel Sambuc     return StructorCodegen::RAUW;
3114*0a6a1f1dSLionel Sambuc 
3115*0a6a1f1dSLionel Sambuc   if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
3116*0a6a1f1dSLionel Sambuc     // Only ELF supports COMDATs with arbitrary names (C5/D5).
3117*0a6a1f1dSLionel Sambuc     if (CGM.getTarget().getTriple().isOSBinFormatELF())
3118*0a6a1f1dSLionel Sambuc       return StructorCodegen::COMDAT;
3119*0a6a1f1dSLionel Sambuc     return StructorCodegen::Emit;
3120*0a6a1f1dSLionel Sambuc   }
3121*0a6a1f1dSLionel Sambuc 
3122*0a6a1f1dSLionel Sambuc   return StructorCodegen::Alias;
3123*0a6a1f1dSLionel Sambuc }
3124*0a6a1f1dSLionel Sambuc 
emitConstructorDestructorAlias(CodeGenModule & CGM,GlobalDecl AliasDecl,GlobalDecl TargetDecl)3125*0a6a1f1dSLionel Sambuc static void emitConstructorDestructorAlias(CodeGenModule &CGM,
3126*0a6a1f1dSLionel Sambuc                                            GlobalDecl AliasDecl,
3127*0a6a1f1dSLionel Sambuc                                            GlobalDecl TargetDecl) {
3128*0a6a1f1dSLionel Sambuc   llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl);
3129*0a6a1f1dSLionel Sambuc 
3130*0a6a1f1dSLionel Sambuc   StringRef MangledName = CGM.getMangledName(AliasDecl);
3131*0a6a1f1dSLionel Sambuc   llvm::GlobalValue *Entry = CGM.GetGlobalValue(MangledName);
3132*0a6a1f1dSLionel Sambuc   if (Entry && !Entry->isDeclaration())
3133*0a6a1f1dSLionel Sambuc     return;
3134*0a6a1f1dSLionel Sambuc 
3135*0a6a1f1dSLionel Sambuc   auto *Aliasee = cast<llvm::GlobalValue>(CGM.GetAddrOfGlobal(TargetDecl));
3136*0a6a1f1dSLionel Sambuc   llvm::PointerType *AliasType = Aliasee->getType();
3137*0a6a1f1dSLionel Sambuc 
3138*0a6a1f1dSLionel Sambuc   // Create the alias with no name.
3139*0a6a1f1dSLionel Sambuc   auto *Alias = llvm::GlobalAlias::create(
3140*0a6a1f1dSLionel Sambuc       AliasType->getElementType(), 0, Linkage, "", Aliasee, &CGM.getModule());
3141*0a6a1f1dSLionel Sambuc 
3142*0a6a1f1dSLionel Sambuc   // Switch any previous uses to the alias.
3143*0a6a1f1dSLionel Sambuc   if (Entry) {
3144*0a6a1f1dSLionel Sambuc     assert(Entry->getType() == AliasType &&
3145*0a6a1f1dSLionel Sambuc            "declaration exists with different type");
3146*0a6a1f1dSLionel Sambuc     Alias->takeName(Entry);
3147*0a6a1f1dSLionel Sambuc     Entry->replaceAllUsesWith(Alias);
3148*0a6a1f1dSLionel Sambuc     Entry->eraseFromParent();
3149*0a6a1f1dSLionel Sambuc   } else {
3150*0a6a1f1dSLionel Sambuc     Alias->setName(MangledName);
3151*0a6a1f1dSLionel Sambuc   }
3152*0a6a1f1dSLionel Sambuc 
3153*0a6a1f1dSLionel Sambuc   // Finally, set up the alias with its proper name and attributes.
3154*0a6a1f1dSLionel Sambuc   CGM.setAliasAttributes(cast<NamedDecl>(AliasDecl.getDecl()), Alias);
3155*0a6a1f1dSLionel Sambuc }
3156*0a6a1f1dSLionel Sambuc 
emitCXXStructor(const CXXMethodDecl * MD,StructorType Type)3157*0a6a1f1dSLionel Sambuc void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
3158*0a6a1f1dSLionel Sambuc                                     StructorType Type) {
3159*0a6a1f1dSLionel Sambuc   auto *CD = dyn_cast<CXXConstructorDecl>(MD);
3160*0a6a1f1dSLionel Sambuc   const CXXDestructorDecl *DD = CD ? nullptr : cast<CXXDestructorDecl>(MD);
3161*0a6a1f1dSLionel Sambuc 
3162*0a6a1f1dSLionel Sambuc   StructorCodegen CGType = getCodegenToUse(CGM, MD);
3163*0a6a1f1dSLionel Sambuc 
3164*0a6a1f1dSLionel Sambuc   if (Type == StructorType::Complete) {
3165*0a6a1f1dSLionel Sambuc     GlobalDecl CompleteDecl;
3166*0a6a1f1dSLionel Sambuc     GlobalDecl BaseDecl;
3167*0a6a1f1dSLionel Sambuc     if (CD) {
3168*0a6a1f1dSLionel Sambuc       CompleteDecl = GlobalDecl(CD, Ctor_Complete);
3169*0a6a1f1dSLionel Sambuc       BaseDecl = GlobalDecl(CD, Ctor_Base);
3170*0a6a1f1dSLionel Sambuc     } else {
3171*0a6a1f1dSLionel Sambuc       CompleteDecl = GlobalDecl(DD, Dtor_Complete);
3172*0a6a1f1dSLionel Sambuc       BaseDecl = GlobalDecl(DD, Dtor_Base);
3173*0a6a1f1dSLionel Sambuc     }
3174*0a6a1f1dSLionel Sambuc 
3175*0a6a1f1dSLionel Sambuc     if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
3176*0a6a1f1dSLionel Sambuc       emitConstructorDestructorAlias(CGM, CompleteDecl, BaseDecl);
3177*0a6a1f1dSLionel Sambuc       return;
3178*0a6a1f1dSLionel Sambuc     }
3179*0a6a1f1dSLionel Sambuc 
3180*0a6a1f1dSLionel Sambuc     if (CGType == StructorCodegen::RAUW) {
3181*0a6a1f1dSLionel Sambuc       StringRef MangledName = CGM.getMangledName(CompleteDecl);
3182*0a6a1f1dSLionel Sambuc       auto *Aliasee = cast<llvm::GlobalValue>(CGM.GetAddrOfGlobal(BaseDecl));
3183*0a6a1f1dSLionel Sambuc       CGM.addReplacement(MangledName, Aliasee);
3184*0a6a1f1dSLionel Sambuc       return;
3185*0a6a1f1dSLionel Sambuc     }
3186*0a6a1f1dSLionel Sambuc   }
3187*0a6a1f1dSLionel Sambuc 
3188*0a6a1f1dSLionel Sambuc   // The base destructor is equivalent to the base destructor of its
3189*0a6a1f1dSLionel Sambuc   // base class if there is exactly one non-virtual base class with a
3190*0a6a1f1dSLionel Sambuc   // non-trivial destructor, there are no fields with a non-trivial
3191*0a6a1f1dSLionel Sambuc   // destructor, and the body of the destructor is trivial.
3192*0a6a1f1dSLionel Sambuc   if (DD && Type == StructorType::Base && CGType != StructorCodegen::COMDAT &&
3193*0a6a1f1dSLionel Sambuc       !CGM.TryEmitBaseDestructorAsAlias(DD))
3194*0a6a1f1dSLionel Sambuc     return;
3195*0a6a1f1dSLionel Sambuc 
3196*0a6a1f1dSLionel Sambuc   llvm::Function *Fn = CGM.codegenCXXStructor(MD, Type);
3197*0a6a1f1dSLionel Sambuc 
3198*0a6a1f1dSLionel Sambuc   if (CGType == StructorCodegen::COMDAT) {
3199*0a6a1f1dSLionel Sambuc     SmallString<256> Buffer;
3200*0a6a1f1dSLionel Sambuc     llvm::raw_svector_ostream Out(Buffer);
3201*0a6a1f1dSLionel Sambuc     if (DD)
3202*0a6a1f1dSLionel Sambuc       getMangleContext().mangleCXXDtorComdat(DD, Out);
3203*0a6a1f1dSLionel Sambuc     else
3204*0a6a1f1dSLionel Sambuc       getMangleContext().mangleCXXCtorComdat(CD, Out);
3205*0a6a1f1dSLionel Sambuc     llvm::Comdat *C = CGM.getModule().getOrInsertComdat(Out.str());
3206*0a6a1f1dSLionel Sambuc     Fn->setComdat(C);
3207*0a6a1f1dSLionel Sambuc   }
3208*0a6a1f1dSLionel Sambuc }
3209