Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/CodeGen/CGCXXABI.cpp
Line
Count
Source (jump to first uncovered line)
1
//===----- CGCXXABI.cpp - Interface to C++ ABIs ---------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This provides an abstract class for C++ code generation. Concrete subclasses
10
// of this implement code generation for specific C++ ABIs.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "CGCXXABI.h"
15
#include "CGCleanup.h"
16
17
using namespace clang;
18
using namespace CodeGen;
19
20
17.6k
CGCXXABI::~CGCXXABI() { }
21
22
0
void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
23
0
  DiagnosticsEngine &Diags = CGF.CGM.getDiags();
24
0
  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
25
0
                                          "cannot yet compile %0 in this ABI");
26
0
  Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
27
0
               DiagID)
28
0
    << S;
29
0
}
30
31
0
llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
32
0
  return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
33
0
}
34
35
llvm::Type *
36
0
CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
37
0
  return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
38
0
}
39
40
CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer(
41
    CodeGenFunction &CGF, const Expr *E, Address This,
42
    llvm::Value *&ThisPtrForCall,
43
0
    llvm::Value *MemPtr, const MemberPointerType *MPT) {
44
0
  ErrorUnsupportedABI(CGF, "calls through member pointers");
45
0
46
0
  ThisPtrForCall = This.getPointer();
47
0
  const FunctionProtoType *FPT =
48
0
    MPT->getPointeeType()->getAs<FunctionProtoType>();
49
0
  const CXXRecordDecl *RD =
50
0
    cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
51
0
  llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
52
0
      CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr));
53
0
  llvm::Constant *FnPtr = llvm::Constant::getNullValue(FTy->getPointerTo());
54
0
  return CGCallee::forDirect(FnPtr, FPT);
55
0
}
56
57
llvm::Value *
58
CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
59
                                       Address Base, llvm::Value *MemPtr,
60
0
                                       const MemberPointerType *MPT) {
61
0
  ErrorUnsupportedABI(CGF, "loads of member pointers");
62
0
  llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType())
63
0
                         ->getPointerTo(Base.getAddressSpace());
64
0
  return llvm::Constant::getNullValue(Ty);
65
0
}
66
67
llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
68
                                                   const CastExpr *E,
69
0
                                                   llvm::Value *Src) {
70
0
  ErrorUnsupportedABI(CGF, "member function pointer conversions");
71
0
  return GetBogusMemberPointer(E->getType());
72
0
}
73
74
llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
75
0
                                                      llvm::Constant *Src) {
76
0
  return GetBogusMemberPointer(E->getType());
77
0
}
78
79
llvm::Value *
80
CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
81
                                      llvm::Value *L,
82
                                      llvm::Value *R,
83
                                      const MemberPointerType *MPT,
84
0
                                      bool Inequality) {
85
0
  ErrorUnsupportedABI(CGF, "member function pointer comparison");
86
0
  return CGF.Builder.getFalse();
87
0
}
88
89
llvm::Value *
90
CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
91
                                     llvm::Value *MemPtr,
92
0
                                     const MemberPointerType *MPT) {
93
0
  ErrorUnsupportedABI(CGF, "member function pointer null testing");
94
0
  return CGF.Builder.getFalse();
95
0
}
96
97
llvm::Constant *
98
0
CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
99
0
  return GetBogusMemberPointer(QualType(MPT, 0));
100
0
}
101
102
0
llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
103
0
  return GetBogusMemberPointer(CGM.getContext().getMemberPointerType(
104
0
      MD->getType(), MD->getParent()->getTypeForDecl()));
105
0
}
106
107
llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
108
0
                                                CharUnits offset) {
109
0
  return GetBogusMemberPointer(QualType(MPT, 0));
110
0
}
111
112
0
llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) {
113
0
  return GetBogusMemberPointer(MPT);
114
0
}
115
116
0
bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
117
0
  // Fake answer.
118
0
  return true;
