Coverage Report

Created: 2021-01-19 06:58

/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
31.3k
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
97.9k
void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList &params) {
123
97.9k
  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
97.9k
  auto *ThisDecl = ImplicitParamDecl::Create(
128
97.9k
      CGM.getContext(), nullptr, MD->getLocation(),
129
97.9k
      &CGM.getContext().Idents.get("this"), MD->getThisType(),
130
97.9k
      ImplicitParamDecl::CXXThis);
131
97.9k
  params.push_back(ThisDecl);
132
97.9k
  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
97.9k
  auto &Layout = CGF.getContext().getASTRecordLayout(MD->getParent());
137
97.9k
  if (MD->getParent()->getNumVBases() == 0 || // avoid vcall in common case
138
1.86k
      MD->getParent()->isEffectivelyFinal() ||
139
96.8k
      
isThisCompleteObject(CGF.CurGD)1.86k
) {
140
96.8k
    CGF.CXXABIThisAlignment = Layout.getAlignment();
141
1.13k
  } else {
142
1.13k
    CGF.CXXABIThisAlignment = Layout.getNonVirtualAlignment();
143
1.13k
  }
144
97.9k
}
145
146
97.9k
llvm::Value *CGCXXABI::loadIncomingCXXThis(CodeGenFunction &CGF) {
147
97.9k
  return CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)),
148
97.9k
                                "this");
149
97.9k
}
150
151
97.9k
void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) {
152
  /// Initialize the 'this' slot.
153
97.9k
  assert(getThisDecl(CGF) && "no 'this' variable for function");
154
97.9k
  CGF.CXXABIThisValue = ThisPtr;
155
97.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
650
CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
165
650
  if (!requiresArrayCookie(expr))
166
524
    return CharUnits::Zero();
167
126
  return getArrayCookieSizeImpl(expr->getAllocatedType());
168
126
}
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
227
                                   QualType elementType) {
187
  // If the class's usual deallocation function takes two arguments,
188
  // it needs a cookie.
189
227
  if (expr->doesUsualArrayDeleteWantSize())
190
18
    return true;
191
192
209
  return elementType.isDestructedType();
193
209
}
194
195
677
bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
196
  // If the class's usual deallocation function takes two arguments,
197
  // it needs a cookie.
198
677
  if (expr->doesUsualArrayDeleteWantSize())
199
45
    return true;
200
201
632
  return expr->getAllocatedType().isDestructedType();
202
632
}
203
204
void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
205
                               const CXXDeleteExpr *expr, QualType eltTy,
206
                               llvm::Value *&numElements,
207
241
                               llvm::Value *&allocPtr, CharUnits &cookieSize) {
208
  // Derive a char* in the same address space as the pointer.
209
241
  ptr = CGF.Builder.CreateElementBitCast(ptr, CGF.Int8Ty);
210
211
  // If we don't need an array cookie, bail out early.
212
241
  if (!requiresArrayCookie(expr, eltTy)) {
213
181
    allocPtr = ptr.getPointer();
214
181
    numElements = nullptr;
215
181
    cookieSize = CharUnits::Zero();
216
181
    return;
217
181
  }
218
219
60
  cookieSize = getArrayCookieSizeImpl(eltTy);
220
60
  Address allocAddr =
221
60
    CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize);
222
60
  allocPtr = allocAddr.getPointer();
223
60
  numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
224
60
}
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
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
246
59
  const CXXRecordDecl *derivedClass =
247
59
    derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
248
249
59
  return CGM.GetNonVirtualBaseClassOffset(derivedClass,
250
59
                                          E->path_begin(),
251
59
                                          E->path_end());
252
59
}
253
254
llvm::BasicBlock *
255
CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
256
0
                                        const CXXRecordDecl *RD) {
257
0
  if (CGM.getTarget().getCXXABI().hasConstructorVariants())
258
0
    llvm_unreachable("shouldn't be called in this ABI");
259
260
0
  ErrorUnsupportedABI(CGF, "complete object detection in ctor");
261
0
  return nullptr;
262
0
}
263
264
void CGCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
265
                                          const CXXDestructorDecl *Dtor,
266
16.2k
                                          CXXDtorType DT) const {
267
  // Assume the base C++ ABI has no special rules for destructor variants.
268
16.2k
  CGM.setDLLImportDLLExport(GV, Dtor);
269
16.2k
}
270
271
llvm::GlobalValue::LinkageTypes CGCXXABI::getCXXDestructorLinkage(
272
32.6k
    GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {
273
  // Delegate back to CGM by default.
274
32.6k
  return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage,
275
32.6k
                                         /*IsConstantVariable=*/false);
276
32.6k
}
277
278
0
bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
279
0
  return false;
280
0
}
281
282
llvm::CallInst *
283
CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
284
12
                                              llvm::Value *Exn) {
285
  // Just call std::terminate and ignore the violating exception.
286
12
  return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
287
12
}
288
289
220
CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() {
290
220
  return CatchTypeInfo{nullptr, 0};
291
220
}
292
293
15
std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) {
294
15
  return std::vector<CharUnits>();
295
15
}
296
297
CGCXXABI::AddedStructorArgCounts CGCXXABI::addImplicitConstructorArgs(
298
    CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
299
51.0k
    bool ForVirtualBase, bool Delegating, CallArgList &Args) {
300
51.0k
  AddedStructorArgs AddedArgs =
301
51.0k
      getImplicitConstructorArgs(CGF, D, Type, ForVirtualBase, Delegating);
302
51.2k
  for (size_t i = 0; i < AddedArgs.Prefix.size(); 
++i136
) {
303
136
    Args.insert(Args.begin() + 1 + i,
304
136
                CallArg(RValue::get(AddedArgs.Prefix[i].Value),
305
136
                        AddedArgs.Prefix[i].Type));
306
136
  }
307
472
  for (const auto &arg : AddedArgs.Suffix) {
308
472
    Args.add(RValue::get(arg.Value), arg.Type);
309
472
  }
310
51.0k
  return AddedStructorArgCounts(AddedArgs.Prefix.size(),
311
51.0k
                                AddedArgs.Suffix.size());
312
51.0k
}