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