1210008Srdivacky//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===// 2210008Srdivacky// 3210008Srdivacky// The LLVM Compiler Infrastructure 4210008Srdivacky// 5210008Srdivacky// This file is distributed under the University of Illinois Open Source 6210008Srdivacky// License. See LICENSE.TXT for details. 7210008Srdivacky// 8210008Srdivacky//===----------------------------------------------------------------------===// 9210008Srdivacky// 10221345Sdim// This provides C++ code generation targeting the Microsoft Visual C++ ABI. 11210008Srdivacky// The class in this file generates structures that follow the Microsoft 12210008Srdivacky// Visual C++ ABI, which is actually not very well documented at all outside 13210008Srdivacky// of Microsoft. 14210008Srdivacky// 15210008Srdivacky//===----------------------------------------------------------------------===// 16210008Srdivacky 17210008Srdivacky#include "CGCXXABI.h" 18210008Srdivacky#include "CodeGenModule.h" 19263508Sdim#include "CGVTables.h" 20263508Sdim#include "MicrosoftVBTables.h" 21210008Srdivacky#include "clang/AST/Decl.h" 22210008Srdivacky#include "clang/AST/DeclCXX.h" 23263508Sdim#include "clang/AST/VTableBuilder.h" 24263508Sdim#include "llvm/ADT/StringSet.h" 25210008Srdivacky 26210008Srdivackyusing namespace clang; 27210008Srdivackyusing namespace CodeGen; 28210008Srdivacky 29210008Srdivackynamespace { 30210008Srdivacky 31212904Sdimclass MicrosoftCXXABI : public CGCXXABI { 32210008Srdivackypublic: 33218893Sdim MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {} 34210008Srdivacky 35263508Sdim bool HasThisReturn(GlobalDecl GD) const; 36263508Sdim 37251662Sdim bool isReturnTypeIndirect(const CXXRecordDecl *RD) const { 38251662Sdim // Structures that are not C++03 PODs are always indirect. 39251662Sdim return !RD->isPOD(); 40251662Sdim } 41251662Sdim 42251662Sdim RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const { 43263508Sdim if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialDestructor()) 44251662Sdim return RAA_DirectInMemory; 45251662Sdim return RAA_Default; 46251662Sdim } 47251662Sdim 48239462Sdim StringRef GetPureVirtualCallName() { return "_purecall"; } 49243830Sdim // No known support for deleted functions in MSVC yet, so this choice is 50243830Sdim // arbitrary. 51243830Sdim StringRef GetDeletedVirtualCallName() { return "_purecall"; } 52239462Sdim 53263508Sdim bool isInlineInitializedStaticDataMemberLinkOnce() { return true; } 54263508Sdim 55243830Sdim llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, 56243830Sdim llvm::Value *ptr, 57243830Sdim QualType type); 58243830Sdim 59263508Sdim llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, 60263508Sdim llvm::Value *This, 61263508Sdim const CXXRecordDecl *ClassDecl, 62263508Sdim const CXXRecordDecl *BaseClassDecl); 63263508Sdim 64212904Sdim void BuildConstructorSignature(const CXXConstructorDecl *Ctor, 65212904Sdim CXXCtorType Type, 66212904Sdim CanQualType &ResTy, 67243830Sdim SmallVectorImpl<CanQualType> &ArgTys); 68212904Sdim 69263508Sdim llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, 70263508Sdim const CXXRecordDecl *RD); 71249423Sdim 72263508Sdim void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, 73263508Sdim const CXXRecordDecl *RD); 74263508Sdim 75263508Sdim void EmitCXXConstructors(const CXXConstructorDecl *D); 76263508Sdim 77263508Sdim // Background on MSVC destructors 78263508Sdim // ============================== 79263508Sdim // 80263508Sdim // Both Itanium and MSVC ABIs have destructor variants. The variant names 81263508Sdim // roughly correspond in the following way: 82263508Sdim // Itanium Microsoft 83263508Sdim // Base -> no name, just ~Class 84263508Sdim // Complete -> vbase destructor 85263508Sdim // Deleting -> scalar deleting destructor 86263508Sdim // vector deleting destructor 87263508Sdim // 88263508Sdim // The base and complete destructors are the same as in Itanium, although the 89263508Sdim // complete destructor does not accept a VTT parameter when there are virtual 90263508Sdim // bases. A separate mechanism involving vtordisps is used to ensure that 91263508Sdim // virtual methods of destroyed subobjects are not called. 92263508Sdim // 93263508Sdim // The deleting destructors accept an i32 bitfield as a second parameter. Bit 94263508Sdim // 1 indicates if the memory should be deleted. Bit 2 indicates if the this 95263508Sdim // pointer points to an array. The scalar deleting destructor assumes that 96263508Sdim // bit 2 is zero, and therefore does not contain a loop. 97263508Sdim // 98263508Sdim // For virtual destructors, only one entry is reserved in the vftable, and it 99263508Sdim // always points to the vector deleting destructor. The vector deleting 100263508Sdim // destructor is the most general, so it can be used to destroy objects in 101263508Sdim // place, delete single heap objects, or delete arrays. 102263508Sdim // 103263508Sdim // A TU defining a non-inline destructor is only guaranteed to emit a base 104263508Sdim // destructor, and all of the other variants are emitted on an as-needed basis 105263508Sdim // in COMDATs. Because a non-base destructor can be emitted in a TU that 106263508Sdim // lacks a definition for the destructor, non-base destructors must always 107263508Sdim // delegate to or alias the base destructor. 108263508Sdim 109263508Sdim void BuildDestructorSignature(const CXXDestructorDecl *Dtor, 110212904Sdim CXXDtorType Type, 111212904Sdim CanQualType &ResTy, 112249423Sdim SmallVectorImpl<CanQualType> &ArgTys); 113212904Sdim 114263508Sdim /// Non-base dtors should be emitted as delegating thunks in this ABI. 115263508Sdim bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, 116263508Sdim CXXDtorType DT) const { 117263508Sdim return DT != Dtor_Base; 118263508Sdim } 119263508Sdim 120263508Sdim void EmitCXXDestructors(const CXXDestructorDecl *D); 121263508Sdim 122263508Sdim const CXXRecordDecl *getThisArgumentTypeForMethod(const CXXMethodDecl *MD) { 123263508Sdim MD = MD->getCanonicalDecl(); 124263508Sdim if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD)) { 125263508Sdim MicrosoftVTableContext::MethodVFTableLocation ML = 126263508Sdim CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD); 127263508Sdim // The vbases might be ordered differently in the final overrider object 128263508Sdim // and the complete object, so the "this" argument may sometimes point to 129263508Sdim // memory that has no particular type (e.g. past the complete object). 130263508Sdim // In this case, we just use a generic pointer type. 131263508Sdim // FIXME: might want to have a more precise type in the non-virtual 132263508Sdim // multiple inheritance case. 133263508Sdim if (ML.VBase || !ML.VFPtrOffset.isZero()) 134263508Sdim return 0; 135263508Sdim } 136263508Sdim return MD->getParent(); 137263508Sdim } 138263508Sdim 139263508Sdim llvm::Value *adjustThisArgumentForVirtualCall(CodeGenFunction &CGF, 140263508Sdim GlobalDecl GD, 141263508Sdim llvm::Value *This); 142263508Sdim 143212904Sdim void BuildInstanceFunctionParams(CodeGenFunction &CGF, 144212904Sdim QualType &ResTy, 145243830Sdim FunctionArgList &Params); 146212904Sdim 147263508Sdim llvm::Value *adjustThisParameterInVirtualFunctionPrologue( 148263508Sdim CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This); 149263508Sdim 150243830Sdim void EmitInstanceFunctionProlog(CodeGenFunction &CGF); 151218893Sdim 152263508Sdim void EmitConstructorCall(CodeGenFunction &CGF, 153263508Sdim const CXXConstructorDecl *D, CXXCtorType Type, 154263508Sdim bool ForVirtualBase, bool Delegating, 155249423Sdim llvm::Value *This, 156249423Sdim CallExpr::const_arg_iterator ArgBeg, 157249423Sdim CallExpr::const_arg_iterator ArgEnd); 158249423Sdim 159263508Sdim void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD); 160249423Sdim 161263508Sdim llvm::Value *getVTableAddressPointInStructor( 162263508Sdim CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, 163263508Sdim BaseSubobject Base, const CXXRecordDecl *NearestVBase, 164263508Sdim bool &NeedsVirtualOffset); 165263508Sdim 166263508Sdim llvm::Constant * 167263508Sdim getVTableAddressPointForConstExpr(BaseSubobject Base, 168263508Sdim const CXXRecordDecl *VTableClass); 169263508Sdim 170263508Sdim llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, 171263508Sdim CharUnits VPtrOffset); 172263508Sdim 173263508Sdim llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, 174263508Sdim llvm::Value *This, llvm::Type *Ty); 175263508Sdim 176263508Sdim void EmitVirtualDestructorCall(CodeGenFunction &CGF, 177263508Sdim const CXXDestructorDecl *Dtor, 178263508Sdim CXXDtorType DtorType, SourceLocation CallLoc, 179263508Sdim llvm::Value *This); 180263508Sdim 181263508Sdim void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, 182263508Sdim CallArgList &CallArgs) { 183263508Sdim assert(GD.getDtorType() == Dtor_Deleting && 184263508Sdim "Only deleting destructor thunks are available in this ABI"); 185263508Sdim CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)), 186263508Sdim CGM.getContext().IntTy); 187263508Sdim } 188263508Sdim 189263508Sdim void emitVirtualInheritanceTables(const CXXRecordDecl *RD); 190263508Sdim 191263508Sdim void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) { 192263508Sdim Thunk->setLinkage(llvm::GlobalValue::WeakAnyLinkage); 193263508Sdim } 194263508Sdim 195263508Sdim llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This, 196263508Sdim const ThisAdjustment &TA); 197263508Sdim 198263508Sdim llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret, 199263508Sdim const ReturnAdjustment &RA); 200263508Sdim 201239462Sdim void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 202239462Sdim llvm::GlobalVariable *DeclPtr, 203239462Sdim bool PerformInit); 204239462Sdim 205218893Sdim // ==== Notes on array cookies ========= 206218893Sdim // 207218893Sdim // MSVC seems to only use cookies when the class has a destructor; a 208218893Sdim // two-argument usual array deallocation function isn't sufficient. 209218893Sdim // 210218893Sdim // For example, this code prints "100" and "1": 211218893Sdim // struct A { 212218893Sdim // char x; 213218893Sdim // void *operator new[](size_t sz) { 214218893Sdim // printf("%u\n", sz); 215218893Sdim // return malloc(sz); 216218893Sdim // } 217218893Sdim // void operator delete[](void *p, size_t sz) { 218218893Sdim // printf("%u\n", sz); 219218893Sdim // free(p); 220218893Sdim // } 221218893Sdim // }; 222218893Sdim // int main() { 223218893Sdim // A *p = new A[100]; 224218893Sdim // delete[] p; 225218893Sdim // } 226218893Sdim // Whereas it prints "104" and "104" if you give A a destructor. 227239462Sdim 228239462Sdim bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType); 229239462Sdim bool requiresArrayCookie(const CXXNewExpr *expr); 230239462Sdim CharUnits getArrayCookieSizeImpl(QualType type); 231239462Sdim llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, 232239462Sdim llvm::Value *NewPtr, 233239462Sdim llvm::Value *NumElements, 234239462Sdim const CXXNewExpr *expr, 235239462Sdim QualType ElementType); 236239462Sdim llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, 237239462Sdim llvm::Value *allocPtr, 238239462Sdim CharUnits cookieSize); 239249423Sdim 240249423Sdimprivate: 241263508Sdim MicrosoftMangleContext &getMangleContext() { 242263508Sdim return cast<MicrosoftMangleContext>(CodeGen::CGCXXABI::getMangleContext()); 243263508Sdim } 244263508Sdim 245251662Sdim llvm::Constant *getZeroInt() { 246251662Sdim return llvm::ConstantInt::get(CGM.IntTy, 0); 247249423Sdim } 248249423Sdim 249251662Sdim llvm::Constant *getAllOnesInt() { 250251662Sdim return llvm::Constant::getAllOnesValue(CGM.IntTy); 251249423Sdim } 252249423Sdim 253263508Sdim llvm::Constant *getConstantOrZeroInt(llvm::Constant *C) { 254263508Sdim return C ? C : getZeroInt(); 255263508Sdim } 256263508Sdim 257263508Sdim llvm::Value *getValueOrZeroInt(llvm::Value *C) { 258263508Sdim return C ? C : getZeroInt(); 259263508Sdim } 260263508Sdim 261251662Sdim void 262251662Sdim GetNullMemberPointerFields(const MemberPointerType *MPT, 263251662Sdim llvm::SmallVectorImpl<llvm::Constant *> &fields); 264251662Sdim 265263508Sdim /// \brief Finds the offset from the base of RD to the vbptr it uses, even if 266263508Sdim /// it is reusing a vbptr from a non-virtual base. RD must have morally 267263508Sdim /// virtual bases. 268263508Sdim CharUnits GetVBPtrOffsetFromBases(const CXXRecordDecl *RD); 269263508Sdim 270263508Sdim /// \brief Shared code for virtual base adjustment. Returns the offset from 271263508Sdim /// the vbptr to the virtual base. Optionally returns the address of the 272263508Sdim /// vbptr itself. 273263508Sdim llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, 274263508Sdim llvm::Value *Base, 275263508Sdim llvm::Value *VBPtrOffset, 276263508Sdim llvm::Value *VBTableOffset, 277263508Sdim llvm::Value **VBPtr = 0); 278263508Sdim 279263508Sdim llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, 280263508Sdim llvm::Value *Base, 281263508Sdim int32_t VBPtrOffset, 282263508Sdim int32_t VBTableOffset, 283263508Sdim llvm::Value **VBPtr = 0) { 284263508Sdim llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset), 285263508Sdim *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset); 286263508Sdim return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr); 287263508Sdim } 288263508Sdim 289263508Sdim /// \brief Performs a full virtual base adjustment. Used to dereference 290263508Sdim /// pointers to members of virtual bases. 291251662Sdim llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD, 292251662Sdim llvm::Value *Base, 293251662Sdim llvm::Value *VirtualBaseAdjustmentOffset, 294251662Sdim llvm::Value *VBPtrOffset /* optional */); 295251662Sdim 296251662Sdim /// \brief Emits a full member pointer with the fields common to data and 297251662Sdim /// function member pointers. 298251662Sdim llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField, 299251662Sdim bool IsMemberFunction, 300263508Sdim const CXXRecordDecl *RD, 301263508Sdim CharUnits NonVirtualBaseAdjustment); 302251662Sdim 303263508Sdim llvm::Constant *BuildMemberPointer(const CXXRecordDecl *RD, 304263508Sdim const CXXMethodDecl *MD, 305263508Sdim CharUnits NonVirtualBaseAdjustment); 306263508Sdim 307263508Sdim bool MemberPointerConstantIsNull(const MemberPointerType *MPT, 308263508Sdim llvm::Constant *MP); 309263508Sdim 310263508Sdim /// \brief - Initialize all vbptrs of 'this' with RD as the complete type. 311263508Sdim void EmitVBPtrStores(CodeGenFunction &CGF, const CXXRecordDecl *RD); 312263508Sdim 313263508Sdim /// \brief Caching wrapper around VBTableBuilder::enumerateVBTables(). 314263508Sdim const VBTableVector &EnumerateVBTables(const CXXRecordDecl *RD); 315263508Sdim 316263508Sdim /// \brief Generate a thunk for calling a virtual member function MD. 317263508Sdim llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, 318263508Sdim StringRef ThunkName); 319263508Sdim 320249423Sdimpublic: 321251662Sdim virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT); 322251662Sdim 323251662Sdim virtual bool isZeroInitializable(const MemberPointerType *MPT); 324251662Sdim 325249423Sdim virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); 326249423Sdim 327249423Sdim virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, 328249423Sdim CharUnits offset); 329251662Sdim virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); 330251662Sdim virtual llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT); 331249423Sdim 332251662Sdim virtual llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, 333251662Sdim llvm::Value *L, 334251662Sdim llvm::Value *R, 335251662Sdim const MemberPointerType *MPT, 336251662Sdim bool Inequality); 337251662Sdim 338249423Sdim virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 339249423Sdim llvm::Value *MemPtr, 340249423Sdim const MemberPointerType *MPT); 341249423Sdim 342249423Sdim virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, 343249423Sdim llvm::Value *Base, 344249423Sdim llvm::Value *MemPtr, 345249423Sdim const MemberPointerType *MPT); 346249423Sdim 347263508Sdim virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, 348263508Sdim const CastExpr *E, 349263508Sdim llvm::Value *Src); 350263508Sdim 351263508Sdim virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, 352263508Sdim llvm::Constant *Src); 353263508Sdim 354251662Sdim virtual llvm::Value * 355251662Sdim EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 356251662Sdim llvm::Value *&This, 357251662Sdim llvm::Value *MemPtr, 358251662Sdim const MemberPointerType *MPT); 359251662Sdim 360263508Sdimprivate: 361263508Sdim typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy; 362263508Sdim typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VFTablesMapTy; 363263508Sdim /// \brief All the vftables that have been referenced. 364263508Sdim VFTablesMapTy VFTablesMap; 365263508Sdim 366263508Sdim /// \brief This set holds the record decls we've deferred vtable emission for. 367263508Sdim llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables; 368263508Sdim 369263508Sdim 370263508Sdim /// \brief All the vbtables which have been referenced. 371263508Sdim llvm::DenseMap<const CXXRecordDecl *, VBTableVector> VBTablesMap; 372263508Sdim 373263508Sdim /// Info on the global variable used to guard initialization of static locals. 374263508Sdim /// The BitIndex field is only used for externally invisible declarations. 375263508Sdim struct GuardInfo { 376263508Sdim GuardInfo() : Guard(0), BitIndex(0) {} 377263508Sdim llvm::GlobalVariable *Guard; 378263508Sdim unsigned BitIndex; 379263508Sdim }; 380263508Sdim 381263508Sdim /// Map from DeclContext to the current guard variable. We assume that the 382263508Sdim /// AST is visited in source code order. 383263508Sdim llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap; 384210008Srdivacky}; 385210008Srdivacky 386210008Srdivacky} 387210008Srdivacky 388243830Sdimllvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF, 389243830Sdim llvm::Value *ptr, 390243830Sdim QualType type) { 391243830Sdim // FIXME: implement 392243830Sdim return ptr; 393243830Sdim} 394243830Sdim 395263508Sdim/// \brief Finds the first non-virtual base of RD that has virtual bases. If RD 396263508Sdim/// doesn't have a vbptr, it will reuse the vbptr of the returned class. 397263508Sdimstatic const CXXRecordDecl *FindFirstNVBaseWithVBases(const CXXRecordDecl *RD) { 398263508Sdim for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 399263508Sdim E = RD->bases_end(); I != E; ++I) { 400263508Sdim const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); 401263508Sdim if (!I->isVirtual() && Base->getNumVBases() > 0) 402263508Sdim return Base; 403263508Sdim } 404263508Sdim llvm_unreachable("RD must have an nv base with vbases"); 405243830Sdim} 406243830Sdim 407263508SdimCharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl *RD) { 408263508Sdim assert(RD->getNumVBases()); 409263508Sdim CharUnits Total = CharUnits::Zero(); 410263508Sdim while (RD) { 411263508Sdim const ASTRecordLayout &RDLayout = getContext().getASTRecordLayout(RD); 412263508Sdim CharUnits VBPtrOffset = RDLayout.getVBPtrOffset(); 413263508Sdim // -1 is the sentinel for no vbptr. 414263508Sdim if (VBPtrOffset != CharUnits::fromQuantity(-1)) { 415263508Sdim Total += VBPtrOffset; 416263508Sdim break; 417263508Sdim } 418263508Sdim RD = FindFirstNVBaseWithVBases(RD); 419263508Sdim Total += RDLayout.getBaseClassOffset(RD); 420263508Sdim } 421263508Sdim return Total; 422263508Sdim} 423263508Sdim 424263508Sdimllvm::Value * 425263508SdimMicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, 426263508Sdim llvm::Value *This, 427263508Sdim const CXXRecordDecl *ClassDecl, 428263508Sdim const CXXRecordDecl *BaseClassDecl) { 429263508Sdim int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity(); 430263508Sdim llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars); 431263508Sdim CharUnits IntSize = getContext().getTypeSizeInChars(getContext().IntTy); 432263508Sdim CharUnits VBTableChars = 433263508Sdim IntSize * 434263508Sdim CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl); 435263508Sdim llvm::Value *VBTableOffset = 436263508Sdim llvm::ConstantInt::get(CGM.IntTy, VBTableChars.getQuantity()); 437263508Sdim 438263508Sdim llvm::Value *VBPtrToNewBase = 439263508Sdim GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset); 440263508Sdim VBPtrToNewBase = 441263508Sdim CGF.Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy); 442263508Sdim return CGF.Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase); 443263508Sdim} 444263508Sdim 445263508Sdimbool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const { 446263508Sdim return isa<CXXConstructorDecl>(GD.getDecl()); 447263508Sdim} 448263508Sdim 449243830Sdimvoid MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, 450243830Sdim CXXCtorType Type, 451243830Sdim CanQualType &ResTy, 452243830Sdim SmallVectorImpl<CanQualType> &ArgTys) { 453263508Sdim // 'this' parameter and 'this' return are already in place 454249423Sdim 455249423Sdim const CXXRecordDecl *Class = Ctor->getParent(); 456249423Sdim if (Class->getNumVBases()) { 457249423Sdim // Constructors of classes with virtual bases take an implicit parameter. 458249423Sdim ArgTys.push_back(CGM.getContext().IntTy); 459249423Sdim } 460243830Sdim} 461243830Sdim 462263508Sdimllvm::BasicBlock * 463263508SdimMicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, 464263508Sdim const CXXRecordDecl *RD) { 465249423Sdim llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF); 466249423Sdim assert(IsMostDerivedClass && 467249423Sdim "ctor for a class with virtual bases must have an implicit parameter"); 468263508Sdim llvm::Value *IsCompleteObject = 469263508Sdim CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object"); 470249423Sdim 471249423Sdim llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases"); 472249423Sdim llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases"); 473249423Sdim CGF.Builder.CreateCondBr(IsCompleteObject, 474249423Sdim CallVbaseCtorsBB, SkipVbaseCtorsBB); 475249423Sdim 476249423Sdim CGF.EmitBlock(CallVbaseCtorsBB); 477249423Sdim 478263508Sdim // Fill in the vbtable pointers here. 479263508Sdim EmitVBPtrStores(CGF, RD); 480263508Sdim 481249423Sdim // CGF will put the base ctor calls in this basic block for us later. 482249423Sdim 483249423Sdim return SkipVbaseCtorsBB; 484249423Sdim} 485249423Sdim 486263508Sdimvoid MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers( 487263508Sdim CodeGenFunction &CGF, const CXXRecordDecl *RD) { 488263508Sdim // In most cases, an override for a vbase virtual method can adjust 489263508Sdim // the "this" parameter by applying a constant offset. 490263508Sdim // However, this is not enough while a constructor or a destructor of some 491263508Sdim // class X is being executed if all the following conditions are met: 492263508Sdim // - X has virtual bases, (1) 493263508Sdim // - X overrides a virtual method M of a vbase Y, (2) 494263508Sdim // - X itself is a vbase of the most derived class. 495263508Sdim // 496263508Sdim // If (1) and (2) are true, the vtorDisp for vbase Y is a hidden member of X 497263508Sdim // which holds the extra amount of "this" adjustment we must do when we use 498263508Sdim // the X vftables (i.e. during X ctor or dtor). 499263508Sdim // Outside the ctors and dtors, the values of vtorDisps are zero. 500263508Sdim 501263508Sdim const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 502263508Sdim typedef ASTRecordLayout::VBaseOffsetsMapTy VBOffsets; 503263508Sdim const VBOffsets &VBaseMap = Layout.getVBaseOffsetsMap(); 504263508Sdim CGBuilderTy &Builder = CGF.Builder; 505263508Sdim 506263508Sdim unsigned AS = 507263508Sdim cast<llvm::PointerType>(getThisValue(CGF)->getType())->getAddressSpace(); 508263508Sdim llvm::Value *Int8This = 0; // Initialize lazily. 509263508Sdim 510263508Sdim for (VBOffsets::const_iterator I = VBaseMap.begin(), E = VBaseMap.end(); 511263508Sdim I != E; ++I) { 512263508Sdim if (!I->second.hasVtorDisp()) 513263508Sdim continue; 514263508Sdim 515263508Sdim llvm::Value *VBaseOffset = 516263508Sdim GetVirtualBaseClassOffset(CGF, getThisValue(CGF), RD, I->first); 517263508Sdim // FIXME: it doesn't look right that we SExt in GetVirtualBaseClassOffset() 518263508Sdim // just to Trunc back immediately. 519263508Sdim VBaseOffset = Builder.CreateTruncOrBitCast(VBaseOffset, CGF.Int32Ty); 520263508Sdim uint64_t ConstantVBaseOffset = 521263508Sdim Layout.getVBaseClassOffset(I->first).getQuantity(); 522263508Sdim 523263508Sdim // vtorDisp_for_vbase = vbptr[vbase_idx] - offsetof(RD, vbase). 524263508Sdim llvm::Value *VtorDispValue = Builder.CreateSub( 525263508Sdim VBaseOffset, llvm::ConstantInt::get(CGM.Int32Ty, ConstantVBaseOffset), 526263508Sdim "vtordisp.value"); 527263508Sdim 528263508Sdim if (!Int8This) 529263508Sdim Int8This = Builder.CreateBitCast(getThisValue(CGF), 530263508Sdim CGF.Int8Ty->getPointerTo(AS)); 531263508Sdim llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset); 532263508Sdim // vtorDisp is always the 32-bits before the vbase in the class layout. 533263508Sdim VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4); 534263508Sdim VtorDispPtr = Builder.CreateBitCast( 535263508Sdim VtorDispPtr, CGF.Int32Ty->getPointerTo(AS), "vtordisp.ptr"); 536263508Sdim 537263508Sdim Builder.CreateStore(VtorDispValue, VtorDispPtr); 538263508Sdim } 539263508Sdim} 540263508Sdim 541263508Sdimvoid MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { 542263508Sdim // There's only one constructor type in this ABI. 543263508Sdim CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete)); 544263508Sdim} 545263508Sdim 546263508Sdimvoid MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF, 547263508Sdim const CXXRecordDecl *RD) { 548263508Sdim llvm::Value *ThisInt8Ptr = 549263508Sdim CGF.Builder.CreateBitCast(getThisValue(CGF), CGM.Int8PtrTy, "this.int8"); 550263508Sdim 551263508Sdim const VBTableVector &VBTables = EnumerateVBTables(RD); 552263508Sdim for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end(); 553263508Sdim I != E; ++I) { 554263508Sdim const ASTRecordLayout &SubobjectLayout = 555263508Sdim CGM.getContext().getASTRecordLayout(I->VBPtrSubobject.getBase()); 556263508Sdim uint64_t Offs = (I->VBPtrSubobject.getBaseOffset() + 557263508Sdim SubobjectLayout.getVBPtrOffset()).getQuantity(); 558263508Sdim llvm::Value *VBPtr = 559263508Sdim CGF.Builder.CreateConstInBoundsGEP1_64(ThisInt8Ptr, Offs); 560263508Sdim VBPtr = CGF.Builder.CreateBitCast(VBPtr, I->GV->getType()->getPointerTo(0), 561263508Sdim "vbptr." + I->ReusingBase->getName()); 562263508Sdim CGF.Builder.CreateStore(I->GV, VBPtr); 563263508Sdim } 564263508Sdim} 565263508Sdim 566249423Sdimvoid MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, 567249423Sdim CXXDtorType Type, 568249423Sdim CanQualType &ResTy, 569249423Sdim SmallVectorImpl<CanQualType> &ArgTys) { 570249423Sdim // 'this' is already in place 571263508Sdim 572249423Sdim // TODO: 'for base' flag 573249423Sdim 574249423Sdim if (Type == Dtor_Deleting) { 575263508Sdim // The scalar deleting destructor takes an implicit int parameter. 576263508Sdim ArgTys.push_back(CGM.getContext().IntTy); 577249423Sdim } 578249423Sdim} 579249423Sdim 580263508Sdimvoid MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { 581263508Sdim // The TU defining a dtor is only guaranteed to emit a base destructor. All 582263508Sdim // other destructor variants are delegating thunks. 583263508Sdim CGM.EmitGlobal(GlobalDecl(D, Dtor_Base)); 584263508Sdim} 585263508Sdim 586263508Sdimllvm::Value *MicrosoftCXXABI::adjustThisArgumentForVirtualCall( 587263508Sdim CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) { 588263508Sdim GD = GD.getCanonicalDecl(); 589263508Sdim const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 590263508Sdim // FIXME: consider splitting the vdtor vs regular method code into two 591263508Sdim // functions. 592263508Sdim 593263508Sdim GlobalDecl LookupGD = GD; 594263508Sdim if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 595263508Sdim // Complete dtors take a pointer to the complete object, 596263508Sdim // thus don't need adjustment. 597263508Sdim if (GD.getDtorType() == Dtor_Complete) 598263508Sdim return This; 599263508Sdim 600263508Sdim // There's only Dtor_Deleting in vftable but it shares the this adjustment 601263508Sdim // with the base one, so look up the deleting one instead. 602263508Sdim LookupGD = GlobalDecl(DD, Dtor_Deleting); 603263508Sdim } 604263508Sdim MicrosoftVTableContext::MethodVFTableLocation ML = 605263508Sdim CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); 606263508Sdim 607263508Sdim unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace(); 608263508Sdim llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS); 609263508Sdim CharUnits StaticOffset = ML.VFPtrOffset; 610263508Sdim if (ML.VBase) { 611263508Sdim bool AvoidVirtualOffset = false; 612263508Sdim if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) { 613263508Sdim // A base destructor can only be called from a complete destructor of the 614263508Sdim // same record type or another destructor of a more derived type; 615263508Sdim // or a constructor of the same record type if an exception is thrown. 616263508Sdim assert(isa<CXXDestructorDecl>(CGF.CurGD.getDecl()) || 617263508Sdim isa<CXXConstructorDecl>(CGF.CurGD.getDecl())); 618263508Sdim const CXXRecordDecl *CurRD = 619263508Sdim cast<CXXMethodDecl>(CGF.CurGD.getDecl())->getParent(); 620263508Sdim 621263508Sdim if (MD->getParent() == CurRD) { 622263508Sdim if (isa<CXXDestructorDecl>(CGF.CurGD.getDecl())) 623263508Sdim assert(CGF.CurGD.getDtorType() == Dtor_Complete); 624263508Sdim if (isa<CXXConstructorDecl>(CGF.CurGD.getDecl())) 625263508Sdim assert(CGF.CurGD.getCtorType() == Ctor_Complete); 626263508Sdim // We're calling the main base dtor from a complete structor, 627263508Sdim // so we know the "this" offset statically. 628263508Sdim AvoidVirtualOffset = true; 629263508Sdim } else { 630263508Sdim // Let's see if we try to call a destructor of a non-virtual base. 631263508Sdim for (CXXRecordDecl::base_class_const_iterator I = CurRD->bases_begin(), 632263508Sdim E = CurRD->bases_end(); I != E; ++I) { 633263508Sdim if (I->getType()->getAsCXXRecordDecl() != MD->getParent()) 634263508Sdim continue; 635263508Sdim // If we call a base destructor for a non-virtual base, we statically 636263508Sdim // know where it expects the vfptr and "this" to be. 637263508Sdim // The total offset should reflect the adjustment done by 638263508Sdim // adjustThisParameterInVirtualFunctionPrologue(). 639263508Sdim AvoidVirtualOffset = true; 640263508Sdim break; 641263508Sdim } 642263508Sdim } 643263508Sdim } 644263508Sdim 645263508Sdim if (AvoidVirtualOffset) { 646263508Sdim const ASTRecordLayout &Layout = 647263508Sdim CGF.getContext().getASTRecordLayout(MD->getParent()); 648263508Sdim StaticOffset += Layout.getVBaseClassOffset(ML.VBase); 649263508Sdim } else { 650263508Sdim This = CGF.Builder.CreateBitCast(This, charPtrTy); 651263508Sdim llvm::Value *VBaseOffset = 652263508Sdim GetVirtualBaseClassOffset(CGF, This, MD->getParent(), ML.VBase); 653263508Sdim This = CGF.Builder.CreateInBoundsGEP(This, VBaseOffset); 654263508Sdim } 655263508Sdim } 656263508Sdim if (!StaticOffset.isZero()) { 657263508Sdim assert(StaticOffset.isPositive()); 658263508Sdim This = CGF.Builder.CreateBitCast(This, charPtrTy); 659263508Sdim if (ML.VBase) { 660263508Sdim // Non-virtual adjustment might result in a pointer outside the allocated 661263508Sdim // object, e.g. if the final overrider class is laid out after the virtual 662263508Sdim // base that declares a method in the most derived class. 663263508Sdim // FIXME: Update the code that emits this adjustment in thunks prologues. 664263508Sdim This = CGF.Builder.CreateConstGEP1_32(This, StaticOffset.getQuantity()); 665263508Sdim } else { 666263508Sdim This = CGF.Builder.CreateConstInBoundsGEP1_32(This, 667263508Sdim StaticOffset.getQuantity()); 668263508Sdim } 669263508Sdim } 670263508Sdim return This; 671263508Sdim} 672263508Sdim 673249423Sdimstatic bool IsDeletingDtor(GlobalDecl GD) { 674249423Sdim const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); 675249423Sdim if (isa<CXXDestructorDecl>(MD)) { 676249423Sdim return GD.getDtorType() == Dtor_Deleting; 677249423Sdim } 678249423Sdim return false; 679249423Sdim} 680249423Sdim 681243830Sdimvoid MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, 682243830Sdim QualType &ResTy, 683243830Sdim FunctionArgList &Params) { 684243830Sdim BuildThisParam(CGF, Params); 685249423Sdim 686249423Sdim ASTContext &Context = getContext(); 687249423Sdim const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 688249423Sdim if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 689249423Sdim ImplicitParamDecl *IsMostDerived 690249423Sdim = ImplicitParamDecl::Create(Context, 0, 691249423Sdim CGF.CurGD.getDecl()->getLocation(), 692249423Sdim &Context.Idents.get("is_most_derived"), 693249423Sdim Context.IntTy); 694249423Sdim Params.push_back(IsMostDerived); 695249423Sdim getStructorImplicitParamDecl(CGF) = IsMostDerived; 696249423Sdim } else if (IsDeletingDtor(CGF.CurGD)) { 697249423Sdim ImplicitParamDecl *ShouldDelete 698249423Sdim = ImplicitParamDecl::Create(Context, 0, 699249423Sdim CGF.CurGD.getDecl()->getLocation(), 700249423Sdim &Context.Idents.get("should_call_delete"), 701263508Sdim Context.IntTy); 702249423Sdim Params.push_back(ShouldDelete); 703249423Sdim getStructorImplicitParamDecl(CGF) = ShouldDelete; 704249423Sdim } 705243830Sdim} 706243830Sdim 707263508Sdimllvm::Value *MicrosoftCXXABI::adjustThisParameterInVirtualFunctionPrologue( 708263508Sdim CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) { 709263508Sdim GD = GD.getCanonicalDecl(); 710263508Sdim const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 711263508Sdim 712263508Sdim GlobalDecl LookupGD = GD; 713263508Sdim if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 714263508Sdim // Complete destructors take a pointer to the complete object as a 715263508Sdim // parameter, thus don't need this adjustment. 716263508Sdim if (GD.getDtorType() == Dtor_Complete) 717263508Sdim return This; 718263508Sdim 719263508Sdim // There's no Dtor_Base in vftable but it shares the this adjustment with 720263508Sdim // the deleting one, so look it up instead. 721263508Sdim LookupGD = GlobalDecl(DD, Dtor_Deleting); 722263508Sdim } 723263508Sdim 724263508Sdim // In this ABI, every virtual function takes a pointer to one of the 725263508Sdim // subobjects that first defines it as the 'this' parameter, rather than a 726263508Sdim // pointer to ther final overrider subobject. Thus, we need to adjust it back 727263508Sdim // to the final overrider subobject before use. 728263508Sdim // See comments in the MicrosoftVFTableContext implementation for the details. 729263508Sdim 730263508Sdim MicrosoftVTableContext::MethodVFTableLocation ML = 731263508Sdim CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); 732263508Sdim CharUnits Adjustment = ML.VFPtrOffset; 733263508Sdim if (ML.VBase) { 734263508Sdim const ASTRecordLayout &DerivedLayout = 735263508Sdim CGF.getContext().getASTRecordLayout(MD->getParent()); 736263508Sdim Adjustment += DerivedLayout.getVBaseClassOffset(ML.VBase); 737263508Sdim } 738263508Sdim 739263508Sdim if (Adjustment.isZero()) 740263508Sdim return This; 741263508Sdim 742263508Sdim unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace(); 743263508Sdim llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS), 744263508Sdim *thisTy = This->getType(); 745263508Sdim 746263508Sdim This = CGF.Builder.CreateBitCast(This, charPtrTy); 747263508Sdim assert(Adjustment.isPositive()); 748263508Sdim This = 749263508Sdim CGF.Builder.CreateConstInBoundsGEP1_32(This, -Adjustment.getQuantity()); 750263508Sdim return CGF.Builder.CreateBitCast(This, thisTy); 751263508Sdim} 752263508Sdim 753243830Sdimvoid MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { 754243830Sdim EmitThisParam(CGF); 755263508Sdim 756263508Sdim /// If this is a function that the ABI specifies returns 'this', initialize 757263508Sdim /// the return slot to 'this' at the start of the function. 758263508Sdim /// 759263508Sdim /// Unlike the setting of return types, this is done within the ABI 760263508Sdim /// implementation instead of by clients of CGCXXABI because: 761263508Sdim /// 1) getThisValue is currently protected 762263508Sdim /// 2) in theory, an ABI could implement 'this' returns some other way; 763263508Sdim /// HasThisReturn only specifies a contract, not the implementation 764263508Sdim if (HasThisReturn(CGF.CurGD)) 765243830Sdim CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); 766249423Sdim 767249423Sdim const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 768249423Sdim if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 769249423Sdim assert(getStructorImplicitParamDecl(CGF) && 770249423Sdim "no implicit parameter for a constructor with virtual bases?"); 771249423Sdim getStructorImplicitParamValue(CGF) 772249423Sdim = CGF.Builder.CreateLoad( 773249423Sdim CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 774249423Sdim "is_most_derived"); 775249423Sdim } 776249423Sdim 777249423Sdim if (IsDeletingDtor(CGF.CurGD)) { 778249423Sdim assert(getStructorImplicitParamDecl(CGF) && 779249423Sdim "no implicit parameter for a deleting destructor?"); 780249423Sdim getStructorImplicitParamValue(CGF) 781249423Sdim = CGF.Builder.CreateLoad( 782249423Sdim CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 783249423Sdim "should_call_delete"); 784249423Sdim } 785243830Sdim} 786243830Sdim 787263508Sdimvoid MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF, 788249423Sdim const CXXConstructorDecl *D, 789263508Sdim CXXCtorType Type, 790263508Sdim bool ForVirtualBase, 791249423Sdim bool Delegating, 792249423Sdim llvm::Value *This, 793249423Sdim CallExpr::const_arg_iterator ArgBeg, 794249423Sdim CallExpr::const_arg_iterator ArgEnd) { 795249423Sdim assert(Type == Ctor_Complete || Type == Ctor_Base); 796249423Sdim llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete); 797249423Sdim 798249423Sdim llvm::Value *ImplicitParam = 0; 799249423Sdim QualType ImplicitParamTy; 800249423Sdim if (D->getParent()->getNumVBases()) { 801249423Sdim ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete); 802249423Sdim ImplicitParamTy = getContext().IntTy; 803249423Sdim } 804249423Sdim 805249423Sdim // FIXME: Provide a source location here. 806249423Sdim CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, 807263508Sdim ImplicitParam, ImplicitParamTy, ArgBeg, ArgEnd); 808249423Sdim} 809249423Sdim 810263508Sdimvoid MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, 811263508Sdim const CXXRecordDecl *RD) { 812263508Sdim MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext(); 813263508Sdim MicrosoftVTableContext::VFPtrListTy VFPtrs = VFTContext.getVFPtrOffsets(RD); 814263508Sdim llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD); 815263508Sdim 816263508Sdim for (MicrosoftVTableContext::VFPtrListTy::iterator I = VFPtrs.begin(), 817263508Sdim E = VFPtrs.end(); I != E; ++I) { 818263508Sdim llvm::GlobalVariable *VTable = getAddrOfVTable(RD, I->VFPtrFullOffset); 819263508Sdim if (VTable->hasInitializer()) 820263508Sdim continue; 821263508Sdim 822263508Sdim const VTableLayout &VTLayout = 823263508Sdim VFTContext.getVFTableLayout(RD, I->VFPtrFullOffset); 824263508Sdim llvm::Constant *Init = CGVT.CreateVTableInitializer( 825263508Sdim RD, VTLayout.vtable_component_begin(), 826263508Sdim VTLayout.getNumVTableComponents(), VTLayout.vtable_thunk_begin(), 827263508Sdim VTLayout.getNumVTableThunks()); 828263508Sdim VTable->setInitializer(Init); 829263508Sdim 830263508Sdim VTable->setLinkage(Linkage); 831263508Sdim CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable); 832263508Sdim } 833263508Sdim} 834263508Sdim 835263508Sdimllvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor( 836263508Sdim CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, 837263508Sdim const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) { 838263508Sdim NeedsVirtualOffset = (NearestVBase != 0); 839263508Sdim 840263508Sdim llvm::Value *VTableAddressPoint = 841263508Sdim getAddrOfVTable(VTableClass, Base.getBaseOffset()); 842263508Sdim if (!VTableAddressPoint) { 843263508Sdim assert(Base.getBase()->getNumVBases() && 844263508Sdim !CGM.getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr()); 845263508Sdim } 846263508Sdim return VTableAddressPoint; 847263508Sdim} 848263508Sdim 849263508Sdimstatic void mangleVFTableName(MicrosoftMangleContext &MangleContext, 850263508Sdim const CXXRecordDecl *RD, const VFPtrInfo &VFPtr, 851263508Sdim SmallString<256> &Name) { 852263508Sdim llvm::raw_svector_ostream Out(Name); 853263508Sdim MangleContext.mangleCXXVFTable(RD, VFPtr.PathToMangle, Out); 854263508Sdim} 855263508Sdim 856263508Sdimllvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr( 857263508Sdim BaseSubobject Base, const CXXRecordDecl *VTableClass) { 858263508Sdim llvm::Constant *VTable = getAddrOfVTable(VTableClass, Base.getBaseOffset()); 859263508Sdim assert(VTable && "Couldn't find a vftable for the given base?"); 860263508Sdim return VTable; 861263508Sdim} 862263508Sdim 863263508Sdimllvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, 864263508Sdim CharUnits VPtrOffset) { 865263508Sdim // getAddrOfVTable may return 0 if asked to get an address of a vtable which 866263508Sdim // shouldn't be used in the given record type. We want to cache this result in 867263508Sdim // VFTablesMap, thus a simple zero check is not sufficient. 868263508Sdim VFTableIdTy ID(RD, VPtrOffset); 869263508Sdim VFTablesMapTy::iterator I; 870263508Sdim bool Inserted; 871263508Sdim llvm::tie(I, Inserted) = VFTablesMap.insert( 872263508Sdim std::make_pair(ID, static_cast<llvm::GlobalVariable *>(0))); 873263508Sdim if (!Inserted) 874263508Sdim return I->second; 875263508Sdim 876263508Sdim llvm::GlobalVariable *&VTable = I->second; 877263508Sdim 878263508Sdim MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext(); 879263508Sdim const MicrosoftVTableContext::VFPtrListTy &VFPtrs = 880263508Sdim VTContext.getVFPtrOffsets(RD); 881263508Sdim 882263508Sdim if (DeferredVFTables.insert(RD)) { 883263508Sdim // We haven't processed this record type before. 884263508Sdim // Queue up this v-table for possible deferred emission. 885263508Sdim CGM.addDeferredVTable(RD); 886263508Sdim 887263508Sdim#ifndef NDEBUG 888263508Sdim // Create all the vftables at once in order to make sure each vftable has 889263508Sdim // a unique mangled name. 890263508Sdim llvm::StringSet<> ObservedMangledNames; 891263508Sdim for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) { 892263508Sdim SmallString<256> Name; 893263508Sdim mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name); 894263508Sdim if (!ObservedMangledNames.insert(Name.str())) 895263508Sdim llvm_unreachable("Already saw this mangling before?"); 896263508Sdim } 897263508Sdim#endif 898263508Sdim } 899263508Sdim 900263508Sdim for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) { 901263508Sdim if (VFPtrs[J].VFPtrFullOffset != VPtrOffset) 902263508Sdim continue; 903263508Sdim 904263508Sdim llvm::ArrayType *ArrayType = llvm::ArrayType::get( 905263508Sdim CGM.Int8PtrTy, 906263508Sdim VTContext.getVFTableLayout(RD, VFPtrs[J].VFPtrFullOffset) 907263508Sdim .getNumVTableComponents()); 908263508Sdim 909263508Sdim SmallString<256> Name; 910263508Sdim mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name); 911263508Sdim VTable = CGM.CreateOrReplaceCXXRuntimeVariable( 912263508Sdim Name.str(), ArrayType, llvm::GlobalValue::ExternalLinkage); 913263508Sdim VTable->setUnnamedAddr(true); 914263508Sdim break; 915263508Sdim } 916263508Sdim 917263508Sdim return VTable; 918263508Sdim} 919263508Sdim 920263508Sdimllvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, 921263508Sdim GlobalDecl GD, 922263508Sdim llvm::Value *This, 923263508Sdim llvm::Type *Ty) { 924263508Sdim GD = GD.getCanonicalDecl(); 925263508Sdim CGBuilderTy &Builder = CGF.Builder; 926263508Sdim 927263508Sdim Ty = Ty->getPointerTo()->getPointerTo(); 928263508Sdim llvm::Value *VPtr = adjustThisArgumentForVirtualCall(CGF, GD, This); 929263508Sdim llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty); 930263508Sdim 931263508Sdim MicrosoftVTableContext::MethodVFTableLocation ML = 932263508Sdim CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); 933263508Sdim llvm::Value *VFuncPtr = 934263508Sdim Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn"); 935263508Sdim return Builder.CreateLoad(VFuncPtr); 936263508Sdim} 937263508Sdim 938263508Sdimvoid MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, 939263508Sdim const CXXDestructorDecl *Dtor, 940263508Sdim CXXDtorType DtorType, 941263508Sdim SourceLocation CallLoc, 942263508Sdim llvm::Value *This) { 943249423Sdim assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); 944249423Sdim 945249423Sdim // We have only one destructor in the vftable but can get both behaviors 946263508Sdim // by passing an implicit int parameter. 947263508Sdim GlobalDecl GD(Dtor, Dtor_Deleting); 948263508Sdim const CGFunctionInfo *FInfo = 949263508Sdim &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting); 950249423Sdim llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); 951263508Sdim llvm::Value *Callee = getVirtualFunctionPointer(CGF, GD, This, Ty); 952249423Sdim 953249423Sdim ASTContext &Context = CGF.getContext(); 954263508Sdim llvm::Value *ImplicitParam = 955263508Sdim llvm::ConstantInt::get(llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()), 956249423Sdim DtorType == Dtor_Deleting); 957249423Sdim 958263508Sdim This = adjustThisArgumentForVirtualCall(CGF, GD, This); 959263508Sdim CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValueSlot(), This, 960263508Sdim ImplicitParam, Context.IntTy, 0, 0); 961249423Sdim} 962249423Sdim 963263508Sdimconst VBTableVector & 964263508SdimMicrosoftCXXABI::EnumerateVBTables(const CXXRecordDecl *RD) { 965263508Sdim // At this layer, we can key the cache off of a single class, which is much 966263508Sdim // easier than caching at the GlobalVariable layer. 967263508Sdim llvm::DenseMap<const CXXRecordDecl*, VBTableVector>::iterator I; 968263508Sdim bool added; 969263508Sdim llvm::tie(I, added) = VBTablesMap.insert(std::make_pair(RD, VBTableVector())); 970263508Sdim VBTableVector &VBTables = I->second; 971263508Sdim if (!added) 972263508Sdim return VBTables; 973263508Sdim 974263508Sdim VBTableBuilder(CGM, RD).enumerateVBTables(VBTables); 975263508Sdim 976263508Sdim return VBTables; 977263508Sdim} 978263508Sdim 979263508Sdimllvm::Function * 980263508SdimMicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, 981263508Sdim StringRef ThunkName) { 982263508Sdim // If the thunk has been generated previously, just return it. 983263508Sdim if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName)) 984263508Sdim return cast<llvm::Function>(GV); 985263508Sdim 986263508Sdim // Create the llvm::Function. 987263508Sdim const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(MD); 988263508Sdim llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo); 989263508Sdim llvm::Function *ThunkFn = 990263508Sdim llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage, 991263508Sdim ThunkName.str(), &CGM.getModule()); 992263508Sdim assert(ThunkFn->getName() == ThunkName && "name was uniqued!"); 993263508Sdim 994263508Sdim ThunkFn->setLinkage(MD->isExternallyVisible() 995263508Sdim ? llvm::GlobalValue::LinkOnceODRLinkage 996263508Sdim : llvm::GlobalValue::InternalLinkage); 997263508Sdim 998263508Sdim CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn); 999263508Sdim CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn); 1000263508Sdim 1001263508Sdim // Start codegen. 1002263508Sdim CodeGenFunction CGF(CGM); 1003263508Sdim CGF.StartThunk(ThunkFn, MD, FnInfo); 1004263508Sdim 1005263508Sdim // Get to the Callee. 1006263508Sdim llvm::Value *This = CGF.LoadCXXThis(); 1007263508Sdim llvm::Value *Callee = getVirtualFunctionPointer(CGF, MD, This, ThunkTy); 1008263508Sdim 1009263508Sdim // Make the call and return the result. 1010263508Sdim CGF.EmitCallAndReturnForThunk(MD, Callee, 0); 1011263508Sdim 1012263508Sdim return ThunkFn; 1013263508Sdim} 1014263508Sdim 1015263508Sdimvoid MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) { 1016263508Sdim const VBTableVector &VBTables = EnumerateVBTables(RD); 1017263508Sdim llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD); 1018263508Sdim 1019263508Sdim for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end(); 1020263508Sdim I != E; ++I) { 1021263508Sdim I->EmitVBTableDefinition(CGM, RD, Linkage); 1022263508Sdim } 1023263508Sdim} 1024263508Sdim 1025263508Sdimllvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF, 1026263508Sdim llvm::Value *This, 1027263508Sdim const ThisAdjustment &TA) { 1028263508Sdim if (TA.isEmpty()) 1029263508Sdim return This; 1030263508Sdim 1031263508Sdim llvm::Value *V = CGF.Builder.CreateBitCast(This, CGF.Int8PtrTy); 1032263508Sdim 1033263508Sdim if (!TA.Virtual.isEmpty()) { 1034263508Sdim assert(TA.Virtual.Microsoft.VtordispOffset < 0); 1035263508Sdim // Adjust the this argument based on the vtordisp value. 1036263508Sdim llvm::Value *VtorDispPtr = 1037263508Sdim CGF.Builder.CreateConstGEP1_32(V, TA.Virtual.Microsoft.VtordispOffset); 1038263508Sdim VtorDispPtr = 1039263508Sdim CGF.Builder.CreateBitCast(VtorDispPtr, CGF.Int32Ty->getPointerTo()); 1040263508Sdim llvm::Value *VtorDisp = CGF.Builder.CreateLoad(VtorDispPtr, "vtordisp"); 1041263508Sdim V = CGF.Builder.CreateGEP(V, CGF.Builder.CreateNeg(VtorDisp)); 1042263508Sdim 1043263508Sdim if (TA.Virtual.Microsoft.VBPtrOffset) { 1044263508Sdim // If the final overrider is defined in a virtual base other than the one 1045263508Sdim // that holds the vfptr, we have to use a vtordispex thunk which looks up 1046263508Sdim // the vbtable of the derived class. 1047263508Sdim assert(TA.Virtual.Microsoft.VBPtrOffset > 0); 1048263508Sdim assert(TA.Virtual.Microsoft.VBOffsetOffset >= 0); 1049263508Sdim llvm::Value *VBPtr; 1050263508Sdim llvm::Value *VBaseOffset = 1051263508Sdim GetVBaseOffsetFromVBPtr(CGF, V, -TA.Virtual.Microsoft.VBPtrOffset, 1052263508Sdim TA.Virtual.Microsoft.VBOffsetOffset, &VBPtr); 1053263508Sdim V = CGF.Builder.CreateInBoundsGEP(VBPtr, VBaseOffset); 1054263508Sdim } 1055263508Sdim } 1056263508Sdim 1057263508Sdim if (TA.NonVirtual) { 1058263508Sdim // Non-virtual adjustment might result in a pointer outside the allocated 1059263508Sdim // object, e.g. if the final overrider class is laid out after the virtual 1060263508Sdim // base that declares a method in the most derived class. 1061263508Sdim V = CGF.Builder.CreateConstGEP1_32(V, TA.NonVirtual); 1062263508Sdim } 1063263508Sdim 1064263508Sdim // Don't need to bitcast back, the call CodeGen will handle this. 1065263508Sdim return V; 1066263508Sdim} 1067263508Sdim 1068263508Sdimllvm::Value * 1069263508SdimMicrosoftCXXABI::performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret, 1070263508Sdim const ReturnAdjustment &RA) { 1071263508Sdim if (RA.isEmpty()) 1072263508Sdim return Ret; 1073263508Sdim 1074263508Sdim llvm::Value *V = CGF.Builder.CreateBitCast(Ret, CGF.Int8PtrTy); 1075263508Sdim 1076263508Sdim if (RA.Virtual.Microsoft.VBIndex) { 1077263508Sdim assert(RA.Virtual.Microsoft.VBIndex > 0); 1078263508Sdim int32_t IntSize = 1079263508Sdim getContext().getTypeSizeInChars(getContext().IntTy).getQuantity(); 1080263508Sdim llvm::Value *VBPtr; 1081263508Sdim llvm::Value *VBaseOffset = 1082263508Sdim GetVBaseOffsetFromVBPtr(CGF, V, RA.Virtual.Microsoft.VBPtrOffset, 1083263508Sdim IntSize * RA.Virtual.Microsoft.VBIndex, &VBPtr); 1084263508Sdim V = CGF.Builder.CreateInBoundsGEP(VBPtr, VBaseOffset); 1085263508Sdim } 1086263508Sdim 1087263508Sdim if (RA.NonVirtual) 1088263508Sdim V = CGF.Builder.CreateConstInBoundsGEP1_32(V, RA.NonVirtual); 1089263508Sdim 1090263508Sdim // Cast back to the original type. 1091263508Sdim return CGF.Builder.CreateBitCast(V, Ret->getType()); 1092263508Sdim} 1093263508Sdim 1094239462Sdimbool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, 1095239462Sdim QualType elementType) { 1096239462Sdim // Microsoft seems to completely ignore the possibility of a 1097239462Sdim // two-argument usual deallocation function. 1098239462Sdim return elementType.isDestructedType(); 1099239462Sdim} 1100239462Sdim 1101239462Sdimbool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) { 1102239462Sdim // Microsoft seems to completely ignore the possibility of a 1103239462Sdim // two-argument usual deallocation function. 1104239462Sdim return expr->getAllocatedType().isDestructedType(); 1105239462Sdim} 1106239462Sdim 1107239462SdimCharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) { 1108239462Sdim // The array cookie is always a size_t; we then pad that out to the 1109239462Sdim // alignment of the element type. 1110239462Sdim ASTContext &Ctx = getContext(); 1111239462Sdim return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()), 1112239462Sdim Ctx.getTypeAlignInChars(type)); 1113239462Sdim} 1114239462Sdim 1115239462Sdimllvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 1116239462Sdim llvm::Value *allocPtr, 1117239462Sdim CharUnits cookieSize) { 1118243830Sdim unsigned AS = allocPtr->getType()->getPointerAddressSpace(); 1119239462Sdim llvm::Value *numElementsPtr = 1120239462Sdim CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS)); 1121239462Sdim return CGF.Builder.CreateLoad(numElementsPtr); 1122239462Sdim} 1123239462Sdim 1124239462Sdimllvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 1125239462Sdim llvm::Value *newPtr, 1126239462Sdim llvm::Value *numElements, 1127239462Sdim const CXXNewExpr *expr, 1128239462Sdim QualType elementType) { 1129239462Sdim assert(requiresArrayCookie(expr)); 1130239462Sdim 1131239462Sdim // The size of the cookie. 1132239462Sdim CharUnits cookieSize = getArrayCookieSizeImpl(elementType); 1133239462Sdim 1134239462Sdim // Compute an offset to the cookie. 1135239462Sdim llvm::Value *cookiePtr = newPtr; 1136239462Sdim 1137239462Sdim // Write the number of elements into the appropriate slot. 1138243830Sdim unsigned AS = newPtr->getType()->getPointerAddressSpace(); 1139239462Sdim llvm::Value *numElementsPtr 1140239462Sdim = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS)); 1141239462Sdim CGF.Builder.CreateStore(numElements, numElementsPtr); 1142239462Sdim 1143239462Sdim // Finally, compute a pointer to the actual data buffer by skipping 1144239462Sdim // over the cookie completely. 1145239462Sdim return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr, 1146239462Sdim cookieSize.getQuantity()); 1147239462Sdim} 1148239462Sdim 1149239462Sdimvoid MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 1150263508Sdim llvm::GlobalVariable *GV, 1151239462Sdim bool PerformInit) { 1152263508Sdim // MSVC always uses an i32 bitfield to guard initialization, which is *not* 1153263508Sdim // threadsafe. Since the user may be linking in inline functions compiled by 1154263508Sdim // cl.exe, there's no reason to provide a false sense of security by using 1155263508Sdim // critical sections here. 1156239462Sdim 1157251662Sdim if (D.getTLSKind()) 1158251662Sdim CGM.ErrorUnsupported(&D, "dynamic TLS initialization"); 1159251662Sdim 1160263508Sdim CGBuilderTy &Builder = CGF.Builder; 1161263508Sdim llvm::IntegerType *GuardTy = CGF.Int32Ty; 1162263508Sdim llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0); 1163263508Sdim 1164263508Sdim // Get the guard variable for this function if we have one already. 1165263508Sdim GuardInfo &GI = GuardVariableMap[D.getDeclContext()]; 1166263508Sdim 1167263508Sdim unsigned BitIndex; 1168263508Sdim if (D.isExternallyVisible()) { 1169263508Sdim // Externally visible variables have to be numbered in Sema to properly 1170263508Sdim // handle unreachable VarDecls. 1171263508Sdim BitIndex = getContext().getManglingNumber(&D); 1172263508Sdim assert(BitIndex > 0); 1173263508Sdim BitIndex--; 1174263508Sdim } else { 1175263508Sdim // Non-externally visible variables are numbered here in CodeGen. 1176263508Sdim BitIndex = GI.BitIndex++; 1177263508Sdim } 1178263508Sdim 1179263508Sdim if (BitIndex >= 32) { 1180263508Sdim if (D.isExternallyVisible()) 1181263508Sdim ErrorUnsupportedABI(CGF, "more than 32 guarded initializations"); 1182263508Sdim BitIndex %= 32; 1183263508Sdim GI.Guard = 0; 1184263508Sdim } 1185263508Sdim 1186263508Sdim // Lazily create the i32 bitfield for this function. 1187263508Sdim if (!GI.Guard) { 1188263508Sdim // Mangle the name for the guard. 1189263508Sdim SmallString<256> GuardName; 1190263508Sdim { 1191263508Sdim llvm::raw_svector_ostream Out(GuardName); 1192263508Sdim getMangleContext().mangleStaticGuardVariable(&D, Out); 1193263508Sdim Out.flush(); 1194263508Sdim } 1195263508Sdim 1196263508Sdim // Create the guard variable with a zero-initializer. Just absorb linkage 1197263508Sdim // and visibility from the guarded variable. 1198263508Sdim GI.Guard = new llvm::GlobalVariable(CGM.getModule(), GuardTy, false, 1199263508Sdim GV->getLinkage(), Zero, GuardName.str()); 1200263508Sdim GI.Guard->setVisibility(GV->getVisibility()); 1201263508Sdim } else { 1202263508Sdim assert(GI.Guard->getLinkage() == GV->getLinkage() && 1203263508Sdim "static local from the same function had different linkage"); 1204263508Sdim } 1205263508Sdim 1206263508Sdim // Pseudo code for the test: 1207263508Sdim // if (!(GuardVar & MyGuardBit)) { 1208263508Sdim // GuardVar |= MyGuardBit; 1209263508Sdim // ... initialize the object ...; 1210263508Sdim // } 1211263508Sdim 1212263508Sdim // Test our bit from the guard variable. 1213263508Sdim llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1U << BitIndex); 1214263508Sdim llvm::LoadInst *LI = Builder.CreateLoad(GI.Guard); 1215263508Sdim llvm::Value *IsInitialized = 1216263508Sdim Builder.CreateICmpNE(Builder.CreateAnd(LI, Bit), Zero); 1217263508Sdim llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init"); 1218263508Sdim llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end"); 1219263508Sdim Builder.CreateCondBr(IsInitialized, EndBlock, InitBlock); 1220263508Sdim 1221263508Sdim // Set our bit in the guard variable and emit the initializer and add a global 1222263508Sdim // destructor if appropriate. 1223263508Sdim CGF.EmitBlock(InitBlock); 1224263508Sdim Builder.CreateStore(Builder.CreateOr(LI, Bit), GI.Guard); 1225263508Sdim CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit); 1226263508Sdim Builder.CreateBr(EndBlock); 1227263508Sdim 1228263508Sdim // Continue. 1229263508Sdim CGF.EmitBlock(EndBlock); 1230239462Sdim} 1231239462Sdim 1232251662Sdim// Member pointer helpers. 1233251662Sdimstatic bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) { 1234251662Sdim return Inheritance == MSIM_Unspecified; 1235251662Sdim} 1236251662Sdim 1237263508Sdimstatic bool hasOnlyOneField(bool IsMemberFunction, 1238263508Sdim MSInheritanceModel Inheritance) { 1239263508Sdim return Inheritance <= MSIM_SinglePolymorphic || 1240263508Sdim (!IsMemberFunction && Inheritance <= MSIM_MultiplePolymorphic); 1241251662Sdim} 1242251662Sdim 1243251662Sdim// Only member pointers to functions need a this adjustment, since it can be 1244251662Sdim// combined with the field offset for data pointers. 1245251662Sdimstatic bool hasNonVirtualBaseAdjustmentField(bool IsMemberFunction, 1246251662Sdim MSInheritanceModel Inheritance) { 1247251662Sdim return (IsMemberFunction && Inheritance >= MSIM_Multiple); 1248251662Sdim} 1249251662Sdim 1250251662Sdimstatic bool hasVirtualBaseAdjustmentField(MSInheritanceModel Inheritance) { 1251251662Sdim return Inheritance >= MSIM_Virtual; 1252251662Sdim} 1253251662Sdim 1254251662Sdim// Use zero for the field offset of a null data member pointer if we can 1255251662Sdim// guarantee that zero is not a valid field offset, or if the member pointer has 1256251662Sdim// multiple fields. Polymorphic classes have a vfptr at offset zero, so we can 1257251662Sdim// use zero for null. If there are multiple fields, we can use zero even if it 1258251662Sdim// is a valid field offset because null-ness testing will check the other 1259251662Sdim// fields. 1260251662Sdimstatic bool nullFieldOffsetIsZero(MSInheritanceModel Inheritance) { 1261251662Sdim return Inheritance != MSIM_Multiple && Inheritance != MSIM_Single; 1262251662Sdim} 1263251662Sdim 1264251662Sdimbool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) { 1265251662Sdim // Null-ness for function memptrs only depends on the first field, which is 1266251662Sdim // the function pointer. The rest don't matter, so we can zero initialize. 1267251662Sdim if (MPT->isMemberFunctionPointer()) 1268251662Sdim return true; 1269251662Sdim 1270251662Sdim // The virtual base adjustment field is always -1 for null, so if we have one 1271251662Sdim // we can't zero initialize. The field offset is sometimes also -1 if 0 is a 1272251662Sdim // valid field offset. 1273249423Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1274251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1275251662Sdim return (!hasVirtualBaseAdjustmentField(Inheritance) && 1276251662Sdim nullFieldOffsetIsZero(Inheritance)); 1277239462Sdim} 1278239462Sdim 1279251662Sdimllvm::Type * 1280251662SdimMicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { 1281251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1282251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1283251662Sdim llvm::SmallVector<llvm::Type *, 4> fields; 1284251662Sdim if (MPT->isMemberFunctionPointer()) 1285251662Sdim fields.push_back(CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk 1286251662Sdim else 1287251662Sdim fields.push_back(CGM.IntTy); // FieldOffset 1288251662Sdim 1289251662Sdim if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(), 1290251662Sdim Inheritance)) 1291251662Sdim fields.push_back(CGM.IntTy); 1292251662Sdim if (hasVBPtrOffsetField(Inheritance)) 1293251662Sdim fields.push_back(CGM.IntTy); 1294251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 1295251662Sdim fields.push_back(CGM.IntTy); // VirtualBaseAdjustmentOffset 1296251662Sdim 1297251662Sdim if (fields.size() == 1) 1298251662Sdim return fields[0]; 1299251662Sdim return llvm::StructType::get(CGM.getLLVMContext(), fields); 1300251662Sdim} 1301251662Sdim 1302251662Sdimvoid MicrosoftCXXABI:: 1303251662SdimGetNullMemberPointerFields(const MemberPointerType *MPT, 1304251662Sdim llvm::SmallVectorImpl<llvm::Constant *> &fields) { 1305251662Sdim assert(fields.empty()); 1306251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1307251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1308251662Sdim if (MPT->isMemberFunctionPointer()) { 1309251662Sdim // FunctionPointerOrVirtualThunk 1310251662Sdim fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); 1311251662Sdim } else { 1312251662Sdim if (nullFieldOffsetIsZero(Inheritance)) 1313251662Sdim fields.push_back(getZeroInt()); // FieldOffset 1314251662Sdim else 1315251662Sdim fields.push_back(getAllOnesInt()); // FieldOffset 1316249423Sdim } 1317251662Sdim 1318251662Sdim if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(), 1319251662Sdim Inheritance)) 1320251662Sdim fields.push_back(getZeroInt()); 1321251662Sdim if (hasVBPtrOffsetField(Inheritance)) 1322251662Sdim fields.push_back(getZeroInt()); 1323251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 1324251662Sdim fields.push_back(getAllOnesInt()); 1325249423Sdim} 1326249423Sdim 1327249423Sdimllvm::Constant * 1328249423SdimMicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { 1329251662Sdim llvm::SmallVector<llvm::Constant *, 4> fields; 1330251662Sdim GetNullMemberPointerFields(MPT, fields); 1331251662Sdim if (fields.size() == 1) 1332251662Sdim return fields[0]; 1333251662Sdim llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields); 1334251662Sdim assert(Res->getType() == ConvertMemberPointerType(MPT)); 1335251662Sdim return Res; 1336249423Sdim} 1337249423Sdim 1338249423Sdimllvm::Constant * 1339251662SdimMicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField, 1340251662Sdim bool IsMemberFunction, 1341263508Sdim const CXXRecordDecl *RD, 1342263508Sdim CharUnits NonVirtualBaseAdjustment) 1343251662Sdim{ 1344251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1345251662Sdim 1346251662Sdim // Single inheritance class member pointer are represented as scalars instead 1347251662Sdim // of aggregates. 1348263508Sdim if (hasOnlyOneField(IsMemberFunction, Inheritance)) 1349251662Sdim return FirstField; 1350251662Sdim 1351251662Sdim llvm::SmallVector<llvm::Constant *, 4> fields; 1352251662Sdim fields.push_back(FirstField); 1353251662Sdim 1354251662Sdim if (hasNonVirtualBaseAdjustmentField(IsMemberFunction, Inheritance)) 1355263508Sdim fields.push_back(llvm::ConstantInt::get( 1356263508Sdim CGM.IntTy, NonVirtualBaseAdjustment.getQuantity())); 1357251662Sdim 1358251662Sdim if (hasVBPtrOffsetField(Inheritance)) { 1359263508Sdim CharUnits Offs = CharUnits::Zero(); 1360263508Sdim if (RD->getNumVBases()) 1361263508Sdim Offs = GetVBPtrOffsetFromBases(RD); 1362263508Sdim fields.push_back(llvm::ConstantInt::get(CGM.IntTy, Offs.getQuantity())); 1363251662Sdim } 1364251662Sdim 1365251662Sdim // The rest of the fields are adjusted by conversions to a more derived class. 1366251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 1367251662Sdim fields.push_back(getZeroInt()); 1368251662Sdim 1369251662Sdim return llvm::ConstantStruct::getAnon(fields); 1370251662Sdim} 1371251662Sdim 1372251662Sdimllvm::Constant * 1373249423SdimMicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, 1374249423Sdim CharUnits offset) { 1375251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1376251662Sdim llvm::Constant *FirstField = 1377251662Sdim llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()); 1378263508Sdim return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD, 1379263508Sdim CharUnits::Zero()); 1380249423Sdim} 1381249423Sdim 1382263508Sdimllvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { 1383263508Sdim return BuildMemberPointer(MD->getParent(), MD, CharUnits::Zero()); 1384263508Sdim} 1385263508Sdim 1386263508Sdimllvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP, 1387263508Sdim QualType MPType) { 1388263508Sdim const MemberPointerType *MPT = MPType->castAs<MemberPointerType>(); 1389263508Sdim const ValueDecl *MPD = MP.getMemberPointerDecl(); 1390263508Sdim if (!MPD) 1391263508Sdim return EmitNullMemberPointer(MPT); 1392263508Sdim 1393263508Sdim CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP); 1394263508Sdim 1395263508Sdim // FIXME PR15713: Support virtual inheritance paths. 1396263508Sdim 1397263508Sdim if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) 1398263508Sdim return BuildMemberPointer(MPT->getClass()->getAsCXXRecordDecl(), 1399263508Sdim MD, ThisAdjustment); 1400263508Sdim 1401263508Sdim CharUnits FieldOffset = 1402263508Sdim getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); 1403263508Sdim return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); 1404263508Sdim} 1405263508Sdim 1406251662Sdimllvm::Constant * 1407263508SdimMicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD, 1408263508Sdim const CXXMethodDecl *MD, 1409263508Sdim CharUnits NonVirtualBaseAdjustment) { 1410251662Sdim assert(MD->isInstance() && "Member function must not be static!"); 1411251662Sdim MD = MD->getCanonicalDecl(); 1412251662Sdim CodeGenTypes &Types = CGM.getTypes(); 1413251662Sdim 1414251662Sdim llvm::Constant *FirstField; 1415263508Sdim if (!MD->isVirtual()) { 1416251662Sdim const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); 1417251662Sdim llvm::Type *Ty; 1418251662Sdim // Check whether the function has a computable LLVM signature. 1419251662Sdim if (Types.isFuncTypeConvertible(FPT)) { 1420251662Sdim // The function has a computable LLVM signature; use the correct type. 1421251662Sdim Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD)); 1422251662Sdim } else { 1423251662Sdim // Use an arbitrary non-function type to tell GetAddrOfFunction that the 1424251662Sdim // function type is incomplete. 1425251662Sdim Ty = CGM.PtrDiffTy; 1426251662Sdim } 1427251662Sdim FirstField = CGM.GetAddrOfFunction(MD, Ty); 1428251662Sdim FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy); 1429263508Sdim } else { 1430263508Sdim MicrosoftVTableContext::MethodVFTableLocation ML = 1431263508Sdim CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD); 1432263508Sdim if (MD->isVariadic()) { 1433263508Sdim CGM.ErrorUnsupported(MD, "pointer to variadic virtual member function"); 1434263508Sdim FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); 1435263508Sdim } else if (!CGM.getTypes().isFuncTypeConvertible( 1436263508Sdim MD->getType()->castAs<FunctionType>())) { 1437263508Sdim CGM.ErrorUnsupported(MD, "pointer to virtual member function with " 1438263508Sdim "incomplete return or parameter type"); 1439263508Sdim FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); 1440263508Sdim } else if (ML.VBase) { 1441263508Sdim CGM.ErrorUnsupported(MD, "pointer to virtual member function overriding " 1442263508Sdim "member function in virtual base class"); 1443263508Sdim FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); 1444263508Sdim } else { 1445263508Sdim SmallString<256> ThunkName; 1446263508Sdim CharUnits PointerWidth = getContext().toCharUnitsFromBits( 1447263508Sdim getContext().getTargetInfo().getPointerWidth(0)); 1448263508Sdim uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity(); 1449263508Sdim llvm::raw_svector_ostream Out(ThunkName); 1450263508Sdim getMangleContext().mangleVirtualMemPtrThunk(MD, OffsetInVFTable, Out); 1451263508Sdim Out.flush(); 1452263508Sdim 1453263508Sdim llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ThunkName.str()); 1454263508Sdim FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy); 1455263508Sdim } 1456251662Sdim } 1457251662Sdim 1458251662Sdim // The rest of the fields are common with data member pointers. 1459263508Sdim return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD, 1460263508Sdim NonVirtualBaseAdjustment); 1461251662Sdim} 1462251662Sdim 1463251662Sdim/// Member pointers are the same if they're either bitwise identical *or* both 1464251662Sdim/// null. Null-ness for function members is determined by the first field, 1465251662Sdim/// while for data member pointers we must compare all fields. 1466249423Sdimllvm::Value * 1467251662SdimMicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, 1468251662Sdim llvm::Value *L, 1469251662Sdim llvm::Value *R, 1470251662Sdim const MemberPointerType *MPT, 1471251662Sdim bool Inequality) { 1472251662Sdim CGBuilderTy &Builder = CGF.Builder; 1473251662Sdim 1474251662Sdim // Handle != comparisons by switching the sense of all boolean operations. 1475251662Sdim llvm::ICmpInst::Predicate Eq; 1476251662Sdim llvm::Instruction::BinaryOps And, Or; 1477251662Sdim if (Inequality) { 1478251662Sdim Eq = llvm::ICmpInst::ICMP_NE; 1479251662Sdim And = llvm::Instruction::Or; 1480251662Sdim Or = llvm::Instruction::And; 1481251662Sdim } else { 1482251662Sdim Eq = llvm::ICmpInst::ICMP_EQ; 1483251662Sdim And = llvm::Instruction::And; 1484251662Sdim Or = llvm::Instruction::Or; 1485251662Sdim } 1486251662Sdim 1487251662Sdim // If this is a single field member pointer (single inheritance), this is a 1488251662Sdim // single icmp. 1489251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1490251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1491263508Sdim if (hasOnlyOneField(MPT->isMemberFunctionPointer(), Inheritance)) 1492251662Sdim return Builder.CreateICmp(Eq, L, R); 1493251662Sdim 1494251662Sdim // Compare the first field. 1495251662Sdim llvm::Value *L0 = Builder.CreateExtractValue(L, 0, "lhs.0"); 1496251662Sdim llvm::Value *R0 = Builder.CreateExtractValue(R, 0, "rhs.0"); 1497251662Sdim llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0, "memptr.cmp.first"); 1498251662Sdim 1499251662Sdim // Compare everything other than the first field. 1500251662Sdim llvm::Value *Res = 0; 1501251662Sdim llvm::StructType *LType = cast<llvm::StructType>(L->getType()); 1502251662Sdim for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) { 1503251662Sdim llvm::Value *LF = Builder.CreateExtractValue(L, I); 1504251662Sdim llvm::Value *RF = Builder.CreateExtractValue(R, I); 1505251662Sdim llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF, "memptr.cmp.rest"); 1506251662Sdim if (Res) 1507251662Sdim Res = Builder.CreateBinOp(And, Res, Cmp); 1508251662Sdim else 1509251662Sdim Res = Cmp; 1510251662Sdim } 1511251662Sdim 1512251662Sdim // Check if the first field is 0 if this is a function pointer. 1513251662Sdim if (MPT->isMemberFunctionPointer()) { 1514251662Sdim // (l1 == r1 && ...) || l0 == 0 1515251662Sdim llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType()); 1516251662Sdim llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero, "memptr.cmp.iszero"); 1517251662Sdim Res = Builder.CreateBinOp(Or, Res, IsZero); 1518251662Sdim } 1519251662Sdim 1520251662Sdim // Combine the comparison of the first field, which must always be true for 1521251662Sdim // this comparison to succeeed. 1522251662Sdim return Builder.CreateBinOp(And, Res, Cmp0, "memptr.cmp"); 1523251662Sdim} 1524251662Sdim 1525251662Sdimllvm::Value * 1526249423SdimMicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 1527249423Sdim llvm::Value *MemPtr, 1528249423Sdim const MemberPointerType *MPT) { 1529249423Sdim CGBuilderTy &Builder = CGF.Builder; 1530251662Sdim llvm::SmallVector<llvm::Constant *, 4> fields; 1531251662Sdim // We only need one field for member functions. 1532251662Sdim if (MPT->isMemberFunctionPointer()) 1533251662Sdim fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); 1534251662Sdim else 1535251662Sdim GetNullMemberPointerFields(MPT, fields); 1536251662Sdim assert(!fields.empty()); 1537251662Sdim llvm::Value *FirstField = MemPtr; 1538251662Sdim if (MemPtr->getType()->isStructTy()) 1539251662Sdim FirstField = Builder.CreateExtractValue(MemPtr, 0); 1540251662Sdim llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0], "memptr.cmp0"); 1541249423Sdim 1542251662Sdim // For function member pointers, we only need to test the function pointer 1543251662Sdim // field. The other fields if any can be garbage. 1544251662Sdim if (MPT->isMemberFunctionPointer()) 1545251662Sdim return Res; 1546251662Sdim 1547251662Sdim // Otherwise, emit a series of compares and combine the results. 1548251662Sdim for (int I = 1, E = fields.size(); I < E; ++I) { 1549251662Sdim llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I); 1550251662Sdim llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp"); 1551251662Sdim Res = Builder.CreateAnd(Res, Next, "memptr.tobool"); 1552249423Sdim } 1553251662Sdim return Res; 1554251662Sdim} 1555249423Sdim 1556263508Sdimbool MicrosoftCXXABI::MemberPointerConstantIsNull(const MemberPointerType *MPT, 1557263508Sdim llvm::Constant *Val) { 1558263508Sdim // Function pointers are null if the pointer in the first field is null. 1559263508Sdim if (MPT->isMemberFunctionPointer()) { 1560263508Sdim llvm::Constant *FirstField = Val->getType()->isStructTy() ? 1561263508Sdim Val->getAggregateElement(0U) : Val; 1562263508Sdim return FirstField->isNullValue(); 1563263508Sdim } 1564263508Sdim 1565263508Sdim // If it's not a function pointer and it's zero initializable, we can easily 1566263508Sdim // check zero. 1567263508Sdim if (isZeroInitializable(MPT) && Val->isNullValue()) 1568263508Sdim return true; 1569263508Sdim 1570263508Sdim // Otherwise, break down all the fields for comparison. Hopefully these 1571263508Sdim // little Constants are reused, while a big null struct might not be. 1572263508Sdim llvm::SmallVector<llvm::Constant *, 4> Fields; 1573263508Sdim GetNullMemberPointerFields(MPT, Fields); 1574263508Sdim if (Fields.size() == 1) { 1575263508Sdim assert(Val->getType()->isIntegerTy()); 1576263508Sdim return Val == Fields[0]; 1577263508Sdim } 1578263508Sdim 1579263508Sdim unsigned I, E; 1580263508Sdim for (I = 0, E = Fields.size(); I != E; ++I) { 1581263508Sdim if (Val->getAggregateElement(I) != Fields[I]) 1582263508Sdim break; 1583263508Sdim } 1584263508Sdim return I == E; 1585263508Sdim} 1586263508Sdim 1587263508Sdimllvm::Value * 1588263508SdimMicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, 1589263508Sdim llvm::Value *This, 1590263508Sdim llvm::Value *VBPtrOffset, 1591263508Sdim llvm::Value *VBTableOffset, 1592263508Sdim llvm::Value **VBPtrOut) { 1593263508Sdim CGBuilderTy &Builder = CGF.Builder; 1594263508Sdim // Load the vbtable pointer from the vbptr in the instance. 1595263508Sdim This = Builder.CreateBitCast(This, CGM.Int8PtrTy); 1596263508Sdim llvm::Value *VBPtr = 1597263508Sdim Builder.CreateInBoundsGEP(This, VBPtrOffset, "vbptr"); 1598263508Sdim if (VBPtrOut) *VBPtrOut = VBPtr; 1599263508Sdim VBPtr = Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0)); 1600263508Sdim llvm::Value *VBTable = Builder.CreateLoad(VBPtr, "vbtable"); 1601263508Sdim 1602263508Sdim // Load an i32 offset from the vb-table. 1603263508Sdim llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableOffset); 1604263508Sdim VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0)); 1605263508Sdim return Builder.CreateLoad(VBaseOffs, "vbase_offs"); 1606263508Sdim} 1607263508Sdim 1608251662Sdim// Returns an adjusted base cast to i8*, since we do more address arithmetic on 1609251662Sdim// it. 1610251662Sdimllvm::Value * 1611251662SdimMicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF, 1612251662Sdim const CXXRecordDecl *RD, llvm::Value *Base, 1613263508Sdim llvm::Value *VBTableOffset, 1614251662Sdim llvm::Value *VBPtrOffset) { 1615251662Sdim CGBuilderTy &Builder = CGF.Builder; 1616251662Sdim Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy); 1617251662Sdim llvm::BasicBlock *OriginalBB = 0; 1618251662Sdim llvm::BasicBlock *SkipAdjustBB = 0; 1619251662Sdim llvm::BasicBlock *VBaseAdjustBB = 0; 1620251662Sdim 1621251662Sdim // In the unspecified inheritance model, there might not be a vbtable at all, 1622251662Sdim // in which case we need to skip the virtual base lookup. If there is a 1623251662Sdim // vbtable, the first entry is a no-op entry that gives back the original 1624251662Sdim // base, so look for a virtual base adjustment offset of zero. 1625251662Sdim if (VBPtrOffset) { 1626251662Sdim OriginalBB = Builder.GetInsertBlock(); 1627251662Sdim VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust"); 1628251662Sdim SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust"); 1629251662Sdim llvm::Value *IsVirtual = 1630263508Sdim Builder.CreateICmpNE(VBTableOffset, getZeroInt(), 1631251662Sdim "memptr.is_vbase"); 1632251662Sdim Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB); 1633251662Sdim CGF.EmitBlock(VBaseAdjustBB); 1634251662Sdim } 1635251662Sdim 1636251662Sdim // If we weren't given a dynamic vbptr offset, RD should be complete and we'll 1637251662Sdim // know the vbptr offset. 1638251662Sdim if (!VBPtrOffset) { 1639263508Sdim CharUnits offs = CharUnits::Zero(); 1640263508Sdim if (RD->getNumVBases()) { 1641263508Sdim offs = GetVBPtrOffsetFromBases(RD); 1642263508Sdim } 1643251662Sdim VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity()); 1644251662Sdim } 1645263508Sdim llvm::Value *VBPtr = 0; 1646251662Sdim llvm::Value *VBaseOffs = 1647263508Sdim GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr); 1648251662Sdim llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs); 1649251662Sdim 1650251662Sdim // Merge control flow with the case where we didn't have to adjust. 1651251662Sdim if (VBaseAdjustBB) { 1652251662Sdim Builder.CreateBr(SkipAdjustBB); 1653251662Sdim CGF.EmitBlock(SkipAdjustBB); 1654251662Sdim llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base"); 1655251662Sdim Phi->addIncoming(Base, OriginalBB); 1656251662Sdim Phi->addIncoming(AdjustedBase, VBaseAdjustBB); 1657251662Sdim return Phi; 1658251662Sdim } 1659251662Sdim return AdjustedBase; 1660249423Sdim} 1661249423Sdim 1662249423Sdimllvm::Value * 1663249423SdimMicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, 1664249423Sdim llvm::Value *Base, 1665249423Sdim llvm::Value *MemPtr, 1666249423Sdim const MemberPointerType *MPT) { 1667251662Sdim assert(MPT->isMemberDataPointer()); 1668249423Sdim unsigned AS = Base->getType()->getPointerAddressSpace(); 1669249423Sdim llvm::Type *PType = 1670249423Sdim CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS); 1671249423Sdim CGBuilderTy &Builder = CGF.Builder; 1672251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1673251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1674249423Sdim 1675251662Sdim // Extract the fields we need, regardless of model. We'll apply them if we 1676251662Sdim // have them. 1677251662Sdim llvm::Value *FieldOffset = MemPtr; 1678251662Sdim llvm::Value *VirtualBaseAdjustmentOffset = 0; 1679251662Sdim llvm::Value *VBPtrOffset = 0; 1680251662Sdim if (MemPtr->getType()->isStructTy()) { 1681251662Sdim // We need to extract values. 1682251662Sdim unsigned I = 0; 1683251662Sdim FieldOffset = Builder.CreateExtractValue(MemPtr, I++); 1684251662Sdim if (hasVBPtrOffsetField(Inheritance)) 1685251662Sdim VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); 1686251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 1687251662Sdim VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); 1688249423Sdim } 1689249423Sdim 1690251662Sdim if (VirtualBaseAdjustmentOffset) { 1691251662Sdim Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset, 1692251662Sdim VBPtrOffset); 1693249423Sdim } 1694251662Sdim llvm::Value *Addr = 1695251662Sdim Builder.CreateInBoundsGEP(Base, FieldOffset, "memptr.offset"); 1696249423Sdim 1697249423Sdim // Cast the address to the appropriate pointer type, adopting the address 1698249423Sdim // space of the base pointer. 1699249423Sdim return Builder.CreateBitCast(Addr, PType); 1700249423Sdim} 1701249423Sdim 1702263508Sdimstatic MSInheritanceModel 1703263508SdimgetInheritanceFromMemptr(const MemberPointerType *MPT) { 1704263508Sdim return MPT->getClass()->getAsCXXRecordDecl()->getMSInheritanceModel(); 1705263508Sdim} 1706263508Sdim 1707251662Sdimllvm::Value * 1708263508SdimMicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, 1709263508Sdim const CastExpr *E, 1710263508Sdim llvm::Value *Src) { 1711263508Sdim assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 1712263508Sdim E->getCastKind() == CK_BaseToDerivedMemberPointer || 1713263508Sdim E->getCastKind() == CK_ReinterpretMemberPointer); 1714263508Sdim 1715263508Sdim // Use constant emission if we can. 1716263508Sdim if (isa<llvm::Constant>(Src)) 1717263508Sdim return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src)); 1718263508Sdim 1719263508Sdim // We may be adding or dropping fields from the member pointer, so we need 1720263508Sdim // both types and the inheritance models of both records. 1721263508Sdim const MemberPointerType *SrcTy = 1722263508Sdim E->getSubExpr()->getType()->castAs<MemberPointerType>(); 1723263508Sdim const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); 1724263508Sdim MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy); 1725263508Sdim MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy); 1726263508Sdim bool IsFunc = SrcTy->isMemberFunctionPointer(); 1727263508Sdim 1728263508Sdim // If the classes use the same null representation, reinterpret_cast is a nop. 1729263508Sdim bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer; 1730263508Sdim if (IsReinterpret && (IsFunc || 1731263508Sdim nullFieldOffsetIsZero(SrcInheritance) == 1732263508Sdim nullFieldOffsetIsZero(DstInheritance))) 1733263508Sdim return Src; 1734263508Sdim 1735263508Sdim CGBuilderTy &Builder = CGF.Builder; 1736263508Sdim 1737263508Sdim // Branch past the conversion if Src is null. 1738263508Sdim llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy); 1739263508Sdim llvm::Constant *DstNull = EmitNullMemberPointer(DstTy); 1740263508Sdim 1741263508Sdim // C++ 5.2.10p9: The null member pointer value is converted to the null member 1742263508Sdim // pointer value of the destination type. 1743263508Sdim if (IsReinterpret) { 1744263508Sdim // For reinterpret casts, sema ensures that src and dst are both functions 1745263508Sdim // or data and have the same size, which means the LLVM types should match. 1746263508Sdim assert(Src->getType() == DstNull->getType()); 1747263508Sdim return Builder.CreateSelect(IsNotNull, Src, DstNull); 1748263508Sdim } 1749263508Sdim 1750263508Sdim llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock(); 1751263508Sdim llvm::BasicBlock *ConvertBB = CGF.createBasicBlock("memptr.convert"); 1752263508Sdim llvm::BasicBlock *ContinueBB = CGF.createBasicBlock("memptr.converted"); 1753263508Sdim Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB); 1754263508Sdim CGF.EmitBlock(ConvertBB); 1755263508Sdim 1756263508Sdim // Decompose src. 1757263508Sdim llvm::Value *FirstField = Src; 1758263508Sdim llvm::Value *NonVirtualBaseAdjustment = 0; 1759263508Sdim llvm::Value *VirtualBaseAdjustmentOffset = 0; 1760263508Sdim llvm::Value *VBPtrOffset = 0; 1761263508Sdim if (!hasOnlyOneField(IsFunc, SrcInheritance)) { 1762263508Sdim // We need to extract values. 1763263508Sdim unsigned I = 0; 1764263508Sdim FirstField = Builder.CreateExtractValue(Src, I++); 1765263508Sdim if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance)) 1766263508Sdim NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++); 1767263508Sdim if (hasVBPtrOffsetField(SrcInheritance)) 1768263508Sdim VBPtrOffset = Builder.CreateExtractValue(Src, I++); 1769263508Sdim if (hasVirtualBaseAdjustmentField(SrcInheritance)) 1770263508Sdim VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++); 1771263508Sdim } 1772263508Sdim 1773263508Sdim // For data pointers, we adjust the field offset directly. For functions, we 1774263508Sdim // have a separate field. 1775263508Sdim llvm::Constant *Adj = getMemberPointerAdjustment(E); 1776263508Sdim if (Adj) { 1777263508Sdim Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); 1778263508Sdim llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField; 1779263508Sdim bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 1780263508Sdim if (!NVAdjustField) // If this field didn't exist in src, it's zero. 1781263508Sdim NVAdjustField = getZeroInt(); 1782263508Sdim if (isDerivedToBase) 1783263508Sdim NVAdjustField = Builder.CreateNSWSub(NVAdjustField, Adj, "adj"); 1784263508Sdim else 1785263508Sdim NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, Adj, "adj"); 1786263508Sdim } 1787263508Sdim 1788263508Sdim // FIXME PR15713: Support conversions through virtually derived classes. 1789263508Sdim 1790263508Sdim // Recompose dst from the null struct and the adjusted fields from src. 1791263508Sdim llvm::Value *Dst; 1792263508Sdim if (hasOnlyOneField(IsFunc, DstInheritance)) { 1793263508Sdim Dst = FirstField; 1794263508Sdim } else { 1795263508Sdim Dst = llvm::UndefValue::get(DstNull->getType()); 1796263508Sdim unsigned Idx = 0; 1797263508Sdim Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++); 1798263508Sdim if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance)) 1799263508Sdim Dst = Builder.CreateInsertValue( 1800263508Sdim Dst, getValueOrZeroInt(NonVirtualBaseAdjustment), Idx++); 1801263508Sdim if (hasVBPtrOffsetField(DstInheritance)) 1802263508Sdim Dst = Builder.CreateInsertValue( 1803263508Sdim Dst, getValueOrZeroInt(VBPtrOffset), Idx++); 1804263508Sdim if (hasVirtualBaseAdjustmentField(DstInheritance)) 1805263508Sdim Dst = Builder.CreateInsertValue( 1806263508Sdim Dst, getValueOrZeroInt(VirtualBaseAdjustmentOffset), Idx++); 1807263508Sdim } 1808263508Sdim Builder.CreateBr(ContinueBB); 1809263508Sdim 1810263508Sdim // In the continuation, choose between DstNull and Dst. 1811263508Sdim CGF.EmitBlock(ContinueBB); 1812263508Sdim llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2, "memptr.converted"); 1813263508Sdim Phi->addIncoming(DstNull, OriginalBB); 1814263508Sdim Phi->addIncoming(Dst, ConvertBB); 1815263508Sdim return Phi; 1816263508Sdim} 1817263508Sdim 1818263508Sdimllvm::Constant * 1819263508SdimMicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E, 1820263508Sdim llvm::Constant *Src) { 1821263508Sdim const MemberPointerType *SrcTy = 1822263508Sdim E->getSubExpr()->getType()->castAs<MemberPointerType>(); 1823263508Sdim const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); 1824263508Sdim 1825263508Sdim // If src is null, emit a new null for dst. We can't return src because dst 1826263508Sdim // might have a new representation. 1827263508Sdim if (MemberPointerConstantIsNull(SrcTy, Src)) 1828263508Sdim return EmitNullMemberPointer(DstTy); 1829263508Sdim 1830263508Sdim // We don't need to do anything for reinterpret_casts of non-null member 1831263508Sdim // pointers. We should only get here when the two type representations have 1832263508Sdim // the same size. 1833263508Sdim if (E->getCastKind() == CK_ReinterpretMemberPointer) 1834263508Sdim return Src; 1835263508Sdim 1836263508Sdim MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy); 1837263508Sdim MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy); 1838263508Sdim 1839263508Sdim // Decompose src. 1840263508Sdim llvm::Constant *FirstField = Src; 1841263508Sdim llvm::Constant *NonVirtualBaseAdjustment = 0; 1842263508Sdim llvm::Constant *VirtualBaseAdjustmentOffset = 0; 1843263508Sdim llvm::Constant *VBPtrOffset = 0; 1844263508Sdim bool IsFunc = SrcTy->isMemberFunctionPointer(); 1845263508Sdim if (!hasOnlyOneField(IsFunc, SrcInheritance)) { 1846263508Sdim // We need to extract values. 1847263508Sdim unsigned I = 0; 1848263508Sdim FirstField = Src->getAggregateElement(I++); 1849263508Sdim if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance)) 1850263508Sdim NonVirtualBaseAdjustment = Src->getAggregateElement(I++); 1851263508Sdim if (hasVBPtrOffsetField(SrcInheritance)) 1852263508Sdim VBPtrOffset = Src->getAggregateElement(I++); 1853263508Sdim if (hasVirtualBaseAdjustmentField(SrcInheritance)) 1854263508Sdim VirtualBaseAdjustmentOffset = Src->getAggregateElement(I++); 1855263508Sdim } 1856263508Sdim 1857263508Sdim // For data pointers, we adjust the field offset directly. For functions, we 1858263508Sdim // have a separate field. 1859263508Sdim llvm::Constant *Adj = getMemberPointerAdjustment(E); 1860263508Sdim if (Adj) { 1861263508Sdim Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); 1862263508Sdim llvm::Constant *&NVAdjustField = 1863263508Sdim IsFunc ? NonVirtualBaseAdjustment : FirstField; 1864263508Sdim bool IsDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 1865263508Sdim if (!NVAdjustField) // If this field didn't exist in src, it's zero. 1866263508Sdim NVAdjustField = getZeroInt(); 1867263508Sdim if (IsDerivedToBase) 1868263508Sdim NVAdjustField = llvm::ConstantExpr::getNSWSub(NVAdjustField, Adj); 1869263508Sdim else 1870263508Sdim NVAdjustField = llvm::ConstantExpr::getNSWAdd(NVAdjustField, Adj); 1871263508Sdim } 1872263508Sdim 1873263508Sdim // FIXME PR15713: Support conversions through virtually derived classes. 1874263508Sdim 1875263508Sdim // Recompose dst from the null struct and the adjusted fields from src. 1876263508Sdim if (hasOnlyOneField(IsFunc, DstInheritance)) 1877263508Sdim return FirstField; 1878263508Sdim 1879263508Sdim llvm::SmallVector<llvm::Constant *, 4> Fields; 1880263508Sdim Fields.push_back(FirstField); 1881263508Sdim if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance)) 1882263508Sdim Fields.push_back(getConstantOrZeroInt(NonVirtualBaseAdjustment)); 1883263508Sdim if (hasVBPtrOffsetField(DstInheritance)) 1884263508Sdim Fields.push_back(getConstantOrZeroInt(VBPtrOffset)); 1885263508Sdim if (hasVirtualBaseAdjustmentField(DstInheritance)) 1886263508Sdim Fields.push_back(getConstantOrZeroInt(VirtualBaseAdjustmentOffset)); 1887263508Sdim return llvm::ConstantStruct::getAnon(Fields); 1888263508Sdim} 1889263508Sdim 1890263508Sdimllvm::Value * 1891251662SdimMicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 1892251662Sdim llvm::Value *&This, 1893251662Sdim llvm::Value *MemPtr, 1894251662Sdim const MemberPointerType *MPT) { 1895251662Sdim assert(MPT->isMemberFunctionPointer()); 1896251662Sdim const FunctionProtoType *FPT = 1897251662Sdim MPT->getPointeeType()->castAs<FunctionProtoType>(); 1898251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1899251662Sdim llvm::FunctionType *FTy = 1900251662Sdim CGM.getTypes().GetFunctionType( 1901251662Sdim CGM.getTypes().arrangeCXXMethodType(RD, FPT)); 1902251662Sdim CGBuilderTy &Builder = CGF.Builder; 1903251662Sdim 1904251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1905251662Sdim 1906251662Sdim // Extract the fields we need, regardless of model. We'll apply them if we 1907251662Sdim // have them. 1908251662Sdim llvm::Value *FunctionPointer = MemPtr; 1909251662Sdim llvm::Value *NonVirtualBaseAdjustment = NULL; 1910251662Sdim llvm::Value *VirtualBaseAdjustmentOffset = NULL; 1911251662Sdim llvm::Value *VBPtrOffset = NULL; 1912251662Sdim if (MemPtr->getType()->isStructTy()) { 1913251662Sdim // We need to extract values. 1914251662Sdim unsigned I = 0; 1915251662Sdim FunctionPointer = Builder.CreateExtractValue(MemPtr, I++); 1916251662Sdim if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance)) 1917251662Sdim NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++); 1918251662Sdim if (hasVBPtrOffsetField(Inheritance)) 1919251662Sdim VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); 1920251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 1921251662Sdim VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); 1922251662Sdim } 1923251662Sdim 1924251662Sdim if (VirtualBaseAdjustmentOffset) { 1925251662Sdim This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset, 1926251662Sdim VBPtrOffset); 1927251662Sdim } 1928251662Sdim 1929251662Sdim if (NonVirtualBaseAdjustment) { 1930251662Sdim // Apply the adjustment and cast back to the original struct type. 1931251662Sdim llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy()); 1932251662Sdim Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment); 1933251662Sdim This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted"); 1934251662Sdim } 1935251662Sdim 1936251662Sdim return Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo()); 1937251662Sdim} 1938251662Sdim 1939212904SdimCGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) { 1940210008Srdivacky return new MicrosoftCXXABI(CGM); 1941210008Srdivacky} 1942