1//===----------------------------------------------------------------------===//
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 contains code dealing with C++ code generation of classes
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenCXXABI.h"
14#include "CIRGenFunction.h"
15
16#include "clang/AST/ExprCXX.h"
17#include "clang/AST/RecordLayout.h"
18#include "clang/AST/Type.h"
19#include "clang/CIR/MissingFeatures.h"
20
21using namespace clang;
22using namespace clang::CIRGen;
23
24/// Checks whether the given constructor is a valid subject for the
25/// complete-to-base constructor delegation optimization, i.e. emitting the
26/// complete constructor as a simple call to the base constructor.
27bool CIRGenFunction::isConstructorDelegationValid(
28 const CXXConstructorDecl *ctor) {
29 // Currently we disable the optimization for classes with virtual bases
30 // because (1) the address of parameter variables need to be consistent across
31 // all initializers but (2) the delegate function call necessarily creates a
32 // second copy of the parameter variable.
33 //
34 // The limiting example (purely theoretical AFAIK):
35 // struct A { A(int &c) { c++; } };
36 // struct A : virtual A {
37 // B(int count) : A(count) { printf("%d\n", count); }
38 // };
39 // ...although even this example could in principle be emitted as a delegation
40 // since the address of the parameter doesn't escape.
41 if (ctor->getParent()->getNumVBases())
42 return false;
43
44 // We also disable the optimization for variadic functions because it's
45 // impossible to "re-pass" varargs.
46 if (ctor->getType()->castAs<FunctionProtoType>()->isVariadic())
47 return false;
48
49 // FIXME: Decide if we can do a delegation of a delegating constructor.
50 if (ctor->isDelegatingConstructor())
51 return false;
52
53 return true;
54}
55
56static void emitLValueForAnyFieldInitialization(CIRGenFunction &cgf,
57 CXXCtorInitializer *memberInit,
58 LValue &lhs) {
59 FieldDecl *field = memberInit->getAnyMember();
60 if (memberInit->isIndirectMemberInitializer()) {
61 // If we are initializing an anonymous union field, drill down to the field.
62 IndirectFieldDecl *indirectField = memberInit->getIndirectMember();
63 for (const auto *nd : indirectField->chain()) {
64 auto *fd = cast<clang::FieldDecl>(Val: nd);
65 lhs = cgf.emitLValueForFieldInitialization(base: lhs, field: fd, fieldName: fd->getName());
66 }
67 } else {
68 lhs = cgf.emitLValueForFieldInitialization(base: lhs, field, fieldName: field->getName());
69 }
70}
71
72static void emitMemberInitializer(CIRGenFunction &cgf,
73 const CXXRecordDecl *classDecl,
74 CXXCtorInitializer *memberInit,
75 const CXXConstructorDecl *constructor,
76 FunctionArgList &args) {
77 assert(memberInit->isAnyMemberInitializer() &&
78 "Mush have member initializer!");
79 assert(memberInit->getInit() && "Must have initializer!");
80
81 assert(!cir::MissingFeatures::generateDebugInfo());
82
83 // non-static data member initializers
84 FieldDecl *field = memberInit->getAnyMember();
85 QualType fieldType = field->getType();
86
87 mlir::Value thisPtr = cgf.loadCXXThis();
88 QualType recordTy = cgf.getContext().getTypeDeclType(Decl: classDecl);
89
90 // If a base constructor is being emitted, create an LValue that has the
91 // non-virtual alignment.
92 LValue lhs = (cgf.curGD.getCtorType() == Ctor_Base)
93 ? cgf.makeNaturalAlignPointeeAddrLValue(thisPtr, recordTy)
94 : cgf.makeNaturalAlignAddrLValue(thisPtr, recordTy);
95
96 emitLValueForAnyFieldInitialization(cgf, memberInit, lhs);
97
98 // Special case: If we are in a copy or move constructor, and we are copying
99 // an array off PODs or classes with trivial copy constructors, ignore the AST
100 // and perform the copy we know is equivalent.
101 // FIXME: This is hacky at best... if we had a bit more explicit information
102 // in the AST, we could generalize it more easily.
103 const ConstantArrayType *array =
104 cgf.getContext().getAsConstantArrayType(T: fieldType);
105 if (array && constructor->isDefaulted() &&
106 constructor->isCopyOrMoveConstructor()) {
107 QualType baseElementTy = cgf.getContext().getBaseElementType(VAT: array);
108 // NOTE(cir): CodeGen allows record types to be memcpy'd if applicable,
109 // whereas ClangIR wants to represent all object construction explicitly.
110 if (!baseElementTy->isRecordType()) {
111 cgf.cgm.errorNYI(memberInit->getSourceRange(),
112 "emitMemberInitializer: array of non-record type");
113 return;
114 }
115 }
116
117 cgf.emitInitializerForField(field, lhs, init: memberInit->getInit());
118}
119
120static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit) {
121 const Type *baseType = baseInit->getBaseClass();
122 const auto *baseClassDecl =
123 cast<CXXRecordDecl>(Val: baseType->castAs<RecordType>()->getDecl());
124 return baseClassDecl->isDynamicClass();
125}
126
127/// Gets the address of a direct base class within a complete object.
128/// This should only be used for (1) non-virtual bases or (2) virtual bases
129/// when the type is known to be complete (e.g. in complete destructors).
130///
131/// The object pointed to by 'thisAddr' is assumed to be non-null.
132Address CIRGenFunction::getAddressOfDirectBaseInCompleteClass(
133 mlir::Location loc, Address thisAddr, const CXXRecordDecl *derived,
134 const CXXRecordDecl *base, bool baseIsVirtual) {
135 // 'thisAddr' must be a pointer (in some address space) to Derived.
136 assert(thisAddr.getElementType() == convertType(derived));
137
138 // Compute the offset of the virtual base.
139 CharUnits offset;
140 const ASTRecordLayout &layout = getContext().getASTRecordLayout(D: derived);
141 if (baseIsVirtual)
142 offset = layout.getVBaseClassOffset(VBase: base);
143 else
144 offset = layout.getBaseClassOffset(Base: base);
145
146 return builder.createBaseClassAddr(loc, thisAddr, convertType(base),
147 offset.getQuantity(),
148 /*assumeNotNull=*/true);
149}
150
151void CIRGenFunction::emitBaseInitializer(mlir::Location loc,
152 const CXXRecordDecl *classDecl,
153 CXXCtorInitializer *baseInit) {
154 assert(curFuncDecl && "loading 'this' without a func declaration?");
155 assert(isa<CXXMethodDecl>(curFuncDecl));
156
157 assert(baseInit->isBaseInitializer() && "Must have base initializer!");
158
159 Address thisPtr = loadCXXThisAddress();
160
161 const Type *baseType = baseInit->getBaseClass();
162 const auto *baseClassDecl =
163 cast<CXXRecordDecl>(Val: baseType->castAs<RecordType>()->getDecl());
164
165 bool isBaseVirtual = baseInit->isBaseVirtual();
166
167 // If the initializer for the base (other than the constructor
168 // itself) accesses 'this' in any way, we need to initialize the
169 // vtables.
170 if (classDecl->isDynamicClass()) {
171 cgm.errorNYI(loc, "emitBaseInitializer: dynamic class");
172 return;
173 }
174
175 // We can pretend to be a complete class because it only matters for
176 // virtual bases, and we only do virtual bases for complete ctors.
177 Address v = getAddressOfDirectBaseInCompleteClass(
178 loc, thisPtr, classDecl, baseClassDecl, isBaseVirtual);
179 assert(!cir::MissingFeatures::aggValueSlotGC());
180 AggValueSlot aggSlot = AggValueSlot::forAddr(
181 addr: v, quals: Qualifiers(), isDestructed: AggValueSlot::IsDestructed, isAliased: AggValueSlot::IsNotAliased,
182 mayOverlap: getOverlapForBaseInit(rd: classDecl, baseRD: baseClassDecl, isVirtual: isBaseVirtual));
183
184 emitAggExpr(e: baseInit->getInit(), slot: aggSlot);
185
186 assert(!cir::MissingFeatures::requiresCleanups());
187}
188
189/// This routine generates necessary code to initialize base classes and
190/// non-static data members belonging to this constructor.
191void CIRGenFunction::emitCtorPrologue(const CXXConstructorDecl *cd,
192 CXXCtorType ctorType,
193 FunctionArgList &args) {
194 if (cd->isDelegatingConstructor()) {
195 emitDelegatingCXXConstructorCall(ctor: cd, args);
196 return;
197 }
198
199 // If there are no member initializers, we can just return.
200 if (cd->getNumCtorInitializers() == 0)
201 return;
202
203 const CXXRecordDecl *classDecl = cd->getParent();
204
205 // This code doesn't use range-based iteration because we may need to emit
206 // code between the virtual base initializers and the non-virtual base or
207 // between the non-virtual base initializers and the member initializers.
208 CXXConstructorDecl::init_const_iterator b = cd->init_begin(),
209 e = cd->init_end();
210
211 // Virtual base initializers first, if any. They aren't needed if:
212 // - This is a base ctor variant
213 // - There are no vbases
214 // - The class is abstract, so a complete object of it cannot be constructed
215 //
216 // The check for an abstract class is necessary because sema may not have
217 // marked virtual base destructors referenced.
218 bool constructVBases = ctorType != Ctor_Base &&
219 classDecl->getNumVBases() != 0 &&
220 !classDecl->isAbstract();
221 if (constructVBases) {
222 cgm.errorNYI(cd->getSourceRange(), "emitCtorPrologue: virtual base");
223 return;
224 }
225
226 const mlir::Value oldThisValue = cxxThisValue;
227 if (!constructVBases && (*b)->isBaseInitializer() && (*b)->isBaseVirtual()) {
228 cgm.errorNYI(cd->getSourceRange(),
229 "emitCtorPrologue: virtual base initializer");
230 return;
231 }
232
233 // Handle non-virtual base initializers.
234 for (; b != e && (*b)->isBaseInitializer(); b++) {
235 assert(!(*b)->isBaseVirtual());
236
237 if (cgm.getCodeGenOpts().StrictVTablePointers &&
238 cgm.getCodeGenOpts().OptimizationLevel > 0 &&
239 isInitializerOfDynamicClass(baseInit: *b)) {
240 cgm.errorNYI(cd->getSourceRange(),
241 "emitCtorPrologue: strict vtable pointers");
242 return;
243 }
244 emitBaseInitializer(getLoc(cd->getBeginLoc()), classDecl, *b);
245 }
246
247 cxxThisValue = oldThisValue;
248
249 if (classDecl->isDynamicClass()) {
250 cgm.errorNYI(cd->getSourceRange(),
251 "emitCtorPrologue: initialize vtable pointers");
252 return;
253 }
254
255 // Finally, initialize class members.
256 FieldConstructionScope fcs(*this, loadCXXThisAddress());
257 // Classic codegen uses a special class to attempt to replace member
258 // initializers with memcpy. We could possibly defer that to the
259 // lowering or optimization phases to keep the memory accesses more
260 // explicit. For now, we don't insert memcpy at all.
261 assert(!cir::MissingFeatures::ctorMemcpyizer());
262 for (; b != e; b++) {
263 CXXCtorInitializer *member = (*b);
264 assert(!member->isBaseInitializer());
265 assert(member->isAnyMemberInitializer() &&
266 "Delegating initializer on non-delegating constructor");
267 emitMemberInitializer(cgf&: *this, classDecl: cd->getParent(), memberInit: member, constructor: cd, args);
268 }
269}
270
271Address CIRGenFunction::loadCXXThisAddress() {
272 assert(curFuncDecl && "loading 'this' without a func declaration?");
273 assert(isa<CXXMethodDecl>(curFuncDecl));
274
275 // Lazily compute CXXThisAlignment.
276 if (cxxThisAlignment.isZero()) {
277 // Just use the best known alignment for the parent.
278 // TODO: if we're currently emitting a complete-object ctor/dtor, we can
279 // always use the complete-object alignment.
280 auto rd = cast<CXXMethodDecl>(Val: curFuncDecl)->getParent();
281 cxxThisAlignment = cgm.getClassPointerAlignment(rd);
282 }
283
284 return Address(loadCXXThis(), cxxThisAlignment);
285}
286
287void CIRGenFunction::emitInitializerForField(FieldDecl *field, LValue lhs,
288 Expr *init) {
289 QualType fieldType = field->getType();
290 switch (getEvaluationKind(type: fieldType)) {
291 case cir::TEK_Scalar:
292 if (lhs.isSimple())
293 emitExprAsInit(init, d: field, lvalue: lhs, capturedByInit: false);
294 else
295 cgm.errorNYI(field->getSourceRange(),
296 "emitInitializerForField: non-simple scalar");
297 break;
298 case cir::TEK_Complex:
299 cgm.errorNYI(field->getSourceRange(), "emitInitializerForField: complex");
300 break;
301 case cir::TEK_Aggregate: {
302 cgm.errorNYI(field->getSourceRange(), "emitInitializerForField: aggregate");
303 break;
304 }
305 }
306
307 // Ensure that we destroy this object if an exception is thrown later in the
308 // constructor.
309 QualType::DestructionKind dtorKind = fieldType.isDestructedType();
310 (void)dtorKind;
311 assert(!cir::MissingFeatures::requiresCleanups());
312}
313
314void CIRGenFunction::emitDelegateCXXConstructorCall(
315 const CXXConstructorDecl *ctor, CXXCtorType ctorType,
316 const FunctionArgList &args, SourceLocation loc) {
317 CallArgList delegateArgs;
318
319 FunctionArgList::const_iterator i = args.begin(), e = args.end();
320 assert(i != e && "no parameters to constructor");
321
322 // this
323 Address thisAddr = loadCXXThisAddress();
324 delegateArgs.add(RValue::rvalue: get(thisAddr.getPointer()), type: (*i)->getType());
325 ++i;
326
327 // FIXME: The location of the VTT parameter in the parameter list is specific
328 // to the Itanium ABI and shouldn't be hardcoded here.
329 if (cgm.getCXXABI().needsVTTParameter(gd: curGD)) {
330 cgm.errorNYI(loc, "emitDelegateCXXConstructorCall: VTT parameter");
331 return;
332 }
333
334 // Explicit arguments.
335 for (; i != e; ++i) {
336 const VarDecl *param = *i;
337 // FIXME: per-argument source location
338 emitDelegateCallArg(args&: delegateArgs, param, loc);
339 }
340
341 assert(!cir::MissingFeatures::sanitizers());
342
343 emitCXXConstructorCall(d: ctor, type: ctorType, /*ForVirtualBase=*/forVirtualBase: false,
344 /*Delegating=*/delegating: true, thisAddr, args&: delegateArgs, loc);
345}
346
347void CIRGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &args) {
348 const auto *assignOp = cast<CXXMethodDecl>(Val: curGD.getDecl());
349 assert(assignOp->isCopyAssignmentOperator() ||
350 assignOp->isMoveAssignmentOperator());
351 const Stmt *rootS = assignOp->getBody();
352 assert(isa<CompoundStmt>(rootS) &&
353 "Body of an implicit assignment operator should be compound stmt.");
354 const auto *rootCS = cast<CompoundStmt>(Val: rootS);
355
356 assert(!cir::MissingFeatures::incrementProfileCounter());
357 assert(!cir::MissingFeatures::runCleanupsScope());
358
359 // Classic codegen uses a special class to attempt to replace member
360 // initializers with memcpy. We could possibly defer that to the
361 // lowering or optimization phases to keep the memory accesses more
362 // explicit. For now, we don't insert memcpy at all, though in some
363 // cases the AST contains a call to memcpy.
364 assert(!cir::MissingFeatures::assignMemcpyizer());
365 for (Stmt *s : rootCS->body())
366 if (emitStmt(s, /*useCurrentScope=*/true).failed())
367 cgm.errorNYI(s->getSourceRange(),
368 std::string("emitImplicitAssignmentOperatorBody: ") +
369 s->getStmtClassName());
370}
371
372void CIRGenFunction::emitDelegatingCXXConstructorCall(
373 const CXXConstructorDecl *ctor, const FunctionArgList &args) {
374 assert(ctor->isDelegatingConstructor());
375
376 Address thisPtr = loadCXXThisAddress();
377
378 assert(!cir::MissingFeatures::objCGC());
379 assert(!cir::MissingFeatures::sanitizers());
380 AggValueSlot aggSlot = AggValueSlot::forAddr(
381 addr: thisPtr, quals: Qualifiers(), isDestructed: AggValueSlot::IsDestructed,
382 isAliased: AggValueSlot::IsNotAliased, mayOverlap: AggValueSlot::MayOverlap,
383 isZeroed: AggValueSlot::IsNotZeroed);
384
385 emitAggExpr(e: ctor->init_begin()[0]->getInit(), slot: aggSlot);
386
387 const CXXRecordDecl *classDecl = ctor->getParent();
388 if (cgm.getLangOpts().Exceptions && !classDecl->hasTrivialDestructor()) {
389 cgm.errorNYI(ctor->getSourceRange(),
390 "emitDelegatingCXXConstructorCall: exception");
391 return;
392 }
393}
394
395Address CIRGenFunction::getAddressOfBaseClass(
396 Address value, const CXXRecordDecl *derived,
397 llvm::iterator_range<CastExpr::path_const_iterator> path,
398 bool nullCheckValue, SourceLocation loc) {
399 assert(!path.empty() && "Base path should not be empty!");
400
401 if ((*path.begin())->isVirtual()) {
402 // The implementation here is actually complete, but let's flag this
403 // as an error until the rest of the virtual base class support is in place.
404 cgm.errorNYI(loc, "getAddrOfBaseClass: virtual base");
405 return Address::invalid();
406 }
407
408 // Compute the static offset of the ultimate destination within its
409 // allocating subobject (the virtual base, if there is one, or else
410 // the "complete" object that we see).
411 CharUnits nonVirtualOffset =
412 cgm.computeNonVirtualBaseClassOffset(derivedClass: derived, path);
413
414 // Get the base pointer type.
415 mlir::Type baseValueTy = convertType((path.end()[-1])->getType());
416 assert(!cir::MissingFeatures::addressSpace());
417
418 // The if statement here is redundant now, but it will be needed when we add
419 // support for virtual base classes.
420 // If there is no virtual base, use cir.base_class_addr. It takes care of
421 // the adjustment and the null pointer check.
422 if (nonVirtualOffset.isZero()) {
423 assert(!cir::MissingFeatures::sanitizers());
424 return builder.createBaseClassAddr(getLoc(loc), value, baseValueTy, 0,
425 /*assumeNotNull=*/true);
426 }
427
428 assert(!cir::MissingFeatures::sanitizers());
429
430 // Apply the offset
431 value = builder.createBaseClassAddr(getLoc(loc), value, baseValueTy,
432 nonVirtualOffset.getQuantity(),
433 /*assumeNotNull=*/true);
434
435 // Cast to the destination type.
436 value = value.withElementType(builder, baseValueTy);
437
438 return value;
439}
440
441void CIRGenFunction::emitCXXConstructorCall(const clang::CXXConstructorDecl *d,
442 clang::CXXCtorType type,
443 bool forVirtualBase,
444 bool delegating,
445 AggValueSlot thisAVS,
446 const clang::CXXConstructExpr *e) {
447 CallArgList args;
448 Address thisAddr = thisAVS.getAddress();
449 QualType thisType = d->getThisType();
450 mlir::Value thisPtr = thisAddr.getPointer();
451
452 assert(!cir::MissingFeatures::addressSpace());
453
454 args.add(RValue::rvalue: get(thisPtr), type: thisType);
455
456 // In LLVM Codegen: If this is a trivial constructor, just emit what's needed.
457 // If this is a union copy constructor, we must emit a memcpy, because the AST
458 // does not model that copy.
459 assert(!cir::MissingFeatures::isMemcpyEquivalentSpecialMember());
460
461 const FunctionProtoType *fpt = d->getType()->castAs<FunctionProtoType>();
462
463 assert(!cir::MissingFeatures::opCallArgEvaluationOrder());
464
465 emitCallArgs(args, prototype: fpt, argRange: e->arguments(), callee: e->getConstructor(),
466 /*ParamsToSkip=*/paramsToSkip: 0);
467
468 assert(!cir::MissingFeatures::sanitizers());
469 emitCXXConstructorCall(d, type, forVirtualBase, delegating, thisAddr, args,
470 loc: e->getExprLoc());
471}
472
473void CIRGenFunction::emitCXXConstructorCall(
474 const CXXConstructorDecl *d, CXXCtorType type, bool forVirtualBase,
475 bool delegating, Address thisAddr, CallArgList &args, SourceLocation loc) {
476
477 const CXXRecordDecl *crd = d->getParent();
478
479 // If this is a call to a trivial default constructor:
480 // In LLVM: do nothing.
481 // In CIR: emit as a regular call, other later passes should lower the
482 // ctor call into trivial initialization.
483 assert(!cir::MissingFeatures::isTrivialCtorOrDtor());
484
485 assert(!cir::MissingFeatures::isMemcpyEquivalentSpecialMember());
486
487 bool passPrototypeArgs = true;
488
489 // Check whether we can actually emit the constructor before trying to do so.
490 if (d->getInheritedConstructor()) {
491 cgm.errorNYI(d->getSourceRange(),
492 "emitCXXConstructorCall: inherited constructor");
493 return;
494 }
495
496 // Insert any ABI-specific implicit constructor arguments.
497 assert(!cir::MissingFeatures::implicitConstructorArgs());
498
499 // Emit the call.
500 auto calleePtr = cgm.getAddrOfCXXStructor(GlobalDecl(d, type));
501 const CIRGenFunctionInfo &info = cgm.getTypes().arrangeCXXConstructorCall(
502 args, d, ctorKind: type, passProtoArgs: passPrototypeArgs);
503 CIRGenCallee callee = CIRGenCallee::forDirect(calleePtr, GlobalDecl(d, type));
504 cir::CIRCallOpInterface c;
505 emitCall(info, callee, ReturnValueSlot(), args, &c, getLoc(loc));
506
507 if (cgm.getCodeGenOpts().OptimizationLevel != 0 && !crd->isDynamicClass() &&
508 type != Ctor_Base && cgm.getCodeGenOpts().StrictVTablePointers)
509 cgm.errorNYI(d->getSourceRange(), "vtable assumption loads");
510}
511

source code of clang/lib/CIR/CodeGen/CIRGenClass.cpp