1 //===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This provides C++ code generation targeting the Microsoft Visual C++ ABI.
11 // 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
15 //===----------------------------------------------------------------------===//
18 #include "CodeGenModule.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
22 using namespace clang;
23 using namespace CodeGen;
27 class MicrosoftCXXABI : public CGCXXABI {
29 MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
31 StringRef GetPureVirtualCallName() { return "_purecall"; }
32 // No known support for deleted functions in MSVC yet, so this choice is
34 StringRef GetDeletedVirtualCallName() { return "_purecall"; }
36 llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
40 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
43 SmallVectorImpl<CanQualType> &ArgTys);
45 void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
48 SmallVectorImpl<CanQualType> &ArgTys) {
49 // 'this' is already in place
50 // TODO: 'for base' flag
53 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
55 FunctionArgList &Params);
57 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
59 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
60 llvm::GlobalVariable *DeclPtr,
63 void EmitVTables(const CXXRecordDecl *Class);
66 // ==== Notes on array cookies =========
68 // MSVC seems to only use cookies when the class has a destructor; a
69 // two-argument usual array deallocation function isn't sufficient.
71 // For example, this code prints "100" and "1":
74 // void *operator new[](size_t sz) {
75 // printf("%u\n", sz);
78 // void operator delete[](void *p, size_t sz) {
79 // printf("%u\n", sz);
87 // Whereas it prints "104" and "104" if you give A a destructor.
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,
94 llvm::Value *NumElements,
95 const CXXNewExpr *expr,
96 QualType ElementType);
97 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
98 llvm::Value *allocPtr,
99 CharUnits cookieSize);
100 static bool needThisReturn(GlobalDecl GD);
105 llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
112 bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
113 const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
114 return isa<CXXConstructorDecl>(MD);
117 void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
120 SmallVectorImpl<CanQualType> &ArgTys) {
121 // 'this' is already in place
122 // TODO: 'for base' flag
123 // Ctor returns this ptr
127 void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
129 FunctionArgList &Params) {
130 BuildThisParam(CGF, Params);
131 if (needThisReturn(CGF.CurGD)) {
132 ResTy = Params[0]->getType();
136 void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
138 if (needThisReturn(CGF.CurGD)) {
139 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
143 bool 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();
150 bool 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();
156 CharUnits 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));
164 llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
165 llvm::Value *allocPtr,
166 CharUnits cookieSize) {
167 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
168 llvm::Value *numElementsPtr =
169 CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
170 return CGF.Builder.CreateLoad(numElementsPtr);
173 llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
175 llvm::Value *numElements,
176 const CXXNewExpr *expr,
177 QualType elementType) {
178 assert(requiresArrayCookie(expr));
180 // The size of the cookie.
181 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
183 // Compute an offset to the cookie.
184 llvm::Value *cookiePtr = newPtr;
186 // Write the number of elements into the appropriate slot.
187 unsigned AS = newPtr->getType()->getPointerAddressSpace();
188 llvm::Value *numElementsPtr
189 = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
190 CGF.Builder.CreateStore(numElements, numElementsPtr);
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());
198 void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
199 llvm::GlobalVariable *DeclPtr,
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.
205 // Emit the initializer and add a global destructor if appropriate.
206 CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
209 void MicrosoftCXXABI::EmitVTables(const CXXRecordDecl *Class) {
213 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
214 return new MicrosoftCXXABI(CGM);