Coverage Report

Created: 2022-01-22 13:19

/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
35.0k
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
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
105k
void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList &params) {
123
105k
  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
124
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
105k
  auto *ThisDecl = ImplicitParamDecl::Create(
128
105k
      CGM.getContext(), nullptr, MD->getLocation(),
129
105k
      &CGM.getContext().Idents.get("this"), MD->getThisType(),
130
105k
      ImplicitParamDecl::CXXThis);
131
105k
  params.push_back(ThisDecl);
132
105k
  CGF.CXXABIThisDecl = ThisDecl;
133
134
  // Compute the presumed alignment of 'this', which basically comes
135
  // down to whether we know it's a complete object or not.
136
105k
  auto &Layout = CGF.getContext().getASTRecordLayout(MD->getParent());
137
105k
  if (MD->getParent()->getNumVBases() == 0 || // avoid vcall in common case
138
105k
      
MD->getParent()->isEffectivelyFinal()1.84k
||
139
105k
      
isThisCompleteObject(CGF.CurGD)1.84k
) {
140
104k
    CGF.CXXABIThisAlignment = Layout.getAlignment();
141
104k
  } else {
142
1.12k
    CGF.CXXABIThisAlignment = Layout.getNonVirtualAlignment();
143
1.12k
  }
144
105k
}
145
146
105k
llvm::Value *CGCXXABI::loadIncomingCXXThis(CodeGenFunction &CGF) {
147
105k
  return CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)),
148
105k
                                "this");
149
105k
}
150
151
105k
void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) {
152
  /// Initialize the 'this' slot.
153
105k
  assert(getThisDecl(CGF) && "no 'this' variable for function");
154
0
  CGF.CXXABIThisValue = ThisPtr;
155
105k
}
156
157
334
bool CGCXXABI::mayNeedDestruction(const VarDecl *VD) const {
158
334
  if (VD->needsDestruction(getContext()))
159
90
    return true;
160
161
  // If the variable has an incomplete class type (or array thereof), it
162
  // might need destruction.
163
244
  const Type *T = VD->getType()->getBaseElementTypeUnsafe();
164
244
  if (T->getAs<RecordType>() && 
T->isIncompleteType()38
)
165
3
    return true;
166
167
241
  return false;
168
244
}
169
170
bool CGCXXABI::isEmittedWithConstantInitializer(
171
483
    const VarDecl *VD, bool InspectInitForWeakDef) const {
172
483
  VD = VD->getMostRecentDecl();
173
483
  if (VD->hasAttr<ConstInitAttr>())
174
14
    return true;
175
176
  // All later checks examine the initializer specified on the variable. If
177
  // the variable is weak, such examination would not be correct.
178
469
  if (!InspectInitForWeakDef && 
(457
VD->isWeak()457
||
VD->hasAttr<SelectAnyAttr>()457
))
179
0
    return false;
180
181
469
  const VarDecl *InitDecl = VD->getInitializingDeclaration();
182
469
  if (!InitDecl)
183
166
    return false;
184
185
  // If there's no initializer to run, this is constant initialization.
186
303
  if (!InitDecl->hasInit())
187
29
    return true;
188
189
  // If we have the only definition, we don't need a thread wrapper if we
190
  // will emit the value as a constant.
191
274
  if (isUniqueGVALinkage(getContext().GetGVALinkageForVariable(VD)))
192
185
    return !mayNeedDestruction(VD) && 
InitDecl->evaluateValue()120
;
193
194
  // Otherwise, we need a thread wrapper unless we know that every
195
  // translation unit will emit the value as a constant. We rely on the
196
  // variable being constant-initialized in every translation unit if it's
197
  // constant-initialized in any translation unit, which isn't actually
198
  // guaranteed by the standard but is necessary for sanity.
199
89
  return InitDecl->hasConstantInitialization();
200
274
}
201
202
void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
203
196
                                   RValue RV, QualType ResultType) {
204
196
  assert(!CGF.hasAggregateEvaluationKind(ResultType) &&
205
196
         "cannot handle aggregates");
206
0
  CGF.EmitReturnOfRValue(RV, ResultType);
207
196
}
208
209
660
CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
210
660
  if (!requiresArrayCookie(expr))
211
536
    return CharUnits::Zero();
212
124
  return getArrayCookieSizeImpl(expr->getAllocatedType());
213
660
}
214
215
0
CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) {
216
  // BOGUS
217
0
  return CharUnits::Zero();
218
0
}
219
220
Address CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
221
                                        Address NewPtr,
222
                                        llvm::Value *NumElements,
223
                                        const CXXNewExpr *expr,
224
0
                                        QualType ElementType) {
225
  // Should never be called.
226
0
  ErrorUnsupportedABI(CGF, "array cookie initialization");
227
0
  return Address::invalid();
228
0
}
229
230
bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
231
235
                                   QualType elementType) {
232
  // If the class's usual deallocation function takes two arguments,
233
  // it needs a cookie.
234
235
  if (expr->doesUsualArrayDeleteWantSize())
235
18
    return true;
236
237
217
  return elementType.isDestructedType();
238
235
}
239
240
686
bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
241
  // If the class's usual deallocation function takes two arguments,
