blob: 2c8173ba38419f8396db0a3042188356de021fcb [file] [log] [blame]
Charles Davisc3926642010-06-09 23:25:41 +00001//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Chris Lattnerfc8f0e12011-04-15 05:22:18 +000010// This provides C++ code generation targeting the Microsoft Visual C++ ABI.
Charles Davisc3926642010-06-09 23:25:41 +000011// The class in this file generates structures that follow the Microsoft
12// Visual C++ ABI, which is actually not very well documented at all outside
13// of Microsoft.
14//
15//===----------------------------------------------------------------------===//
16
17#include "CGCXXABI.h"
18#include "CodeGenModule.h"
Charles Davisc3926642010-06-09 23:25:41 +000019#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
Charles Davisc3926642010-06-09 23:25:41 +000021
22using namespace clang;
23using namespace CodeGen;
24
25namespace {
26
Charles Davis071cc7d2010-08-16 03:33:14 +000027class MicrosoftCXXABI : public CGCXXABI {
Charles Davisc3926642010-06-09 23:25:41 +000028public:
Peter Collingbourne14110472011-01-13 18:57:25 +000029 MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
John McCall4c40d982010-08-31 07:33:07 +000030
Joao Matos285baac2012-07-17 17:10:11 +000031 StringRef GetPureVirtualCallName() { return "_purecall"; }
32
John McCallecd03b42012-09-25 10:10:39 +000033 llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
34 llvm::Value *ptr,
35 QualType type);
36
John McCall4c40d982010-08-31 07:33:07 +000037 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
38 CXXCtorType Type,
39 CanQualType &ResTy,
John McCallbd315742012-09-25 08:00:39 +000040 SmallVectorImpl<CanQualType> &ArgTys);
John McCall4c40d982010-08-31 07:33:07 +000041
42 void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
43 CXXDtorType Type,
44 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +000045 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall4c40d982010-08-31 07:33:07 +000046 // 'this' is already in place
47 // TODO: 'for base' flag
48 }
49
50 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
51 QualType &ResTy,
John McCallbd315742012-09-25 08:00:39 +000052 FunctionArgList &Params);
John McCall4c40d982010-08-31 07:33:07 +000053
John McCallbd315742012-09-25 08:00:39 +000054 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
John McCallfd708262011-01-27 02:46:02 +000055
John McCall20bb1752012-05-01 06:13:13 +000056 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
57 llvm::GlobalVariable *DeclPtr,
58 bool PerformInit);
59
Charles Davis9ee494f2012-06-23 23:44:00 +000060 void EmitVTables(const CXXRecordDecl *Class);
61
John McCall20bb1752012-05-01 06:13:13 +000062
John McCallfd708262011-01-27 02:46:02 +000063 // ==== Notes on array cookies =========
64 //
65 // MSVC seems to only use cookies when the class has a destructor; a
66 // two-argument usual array deallocation function isn't sufficient.
67 //
68 // For example, this code prints "100" and "1":
69 // struct A {
70 // char x;
71 // void *operator new[](size_t sz) {
72 // printf("%u\n", sz);
73 // return malloc(sz);
74 // }
75 // void operator delete[](void *p, size_t sz) {
76 // printf("%u\n", sz);
77 // free(p);
78 // }
79 // };
80 // int main() {
81 // A *p = new A[100];
82 // delete[] p;
83 // }
84 // Whereas it prints "104" and "104" if you give A a destructor.
John McCalle2b45e22012-05-01 05:23:51 +000085
86 bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType);
87 bool requiresArrayCookie(const CXXNewExpr *expr);
88 CharUnits getArrayCookieSizeImpl(QualType type);
89 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
90 llvm::Value *NewPtr,
91 llvm::Value *NumElements,
92 const CXXNewExpr *expr,
93 QualType ElementType);
94 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
95 llvm::Value *allocPtr,
96 CharUnits cookieSize);
John McCallbd315742012-09-25 08:00:39 +000097 static bool needThisReturn(GlobalDecl GD);
Charles Davisc3926642010-06-09 23:25:41 +000098};
99
100}
101
John McCallecd03b42012-09-25 10:10:39 +0000102llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
103 llvm::Value *ptr,
104 QualType type) {
105 // FIXME: implement
106 return ptr;
107}
108
John McCallbd315742012-09-25 08:00:39 +0000109bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
110 const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
111 return isa<CXXConstructorDecl>(MD);
112}
113
114void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
115 CXXCtorType Type,
116 CanQualType &ResTy,
117 SmallVectorImpl<CanQualType> &ArgTys) {
118 // 'this' is already in place
119 // TODO: 'for base' flag
120 // Ctor returns this ptr
121 ResTy = ArgTys[0];
122}
123
124void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
125 QualType &ResTy,
126 FunctionArgList &Params) {
127 BuildThisParam(CGF, Params);
128 if (needThisReturn(CGF.CurGD)) {
129 ResTy = Params[0]->getType();
130 }
131}
132
133void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
134 EmitThisParam(CGF);
135 if (needThisReturn(CGF.CurGD)) {
136 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
137 }
138}
139
John McCalle2b45e22012-05-01 05:23:51 +0000140bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
141 QualType elementType) {
142 // Microsoft seems to completely ignore the possibility of a
143 // two-argument usual deallocation function.
144 return elementType.isDestructedType();
145}
146
147bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
148 // Microsoft seems to completely ignore the possibility of a
149 // two-argument usual deallocation function.
150 return expr->getAllocatedType().isDestructedType();
151}
152
153CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
154 // The array cookie is always a size_t; we then pad that out to the
155 // alignment of the element type.
156 ASTContext &Ctx = getContext();
157 return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
158 Ctx.getTypeAlignInChars(type));
159}
160
161llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
162 llvm::Value *allocPtr,
163 CharUnits cookieSize) {
164 unsigned AS = cast<llvm::PointerType>(allocPtr->getType())->getAddressSpace();
165 llvm::Value *numElementsPtr =
166 CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
167 return CGF.Builder.CreateLoad(numElementsPtr);
168}
169
170llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
171 llvm::Value *newPtr,
172 llvm::Value *numElements,
173 const CXXNewExpr *expr,
174 QualType elementType) {
175 assert(requiresArrayCookie(expr));
176
177 // The size of the cookie.
178 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
179
180 // Compute an offset to the cookie.
181 llvm::Value *cookiePtr = newPtr;
182
183 // Write the number of elements into the appropriate slot.
184 unsigned AS = cast<llvm::PointerType>(newPtr->getType())->getAddressSpace();
185 llvm::Value *numElementsPtr
186 = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
187 CGF.Builder.CreateStore(numElements, numElementsPtr);
188
189 // Finally, compute a pointer to the actual data buffer by skipping
190 // over the cookie completely.
191 return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
192 cookieSize.getQuantity());
193}
194
John McCall20bb1752012-05-01 06:13:13 +0000195void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
196 llvm::GlobalVariable *DeclPtr,
197 bool PerformInit) {
198 // FIXME: this code was only tested for global initialization.
199 // Not sure whether we want thread-safe static local variables as VS
200 // doesn't make them thread-safe.
201
202 // Emit the initializer and add a global destructor if appropriate.
203 CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
204}
205
Charles Davis9ee494f2012-06-23 23:44:00 +0000206void MicrosoftCXXABI::EmitVTables(const CXXRecordDecl *Class) {
207 // FIXME: implement
208}
209
Charles Davis071cc7d2010-08-16 03:33:14 +0000210CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
Charles Davisc3926642010-06-09 23:25:41 +0000211 return new MicrosoftCXXABI(CGM);
212}
213