xref: /freebsd/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
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 // Internal per-function state used for AST-to-ClangIR code gen
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "CIRGenFunction.h"
14 
15 #include "CIRGenCXXABI.h"
16 #include "CIRGenCall.h"
17 #include "CIRGenValue.h"
18 #include "mlir/IR/Location.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/GlobalDecl.h"
21 #include "clang/CIR/MissingFeatures.h"
22 
23 #include <cassert>
24 
25 namespace clang::CIRGen {
26 
27 CIRGenFunction::CIRGenFunction(CIRGenModule &cgm, CIRGenBuilderTy &builder,
28                                bool suppressNewContext)
29     : CIRGenTypeCache(cgm), cgm{cgm}, builder(builder) {}
30 
31 CIRGenFunction::~CIRGenFunction() {}
32 
33 // This is copied from clang/lib/CodeGen/CodeGenFunction.cpp
34 cir::TypeEvaluationKind CIRGenFunction::getEvaluationKind(QualType type) {
35   type = type.getCanonicalType();
36   while (true) {
37     switch (type->getTypeClass()) {
38 #define TYPE(name, parent)
39 #define ABSTRACT_TYPE(name, parent)
40 #define NON_CANONICAL_TYPE(name, parent) case Type::name:
41 #define DEPENDENT_TYPE(name, parent) case Type::name:
42 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
43 #include "clang/AST/TypeNodes.inc"
44       llvm_unreachable("non-canonical or dependent type in IR-generation");
45 
46     case Type::Auto:
47     case Type::DeducedTemplateSpecialization:
48       llvm_unreachable("undeduced type in IR-generation");
49 
50     // Various scalar types.
51     case Type::Builtin:
52     case Type::Pointer:
53     case Type::BlockPointer:
54     case Type::LValueReference:
55     case Type::RValueReference:
56     case Type::MemberPointer:
57     case Type::Vector:
58     case Type::ExtVector:
59     case Type::ConstantMatrix:
60     case Type::FunctionProto:
61     case Type::FunctionNoProto:
62     case Type::Enum:
63     case Type::ObjCObjectPointer:
64     case Type::Pipe:
65     case Type::BitInt:
66     case Type::HLSLAttributedResource:
67     case Type::HLSLInlineSpirv:
68       return cir::TEK_Scalar;
69 
70     // Complexes.
71     case Type::Complex:
72       return cir::TEK_Complex;
73 
74     // Arrays, records, and Objective-C objects.
75     case Type::ConstantArray:
76     case Type::IncompleteArray:
77     case Type::VariableArray:
78     case Type::Record:
79     case Type::ObjCObject:
80     case Type::ObjCInterface:
81     case Type::ArrayParameter:
82       return cir::TEK_Aggregate;
83 
84     // We operate on atomic values according to their underlying type.
85     case Type::Atomic:
86       type = cast<AtomicType>(type)->getValueType();
87       continue;
88     }
89     llvm_unreachable("unknown type kind!");
90   }
91 }
92 
93 mlir::Type CIRGenFunction::convertTypeForMem(QualType t) {
94   return cgm.getTypes().convertTypeForMem(t);
95 }
96 
97 mlir::Type CIRGenFunction::convertType(QualType t) {
98   return cgm.getTypes().convertType(t);
99 }
100 
101 mlir::Location CIRGenFunction::getLoc(SourceLocation srcLoc) {
102   // Some AST nodes might contain invalid source locations (e.g.
103   // CXXDefaultArgExpr), workaround that to still get something out.
104   if (srcLoc.isValid()) {
105     const SourceManager &sm = getContext().getSourceManager();
106     PresumedLoc pLoc = sm.getPresumedLoc(srcLoc);
107     StringRef filename = pLoc.getFilename();
108     return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
109                                      pLoc.getLine(), pLoc.getColumn());
110   }
111   // Do our best...
112   assert(currSrcLoc && "expected to inherit some source location");
113   return *currSrcLoc;
114 }
115 
116 mlir::Location CIRGenFunction::getLoc(SourceRange srcLoc) {
117   // Some AST nodes might contain invalid source locations (e.g.
118   // CXXDefaultArgExpr), workaround that to still get something out.
119   if (srcLoc.isValid()) {
120     mlir::Location beg = getLoc(srcLoc.getBegin());
121     mlir::Location end = getLoc(srcLoc.getEnd());
122     SmallVector<mlir::Location, 2> locs = {beg, end};
123     mlir::Attribute metadata;
124     return mlir::FusedLoc::get(locs, metadata, &getMLIRContext());
125   }
126   if (currSrcLoc) {
127     return *currSrcLoc;
128   }
129   // We're brave, but time to give up.
130   return builder.getUnknownLoc();
131 }
132 
133 mlir::Location CIRGenFunction::getLoc(mlir::Location lhs, mlir::Location rhs) {
134   SmallVector<mlir::Location, 2> locs = {lhs, rhs};
135   mlir::Attribute metadata;
136   return mlir::FusedLoc::get(locs, metadata, &getMLIRContext());
137 }
138 
139 bool CIRGenFunction::containsLabel(const Stmt *s, bool ignoreCaseStmts) {
140   // Null statement, not a label!
141   if (!s)
142     return false;
143 
144   // If this is a label, we have to emit the code, consider something like:
145   // if (0) {  ...  foo:  bar(); }  goto foo;
146   //
147   // TODO: If anyone cared, we could track __label__'s, since we know that you
148   // can't jump to one from outside their declared region.
149   if (isa<LabelStmt>(s))
150     return true;
151 
152   // If this is a case/default statement, and we haven't seen a switch, we
153   // have to emit the code.
154   if (isa<SwitchCase>(s) && !ignoreCaseStmts)
155     return true;
156 
157   // If this is a switch statement, we want to ignore case statements when we
158   // recursively process the sub-statements of the switch. If we haven't
159   // encountered a switch statement, we treat case statements like labels, but
160   // if we are processing a switch statement, case statements are expected.
161   if (isa<SwitchStmt>(s))
162     ignoreCaseStmts = true;
163 
164   // Scan subexpressions for verboten labels.
165   return std::any_of(s->child_begin(), s->child_end(),
166                      [=](const Stmt *subStmt) {
167                        return containsLabel(subStmt, ignoreCaseStmts);
168                      });
169 }
170 
171 /// If the specified expression does not fold to a constant, or if it does but
172 /// contains a label, return false.  If it constant folds return true and set
173 /// the boolean result in Result.
174 bool CIRGenFunction::constantFoldsToBool(const Expr *cond, bool &resultBool,
175                                          bool allowLabels) {
176   llvm::APSInt resultInt;
177   if (!constantFoldsToSimpleInteger(cond, resultInt, allowLabels))
178     return false;
179 
180   resultBool = resultInt.getBoolValue();
181   return true;
182 }
183 
184 /// If the specified expression does not fold to a constant, or if it does
185 /// fold but contains a label, return false. If it constant folds, return
186 /// true and set the folded value.
187 bool CIRGenFunction::constantFoldsToSimpleInteger(const Expr *cond,
188                                                   llvm::APSInt &resultInt,
189                                                   bool allowLabels) {
190   // FIXME: Rename and handle conversion of other evaluatable things
191   // to bool.
192   Expr::EvalResult result;
193   if (!cond->EvaluateAsInt(result, getContext()))
194     return false; // Not foldable, not integer or not fully evaluatable.
195 
196   llvm::APSInt intValue = result.Val.getInt();
197   if (!allowLabels && containsLabel(cond))
198     return false; // Contains a label.
199 
200   resultInt = intValue;
201   return true;
202 }
203 
204 void CIRGenFunction::emitAndUpdateRetAlloca(QualType type, mlir::Location loc,
205                                             CharUnits alignment) {
206   if (!type->isVoidType()) {
207     fnRetAlloca = emitAlloca("__retval", convertType(type), loc, alignment,
208                              /*insertIntoFnEntryBlock=*/false);
209   }
210 }
211 
212 void CIRGenFunction::declare(mlir::Value addrVal, const Decl *var, QualType ty,
213                              mlir::Location loc, CharUnits alignment,
214                              bool isParam) {
215   const auto *namedVar = dyn_cast_or_null<NamedDecl>(var);
216   assert(namedVar && "Needs a named decl");
217   assert(!cir::MissingFeatures::cgfSymbolTable());
218 
219   auto allocaOp = cast<cir::AllocaOp>(addrVal.getDefiningOp());
220   if (isParam)
221     allocaOp.setInitAttr(mlir::UnitAttr::get(&getMLIRContext()));
222   if (ty->isReferenceType() || ty.isConstQualified())
223     allocaOp.setConstantAttr(mlir::UnitAttr::get(&getMLIRContext()));
224 }
225 
226 void CIRGenFunction::LexicalScope::cleanup() {
227   CIRGenBuilderTy &builder = cgf.builder;
228   LexicalScope *localScope = cgf.curLexScope;
229 
230   if (returnBlock != nullptr) {
231     // Write out the return block, which loads the value from `__retval` and
232     // issues the `cir.return`.
233     mlir::OpBuilder::InsertionGuard guard(builder);
234     builder.setInsertionPointToEnd(returnBlock);
235     (void)emitReturn(*returnLoc);
236   }
237 
238   mlir::Block *curBlock = builder.getBlock();
239   if (isGlobalInit() && !curBlock)
240     return;
241   if (curBlock->mightHaveTerminator() && curBlock->getTerminator())
242     return;
243 
244   // Get rid of any empty block at the end of the scope.
245   bool entryBlock = builder.getInsertionBlock()->isEntryBlock();
246   if (!entryBlock && curBlock->empty()) {
247     curBlock->erase();
248     if (returnBlock != nullptr && returnBlock->getUses().empty())
249       returnBlock->erase();
250     return;
251   }
252 
253   // Reached the end of the scope.
254   {
255     mlir::OpBuilder::InsertionGuard guard(builder);
256     builder.setInsertionPointToEnd(curBlock);
257 
258     if (localScope->depth == 0) {
259       // Reached the end of the function.
260       if (returnBlock != nullptr) {
261         if (returnBlock->getUses().empty())
262           returnBlock->erase();
263         else {
264           builder.create<cir::BrOp>(*returnLoc, returnBlock);
265           return;
266         }
267       }
268       emitImplicitReturn();
269       return;
270     }
271     // Reached the end of a non-function scope.  Some scopes, such as those
272     // used with the ?: operator, can return a value.
273     if (!localScope->isTernary() && !curBlock->mightHaveTerminator()) {
274       !retVal ? builder.create<cir::YieldOp>(localScope->endLoc)
275               : builder.create<cir::YieldOp>(localScope->endLoc, retVal);
276     }
277   }
278 }
279 
280 cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
281   CIRGenBuilderTy &builder = cgf.getBuilder();
282 
283   if (!cgf.curFn.getFunctionType().hasVoidReturn()) {
284     // Load the value from `__retval` and return it via the `cir.return` op.
285     auto value = builder.create<cir::LoadOp>(
286         loc, cgf.curFn.getFunctionType().getReturnType(), *cgf.fnRetAlloca);
287     return builder.create<cir::ReturnOp>(loc,
288                                          llvm::ArrayRef(value.getResult()));
289   }
290   return builder.create<cir::ReturnOp>(loc);
291 }
292 
293 // This is copied from CodeGenModule::MayDropFunctionReturn.  This is a
294 // candidate for sharing between CIRGen and CodeGen.
295 static bool mayDropFunctionReturn(const ASTContext &astContext,
296                                   QualType returnType) {
297   // We can't just discard the return value for a record type with a complex
298   // destructor or a non-trivially copyable type.
299   if (const RecordType *recordType =
300           returnType.getCanonicalType()->getAs<RecordType>()) {
301     if (const auto *classDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl()))
302       return classDecl->hasTrivialDestructor();
303   }
304   return returnType.isTriviallyCopyableType(astContext);
305 }
306 
307 void CIRGenFunction::LexicalScope::emitImplicitReturn() {
308   CIRGenBuilderTy &builder = cgf.getBuilder();
309   LexicalScope *localScope = cgf.curLexScope;
310 
311   const auto *fd = cast<clang::FunctionDecl>(cgf.curGD.getDecl());
312 
313   // In C++, flowing off the end of a non-void function is always undefined
314   // behavior. In C, flowing off the end of a non-void function is undefined
315   // behavior only if the non-existent return value is used by the caller.
316   // That influences whether the terminating op is trap, unreachable, or
317   // return.
318   if (cgf.getLangOpts().CPlusPlus && !fd->hasImplicitReturnZero() &&
319       !cgf.sawAsmBlock && !fd->getReturnType()->isVoidType() &&
320       builder.getInsertionBlock()) {
321     bool shouldEmitUnreachable =
322         cgf.cgm.getCodeGenOpts().StrictReturn ||
323         !mayDropFunctionReturn(fd->getASTContext(), fd->getReturnType());
324 
325     if (shouldEmitUnreachable) {
326       if (cgf.cgm.getCodeGenOpts().OptimizationLevel == 0)
327         builder.create<cir::TrapOp>(localScope->endLoc);
328       else
329         builder.create<cir::UnreachableOp>(localScope->endLoc);
330       builder.clearInsertionPoint();
331       return;
332     }
333   }
334 
335   (void)emitReturn(localScope->endLoc);
336 }
337 
338 void CIRGenFunction::startFunction(GlobalDecl gd, QualType returnType,
339                                    cir::FuncOp fn, cir::FuncType funcType,
340                                    FunctionArgList args, SourceLocation loc,
341                                    SourceLocation startLoc) {
342   assert(!curFn &&
343          "CIRGenFunction can only be used for one function at a time");
344 
345   curFn = fn;
346 
347   const Decl *d = gd.getDecl();
348   const auto *fd = dyn_cast_or_null<FunctionDecl>(d);
349   curFuncDecl = d->getNonClosureContext();
350 
351   mlir::Block *entryBB = &fn.getBlocks().front();
352   builder.setInsertionPointToStart(entryBB);
353 
354   // TODO(cir): this should live in `emitFunctionProlog
355   // Declare all the function arguments in the symbol table.
356   for (const auto nameValue : llvm::zip(args, entryBB->getArguments())) {
357     const VarDecl *paramVar = std::get<0>(nameValue);
358     mlir::Value paramVal = std::get<1>(nameValue);
359     CharUnits alignment = getContext().getDeclAlign(paramVar);
360     mlir::Location paramLoc = getLoc(paramVar->getSourceRange());
361     paramVal.setLoc(paramLoc);
362 
363     mlir::Value addrVal =
364         emitAlloca(cast<NamedDecl>(paramVar)->getName(),
365                    convertType(paramVar->getType()), paramLoc, alignment,
366                    /*insertIntoFnEntryBlock=*/true);
367 
368     declare(addrVal, paramVar, paramVar->getType(), paramLoc, alignment,
369             /*isParam=*/true);
370 
371     setAddrOfLocalVar(paramVar, Address(addrVal, alignment));
372 
373     bool isPromoted = isa<ParmVarDecl>(paramVar) &&
374                       cast<ParmVarDecl>(paramVar)->isKNRPromoted();
375     assert(!cir::MissingFeatures::constructABIArgDirectExtend());
376     if (isPromoted)
377       cgm.errorNYI(fd->getSourceRange(), "Function argument demotion");
378 
379     // Location of the store to the param storage tracked as beginning of
380     // the function body.
381     mlir::Location fnBodyBegin = getLoc(fd->getBody()->getBeginLoc());
382     builder.CIRBaseBuilderTy::createStore(fnBodyBegin, paramVal, addrVal);
383   }
384   assert(builder.getInsertionBlock() && "Should be valid");
385 
386   // When the current function is not void, create an address to store the
387   // result value.
388   if (!returnType->isVoidType())
389     emitAndUpdateRetAlloca(returnType, getLoc(fd->getBody()->getEndLoc()),
390                            getContext().getTypeAlignInChars(returnType));
391 
392   if (isa_and_nonnull<CXXMethodDecl>(d) &&
393       cast<CXXMethodDecl>(d)->isInstance()) {
394     cgm.getCXXABI().emitInstanceFunctionProlog(loc, *this);
395 
396     const auto *md = cast<CXXMethodDecl>(d);
397     if (md->getParent()->isLambda() && md->getOverloadedOperator() == OO_Call) {
398       cgm.errorNYI(loc, "lambda call operator");
399     } else {
400       // Not in a lambda; just use 'this' from the method.
401       // FIXME: Should we generate a new load for each use of 'this'? The fast
402       // register allocator would be happier...
403       cxxThisValue = cxxabiThisValue;
404     }
405 
406     assert(!cir::MissingFeatures::sanitizers());
407     assert(!cir::MissingFeatures::emitTypeCheck());
408   }
409 }
410 
411 void CIRGenFunction::finishFunction(SourceLocation endLoc) {}
412 
413 mlir::LogicalResult CIRGenFunction::emitFunctionBody(const clang::Stmt *body) {
414   auto result = mlir::LogicalResult::success();
415   if (const CompoundStmt *block = dyn_cast<CompoundStmt>(body))
416     emitCompoundStmtWithoutScope(*block);
417   else
418     result = emitStmt(body, /*useCurrentScope=*/true);
419 
420   return result;
421 }
422 
423 static void eraseEmptyAndUnusedBlocks(cir::FuncOp func) {
424   // Remove any leftover blocks that are unreachable and empty, since they do
425   // not represent unreachable code useful for warnings nor anything deemed
426   // useful in general.
427   SmallVector<mlir::Block *> blocksToDelete;
428   for (mlir::Block &block : func.getBlocks()) {
429     if (block.empty() && block.getUses().empty())
430       blocksToDelete.push_back(&block);
431   }
432   for (mlir::Block *block : blocksToDelete)
433     block->erase();
434 }
435 
436 cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
437                                          cir::FuncType funcType) {
438   const auto funcDecl = cast<FunctionDecl>(gd.getDecl());
439   curGD = gd;
440 
441   SourceLocation loc = funcDecl->getLocation();
442   Stmt *body = funcDecl->getBody();
443   SourceRange bodyRange =
444       body ? body->getSourceRange() : funcDecl->getLocation();
445 
446   SourceLocRAIIObject fnLoc{*this, loc.isValid() ? getLoc(loc)
447                                                  : builder.getUnknownLoc()};
448 
449   auto validMLIRLoc = [&](clang::SourceLocation clangLoc) {
450     return clangLoc.isValid() ? getLoc(clangLoc) : builder.getUnknownLoc();
451   };
452   const mlir::Location fusedLoc = mlir::FusedLoc::get(
453       &getMLIRContext(),
454       {validMLIRLoc(bodyRange.getBegin()), validMLIRLoc(bodyRange.getEnd())});
455   mlir::Block *entryBB = fn.addEntryBlock();
456 
457   FunctionArgList args;
458   QualType retTy = buildFunctionArgList(gd, args);
459 
460   {
461     LexicalScope lexScope(*this, fusedLoc, entryBB);
462 
463     startFunction(gd, retTy, fn, funcType, args, loc, bodyRange.getBegin());
464 
465     if (isa<CXXDestructorDecl>(funcDecl)) {
466       emitDestructorBody(args);
467     } else if (isa<CXXConstructorDecl>(funcDecl)) {
468       emitConstructorBody(args);
469     } else if (getLangOpts().CUDA && !getLangOpts().CUDAIsDevice &&
470                funcDecl->hasAttr<CUDAGlobalAttr>()) {
471       getCIRGenModule().errorNYI(bodyRange, "CUDA kernel");
472     } else if (isa<CXXMethodDecl>(funcDecl) &&
473                cast<CXXMethodDecl>(funcDecl)->isLambdaStaticInvoker()) {
474       getCIRGenModule().errorNYI(bodyRange, "Lambda static invoker");
475     } else if (funcDecl->isDefaulted() && isa<CXXMethodDecl>(funcDecl) &&
476                (cast<CXXMethodDecl>(funcDecl)->isCopyAssignmentOperator() ||
477                 cast<CXXMethodDecl>(funcDecl)->isMoveAssignmentOperator())) {
478       // Implicit copy-assignment gets the same special treatment as implicit
479       // copy-constructors.
480       emitImplicitAssignmentOperatorBody(args);
481     } else if (body) {
482       if (mlir::failed(emitFunctionBody(body))) {
483         fn.erase();
484         return nullptr;
485       }
486     } else {
487       // Anything without a body should have been handled above.
488       llvm_unreachable("no definition for normal function");
489     }
490 
491     if (mlir::failed(fn.verifyBody()))
492       return nullptr;
493 
494     finishFunction(bodyRange.getEnd());
495   }
496 
497   eraseEmptyAndUnusedBlocks(fn);
498   return fn;
499 }
500 
501 void CIRGenFunction::emitConstructorBody(FunctionArgList &args) {
502   assert(!cir::MissingFeatures::sanitizers());
503   const auto *ctor = cast<CXXConstructorDecl>(curGD.getDecl());
504   CXXCtorType ctorType = curGD.getCtorType();
505 
506   assert((cgm.getTarget().getCXXABI().hasConstructorVariants() ||
507           ctorType == Ctor_Complete) &&
508          "can only generate complete ctor for this ABI");
509 
510   if (ctorType == Ctor_Complete && isConstructorDelegationValid(ctor) &&
511       cgm.getTarget().getCXXABI().hasConstructorVariants()) {
512     emitDelegateCXXConstructorCall(ctor, Ctor_Base, args, ctor->getEndLoc());
513     return;
514   }
515 
516   const FunctionDecl *definition = nullptr;
517   Stmt *body = ctor->getBody(definition);
518   assert(definition == ctor && "emitting wrong constructor body");
519 
520   if (isa_and_nonnull<CXXTryStmt>(body)) {
521     cgm.errorNYI(ctor->getSourceRange(), "emitConstructorBody: try body");
522     return;
523   }
524 
525   assert(!cir::MissingFeatures::incrementProfileCounter());
526   assert(!cir::MissingFeatures::runCleanupsScope());
527 
528   // TODO: in restricted cases, we can emit the vbase initializers of a
529   // complete ctor and then delegate to the base ctor.
530 
531   // Emit the constructor prologue, i.e. the base and member initializers.
532   emitCtorPrologue(ctor, ctorType, args);
533 
534   // TODO(cir): propagate this result via mlir::logical result. Just unreachable
535   // now just to have it handled.
536   if (mlir::failed(emitStmt(body, true))) {
537     cgm.errorNYI(ctor->getSourceRange(),
538                  "emitConstructorBody: emit body statement failed.");
539     return;
540   }
541 }
542 
543 /// Emits the body of the current destructor.
544 void CIRGenFunction::emitDestructorBody(FunctionArgList &args) {
545   const CXXDestructorDecl *dtor = cast<CXXDestructorDecl>(curGD.getDecl());
546   CXXDtorType dtorType = curGD.getDtorType();
547 
548   // For an abstract class, non-base destructors are never used (and can't
549   // be emitted in general, because vbase dtors may not have been validated
550   // by Sema), but the Itanium ABI doesn't make them optional and Clang may
551   // in fact emit references to them from other compilations, so emit them
552   // as functions containing a trap instruction.
553   if (dtorType != Dtor_Base && dtor->getParent()->isAbstract()) {
554     cgm.errorNYI(dtor->getSourceRange(), "abstract base class destructors");
555     return;
556   }
557 
558   Stmt *body = dtor->getBody();
559   assert(body && !cir::MissingFeatures::incrementProfileCounter());
560 
561   // The call to operator delete in a deleting destructor happens
562   // outside of the function-try-block, which means it's always
563   // possible to delegate the destructor body to the complete
564   // destructor.  Do so.
565   if (dtorType == Dtor_Deleting) {
566     cgm.errorNYI(dtor->getSourceRange(), "deleting destructor");
567     return;
568   }
569 
570   // If the body is a function-try-block, enter the try before
571   // anything else.
572   const bool isTryBody = isa_and_nonnull<CXXTryStmt>(body);
573   if (isTryBody)
574     cgm.errorNYI(dtor->getSourceRange(), "function-try-block destructor");
575 
576   assert(!cir::MissingFeatures::sanitizers());
577   assert(!cir::MissingFeatures::dtorCleanups());
578 
579   // If this is the complete variant, just invoke the base variant;
580   // the epilogue will destruct the virtual bases.  But we can't do
581   // this optimization if the body is a function-try-block, because
582   // we'd introduce *two* handler blocks.  In the Microsoft ABI, we
583   // always delegate because we might not have a definition in this TU.
584   switch (dtorType) {
585   case Dtor_Comdat:
586     llvm_unreachable("not expecting a COMDAT");
587   case Dtor_Deleting:
588     llvm_unreachable("already handled deleting case");
589 
590   case Dtor_Complete:
591     assert((body || getTarget().getCXXABI().isMicrosoft()) &&
592            "can't emit a dtor without a body for non-Microsoft ABIs");
593 
594     assert(!cir::MissingFeatures::dtorCleanups());
595 
596     // TODO(cir): A complete destructor is supposed to call the base destructor.
597     // Since we have to emit both dtor kinds we just fall through for now and.
598     // As long as we don't support virtual bases this should be functionally
599     // equivalent.
600     assert(!cir::MissingFeatures::completeDtors());
601 
602     // Fallthrough: act like we're in the base variant.
603     [[fallthrough]];
604 
605   case Dtor_Base:
606     assert(body);
607 
608     assert(!cir::MissingFeatures::dtorCleanups());
609     assert(!cir::MissingFeatures::vtableInitialization());
610 
611     if (isTryBody) {
612       cgm.errorNYI(dtor->getSourceRange(), "function-try-block destructor");
613     } else if (body) {
614       (void)emitStmt(body, /*useCurrentScope=*/true);
615     } else {
616       assert(dtor->isImplicit() && "bodyless dtor not implicit");
617       // nothing to do besides what's in the epilogue
618     }
619     // -fapple-kext must inline any call to this dtor into
620     // the caller's body.
621     assert(!cir::MissingFeatures::appleKext());
622 
623     break;
624   }
625 
626   assert(!cir::MissingFeatures::dtorCleanups());
627 
628   // Exit the try if applicable.
629   if (isTryBody)
630     cgm.errorNYI(dtor->getSourceRange(), "function-try-block destructor");
631 }
632 
633 /// Given a value of type T* that may not be to a complete object, construct
634 /// an l-vlaue withi the natural pointee alignment of T.
635 LValue CIRGenFunction::makeNaturalAlignPointeeAddrLValue(mlir::Value val,
636                                                          QualType ty) {
637   // FIXME(cir): is it safe to assume Op->getResult(0) is valid? Perhaps
638   // assert on the result type first.
639   LValueBaseInfo baseInfo;
640   assert(!cir::MissingFeatures::opTBAA());
641   CharUnits align = cgm.getNaturalTypeAlignment(ty, &baseInfo);
642   return makeAddrLValue(Address(val, align), ty, baseInfo);
643 }
644 
645 LValue CIRGenFunction::makeNaturalAlignAddrLValue(mlir::Value val,
646                                                   QualType ty) {
647   LValueBaseInfo baseInfo;
648   CharUnits alignment = cgm.getNaturalTypeAlignment(ty, &baseInfo);
649   Address addr(val, convertTypeForMem(ty), alignment);
650   assert(!cir::MissingFeatures::opTBAA());
651   return makeAddrLValue(addr, ty, baseInfo);
652 }
653 
654 clang::QualType CIRGenFunction::buildFunctionArgList(clang::GlobalDecl gd,
655                                                      FunctionArgList &args) {
656   const auto *fd = cast<FunctionDecl>(gd.getDecl());
657   QualType retTy = fd->getReturnType();
658 
659   const auto *md = dyn_cast<CXXMethodDecl>(fd);
660   if (md && md->isInstance()) {
661     if (cgm.getCXXABI().hasThisReturn(gd))
662       cgm.errorNYI(fd->getSourceRange(), "this return");
663     else if (cgm.getCXXABI().hasMostDerivedReturn(gd))
664       cgm.errorNYI(fd->getSourceRange(), "most derived return");
665     cgm.getCXXABI().buildThisParam(*this, args);
666   }
667 
668   if (const auto *cd = dyn_cast<CXXConstructorDecl>(fd))
669     if (cd->getInheritedConstructor())
670       cgm.errorNYI(fd->getSourceRange(),
671                    "buildFunctionArgList: inherited constructor");
672 
673   for (auto *param : fd->parameters())
674     args.push_back(param);
675 
676   if (md && (isa<CXXConstructorDecl>(md) || isa<CXXDestructorDecl>(md)))
677     assert(!cir::MissingFeatures::cxxabiStructorImplicitParam());
678 
679   return retTy;
680 }
681 
682 /// Emit code to compute a designator that specifies the location
683 /// of the expression.
684 /// FIXME: document this function better.
685 LValue CIRGenFunction::emitLValue(const Expr *e) {
686   // FIXME: ApplyDebugLocation DL(*this, e);
687   switch (e->getStmtClass()) {
688   default:
689     getCIRGenModule().errorNYI(e->getSourceRange(),
690                                std::string("l-value not implemented for '") +
691                                    e->getStmtClassName() + "'");
692     return LValue();
693   case Expr::ArraySubscriptExprClass:
694     return emitArraySubscriptExpr(cast<ArraySubscriptExpr>(e));
695   case Expr::UnaryOperatorClass:
696     return emitUnaryOpLValue(cast<UnaryOperator>(e));
697   case Expr::StringLiteralClass:
698     return emitStringLiteralLValue(cast<StringLiteral>(e));
699   case Expr::MemberExprClass:
700     return emitMemberExpr(cast<MemberExpr>(e));
701   case Expr::BinaryOperatorClass:
702     return emitBinaryOperatorLValue(cast<BinaryOperator>(e));
703   case Expr::CompoundAssignOperatorClass: {
704     QualType ty = e->getType();
705     if (ty->getAs<AtomicType>()) {
706       cgm.errorNYI(e->getSourceRange(),
707                    "CompoundAssignOperator with AtomicType");
708       return LValue();
709     }
710     if (!ty->isAnyComplexType())
711       return emitCompoundAssignmentLValue(cast<CompoundAssignOperator>(e));
712     cgm.errorNYI(e->getSourceRange(),
713                  "CompoundAssignOperator with ComplexType");
714     return LValue();
715   }
716   case Expr::CallExprClass:
717   case Expr::CXXMemberCallExprClass:
718   case Expr::CXXOperatorCallExprClass:
719   case Expr::UserDefinedLiteralClass:
720     return emitCallExprLValue(cast<CallExpr>(e));
721   case Expr::ParenExprClass:
722     return emitLValue(cast<ParenExpr>(e)->getSubExpr());
723   case Expr::DeclRefExprClass:
724     return emitDeclRefLValue(cast<DeclRefExpr>(e));
725   case Expr::CStyleCastExprClass:
726   case Expr::CXXStaticCastExprClass:
727   case Expr::CXXDynamicCastExprClass:
728   case Expr::ImplicitCastExprClass:
729     return emitCastLValue(cast<CastExpr>(e));
730   }
731 }
732 
733 static std::string getVersionedTmpName(llvm::StringRef name, unsigned cnt) {
734   SmallString<256> buffer;
735   llvm::raw_svector_ostream out(buffer);
736   out << name << cnt;
737   return std::string(out.str());
738 }
739 
740 std::string CIRGenFunction::getCounterAggTmpAsString() {
741   return getVersionedTmpName("agg.tmp", counterAggTmp++);
742 }
743 
744 void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
745                                             QualType ty) {
746   // Ignore empty classes in C++.
747   if (getLangOpts().CPlusPlus) {
748     if (const RecordType *rt = ty->getAs<RecordType>()) {
749       if (cast<CXXRecordDecl>(rt->getDecl())->isEmpty())
750         return;
751     }
752   }
753 
754   // Cast the dest ptr to the appropriate i8 pointer type.
755   if (builder.isInt8Ty(destPtr.getElementType())) {
756     cgm.errorNYI(loc, "Cast the dest ptr to the appropriate i8 pointer type");
757   }
758 
759   // Get size and alignment info for this aggregate.
760   const CharUnits size = getContext().getTypeSizeInChars(ty);
761   if (size.isZero()) {
762     // But note that getTypeInfo returns 0 for a VLA.
763     if (isa<VariableArrayType>(getContext().getAsArrayType(ty))) {
764       cgm.errorNYI(loc,
765                    "emitNullInitialization for zero size VariableArrayType");
766     } else {
767       return;
768     }
769   }
770 
771   // If the type contains a pointer to data member we can't memset it to zero.
772   // Instead, create a null constant and copy it to the destination.
773   // TODO: there are other patterns besides zero that we can usefully memset,
774   // like -1, which happens to be the pattern used by member-pointers.
775   if (!cgm.getTypes().isZeroInitializable(ty)) {
776     cgm.errorNYI(loc, "type is not zero initializable");
777   }
778 
779   // In LLVM Codegen: otherwise, just memset the whole thing to zero using
780   // Builder.CreateMemSet. In CIR just emit a store of #cir.zero to the
781   // respective address.
782   // Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, false);
783   const mlir::Value zeroValue = builder.getNullValue(convertType(ty), loc);
784   builder.createStore(loc, zeroValue, destPtr);
785 }
786 
787 // TODO(cir): should be shared with LLVM codegen.
788 bool CIRGenFunction::shouldNullCheckClassCastValue(const CastExpr *ce) {
789   const Expr *e = ce->getSubExpr();
790 
791   if (ce->getCastKind() == CK_UncheckedDerivedToBase)
792     return false;
793 
794   if (isa<CXXThisExpr>(e->IgnoreParens())) {
795     // We always assume that 'this' is never null.
796     return false;
797   }
798 
799   if (const ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(ce)) {
800     // And that glvalue casts are never null.
801     if (ice->isGLValue())
802       return false;
803   }
804 
805   return true;
806 }
807 
808 } // namespace clang::CIRGen
809