242
  // it needs a cookie.
243
686
  if (expr->doesUsualArrayDeleteWantSize())
244
45
    return true;
245
246
641
  return expr->getAllocatedType().isDestructedType();
247
686
}
248
249
void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
250
                               const CXXDeleteExpr *expr, QualType eltTy,
251
                               llvm::Value *&numElements,
252
249
                               llvm::Value *&allocPtr, CharUnits &cookieSize) {
253
  // Derive a char* in the same address space as the pointer.
254
249
  ptr = CGF.Builder.CreateElementBitCast(ptr, CGF.Int8Ty);
255
256
  // If we don't need an array cookie, bail out early.
257
249
  if (!requiresArrayCookie(expr, eltTy)) {
258
190
    allocPtr = ptr.getPointer();
259
190
    numElements = nullptr;
260
190
    cookieSize = CharUnits::Zero();
261
190
    return;
262
190
  }
263
264
59
  cookieSize = getArrayCookieSizeImpl(eltTy);
265
59
  Address allocAddr =
266
59
    CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize);
267
59
  allocPtr = allocAddr.getPointer();
268
59
  numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
269
59
}
270
271
llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
272
                                           Address ptr,
273
0
                                           CharUnits cookieSize) {
274
0
  ErrorUnsupportedABI(CGF, "reading a new[] cookie");
275
0
  return llvm::ConstantInt::get(CGF.SizeTy, 0);
276
0
}
277
278
/// Returns the adjustment, in bytes, required for the given
279
/// member-pointer operation.  Returns null if no adjustment is
280
/// required.
281
56
llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
282
56
  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
283
56
         E->getCastKind() == CK_BaseToDerivedMemberPointer);
284
285
0
  QualType derivedType;
286
56
  if (E->getCastKind() == CK_DerivedToBaseMemberPointer)
287
8
    derivedType = E->getSubExpr()->getType();
288
48
  else
289
48
    derivedType = E->getType();
290
291
56
  const CXXRecordDecl *derivedClass =
292
56
    derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
293
294
56
  return CGM.GetNonVirtualBaseClassOffset(derivedClass,
295
56
                                          E->path_begin(),
296
56
                                          E->path_end());
297
56
}
298
299
llvm::BasicBlock *
300
CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
301
0
                                        const CXXRecordDecl *RD) {
302
0
  if (CGM.getTarget().getCXXABI().hasConstructorVariants())
303
0
    llvm_unreachable("shouldn't be called in this ABI");
304
305
0
  ErrorUnsupportedABI(CGF, "complete object detection in ctor");
306
0
  return nullptr;
307
0
}
308
309
void CGCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
310
                                          const CXXDestructorDecl *Dtor,
311
16.4k
                                          CXXDtorType DT) const {
312
  // Assume the base C++ ABI has no special rules for destructor variants.
313
16.4k
  CGM.setDLLImportDLLExport(GV, Dtor);
314
16.4k
}
315
316
llvm::GlobalValue::LinkageTypes CGCXXABI::getCXXDestructorLinkage(
317
33.1k
    GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {
318
  // Delegate back to CGM by default.
319
33.1k
  return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage,
320
33.1k
                                         /*IsConstantVariable=*/false);
321
33.1k
}
322
323
0
bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
324
0
  return false;
325
0
}
326
327
llvm::CallInst *
328
CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
329
15
                                              llvm::Value *Exn) {
330
  // Just call std::terminate and ignore the violating exception.
331
15
  return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
332
15
}
333
334
220
CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() {
335
220
  return CatchTypeInfo{nullptr, 0};
336
220
}
337
338
15
std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) {
339
15
  return std::vector<CharUnits>();
340
15
}
341
342
CGCXXABI::AddedStructorArgCounts CGCXXABI::addImplicitConstructorArgs(
343
    CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
344
55.2k
    bool ForVirtualBase, bool Delegating, CallArgList &Args) {
345
55.2k
  AddedStructorArgs AddedArgs =
346
55.2k
      getImplicitConstructorArgs(CGF, D, Type, ForVirtualBase, Delegating);
347
55.3k
  for (size_t i = 0; i < AddedArgs.Prefix.size(); 
++i136
) {
348
136
    Args.insert(Args.begin() + 1 + i,
349
136
                CallArg(RValue::get(AddedArgs.Prefix[i].Value),
350
136
                        AddedArgs.Prefix[i].Type));
351
136
  }
352
55.2k
  for (const auto &arg : AddedArgs.Suffix) {
353
472
    Args.add(RValue::get(arg.Value), arg.Type);
354
472
  }
355
55.2k
  return AddedStructorArgCounts(AddedArgs.Prefix.size(),
356
55.2k
                                AddedArgs.Suffix.size());
357
55.2k
}