blob: 6a2925bbd953e7a5fb08857a3d3b2febf1298c0e [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 McCall4c40d982010-08-31 07:33:07 +000033 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
34 CXXCtorType Type,
35 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +000036 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall4c40d982010-08-31 07:33:07 +000037 // 'this' is already in place
38 // TODO: 'for base' flag
39 }
40
41 void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
42 CXXDtorType Type,
43 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +000044 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall4c40d982010-08-31 07:33:07 +000045 // 'this' is already in place
46 // TODO: 'for base' flag
47 }
48
49 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
50 QualType &ResTy,
51 FunctionArgList &Params) {
52 BuildThisParam(CGF, Params);
53 // TODO: 'for base' flag
54 }
55
56 void EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
57 EmitThisParam(CGF);
58 // TODO: 'for base' flag
59 }
John McCallfd708262011-01-27 02:46:02 +000060
John McCall20bb1752012-05-01 06:13:13 +000061 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
62 llvm::GlobalVariable *DeclPtr,
63 bool PerformInit);
64
Charles Davis9ee494f2012-06-23 23:44:00 +000065 void EmitVTables(const CXXRecordDecl *Class);
66
John McCall20bb1752012-05-01 06:13:13 +000067
John McCallfd708262011-01-27 02:46:02 +000068 // ==== Notes on array cookies =========
69 //
70 // MSVC seems to only use cookies when the class has a destructor; a
71 // two-argument usual array deallocation function isn't sufficient.
72 //
73 // For example, this code prints "100" and "1":
74 // struct A {
75 // char x;
76 // void *operator new[](size_t sz) {
77 // printf("%u\n", sz);
78 // return malloc(sz);
79 // }
80 // void operator delete[](void *p, size_t sz) {
81 // printf("%u\n", sz);
82 // free(p);
83 // }
84 // };
85 // int main() {
86 // A *p = new A[100];
87 // delete[] p;
88 // }
89 // Whereas it prints "104" and "104" if you give A a destructor.
John McCalle2b45e22012-05-01 05:23:51 +000090
91 bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType);
92 bool requiresArrayCookie(const CXXNewExpr *expr);
93 CharUnits getArrayCookieSizeImpl(QualType type);
94 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
95 llvm::Value *NewPtr,
96 llvm::Value *NumElements,
97 const CXXNewExpr *expr,
98 QualType ElementType);
99 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
100 llvm::Value *allocPtr,
101 CharUnits cookieSize);
Charles Davisc3926642010-06-09 23:25:41 +0000102};
103
104}
105
John McCalle2b45e22012-05-01 05:23:51 +0000106bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
107 QualType elementType) {
108 // Microsoft seems to completely ignore the possibility of a
109 // two-argument usual deallocation function.
110 return elementType.isDestructedType();
111}
112
113bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
114 // Microsoft seems to completely ignore the possibility of a
115 // two-argument usual deallocation function.
116 return expr->getAllocatedType().isDestructedType();
117}
118
119CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
120 // The array cookie is always a size_t; we then pad that out to the
121 // alignment of the element type.
122 ASTContext &Ctx = getContext();
123 return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
124 Ctx.getTypeAlignInChars(type));
125}
126
127llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
128 llvm::Value *allocPtr,
129 CharUnits cookieSize) {
130 unsigned AS = cast<llvm::PointerType>(allocPtr->getType())->getAddressSpace();
131 llvm::Value *numElementsPtr =
132 CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
133 return CGF.Builder.CreateLoad(numElementsPtr);
134}
135
136llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
137 llvm::Value *newPtr,
138 llvm::Value *numElements,
139 const CXXNewExpr *expr,
140 QualType elementType) {
141 assert(requiresArrayCookie(expr));
142
143 // The size of the cookie.
144 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
145
146 // Compute an offset to the cookie.
147 llvm::Value *cookiePtr = newPtr;
148
149 // Write the number of elements into the appropriate slot.
150 unsigned AS = cast<llvm::PointerType>(newPtr->getType())->getAddressSpace();
151 llvm::Value *numElementsPtr
152 = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
153 CGF.Builder.CreateStore(numElements, numElementsPtr);
154
155 // Finally, compute a pointer to the actual data buffer by skipping
156 // over the cookie completely.
157 return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
158 cookieSize.getQuantity());
159}
160
John McCall20bb1752012-05-01 06:13:13 +0000161void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
162 llvm::GlobalVariable *DeclPtr,
163 bool PerformInit) {
164 // FIXME: this code was only tested for global initialization.
165 // Not sure whether we want thread-safe static local variables as VS
166 // doesn't make them thread-safe.
167
168 // Emit the initializer and add a global destructor if appropriate.
169 CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
170}
171
Charles Davis9ee494f2012-06-23 23:44:00 +0000172void MicrosoftCXXABI::EmitVTables(const CXXRecordDecl *Class) {
173 // FIXME: implement
174}
175
Charles Davis071cc7d2010-08-16 03:33:14 +0000176CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
Charles Davisc3926642010-06-09 23:25:41 +0000177 return new MicrosoftCXXABI(CGM);
178}
179