blob: b000c68a952cd028f14f090be75e36e04e763826 [file] [log] [blame]
Charles Davis74ce8592010-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 Lattner57540c52011-04-15 05:22:18 +000010// This provides C++ code generation targeting the Microsoft Visual C++ ABI.
Charles Davis74ce8592010-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 Davis74ce8592010-06-09 23:25:41 +000019#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
Charles Davis74ce8592010-06-09 23:25:41 +000021
22using namespace clang;
23using namespace CodeGen;
24
25namespace {
26
Charles Davis53c59df2010-08-16 03:33:14 +000027class MicrosoftCXXABI : public CGCXXABI {
Charles Davis74ce8592010-06-09 23:25:41 +000028public:
Peter Collingbourne0ff0b372011-01-13 18:57:25 +000029 MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
John McCall5d865c322010-08-31 07:33:07 +000030
Joao Matos2ce88ef2012-07-17 17:10:11 +000031 StringRef GetPureVirtualCallName() { return "_purecall"; }
32
John McCall5d865c322010-08-31 07:33:07 +000033 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
34 CXXCtorType Type,
35 CanQualType &ResTy,
John McCall0f999f32012-09-25 08:00:39 +000036 SmallVectorImpl<CanQualType> &ArgTys);
John McCall5d865c322010-08-31 07:33:07 +000037
38 void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
39 CXXDtorType Type,
40 CanQualType &ResTy,
Chris Lattner0e62c1c2011-07-23 10:55:15 +000041 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall5d865c322010-08-31 07:33:07 +000042 // 'this' is already in place
43 // TODO: 'for base' flag
44 }
45
46 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
47 QualType &ResTy,
John McCall0f999f32012-09-25 08:00:39 +000048 FunctionArgList &Params);
John McCall5d865c322010-08-31 07:33:07 +000049
John McCall0f999f32012-09-25 08:00:39 +000050 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
John McCall29036752011-01-27 02:46:02 +000051
John McCallc84ed6a2012-05-01 06:13:13 +000052 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
53 llvm::GlobalVariable *DeclPtr,
54 bool PerformInit);
55
Charles Davisa325a6e2012-06-23 23:44:00 +000056 void EmitVTables(const CXXRecordDecl *Class);
57
John McCallc84ed6a2012-05-01 06:13:13 +000058
John McCall29036752011-01-27 02:46:02 +000059 // ==== Notes on array cookies =========
60 //
61 // MSVC seems to only use cookies when the class has a destructor; a
62 // two-argument usual array deallocation function isn't sufficient.
63 //
64 // For example, this code prints "100" and "1":
65 // struct A {
66 // char x;
67 // void *operator new[](size_t sz) {
68 // printf("%u\n", sz);
69 // return malloc(sz);
70 // }
71 // void operator delete[](void *p, size_t sz) {
72 // printf("%u\n", sz);
73 // free(p);
74 // }
75 // };
76 // int main() {
77 // A *p = new A[100];
78 // delete[] p;
79 // }
80 // Whereas it prints "104" and "104" if you give A a destructor.
John McCallb91cd662012-05-01 05:23:51 +000081
82 bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType);
83 bool requiresArrayCookie(const CXXNewExpr *expr);
84 CharUnits getArrayCookieSizeImpl(QualType type);
85 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
86 llvm::Value *NewPtr,
87 llvm::Value *NumElements,
88 const CXXNewExpr *expr,
89 QualType ElementType);
90 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
91 llvm::Value *allocPtr,
92 CharUnits cookieSize);
John McCall0f999f32012-09-25 08:00:39 +000093 static bool needThisReturn(GlobalDecl GD);
Charles Davis74ce8592010-06-09 23:25:41 +000094};
95
96}
97
John McCall0f999f32012-09-25 08:00:39 +000098bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
99 const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
100 return isa<CXXConstructorDecl>(MD);
101}
102
103void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
104 CXXCtorType Type,
105 CanQualType &ResTy,
106 SmallVectorImpl<CanQualType> &ArgTys) {
107 // 'this' is already in place
108 // TODO: 'for base' flag
109 // Ctor returns this ptr
110 ResTy = ArgTys[0];
111}
112
113void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
114 QualType &ResTy,
115 FunctionArgList &Params) {
116 BuildThisParam(CGF, Params);
117 if (needThisReturn(CGF.CurGD)) {
118 ResTy = Params[0]->getType();
119 }
120}
121
122void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
123 EmitThisParam(CGF);
124 if (needThisReturn(CGF.CurGD)) {
125 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
126 }
127}
128
John McCallb91cd662012-05-01 05:23:51 +0000129bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
130 QualType elementType) {
131 // Microsoft seems to completely ignore the possibility of a
132 // two-argument usual deallocation function.
133 return elementType.isDestructedType();
134}
135
136bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
137 // Microsoft seems to completely ignore the possibility of a
138 // two-argument usual deallocation function.
139 return expr->getAllocatedType().isDestructedType();
140}
141
142CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
143 // The array cookie is always a size_t; we then pad that out to the
144 // alignment of the element type.
145 ASTContext &Ctx = getContext();
146 return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
147 Ctx.getTypeAlignInChars(type));
148}
149
150llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
151 llvm::Value *allocPtr,
152 CharUnits cookieSize) {
153 unsigned AS = cast<llvm::PointerType>(allocPtr->getType())->getAddressSpace();
154 llvm::Value *numElementsPtr =
155 CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
156 return CGF.Builder.CreateLoad(numElementsPtr);
157}
158
159llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
160 llvm::Value *newPtr,
161 llvm::Value *numElements,
162 const CXXNewExpr *expr,
163 QualType elementType) {
164 assert(requiresArrayCookie(expr));
165
166 // The size of the cookie.
167 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
168
169 // Compute an offset to the cookie.
170 llvm::Value *cookiePtr = newPtr;
171
172 // Write the number of elements into the appropriate slot.
173 unsigned AS = cast<llvm::PointerType>(newPtr->getType())->getAddressSpace();
174 llvm::Value *numElementsPtr
175 = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
176 CGF.Builder.CreateStore(numElements, numElementsPtr);
177
178 // Finally, compute a pointer to the actual data buffer by skipping
179 // over the cookie completely.
180 return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
181 cookieSize.getQuantity());
182}
183
John McCallc84ed6a2012-05-01 06:13:13 +0000184void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
185 llvm::GlobalVariable *DeclPtr,
186 bool PerformInit) {
187 // FIXME: this code was only tested for global initialization.
188 // Not sure whether we want thread-safe static local variables as VS
189 // doesn't make them thread-safe.
190
191 // Emit the initializer and add a global destructor if appropriate.
192 CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
193}
194
Charles Davisa325a6e2012-06-23 23:44:00 +0000195void MicrosoftCXXABI::EmitVTables(const CXXRecordDecl *Class) {
196 // FIXME: implement
197}
198
Charles Davis53c59df2010-08-16 03:33:14 +0000199CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
Charles Davis74ce8592010-06-09 23:25:41 +0000200 return new MicrosoftCXXABI(CGM);
201}
202