1 //===----- CGCXXABI.cpp - Interface to C++ ABIs ---------------------------===//
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 //
10 // This provides an abstract class for C++ code generation. Concrete subclasses
11 // of this implement code generation for specific C++ ABIs.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "CGCXXABI.h"
16 
17 using namespace clang;
18 using namespace CodeGen;
19 
20 CGCXXABI::~CGCXXABI() { }
21 
22 void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
23   DiagnosticsEngine &Diags = CGF.CGM.getDiags();
24   unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
25                                           "cannot yet compile %0 in this ABI");
26   Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
27                DiagID)
28     << S;
29 }
30 
31 llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
32   return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
33 }
34 
35 llvm::Type *
36 CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
37   return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
38 }
39 
40 llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(
41     CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
42     llvm::Value *MemPtr, const MemberPointerType *MPT) {
43   ErrorUnsupportedABI(CGF, "calls through member pointers");
44 
45   const FunctionProtoType *FPT =
46     MPT->getPointeeType()->getAs<FunctionProtoType>();
47   const CXXRecordDecl *RD =
48     cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
49   llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
50                               CGM.getTypes().arrangeCXXMethodType(RD, FPT));
51   return llvm::Constant::getNullValue(FTy->getPointerTo());
52 }
53 
54 llvm::Value *
55 CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
56                                        llvm::Value *Base, llvm::Value *MemPtr,
57                                        const MemberPointerType *MPT) {
58   ErrorUnsupportedABI(CGF, "loads of member pointers");
59   llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType())->getPointerTo();
60   return llvm::Constant::getNullValue(Ty);
61 }
62 
63 llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
64                                                    const CastExpr *E,
65                                                    llvm::Value *Src) {
66   ErrorUnsupportedABI(CGF, "member function pointer conversions");
67   return GetBogusMemberPointer(E->getType());
68 }
69 
70 llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
71                                                       llvm::Constant *Src) {
72   return GetBogusMemberPointer(E->getType());
73 }
74 
75 llvm::Value *
76 CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
77                                       llvm::Value *L,
78                                       llvm::Value *R,
79                                       const MemberPointerType *MPT,
80                                       bool Inequality) {
81   ErrorUnsupportedABI(CGF, "member function pointer comparison");
82   return CGF.Builder.getFalse();
83 }
84 
85 llvm::Value *
86 CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
87                                      llvm::Value *MemPtr,
88                                      const MemberPointerType *MPT) {
89   ErrorUnsupportedABI(CGF, "member function pointer null testing");
90   return CGF.Builder.getFalse();
91 }
92 
93 llvm::Constant *
94 CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
95   return GetBogusMemberPointer(QualType(MPT, 0));
96 }
97 
98 llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
99   return GetBogusMemberPointer(
100                          CGM.getContext().getMemberPointerType(MD->getType(),
101                                          MD->getParent()->getTypeForDecl()));
102 }
103 
104 llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
105                                                 CharUnits offset) {
106   return GetBogusMemberPointer(QualType(MPT, 0));
107 }
108 
109 llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) {
110   return GetBogusMemberPointer(MPT);
111 }
112 
113 bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
114   // Fake answer.
115   return true;
116 }
117 
118 void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList &params) {
119   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
120 
121   // FIXME: I'm not entirely sure I like using a fake decl just for code
122   // generation. Maybe we can come up with a better way?
123   ImplicitParamDecl *ThisDecl
124     = ImplicitParamDecl::Create(CGM.getContext(), 0, MD->getLocation(),
125                                 &CGM.getContext().Idents.get("this"),
126                                 MD->getThisType(CGM.getContext()));
127   params.push_back(ThisDecl);
128   getThisDecl(CGF) = ThisDecl;
129 }
130 
131 void CGCXXABI::EmitThisParam(CodeGenFunction &CGF) {
132   /// Initialize the 'this' slot.
133   assert(getThisDecl(CGF) && "no 'this' variable for function");
134   getThisValue(CGF)
135     = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)),
136                              "this");
137 }
138 
139 void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
140                                    RValue RV, QualType ResultType) {
141   CGF.EmitReturnOfRValue(RV, ResultType);
142 }
143 
144 CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
145   if (!requiresArrayCookie(expr))
146     return CharUnits::Zero();
147   return getArrayCookieSizeImpl(expr->getAllocatedType());
148 }
149 
150 CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) {
151   // BOGUS
152   return CharUnits::Zero();
153 }
154 
155 llvm::Value *CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
156                                              llvm::Value *NewPtr,
157                                              llvm::Value *NumElements,
158                                              const CXXNewExpr *expr,
159                                              QualType ElementType) {
160   // Should never be called.
161   ErrorUnsupportedABI(CGF, "array cookie initialization");
162   return 0;
163 }
164 
165 bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
166                                    QualType elementType) {
167   // If the class's usual deallocation function takes two arguments,
168   // it needs a cookie.
169   if (expr->doesUsualArrayDeleteWantSize())
170     return true;
171 
172   return elementType.isDestructedType();
173 }
174 
175 bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
176   // If the class's usual deallocation function takes two arguments,
177   // it needs a cookie.
178   if (expr->doesUsualArrayDeleteWantSize())
179     return true;
180 
181   return expr->getAllocatedType().isDestructedType();
182 }
183 
184 void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *ptr,
185                                const CXXDeleteExpr *expr, QualType eltTy,
186                                llvm::Value *&numElements,
187                                llvm::Value *&allocPtr, CharUnits &cookieSize) {
188   // Derive a char* in the same address space as the pointer.
189   unsigned AS = ptr->getType()->getPointerAddressSpace();
190   llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS);
191   ptr = CGF.Builder.CreateBitCast(ptr, charPtrTy);
192 
193   // If we don't need an array cookie, bail out early.
194   if (!requiresArrayCookie(expr, eltTy)) {
195     allocPtr = ptr;
196     numElements = 0;
197     cookieSize = CharUnits::Zero();
198     return;
199   }
200 
201   cookieSize = getArrayCookieSizeImpl(eltTy);
202   allocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(ptr,
203                                                     -cookieSize.getQuantity());
204   numElements = readArrayCookieImpl(CGF, allocPtr, cookieSize);
205 }
206 
207 llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
208                                            llvm::Value *ptr,
209                                            CharUnits cookieSize) {
210   ErrorUnsupportedABI(CGF, "reading a new[] cookie");
211   return llvm::ConstantInt::get(CGF.SizeTy, 0);
212 }
213 
214 void CGCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
215                                   const VarDecl &D,
216                                   llvm::Constant *dtor,
217                                   llvm::Constant *addr) {
218   if (D.getTLSKind())
219     CGM.ErrorUnsupported(&D, "non-trivial TLS destruction");
220 
221   // The default behavior is to use atexit.
222   CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
223 }
224 
225 /// Returns the adjustment, in bytes, required for the given
226 /// member-pointer operation.  Returns null if no adjustment is
227 /// required.
228 llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
229   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
230          E->getCastKind() == CK_BaseToDerivedMemberPointer);
231 
232   QualType derivedType;
233   if (E->getCastKind() == CK_DerivedToBaseMemberPointer)
234     derivedType = E->getSubExpr()->getType();
235   else
236     derivedType = E->getType();
237 
238   const CXXRecordDecl *derivedClass =
239     derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
240 
241   return CGM.GetNonVirtualBaseClassOffset(derivedClass,
242                                           E->path_begin(),
243                                           E->path_end());
244 }
245 
246 CharUnits CGCXXABI::getMemberPointerPathAdjustment(const APValue &MP) {
247   // TODO: Store base specifiers in APValue member pointer paths so we can
248   // easily reuse CGM.GetNonVirtualBaseClassOffset().
249   const ValueDecl *MPD = MP.getMemberPointerDecl();
250   CharUnits ThisAdjustment = CharUnits::Zero();
251   ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath();
252   bool DerivedMember = MP.isMemberPointerToDerivedMember();
253   const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext());
254   for (unsigned I = 0, N = Path.size(); I != N; ++I) {
255     const CXXRecordDecl *Base = RD;
256     const CXXRecordDecl *Derived = Path[I];
257     if (DerivedMember)
258       std::swap(Base, Derived);
259     ThisAdjustment +=
260       getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base);
261     RD = Path[I];
262   }
263   if (DerivedMember)
264     ThisAdjustment = -ThisAdjustment;
265   return ThisAdjustment;
266 }
267 
268 llvm::BasicBlock *
269 CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
270                                         const CXXRecordDecl *RD) {
271   if (CGM.getTarget().getCXXABI().hasConstructorVariants())
272     llvm_unreachable("shouldn't be called in this ABI");
273 
274   ErrorUnsupportedABI(CGF, "complete object detection in ctor");
275   return 0;
276 }
277 
278 void CGCXXABI::EmitThreadLocalInitFuncs(
279     llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
280     llvm::Function *InitFunc) {
281 }
282 
283 LValue CGCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
284                                               const VarDecl *VD,
285                                               QualType LValType) {
286   ErrorUnsupportedABI(CGF, "odr-use of thread_local global");
287   return LValue();
288 }
289 
290 bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
291   return false;
292 }
293 
294 /// What sort of uniqueness rules should we use for the RTTI for the
295 /// given type?
296 CGCXXABI::RTTIUniquenessKind
297 CGCXXABI::classifyRTTIUniqueness(QualType CanTy,
298                                  llvm::GlobalValue::LinkageTypes Linkage) {
299   if (shouldRTTIBeUnique())
300     return RUK_Unique;
301 
302   // It's only necessary for linkonce_odr or weak_odr linkage.
303   if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
304       Linkage != llvm::GlobalValue::WeakODRLinkage)
305     return RUK_Unique;
306 
307   // It's only necessary with default visibility.
308   if (CanTy->getVisibility() != DefaultVisibility)
309     return RUK_Unique;
310 
311   // If we're not required to publish this symbol, hide it.
312   if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
313     return RUK_NonUniqueHidden;
314 
315   // If we're required to publish this symbol, as we might be under an
316   // explicit instantiation, leave it with default visibility but
317   // enable string-comparisons.
318   assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
319   return RUK_NonUniqueVisible;
320 }
321