119
0
}
120
121
174k
void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList &params) {
122
174k
  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
123
174k
124
174k
  // FIXME: I'm not entirely sure I like using a fake decl just for code
125
174k
  // generation. Maybe we can come up with a better way?
126
174k
  auto *ThisDecl = ImplicitParamDecl::Create(
127
174k
      CGM.getContext(), nullptr, MD->getLocation(),
128
174k
      &CGM.getContext().Idents.get("this"), MD->getThisType(),
129
174k
      ImplicitParamDecl::CXXThis);
130
174k
  params.push_back(ThisDecl);
131
174k
  CGF.CXXABIThisDecl = ThisDecl;
132
174k
133
174k
  // Compute the presumed alignment of 'this', which basically comes
134
174k
  // down to whether we know it's a complete object or not.
135
174k
  auto &Layout = CGF.getContext().getASTRecordLayout(MD->getParent());
136
174k
  if (MD->getParent()->getNumVBases() == 0 || // avoid vcall in common case
137
174k
      
MD->getParent()->hasAttr<FinalAttr>()3.00k
||
138
174k
      
!isThisCompleteObject(CGF.CurGD)3.00k
) {
139
172k
    CGF.CXXABIThisAlignment = Layout.getAlignment();
140
172k
  } else {
141
1.60k
    CGF.CXXABIThisAlignment = Layout.getNonVirtualAlignment();
142
1.60k
  }
143
174k
}
144
145
174k
llvm::Value *CGCXXABI::loadIncomingCXXThis(CodeGenFunction &CGF) {
146
174k
  return CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)),
147
174k
                                "this");
148
174k
}
149
150
174k
void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) {
151
174k
  /// Initialize the 'this' slot.
152
174k
  assert(getThisDecl(CGF) && "no 'this' variable for function");
153
174k
  CGF.CXXABIThisValue = ThisPtr;
154
174k
}
155
156
void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
157
986
                                   RValue RV, QualType ResultType) {
158
986
  CGF.EmitReturnOfRValue(RV, ResultType);
159
986
}
160
161
736
CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
162
736
  if (!requiresArrayCookie(expr))
163
666
    return CharUnits::Zero();
164
70
  return getArrayCookieSizeImpl(expr->getAllocatedType());
165
70
}
166
167
0
CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) {
168
0
  // BOGUS
169
0
  return CharUnits::Zero();
170
0
}
171
172
Address CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
173
                                        Address NewPtr,
174
                                        llvm::Value *NumElements,
175
                                        const CXXNewExpr *expr,
176
0
                                        QualType ElementType) {
177
0
  // Should never be called.
178
0
  ErrorUnsupportedABI(CGF, "array cookie initialization");
179
0
  return Address::invalid();
180
0
}
181
182
bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
183
717
                                   QualType elementType) {
184
717
  // If the class's usual deallocation function takes two arguments,
185
717
  // it needs a cookie.
186
717
  if (expr->doesUsualArrayDeleteWantSize())
187
18
    return true;
188
699
189
699
  return elementType.isDestructedType();
190
699
}
191
192
719
bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
193
719
  // If the class's usual deallocation function takes two arguments,
194
719
  // it needs a cookie.
195
719
  if (expr->doesUsualArrayDeleteWantSize())
196
15
    return true;
197
704
198
704
  return expr->getAllocatedType().isDestructedType();
199
704
}
200
201
void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
202
                               const CXXDeleteExpr *expr, QualType eltTy,
203
                               llvm::Value *&numElements,
204
731
                               llvm::Value *&allocPtr, CharUnits &cookieSize) {
205
731
  // Derive a char* in the same address space as the pointer.
206
731
  ptr = CGF.Builder.CreateElementBitCast(ptr, CGF.Int8Ty);
207
731
208
731
  // If we don't need an array cookie, bail out early.
209
731
  if (!requiresArrayCookie(expr, eltTy)) {
210
661
    allocPtr = ptr.getPointer();
211
661
    numElements = nullptr;
212
661
    cookieSize = CharUnits::Zero();
213
661
    return;
214
661
  }
215
70
216
70
  cookieSize = getArrayCookieSizeImpl(eltTy);
217
70
  Address allocAddr =
218
70
    CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize);
