blob: 8e4929294d11af22871bc91eff5ecb752234de18 [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"; }
David Blaikie2eb9a952012-10-16 22:56:05 +000032 // No known support for deleted functions in MSVC yet, so this choice is
33 // arbitrary.
34 StringRef GetDeletedVirtualCallName() { return "_purecall"; }
Joao Matos285baac2012-07-17 17:10:11 +000035
John McCallecd03b42012-09-25 10:10:39 +000036 llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
37 llvm::Value *ptr,
38 QualType type);
39
John McCall4c40d982010-08-31 07:33:07 +000040 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
41 CXXCtorType Type,
42 CanQualType &ResTy,
John McCallbd315742012-09-25 08:00:39 +000043 SmallVectorImpl<CanQualType> &ArgTys);
John McCall4c40d982010-08-31 07:33:07 +000044
45 void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
46 CXXDtorType Type,
47 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +000048 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall4c40d982010-08-31 07:33:07 +000049 // 'this' is already in place
50 // TODO: 'for base' flag
51 }
52
53 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
54 QualType &ResTy,
John McCallbd315742012-09-25 08:00:39 +000055 FunctionArgList &Params);
John McCall4c40d982010-08-31 07:33:07 +000056
John McCallbd315742012-09-25 08:00:39 +000057 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
John McCallfd708262011-01-27 02:46:02 +000058
John McCall20bb1752012-05-01 06:13:13 +000059 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
60 llvm::GlobalVariable *DeclPtr,
61 bool PerformInit);
62
Charles Davis9ee494f2012-06-23 23:44:00 +000063 void EmitVTables(const CXXRecordDecl *Class);
64
John McCall20bb1752012-05-01 06:13:13 +000065
John McCallfd708262011-01-27 02:46:02 +000066 // ==== Notes on array cookies =========
67 //
68 // MSVC seems to only use cookies when the class has a destructor; a
69 // two-argument usual array deallocation function isn't sufficient.
70 //
71 // For example, this code prints "100" and "1":
72 // struct A {
73 // char x;
74 // void *operator new[](size_t sz) {
75 // printf("%u\n", sz);
76 // return malloc(sz);
77 // }
78 // void operator delete[](void *p, size_t sz) {
79 // printf("%u\n", sz);
80 // free(p);
81 // }
82 // };
83 // int main() {
84 // A *p = new A[100];
85 // delete[] p;
86 // }
87 // Whereas it prints "104" and "104" if you give A a destructor.
John McCalle2b45e22012-05-01 05:23:51 +000088
89 bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType);
90 bool requiresArrayCookie(const CXXNewExpr *expr);
91 CharUnits getArrayCookieSizeImpl(QualType type);
92 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
93 llvm::Value *NewPtr,
94 llvm::Value *NumElements,
95 const CXXNewExpr *expr,
96 QualType ElementType);
97 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
98 llvm::Value *allocPtr,
99 CharUnits cookieSize);
John McCallbd315742012-09-25 08:00:39 +0000100 static bool needThisReturn(GlobalDecl GD);
Charles Davisc3926642010-06-09 23:25:41 +0000101};
102
103}
104
John McCallecd03b42012-09-25 10:10:39 +0000105llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
106 llvm::Value *ptr,
107 QualType type) {
108 // FIXME: implement
109 return ptr;
110}
111
John McCallbd315742012-09-25 08:00:39 +0000112bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
113 const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
114 return isa<CXXConstructorDecl>(MD);
115}
116
117void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
118 CXXCtorType Type,
119 CanQualType &ResTy,
120 SmallVectorImpl<CanQualType> &ArgTys) {
121 // 'this' is already in place
122 // TODO: 'for base' flag
123 // Ctor returns this ptr
124 ResTy = ArgTys[0];
125}
126
127void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
128 QualType &ResTy,
129 FunctionArgList &Params) {
130 BuildThisParam(CGF, Params);
131 if (needThisReturn(CGF.CurGD)) {
132 ResTy = Params[0]->getType();
133 }
134}
135
136void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
137 EmitThisParam(CGF);
138 if (needThisReturn(CGF.CurGD)) {
139 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
140 }
141}
142
John McCalle2b45e22012-05-01 05:23:51 +0000143bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
144 QualType elementType) {
145 // Microsoft seems to completely ignore the possibility of a
146 // two-argument usual deallocation function.
147 return elementType.isDestructedType();
148}
149
150bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
151 // Microsoft seems to completely ignore the possibility of a
152 // two-argument usual deallocation function.
153 return expr->getAllocatedType().isDestructedType();
154}
155
156CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
157 // The array cookie is always a size_t; we then pad that out to the
158 // alignment of the element type.
159 ASTContext &Ctx = getContext();
160 return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
161 Ctx.getTypeAlignInChars(type));
162}
163
164llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
165 llvm::Value *allocPtr,
166 CharUnits cookieSize) {
Micah Villmow956a5a12012-10-25 15:39:14 +0000167 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
John McCalle2b45e22012-05-01 05:23:51 +0000168 llvm::Value *numElementsPtr =
169 CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
170 return CGF.Builder.CreateLoad(numElementsPtr);
171}
172
173llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
174 llvm::Value *newPtr,
175 llvm::Value *numElements,
176 const CXXNewExpr *expr,
177 QualType elementType) {
178 assert(requiresArrayCookie(expr));
179
180 // The size of the cookie.
181 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
182
183 // Compute an offset to the cookie.
184 llvm::Value *cookiePtr = newPtr;
185
186 // Write the number of elements into the appropriate slot.
Micah Villmow956a5a12012-10-25 15:39:14 +0000187 unsigned AS = newPtr->getType()->getPointerAddressSpace();
John McCalle2b45e22012-05-01 05:23:51 +0000188 llvm::Value *numElementsPtr
189 = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
190 CGF.Builder.CreateStore(numElements, numElementsPtr);
191
192 // Finally, compute a pointer to the actual data buffer by skipping
193 // over the cookie completely.
194 return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
195 cookieSize.getQuantity());
196}
197
John McCall20bb1752012-05-01 06:13:13 +0000198void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
199 llvm::GlobalVariable *DeclPtr,
200 bool PerformInit) {
201 // FIXME: this code was only tested for global initialization.
202 // Not sure whether we want thread-safe static local variables as VS
203 // doesn't make them thread-safe.
204
205 // Emit the initializer and add a global destructor if appropriate.
206 CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
207}
208
Charles Davis9ee494f2012-06-23 23:44:00 +0000209void MicrosoftCXXABI::EmitVTables(const CXXRecordDecl *Class) {
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000210 CGM.getVTables().GenerateClassData(CGM.getVTableLinkage(Class), Class);
Charles Davis9ee494f2012-06-23 23:44:00 +0000211}
212
Charles Davis071cc7d2010-08-16 03:33:14 +0000213CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
Charles Davisc3926642010-06-09 23:25:41 +0000214 return new MicrosoftCXXABI(CGM);
215}
216