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" 19210008Srdivacky#include "clang/AST/Decl.h" 20210008Srdivacky#include "clang/AST/DeclCXX.h" 21210008Srdivacky 22210008Srdivackyusing namespace clang; 23210008Srdivackyusing namespace CodeGen; 24210008Srdivacky 25210008Srdivackynamespace { 26210008Srdivacky 27212904Sdimclass MicrosoftCXXABI : public CGCXXABI { 28210008Srdivackypublic: 29218893Sdim MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {} 30210008Srdivacky 31251662Sdim bool isReturnTypeIndirect(const CXXRecordDecl *RD) const { 32251662Sdim // Structures that are not C++03 PODs are always indirect. 33251662Sdim return !RD->isPOD(); 34251662Sdim } 35251662Sdim 36251662Sdim RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const { 37251662Sdim if (RD->hasNonTrivialCopyConstructor()) 38251662Sdim return RAA_DirectInMemory; 39251662Sdim return RAA_Default; 40251662Sdim } 41251662Sdim 42239462Sdim StringRef GetPureVirtualCallName() { return "_purecall"; } 43243830Sdim // No known support for deleted functions in MSVC yet, so this choice is 44243830Sdim // arbitrary. 45243830Sdim StringRef GetDeletedVirtualCallName() { return "_purecall"; } 46239462Sdim 47243830Sdim llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, 48243830Sdim llvm::Value *ptr, 49243830Sdim QualType type); 50243830Sdim 51212904Sdim void BuildConstructorSignature(const CXXConstructorDecl *Ctor, 52212904Sdim CXXCtorType Type, 53212904Sdim CanQualType &ResTy, 54243830Sdim SmallVectorImpl<CanQualType> &ArgTys); 55212904Sdim 56249423Sdim llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF); 57249423Sdim 58212904Sdim void BuildDestructorSignature(const CXXDestructorDecl *Ctor, 59212904Sdim CXXDtorType Type, 60212904Sdim CanQualType &ResTy, 61249423Sdim SmallVectorImpl<CanQualType> &ArgTys); 62212904Sdim 63212904Sdim void BuildInstanceFunctionParams(CodeGenFunction &CGF, 64212904Sdim QualType &ResTy, 65243830Sdim FunctionArgList &Params); 66212904Sdim 67243830Sdim void EmitInstanceFunctionProlog(CodeGenFunction &CGF); 68218893Sdim 69249423Sdim llvm::Value *EmitConstructorCall(CodeGenFunction &CGF, 70249423Sdim const CXXConstructorDecl *D, 71249423Sdim CXXCtorType Type, bool ForVirtualBase, 72249423Sdim bool Delegating, 73249423Sdim llvm::Value *This, 74249423Sdim CallExpr::const_arg_iterator ArgBeg, 75249423Sdim CallExpr::const_arg_iterator ArgEnd); 76249423Sdim 77249423Sdim RValue EmitVirtualDestructorCall(CodeGenFunction &CGF, 78249423Sdim const CXXDestructorDecl *Dtor, 79249423Sdim CXXDtorType DtorType, 80249423Sdim SourceLocation CallLoc, 81249423Sdim ReturnValueSlot ReturnValue, 82249423Sdim llvm::Value *This); 83249423Sdim 84239462Sdim void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 85239462Sdim llvm::GlobalVariable *DeclPtr, 86239462Sdim bool PerformInit); 87239462Sdim 88218893Sdim // ==== Notes on array cookies ========= 89218893Sdim // 90218893Sdim // MSVC seems to only use cookies when the class has a destructor; a 91218893Sdim // two-argument usual array deallocation function isn't sufficient. 92218893Sdim // 93218893Sdim // For example, this code prints "100" and "1": 94218893Sdim // struct A { 95218893Sdim // char x; 96218893Sdim // void *operator new[](size_t sz) { 97218893Sdim // printf("%u\n", sz); 98218893Sdim // return malloc(sz); 99218893Sdim // } 100218893Sdim // void operator delete[](void *p, size_t sz) { 101218893Sdim // printf("%u\n", sz); 102218893Sdim // free(p); 103218893Sdim // } 104218893Sdim // }; 105218893Sdim // int main() { 106218893Sdim // A *p = new A[100]; 107218893Sdim // delete[] p; 108218893Sdim // } 109218893Sdim // Whereas it prints "104" and "104" if you give A a destructor. 110239462Sdim 111239462Sdim bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType); 112239462Sdim bool requiresArrayCookie(const CXXNewExpr *expr); 113239462Sdim CharUnits getArrayCookieSizeImpl(QualType type); 114239462Sdim llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, 115239462Sdim llvm::Value *NewPtr, 116239462Sdim llvm::Value *NumElements, 117239462Sdim const CXXNewExpr *expr, 118239462Sdim QualType ElementType); 119239462Sdim llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, 120239462Sdim llvm::Value *allocPtr, 121239462Sdim CharUnits cookieSize); 122243830Sdim static bool needThisReturn(GlobalDecl GD); 123249423Sdim 124249423Sdimprivate: 125251662Sdim llvm::Constant *getZeroInt() { 126251662Sdim return llvm::ConstantInt::get(CGM.IntTy, 0); 127249423Sdim } 128249423Sdim 129251662Sdim llvm::Constant *getAllOnesInt() { 130251662Sdim return llvm::Constant::getAllOnesValue(CGM.IntTy); 131249423Sdim } 132249423Sdim 133251662Sdim void 134251662Sdim GetNullMemberPointerFields(const MemberPointerType *MPT, 135251662Sdim llvm::SmallVectorImpl<llvm::Constant *> &fields); 136251662Sdim 137251662Sdim llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD, 138251662Sdim llvm::Value *Base, 139251662Sdim llvm::Value *VirtualBaseAdjustmentOffset, 140251662Sdim llvm::Value *VBPtrOffset /* optional */); 141251662Sdim 142251662Sdim /// \brief Emits a full member pointer with the fields common to data and 143251662Sdim /// function member pointers. 144251662Sdim llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField, 145251662Sdim bool IsMemberFunction, 146251662Sdim const CXXRecordDecl *RD); 147251662Sdim 148249423Sdimpublic: 149251662Sdim virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT); 150251662Sdim 151251662Sdim virtual bool isZeroInitializable(const MemberPointerType *MPT); 152251662Sdim 153249423Sdim virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); 154249423Sdim 155249423Sdim virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, 156249423Sdim CharUnits offset); 157251662Sdim virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); 158251662Sdim virtual llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT); 159249423Sdim 160251662Sdim virtual llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, 161251662Sdim llvm::Value *L, 162251662Sdim llvm::Value *R, 163251662Sdim const MemberPointerType *MPT, 164251662Sdim bool Inequality); 165251662Sdim 166249423Sdim virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 167249423Sdim llvm::Value *MemPtr, 168249423Sdim const MemberPointerType *MPT); 169249423Sdim 170249423Sdim virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, 171249423Sdim llvm::Value *Base, 172249423Sdim llvm::Value *MemPtr, 173249423Sdim const MemberPointerType *MPT); 174249423Sdim 175251662Sdim virtual llvm::Value * 176251662Sdim EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 177251662Sdim llvm::Value *&This, 178251662Sdim llvm::Value *MemPtr, 179251662Sdim const MemberPointerType *MPT); 180251662Sdim 181210008Srdivacky}; 182210008Srdivacky 183210008Srdivacky} 184210008Srdivacky 185243830Sdimllvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF, 186243830Sdim llvm::Value *ptr, 187243830Sdim QualType type) { 188243830Sdim // FIXME: implement 189243830Sdim return ptr; 190243830Sdim} 191243830Sdim 192243830Sdimbool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) { 193243830Sdim const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); 194243830Sdim return isa<CXXConstructorDecl>(MD); 195243830Sdim} 196243830Sdim 197243830Sdimvoid MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, 198243830Sdim CXXCtorType Type, 199243830Sdim CanQualType &ResTy, 200243830Sdim SmallVectorImpl<CanQualType> &ArgTys) { 201243830Sdim // 'this' is already in place 202249423Sdim 203243830Sdim // Ctor returns this ptr 204243830Sdim ResTy = ArgTys[0]; 205249423Sdim 206249423Sdim const CXXRecordDecl *Class = Ctor->getParent(); 207249423Sdim if (Class->getNumVBases()) { 208249423Sdim // Constructors of classes with virtual bases take an implicit parameter. 209249423Sdim ArgTys.push_back(CGM.getContext().IntTy); 210249423Sdim } 211243830Sdim} 212243830Sdim 213249423Sdimllvm::BasicBlock *MicrosoftCXXABI::EmitCtorCompleteObjectHandler( 214249423Sdim CodeGenFunction &CGF) { 215249423Sdim llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF); 216249423Sdim assert(IsMostDerivedClass && 217249423Sdim "ctor for a class with virtual bases must have an implicit parameter"); 218249423Sdim llvm::Value *IsCompleteObject 219249423Sdim = CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object"); 220249423Sdim 221249423Sdim llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases"); 222249423Sdim llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases"); 223249423Sdim CGF.Builder.CreateCondBr(IsCompleteObject, 224249423Sdim CallVbaseCtorsBB, SkipVbaseCtorsBB); 225249423Sdim 226249423Sdim CGF.EmitBlock(CallVbaseCtorsBB); 227249423Sdim // FIXME: emit vbtables somewhere around here. 228249423Sdim 229249423Sdim // CGF will put the base ctor calls in this basic block for us later. 230249423Sdim 231249423Sdim return SkipVbaseCtorsBB; 232249423Sdim} 233249423Sdim 234249423Sdimvoid MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, 235249423Sdim CXXDtorType Type, 236249423Sdim CanQualType &ResTy, 237249423Sdim SmallVectorImpl<CanQualType> &ArgTys) { 238249423Sdim // 'this' is already in place 239249423Sdim // TODO: 'for base' flag 240249423Sdim 241249423Sdim if (Type == Dtor_Deleting) { 242249423Sdim // The scalar deleting destructor takes an implicit bool parameter. 243249423Sdim ArgTys.push_back(CGM.getContext().BoolTy); 244249423Sdim } 245249423Sdim} 246249423Sdim 247249423Sdimstatic bool IsDeletingDtor(GlobalDecl GD) { 248249423Sdim const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); 249249423Sdim if (isa<CXXDestructorDecl>(MD)) { 250249423Sdim return GD.getDtorType() == Dtor_Deleting; 251249423Sdim } 252249423Sdim return false; 253249423Sdim} 254249423Sdim 255243830Sdimvoid MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, 256243830Sdim QualType &ResTy, 257243830Sdim FunctionArgList &Params) { 258243830Sdim BuildThisParam(CGF, Params); 259243830Sdim if (needThisReturn(CGF.CurGD)) { 260243830Sdim ResTy = Params[0]->getType(); 261243830Sdim } 262249423Sdim 263249423Sdim ASTContext &Context = getContext(); 264249423Sdim const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 265249423Sdim if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 266249423Sdim ImplicitParamDecl *IsMostDerived 267249423Sdim = ImplicitParamDecl::Create(Context, 0, 268249423Sdim CGF.CurGD.getDecl()->getLocation(), 269249423Sdim &Context.Idents.get("is_most_derived"), 270249423Sdim Context.IntTy); 271249423Sdim Params.push_back(IsMostDerived); 272249423Sdim getStructorImplicitParamDecl(CGF) = IsMostDerived; 273249423Sdim } else if (IsDeletingDtor(CGF.CurGD)) { 274249423Sdim ImplicitParamDecl *ShouldDelete 275249423Sdim = ImplicitParamDecl::Create(Context, 0, 276249423Sdim CGF.CurGD.getDecl()->getLocation(), 277249423Sdim &Context.Idents.get("should_call_delete"), 278249423Sdim Context.BoolTy); 279249423Sdim Params.push_back(ShouldDelete); 280249423Sdim getStructorImplicitParamDecl(CGF) = ShouldDelete; 281249423Sdim } 282243830Sdim} 283243830Sdim 284243830Sdimvoid MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { 285243830Sdim EmitThisParam(CGF); 286243830Sdim if (needThisReturn(CGF.CurGD)) { 287243830Sdim CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); 288243830Sdim } 289249423Sdim 290249423Sdim const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 291249423Sdim if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 292249423Sdim assert(getStructorImplicitParamDecl(CGF) && 293249423Sdim "no implicit parameter for a constructor with virtual bases?"); 294249423Sdim getStructorImplicitParamValue(CGF) 295249423Sdim = CGF.Builder.CreateLoad( 296249423Sdim CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 297249423Sdim "is_most_derived"); 298249423Sdim } 299249423Sdim 300249423Sdim if (IsDeletingDtor(CGF.CurGD)) { 301249423Sdim assert(getStructorImplicitParamDecl(CGF) && 302249423Sdim "no implicit parameter for a deleting destructor?"); 303249423Sdim getStructorImplicitParamValue(CGF) 304249423Sdim = CGF.Builder.CreateLoad( 305249423Sdim CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 306249423Sdim "should_call_delete"); 307249423Sdim } 308243830Sdim} 309243830Sdim 310249423Sdimllvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF, 311249423Sdim const CXXConstructorDecl *D, 312249423Sdim CXXCtorType Type, bool ForVirtualBase, 313249423Sdim bool Delegating, 314249423Sdim llvm::Value *This, 315249423Sdim CallExpr::const_arg_iterator ArgBeg, 316249423Sdim CallExpr::const_arg_iterator ArgEnd) { 317249423Sdim assert(Type == Ctor_Complete || Type == Ctor_Base); 318249423Sdim llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete); 319249423Sdim 320249423Sdim llvm::Value *ImplicitParam = 0; 321249423Sdim QualType ImplicitParamTy; 322249423Sdim if (D->getParent()->getNumVBases()) { 323249423Sdim ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete); 324249423Sdim ImplicitParamTy = getContext().IntTy; 325249423Sdim } 326249423Sdim 327249423Sdim // FIXME: Provide a source location here. 328249423Sdim CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, 329249423Sdim ImplicitParam, ImplicitParamTy, 330249423Sdim ArgBeg, ArgEnd); 331249423Sdim return Callee; 332249423Sdim} 333249423Sdim 334249423SdimRValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, 335249423Sdim const CXXDestructorDecl *Dtor, 336249423Sdim CXXDtorType DtorType, 337249423Sdim SourceLocation CallLoc, 338249423Sdim ReturnValueSlot ReturnValue, 339249423Sdim llvm::Value *This) { 340249423Sdim assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); 341249423Sdim 342249423Sdim // We have only one destructor in the vftable but can get both behaviors 343249423Sdim // by passing an implicit bool parameter. 344249423Sdim const CGFunctionInfo *FInfo 345249423Sdim = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting); 346249423Sdim llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); 347249423Sdim llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, Dtor_Deleting, This, Ty); 348249423Sdim 349249423Sdim ASTContext &Context = CGF.getContext(); 350249423Sdim llvm::Value *ImplicitParam 351249423Sdim = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()), 352249423Sdim DtorType == Dtor_Deleting); 353249423Sdim 354249423Sdim return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This, 355249423Sdim ImplicitParam, Context.BoolTy, 0, 0); 356249423Sdim} 357249423Sdim 358239462Sdimbool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, 359239462Sdim QualType elementType) { 360239462Sdim // Microsoft seems to completely ignore the possibility of a 361239462Sdim // two-argument usual deallocation function. 362239462Sdim return elementType.isDestructedType(); 363239462Sdim} 364239462Sdim 365239462Sdimbool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) { 366239462Sdim // Microsoft seems to completely ignore the possibility of a 367239462Sdim // two-argument usual deallocation function. 368239462Sdim return expr->getAllocatedType().isDestructedType(); 369239462Sdim} 370239462Sdim 371239462SdimCharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) { 372239462Sdim // The array cookie is always a size_t; we then pad that out to the 373239462Sdim // alignment of the element type. 374239462Sdim ASTContext &Ctx = getContext(); 375239462Sdim return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()), 376239462Sdim Ctx.getTypeAlignInChars(type)); 377239462Sdim} 378239462Sdim 379239462Sdimllvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 380239462Sdim llvm::Value *allocPtr, 381239462Sdim CharUnits cookieSize) { 382243830Sdim unsigned AS = allocPtr->getType()->getPointerAddressSpace(); 383239462Sdim llvm::Value *numElementsPtr = 384239462Sdim CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS)); 385239462Sdim return CGF.Builder.CreateLoad(numElementsPtr); 386239462Sdim} 387239462Sdim 388239462Sdimllvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 389239462Sdim llvm::Value *newPtr, 390239462Sdim llvm::Value *numElements, 391239462Sdim const CXXNewExpr *expr, 392239462Sdim QualType elementType) { 393239462Sdim assert(requiresArrayCookie(expr)); 394239462Sdim 395239462Sdim // The size of the cookie. 396239462Sdim CharUnits cookieSize = getArrayCookieSizeImpl(elementType); 397239462Sdim 398239462Sdim // Compute an offset to the cookie. 399239462Sdim llvm::Value *cookiePtr = newPtr; 400239462Sdim 401239462Sdim // Write the number of elements into the appropriate slot. 402243830Sdim unsigned AS = newPtr->getType()->getPointerAddressSpace(); 403239462Sdim llvm::Value *numElementsPtr 404239462Sdim = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS)); 405239462Sdim CGF.Builder.CreateStore(numElements, numElementsPtr); 406239462Sdim 407239462Sdim // Finally, compute a pointer to the actual data buffer by skipping 408239462Sdim // over the cookie completely. 409239462Sdim return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr, 410239462Sdim cookieSize.getQuantity()); 411239462Sdim} 412239462Sdim 413239462Sdimvoid MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 414239462Sdim llvm::GlobalVariable *DeclPtr, 415239462Sdim bool PerformInit) { 416239462Sdim // FIXME: this code was only tested for global initialization. 417239462Sdim // Not sure whether we want thread-safe static local variables as VS 418239462Sdim // doesn't make them thread-safe. 419239462Sdim 420251662Sdim if (D.getTLSKind()) 421251662Sdim CGM.ErrorUnsupported(&D, "dynamic TLS initialization"); 422251662Sdim 423239462Sdim // Emit the initializer and add a global destructor if appropriate. 424239462Sdim CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit); 425239462Sdim} 426239462Sdim 427251662Sdim// Member pointer helpers. 428251662Sdimstatic bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) { 429251662Sdim return Inheritance == MSIM_Unspecified; 430251662Sdim} 431251662Sdim 432251662Sdimstatic bool hasOnlyOneField(MSInheritanceModel Inheritance) { 433251662Sdim return Inheritance <= MSIM_SinglePolymorphic; 434251662Sdim} 435251662Sdim 436251662Sdim// Only member pointers to functions need a this adjustment, since it can be 437251662Sdim// combined with the field offset for data pointers. 438251662Sdimstatic bool hasNonVirtualBaseAdjustmentField(bool IsMemberFunction, 439251662Sdim MSInheritanceModel Inheritance) { 440251662Sdim return (IsMemberFunction && Inheritance >= MSIM_Multiple); 441251662Sdim} 442251662Sdim 443251662Sdimstatic bool hasVirtualBaseAdjustmentField(MSInheritanceModel Inheritance) { 444251662Sdim return Inheritance >= MSIM_Virtual; 445251662Sdim} 446251662Sdim 447251662Sdim// Use zero for the field offset of a null data member pointer if we can 448251662Sdim// guarantee that zero is not a valid field offset, or if the member pointer has 449251662Sdim// multiple fields. Polymorphic classes have a vfptr at offset zero, so we can 450251662Sdim// use zero for null. If there are multiple fields, we can use zero even if it 451251662Sdim// is a valid field offset because null-ness testing will check the other 452251662Sdim// fields. 453251662Sdimstatic bool nullFieldOffsetIsZero(MSInheritanceModel Inheritance) { 454251662Sdim return Inheritance != MSIM_Multiple && Inheritance != MSIM_Single; 455251662Sdim} 456251662Sdim 457251662Sdimbool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) { 458251662Sdim // Null-ness for function memptrs only depends on the first field, which is 459251662Sdim // the function pointer. The rest don't matter, so we can zero initialize. 460251662Sdim if (MPT->isMemberFunctionPointer()) 461251662Sdim return true; 462251662Sdim 463251662Sdim // The virtual base adjustment field is always -1 for null, so if we have one 464251662Sdim // we can't zero initialize. The field offset is sometimes also -1 if 0 is a 465251662Sdim // valid field offset. 466249423Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 467251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 468251662Sdim return (!hasVirtualBaseAdjustmentField(Inheritance) && 469251662Sdim nullFieldOffsetIsZero(Inheritance)); 470239462Sdim} 471239462Sdim 472251662Sdimllvm::Type * 473251662SdimMicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { 474251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 475251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 476251662Sdim llvm::SmallVector<llvm::Type *, 4> fields; 477251662Sdim if (MPT->isMemberFunctionPointer()) 478251662Sdim fields.push_back(CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk 479251662Sdim else 480251662Sdim fields.push_back(CGM.IntTy); // FieldOffset 481251662Sdim 482251662Sdim if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(), 483251662Sdim Inheritance)) 484251662Sdim fields.push_back(CGM.IntTy); 485251662Sdim if (hasVBPtrOffsetField(Inheritance)) 486251662Sdim fields.push_back(CGM.IntTy); 487251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 488251662Sdim fields.push_back(CGM.IntTy); // VirtualBaseAdjustmentOffset 489251662Sdim 490251662Sdim if (fields.size() == 1) 491251662Sdim return fields[0]; 492251662Sdim return llvm::StructType::get(CGM.getLLVMContext(), fields); 493251662Sdim} 494251662Sdim 495251662Sdimvoid MicrosoftCXXABI:: 496251662SdimGetNullMemberPointerFields(const MemberPointerType *MPT, 497251662Sdim llvm::SmallVectorImpl<llvm::Constant *> &fields) { 498251662Sdim assert(fields.empty()); 499251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 500251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 501251662Sdim if (MPT->isMemberFunctionPointer()) { 502251662Sdim // FunctionPointerOrVirtualThunk 503251662Sdim fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); 504251662Sdim } else { 505251662Sdim if (nullFieldOffsetIsZero(Inheritance)) 506251662Sdim fields.push_back(getZeroInt()); // FieldOffset 507251662Sdim else 508251662Sdim fields.push_back(getAllOnesInt()); // FieldOffset 509249423Sdim } 510251662Sdim 511251662Sdim if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(), 512251662Sdim Inheritance)) 513251662Sdim fields.push_back(getZeroInt()); 514251662Sdim if (hasVBPtrOffsetField(Inheritance)) 515251662Sdim fields.push_back(getZeroInt()); 516251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 517251662Sdim fields.push_back(getAllOnesInt()); 518249423Sdim} 519249423Sdim 520249423Sdimllvm::Constant * 521249423SdimMicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { 522251662Sdim llvm::SmallVector<llvm::Constant *, 4> fields; 523251662Sdim GetNullMemberPointerFields(MPT, fields); 524251662Sdim if (fields.size() == 1) 525251662Sdim return fields[0]; 526251662Sdim llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields); 527251662Sdim assert(Res->getType() == ConvertMemberPointerType(MPT)); 528251662Sdim return Res; 529249423Sdim} 530249423Sdim 531249423Sdimllvm::Constant * 532251662SdimMicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField, 533251662Sdim bool IsMemberFunction, 534251662Sdim const CXXRecordDecl *RD) 535251662Sdim{ 536251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 537251662Sdim 538251662Sdim // Single inheritance class member pointer are represented as scalars instead 539251662Sdim // of aggregates. 540251662Sdim if (hasOnlyOneField(Inheritance)) 541251662Sdim return FirstField; 542251662Sdim 543251662Sdim llvm::SmallVector<llvm::Constant *, 4> fields; 544251662Sdim fields.push_back(FirstField); 545251662Sdim 546251662Sdim if (hasNonVirtualBaseAdjustmentField(IsMemberFunction, Inheritance)) 547251662Sdim fields.push_back(getZeroInt()); 548251662Sdim 549251662Sdim if (hasVBPtrOffsetField(Inheritance)) { 550251662Sdim int64_t VBPtrOffset = 551251662Sdim getContext().getASTRecordLayout(RD).getVBPtrOffset().getQuantity(); 552251662Sdim if (VBPtrOffset == -1) 553251662Sdim VBPtrOffset = 0; 554251662Sdim fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset)); 555251662Sdim } 556251662Sdim 557251662Sdim // The rest of the fields are adjusted by conversions to a more derived class. 558251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 559251662Sdim fields.push_back(getZeroInt()); 560251662Sdim 561251662Sdim return llvm::ConstantStruct::getAnon(fields); 562251662Sdim} 563251662Sdim 564251662Sdimllvm::Constant * 565249423SdimMicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, 566249423Sdim CharUnits offset) { 567251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 568251662Sdim llvm::Constant *FirstField = 569251662Sdim llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()); 570251662Sdim return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD); 571249423Sdim} 572249423Sdim 573251662Sdimllvm::Constant * 574251662SdimMicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { 575251662Sdim assert(MD->isInstance() && "Member function must not be static!"); 576251662Sdim MD = MD->getCanonicalDecl(); 577251662Sdim const CXXRecordDecl *RD = MD->getParent(); 578251662Sdim CodeGenTypes &Types = CGM.getTypes(); 579251662Sdim 580251662Sdim llvm::Constant *FirstField; 581251662Sdim if (MD->isVirtual()) { 582251662Sdim // FIXME: We have to instantiate a thunk that loads the vftable and jumps to 583251662Sdim // the right offset. 584251662Sdim FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); 585251662Sdim } else { 586251662Sdim const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); 587251662Sdim llvm::Type *Ty; 588251662Sdim // Check whether the function has a computable LLVM signature. 589251662Sdim if (Types.isFuncTypeConvertible(FPT)) { 590251662Sdim // The function has a computable LLVM signature; use the correct type. 591251662Sdim Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD)); 592251662Sdim } else { 593251662Sdim // Use an arbitrary non-function type to tell GetAddrOfFunction that the 594251662Sdim // function type is incomplete. 595251662Sdim Ty = CGM.PtrDiffTy; 596251662Sdim } 597251662Sdim FirstField = CGM.GetAddrOfFunction(MD, Ty); 598251662Sdim FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy); 599251662Sdim } 600251662Sdim 601251662Sdim // The rest of the fields are common with data member pointers. 602251662Sdim return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD); 603251662Sdim} 604251662Sdim 605251662Sdimllvm::Constant * 606251662SdimMicrosoftCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) { 607251662Sdim // FIXME PR15875: Implement member pointer conversions for Constants. 608251662Sdim const CXXRecordDecl *RD = MPT->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl(); 609251662Sdim return EmitFullMemberPointer(llvm::Constant::getNullValue(CGM.VoidPtrTy), 610251662Sdim /*IsMemberFunction=*/true, RD); 611251662Sdim} 612251662Sdim 613251662Sdim/// Member pointers are the same if they're either bitwise identical *or* both 614251662Sdim/// null. Null-ness for function members is determined by the first field, 615251662Sdim/// while for data member pointers we must compare all fields. 616249423Sdimllvm::Value * 617251662SdimMicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, 618251662Sdim llvm::Value *L, 619251662Sdim llvm::Value *R, 620251662Sdim const MemberPointerType *MPT, 621251662Sdim bool Inequality) { 622251662Sdim CGBuilderTy &Builder = CGF.Builder; 623251662Sdim 624251662Sdim // Handle != comparisons by switching the sense of all boolean operations. 625251662Sdim llvm::ICmpInst::Predicate Eq; 626251662Sdim llvm::Instruction::BinaryOps And, Or; 627251662Sdim if (Inequality) { 628251662Sdim Eq = llvm::ICmpInst::ICMP_NE; 629251662Sdim And = llvm::Instruction::Or; 630251662Sdim Or = llvm::Instruction::And; 631251662Sdim } else { 632251662Sdim Eq = llvm::ICmpInst::ICMP_EQ; 633251662Sdim And = llvm::Instruction::And; 634251662Sdim Or = llvm::Instruction::Or; 635251662Sdim } 636251662Sdim 637251662Sdim // If this is a single field member pointer (single inheritance), this is a 638251662Sdim // single icmp. 639251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 640251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 641251662Sdim if (hasOnlyOneField(Inheritance)) 642251662Sdim return Builder.CreateICmp(Eq, L, R); 643251662Sdim 644251662Sdim // Compare the first field. 645251662Sdim llvm::Value *L0 = Builder.CreateExtractValue(L, 0, "lhs.0"); 646251662Sdim llvm::Value *R0 = Builder.CreateExtractValue(R, 0, "rhs.0"); 647251662Sdim llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0, "memptr.cmp.first"); 648251662Sdim 649251662Sdim // Compare everything other than the first field. 650251662Sdim llvm::Value *Res = 0; 651251662Sdim llvm::StructType *LType = cast<llvm::StructType>(L->getType()); 652251662Sdim for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) { 653251662Sdim llvm::Value *LF = Builder.CreateExtractValue(L, I); 654251662Sdim llvm::Value *RF = Builder.CreateExtractValue(R, I); 655251662Sdim llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF, "memptr.cmp.rest"); 656251662Sdim if (Res) 657251662Sdim Res = Builder.CreateBinOp(And, Res, Cmp); 658251662Sdim else 659251662Sdim Res = Cmp; 660251662Sdim } 661251662Sdim 662251662Sdim // Check if the first field is 0 if this is a function pointer. 663251662Sdim if (MPT->isMemberFunctionPointer()) { 664251662Sdim // (l1 == r1 && ...) || l0 == 0 665251662Sdim llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType()); 666251662Sdim llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero, "memptr.cmp.iszero"); 667251662Sdim Res = Builder.CreateBinOp(Or, Res, IsZero); 668251662Sdim } 669251662Sdim 670251662Sdim // Combine the comparison of the first field, which must always be true for 671251662Sdim // this comparison to succeeed. 672251662Sdim return Builder.CreateBinOp(And, Res, Cmp0, "memptr.cmp"); 673251662Sdim} 674251662Sdim 675251662Sdimllvm::Value * 676249423SdimMicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 677249423Sdim llvm::Value *MemPtr, 678249423Sdim const MemberPointerType *MPT) { 679249423Sdim CGBuilderTy &Builder = CGF.Builder; 680251662Sdim llvm::SmallVector<llvm::Constant *, 4> fields; 681251662Sdim // We only need one field for member functions. 682251662Sdim if (MPT->isMemberFunctionPointer()) 683251662Sdim fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); 684251662Sdim else 685251662Sdim GetNullMemberPointerFields(MPT, fields); 686251662Sdim assert(!fields.empty()); 687251662Sdim llvm::Value *FirstField = MemPtr; 688251662Sdim if (MemPtr->getType()->isStructTy()) 689251662Sdim FirstField = Builder.CreateExtractValue(MemPtr, 0); 690251662Sdim llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0], "memptr.cmp0"); 691249423Sdim 692251662Sdim // For function member pointers, we only need to test the function pointer 693251662Sdim // field. The other fields if any can be garbage. 694251662Sdim if (MPT->isMemberFunctionPointer()) 695251662Sdim return Res; 696251662Sdim 697251662Sdim // Otherwise, emit a series of compares and combine the results. 698251662Sdim for (int I = 1, E = fields.size(); I < E; ++I) { 699251662Sdim llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I); 700251662Sdim llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp"); 701251662Sdim Res = Builder.CreateAnd(Res, Next, "memptr.tobool"); 702249423Sdim } 703251662Sdim return Res; 704251662Sdim} 705249423Sdim 706251662Sdim// Returns an adjusted base cast to i8*, since we do more address arithmetic on 707251662Sdim// it. 708251662Sdimllvm::Value * 709251662SdimMicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF, 710251662Sdim const CXXRecordDecl *RD, llvm::Value *Base, 711251662Sdim llvm::Value *VirtualBaseAdjustmentOffset, 712251662Sdim llvm::Value *VBPtrOffset) { 713251662Sdim CGBuilderTy &Builder = CGF.Builder; 714251662Sdim Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy); 715251662Sdim llvm::BasicBlock *OriginalBB = 0; 716251662Sdim llvm::BasicBlock *SkipAdjustBB = 0; 717251662Sdim llvm::BasicBlock *VBaseAdjustBB = 0; 718251662Sdim 719251662Sdim // In the unspecified inheritance model, there might not be a vbtable at all, 720251662Sdim // in which case we need to skip the virtual base lookup. If there is a 721251662Sdim // vbtable, the first entry is a no-op entry that gives back the original 722251662Sdim // base, so look for a virtual base adjustment offset of zero. 723251662Sdim if (VBPtrOffset) { 724251662Sdim OriginalBB = Builder.GetInsertBlock(); 725251662Sdim VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust"); 726251662Sdim SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust"); 727251662Sdim llvm::Value *IsVirtual = 728251662Sdim Builder.CreateICmpNE(VirtualBaseAdjustmentOffset, getZeroInt(), 729251662Sdim "memptr.is_vbase"); 730251662Sdim Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB); 731251662Sdim CGF.EmitBlock(VBaseAdjustBB); 732251662Sdim } 733251662Sdim 734251662Sdim // If we weren't given a dynamic vbptr offset, RD should be complete and we'll 735251662Sdim // know the vbptr offset. 736251662Sdim if (!VBPtrOffset) { 737251662Sdim CharUnits offs = getContext().getASTRecordLayout(RD).getVBPtrOffset(); 738251662Sdim VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity()); 739251662Sdim } 740251662Sdim // Load the vbtable pointer from the vbtable offset in the instance. 741251662Sdim llvm::Value *VBPtr = 742251662Sdim Builder.CreateInBoundsGEP(Base, VBPtrOffset, "memptr.vbptr"); 743251662Sdim llvm::Value *VBTable = 744251662Sdim Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0)); 745251662Sdim VBTable = Builder.CreateLoad(VBTable, "memptr.vbtable"); 746251662Sdim // Load an i32 offset from the vb-table. 747251662Sdim llvm::Value *VBaseOffs = 748251662Sdim Builder.CreateInBoundsGEP(VBTable, VirtualBaseAdjustmentOffset); 749251662Sdim VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0)); 750251662Sdim VBaseOffs = Builder.CreateLoad(VBaseOffs, "memptr.vbase_offs"); 751251662Sdim // Add it to VBPtr. GEP will sign extend the i32 value for us. 752251662Sdim llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs); 753251662Sdim 754251662Sdim // Merge control flow with the case where we didn't have to adjust. 755251662Sdim if (VBaseAdjustBB) { 756251662Sdim Builder.CreateBr(SkipAdjustBB); 757251662Sdim CGF.EmitBlock(SkipAdjustBB); 758251662Sdim llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base"); 759251662Sdim Phi->addIncoming(Base, OriginalBB); 760251662Sdim Phi->addIncoming(AdjustedBase, VBaseAdjustBB); 761251662Sdim return Phi; 762251662Sdim } 763251662Sdim return AdjustedBase; 764249423Sdim} 765249423Sdim 766249423Sdimllvm::Value * 767249423SdimMicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, 768249423Sdim llvm::Value *Base, 769249423Sdim llvm::Value *MemPtr, 770249423Sdim const MemberPointerType *MPT) { 771251662Sdim assert(MPT->isMemberDataPointer()); 772249423Sdim unsigned AS = Base->getType()->getPointerAddressSpace(); 773249423Sdim llvm::Type *PType = 774249423Sdim CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS); 775249423Sdim CGBuilderTy &Builder = CGF.Builder; 776251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 777251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 778249423Sdim 779251662Sdim // Extract the fields we need, regardless of model. We'll apply them if we 780251662Sdim // have them. 781251662Sdim llvm::Value *FieldOffset = MemPtr; 782251662Sdim llvm::Value *VirtualBaseAdjustmentOffset = 0; 783251662Sdim llvm::Value *VBPtrOffset = 0; 784251662Sdim if (MemPtr->getType()->isStructTy()) { 785251662Sdim // We need to extract values. 786251662Sdim unsigned I = 0; 787251662Sdim FieldOffset = Builder.CreateExtractValue(MemPtr, I++); 788251662Sdim if (hasVBPtrOffsetField(Inheritance)) 789251662Sdim VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); 790251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 791251662Sdim VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); 792249423Sdim } 793249423Sdim 794251662Sdim if (VirtualBaseAdjustmentOffset) { 795251662Sdim Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset, 796251662Sdim VBPtrOffset); 797249423Sdim } 798251662Sdim llvm::Value *Addr = 799251662Sdim Builder.CreateInBoundsGEP(Base, FieldOffset, "memptr.offset"); 800249423Sdim 801249423Sdim // Cast the address to the appropriate pointer type, adopting the address 802249423Sdim // space of the base pointer. 803249423Sdim return Builder.CreateBitCast(Addr, PType); 804249423Sdim} 805249423Sdim 806251662Sdimllvm::Value * 807251662SdimMicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 808251662Sdim llvm::Value *&This, 809251662Sdim llvm::Value *MemPtr, 810251662Sdim const MemberPointerType *MPT) { 811251662Sdim assert(MPT->isMemberFunctionPointer()); 812251662Sdim const FunctionProtoType *FPT = 813251662Sdim MPT->getPointeeType()->castAs<FunctionProtoType>(); 814251662Sdim const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 815251662Sdim llvm::FunctionType *FTy = 816251662Sdim CGM.getTypes().GetFunctionType( 817251662Sdim CGM.getTypes().arrangeCXXMethodType(RD, FPT)); 818251662Sdim CGBuilderTy &Builder = CGF.Builder; 819251662Sdim 820251662Sdim MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 821251662Sdim 822251662Sdim // Extract the fields we need, regardless of model. We'll apply them if we 823251662Sdim // have them. 824251662Sdim llvm::Value *FunctionPointer = MemPtr; 825251662Sdim llvm::Value *NonVirtualBaseAdjustment = NULL; 826251662Sdim llvm::Value *VirtualBaseAdjustmentOffset = NULL; 827251662Sdim llvm::Value *VBPtrOffset = NULL; 828251662Sdim if (MemPtr->getType()->isStructTy()) { 829251662Sdim // We need to extract values. 830251662Sdim unsigned I = 0; 831251662Sdim FunctionPointer = Builder.CreateExtractValue(MemPtr, I++); 832251662Sdim if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance)) 833251662Sdim NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++); 834251662Sdim if (hasVBPtrOffsetField(Inheritance)) 835251662Sdim VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); 836251662Sdim if (hasVirtualBaseAdjustmentField(Inheritance)) 837251662Sdim VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); 838251662Sdim } 839251662Sdim 840251662Sdim if (VirtualBaseAdjustmentOffset) { 841251662Sdim This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset, 842251662Sdim VBPtrOffset); 843251662Sdim } 844251662Sdim 845251662Sdim if (NonVirtualBaseAdjustment) { 846251662Sdim // Apply the adjustment and cast back to the original struct type. 847251662Sdim llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy()); 848251662Sdim Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment); 849251662Sdim This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted"); 850251662Sdim } 851251662Sdim 852251662Sdim return Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo()); 853251662Sdim} 854251662Sdim 855212904SdimCGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) { 856210008Srdivacky return new MicrosoftCXXABI(CGM); 857210008Srdivacky} 858210008Srdivacky 859