219
70
  allocPtr = allocAddr.getPointer();
220
70
  numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
221
70
}
222
223
llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
224
                                           Address ptr,
225
0
                                           CharUnits cookieSize) {
226
0
  ErrorUnsupportedABI(CGF, "reading a new[] cookie");
227
0
  return llvm::ConstantInt::get(CGF.SizeTy, 0);
228
0
}
229
230
/// Returns the adjustment, in bytes, required for the given
231
/// member-pointer operation.  Returns null if no adjustment is
232
/// required.
233
59
llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
234
59
  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
235
59
         E->getCastKind() == CK_BaseToDerivedMemberPointer);
236
59
237
59
  QualType derivedType;
238
59
  if (E->getCastKind() == CK_DerivedToBaseMemberPointer)
239
9
    derivedType = E->getSubExpr()->getType();
240
50
  else
241
50
    derivedType = E->getType();
242
59
243
59
  const CXXRecordDecl *derivedClass =
244
59
    derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
245
59
246
59
  return CGM.GetNonVirtualBaseClassOffset(derivedClass,
247
59
                                          E->path_begin(),
248
59
                                          E->path_end());
249
59
}
250
251
266
CharUnits CGCXXABI::getMemberPointerPathAdjustment(const APValue &MP) {
252
266
  // TODO: Store base specifiers in APValue member pointer paths so we can
253
266
  // easily reuse CGM.GetNonVirtualBaseClassOffset().
254
266
  const ValueDecl *MPD = MP.getMemberPointerDecl();
255
266
  CharUnits ThisAdjustment = CharUnits::Zero();
256
266
  ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath();
257
266
  bool DerivedMember = MP.isMemberPointerToDerivedMember();
258
266
  const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext());
259
367
  for (unsigned I = 0, N = Path.size(); I != N; 
++I101
) {
260
101
    const CXXRecordDecl *Base = RD;
261
101
    const CXXRecordDecl *Derived = Path[I];
262
101
    if (DerivedMember)
263
20
      std::swap(Base, Derived);
264
101
    ThisAdjustment +=
265
101
      getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base);
266
101
    RD = Path[I];
267
101
  }
268
266
  if (DerivedMember)
269
17
    ThisAdjustment = -ThisAdjustment;
270
266
  return ThisAdjustment;
271
266
}
272
273
llvm::BasicBlock *
274
CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
275
0
                                        const CXXRecordDecl *RD) {
276
0
  if (CGM.getTarget().getCXXABI().hasConstructorVariants())
277
0
    llvm_unreachable("shouldn't be called in this ABI");
278
0
279
0
  ErrorUnsupportedABI(CGF, "complete object detection in ctor");
280
0
  return nullptr;
281
0
}
282
283
void CGCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
284
                                          const CXXDestructorDecl *Dtor,
285
25.5k
                                          CXXDtorType DT) const {
286
25.5k
  // Assume the base C++ ABI has no special rules for destructor variants.
287
25.5k
  CGM.setDLLImportDLLExport(GV, Dtor);
288
25.5k
}
289
290
llvm::GlobalValue::LinkageTypes CGCXXABI::getCXXDestructorLinkage(
291
47.3k
    GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {
292
47.3k
  // Delegate back to CGM by default.
293
47.3k
  return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage,
294
47.3k
                                         /*IsConstantVariable=*/false);
295
47.3k
}
296
297
0
bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
298
0
  return false;
299
0
}
300
301
llvm::CallInst *
302
CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
303
13
                                              llvm::Value *Exn) {
304
13
  // Just call std::terminate and ignore the violating exception.
305
13
  return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
306
13
}
307
308
376
CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() {
309
376
  return CatchTypeInfo{nullptr, 0};
310
376
}
311
312
15
std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) {
313
15
  return std::vector<CharUnits>();
314
15
}