Coverage Report

Created: 2020-09-19 12:23

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