clang 22.0.0git
CIRGenFunction.h
Go to the documentation of this file.
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#ifndef CLANG_LIB_CIR_CODEGEN_CIRGENFUNCTION_H
14#define CLANG_LIB_CIR_CODEGEN_CIRGENFUNCTION_H
15
16#include "CIRGenBuilder.h"
17#include "CIRGenCall.h"
18#include "CIRGenModule.h"
19#include "CIRGenTypeCache.h"
20#include "CIRGenValue.h"
21#include "EHScopeStack.h"
22
23#include "Address.h"
24
27#include "clang/AST/CharUnits.h"
28#include "clang/AST/Decl.h"
29#include "clang/AST/Stmt.h"
30#include "clang/AST/Type.h"
34#include "llvm/ADT/ScopedHashTable.h"
35
36namespace {
37class ScalarExprEmitter;
38} // namespace
39
40namespace mlir {
41namespace acc {
42class LoopOp;
43} // namespace acc
44} // namespace mlir
45
46namespace clang::CIRGen {
47
49public:
51
52private:
53 friend class ::ScalarExprEmitter;
54 /// The builder is a helper class to create IR inside a function. The
55 /// builder is stateful, in particular it keeps an "insertion point": this
56 /// is where the next operations will be introduced.
57 CIRGenBuilderTy &builder;
58
59public:
60 /// The GlobalDecl for the current function being compiled or the global
61 /// variable currently being initialized.
63
64 /// The compiler-generated variable that holds the return value.
65 std::optional<mlir::Value> fnRetAlloca;
66
67 /// Tracks function scope overall cleanup handling.
69
70 /// CXXThisDecl - When generating code for a C++ member function,
71 /// this will hold the implicit 'this' declaration.
73 mlir::Value cxxabiThisValue = nullptr;
74 mlir::Value cxxThisValue = nullptr;
76
77 /// The value of 'this' to sue when evaluating CXXDefaultInitExprs within this
78 /// expression.
80
81 // Holds the Decl for the current outermost non-closure context
82 const clang::Decl *curFuncDecl = nullptr;
83
84 /// The function for which code is currently being generated.
85 cir::FuncOp curFn;
86
87 using DeclMapTy = llvm::DenseMap<const clang::Decl *, Address>;
88 /// This keeps track of the CIR allocas or globals for local C
89 /// declarations.
91
92 /// The type of the condition for the emitting switch statement.
94
96
97 CIRGenBuilderTy &getBuilder() { return builder; }
98
100 const CIRGenModule &getCIRGenModule() const { return cgm; }
101
102 mlir::Block *getCurFunctionEntryBlock() { return &curFn.getRegion().front(); }
103
104 /// Sanitizers enabled for this function.
106
107 /// The symbol table maps a variable name to a value in the current scope.
108 /// Entering a function creates a new scope, and the function arguments are
109 /// added to the mapping. When the processing of a function is terminated,
110 /// the scope is destroyed and the mappings created in this scope are
111 /// dropped.
112 using SymTableTy = llvm::ScopedHashTable<const clang::Decl *, mlir::Value>;
114
115 /// Whether or not a Microsoft-style asm block has been processed within
116 /// this fuction. These can potentially set the return value.
117 bool sawAsmBlock = false;
118
119 mlir::Type convertTypeForMem(QualType t);
120
121 mlir::Type convertType(clang::QualType t);
122 mlir::Type convertType(const TypeDecl *t) {
123 return convertType(getContext().getTypeDeclType(t));
124 }
125
126 /// Return the cir::TypeEvaluationKind of QualType \c type.
128
131 }
132
135 }
136
138 bool suppressNewContext = false);
140
141 CIRGenTypes &getTypes() const { return cgm.getTypes(); }
142
143 const TargetInfo &getTarget() const { return cgm.getTarget(); }
144 mlir::MLIRContext &getMLIRContext() { return cgm.getMLIRContext(); }
145
146 // ---------------------
147 // Opaque value handling
148 // ---------------------
149
150 /// Keeps track of the current set of opaque value expressions.
151 llvm::DenseMap<const OpaqueValueExpr *, LValue> opaqueLValues;
152 llvm::DenseMap<const OpaqueValueExpr *, RValue> opaqueRValues;
153
154public:
155 /// A non-RAII class containing all the information about a bound
156 /// opaque value. OpaqueValueMapping, below, is a RAII wrapper for
157 /// this which makes individual mappings very simple; using this
158 /// class directly is useful when you have a variable number of
159 /// opaque values or don't want the RAII functionality for some
160 /// reason.
162 const OpaqueValueExpr *opaqueValue;
163 bool boundLValue;
164
165 OpaqueValueMappingData(const OpaqueValueExpr *ov, bool boundLValue)
166 : opaqueValue(ov), boundLValue(boundLValue) {}
167
168 public:
169 OpaqueValueMappingData() : opaqueValue(nullptr) {}
170
171 static bool shouldBindAsLValue(const Expr *expr) {
172 // gl-values should be bound as l-values for obvious reasons.
173 // Records should be bound as l-values because IR generation
174 // always keeps them in memory. Expressions of function type
175 // act exactly like l-values but are formally required to be
176 // r-values in C.
177 return expr->isGLValue() || expr->getType()->isFunctionType() ||
179 }
180
182 bind(CIRGenFunction &cgf, const OpaqueValueExpr *ov, const Expr *e) {
183 if (shouldBindAsLValue(ov))
184 return bind(cgf, ov, cgf.emitLValue(e));
185 return bind(cgf, ov, cgf.emitAnyExpr(e));
186 }
187
189 bind(CIRGenFunction &cgf, const OpaqueValueExpr *ov, const LValue &lv) {
190 assert(shouldBindAsLValue(ov));
191 cgf.opaqueLValues.insert(std::make_pair(ov, lv));
192 return OpaqueValueMappingData(ov, true);
193 }
194
196 bind(CIRGenFunction &cgf, const OpaqueValueExpr *ov, const RValue &rv) {
197 assert(!shouldBindAsLValue(ov));
198 cgf.opaqueRValues.insert(std::make_pair(ov, rv));
199
200 OpaqueValueMappingData data(ov, false);
201
202 // Work around an extremely aggressive peephole optimization in
203 // EmitScalarConversion which assumes that all other uses of a
204 // value are extant.
206 return data;
207 }
208
209 bool isValid() const { return opaqueValue != nullptr; }
210 void clear() { opaqueValue = nullptr; }
211
213 assert(opaqueValue && "no data to unbind!");
214
215 if (boundLValue) {
216 cgf.opaqueLValues.erase(opaqueValue);
217 } else {
218 cgf.opaqueRValues.erase(opaqueValue);
220 }
221 }
222 };
223
224 /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
226 CIRGenFunction &cgf;
228
229 public:
230 static bool shouldBindAsLValue(const Expr *expr) {
232 }
233
234 /// Build the opaque value mapping for the given conditional
235 /// operator if it's the GNU ?: extension. This is a common
236 /// enough pattern that the convenience operator is really
237 /// helpful.
238 ///
241 : cgf(cgf) {
242 if (mlir::isa<ConditionalOperator>(op))
243 // Leave Data empty.
244 return;
245
247 mlir::cast<BinaryConditionalOperator>(op);
249 e->getCommon());
250 }
251
252 /// Build the opaque value mapping for an OpaqueValueExpr whose source
253 /// expression is set to the expression the OVE represents.
255 : cgf(cgf) {
256 if (ov) {
257 assert(ov->getSourceExpr() && "wrong form of OpaqueValueMapping used "
258 "for OVE with no source expression");
259 data = OpaqueValueMappingData::bind(cgf, ov, ov->getSourceExpr());
260 }
261 }
262
264 LValue lvalue)
265 : cgf(cgf),
266 data(OpaqueValueMappingData::bind(cgf, opaqueValue, lvalue)) {}
267
269 RValue rvalue)
270 : cgf(cgf),
271 data(OpaqueValueMappingData::bind(cgf, opaqueValue, rvalue)) {}
272
273 void pop() {
274 data.unbind(cgf);
275 data.clear();
276 }
277
279 if (data.isValid())
280 data.unbind(cgf);
281 }
282 };
283
284private:
285 /// Declare a variable in the current scope, return success if the variable
286 /// wasn't declared yet.
287 void declare(mlir::Value addrVal, const clang::Decl *var, clang::QualType ty,
288 mlir::Location loc, clang::CharUnits alignment,
289 bool isParam = false);
290
291public:
292 mlir::Value createDummyValue(mlir::Location loc, clang::QualType qt);
293
294 void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty);
295
296private:
297 // Track current variable initialization (if there's one)
298 const clang::VarDecl *currVarDecl = nullptr;
299 class VarDeclContext {
301 const clang::VarDecl *oldVal = nullptr;
302
303 public:
304 VarDeclContext(CIRGenFunction &p, const VarDecl *value) : p(p) {
305 if (p.currVarDecl)
306 oldVal = p.currVarDecl;
307 p.currVarDecl = value;
308 }
309
310 /// Can be used to restore the state early, before the dtor
311 /// is run.
312 void restore() { p.currVarDecl = oldVal; }
313 ~VarDeclContext() { restore(); }
314 };
315
316public:
317 /// Use to track source locations across nested visitor traversals.
318 /// Always use a `SourceLocRAIIObject` to change currSrcLoc.
319 std::optional<mlir::Location> currSrcLoc;
321 CIRGenFunction &cgf;
322 std::optional<mlir::Location> oldLoc;
323
324 public:
325 SourceLocRAIIObject(CIRGenFunction &cgf, mlir::Location value) : cgf(cgf) {
326 if (cgf.currSrcLoc)
327 oldLoc = cgf.currSrcLoc;
328 cgf.currSrcLoc = value;
329 }
330
331 /// Can be used to restore the state early, before the dtor
332 /// is run.
333 void restore() { cgf.currSrcLoc = oldLoc; }
335 };
336
338 llvm::ScopedHashTableScope<const clang::Decl *, mlir::Value>;
339
340 /// Hold counters for incrementally naming temporaries
341 unsigned counterRefTmp = 0;
342 unsigned counterAggTmp = 0;
343 std::string getCounterRefTmpAsString();
344 std::string getCounterAggTmpAsString();
345
346 /// Helpers to convert Clang's SourceLocation to a MLIR Location.
347 mlir::Location getLoc(clang::SourceLocation srcLoc);
348 mlir::Location getLoc(clang::SourceRange srcLoc);
349 mlir::Location getLoc(mlir::Location lhs, mlir::Location rhs);
350
351 const clang::LangOptions &getLangOpts() const { return cgm.getLangOpts(); }
352
353 /// True if an insertion point is defined. If not, this indicates that the
354 /// current code being emitted is unreachable.
355 /// FIXME(cir): we need to inspect this and perhaps use a cleaner mechanism
356 /// since we don't yet force null insertion point to designate behavior (like
357 /// LLVM's codegen does) and we probably shouldn't.
358 bool haveInsertPoint() const {
359 return builder.getInsertionBlock() != nullptr;
360 }
361
362 // Wrapper for function prototype sources. Wraps either a FunctionProtoType or
363 // an ObjCMethodDecl.
365 llvm::PointerUnion<const clang::FunctionProtoType *,
366 const clang::ObjCMethodDecl *>
368
371 };
372
374
375 /// An abstract representation of regular/ObjC call/message targets.
377 /// The function declaration of the callee.
378 [[maybe_unused]] const clang::Decl *calleeDecl;
379
380 public:
381 AbstractCallee() : calleeDecl(nullptr) {}
382 AbstractCallee(const clang::FunctionDecl *fd) : calleeDecl(fd) {}
383
384 bool hasFunctionDecl() const {
385 return llvm::isa_and_nonnull<clang::FunctionDecl>(calleeDecl);
386 }
387
388 unsigned getNumParams() const {
389 if (const auto *fd = llvm::dyn_cast<clang::FunctionDecl>(calleeDecl))
390 return fd->getNumParams();
391 return llvm::cast<clang::ObjCMethodDecl>(calleeDecl)->param_size();
392 }
393
394 const clang::ParmVarDecl *getParamDecl(unsigned I) const {
395 if (const auto *fd = llvm::dyn_cast<clang::FunctionDecl>(calleeDecl))
396 return fd->getParamDecl(I);
397 return *(llvm::cast<clang::ObjCMethodDecl>(calleeDecl)->param_begin() +
398 I);
399 }
400 };
401
402 void finishFunction(SourceLocation endLoc);
403
404 /// Determine whether the given initializer is trivial in the sense
405 /// that it requires no code to be generated.
406 bool isTrivialInitializer(const Expr *init);
407
408 /// If the specified expression does not fold to a constant, or if it does but
409 /// contains a label, return false. If it constant folds return true and set
410 /// the boolean result in Result.
411 bool constantFoldsToBool(const clang::Expr *cond, bool &resultBool,
412 bool allowLabels = false);
414 llvm::APSInt &resultInt,
415 bool allowLabels = false);
416
417 /// Return true if the statement contains a label in it. If
418 /// this statement is not executed normally, it not containing a label means
419 /// that we can just remove the code.
420 bool containsLabel(const clang::Stmt *s, bool ignoreCaseStmts = false);
421
423 // Cannot use mlir::TypedAttr directly here because of bit availability.
424 llvm::PointerIntPair<mlir::Attribute, 1, bool> valueAndIsReference;
425 ConstantEmission(mlir::TypedAttr c, bool isReference)
426 : valueAndIsReference(c, isReference) {}
427
428 public:
430 static ConstantEmission forReference(mlir::TypedAttr c) {
431 return ConstantEmission(c, true);
432 }
433 static ConstantEmission forValue(mlir::TypedAttr c) {
434 return ConstantEmission(c, false);
435 }
436
437 explicit operator bool() const {
438 return valueAndIsReference.getOpaqueValue() != nullptr;
439 }
440
441 bool isReference() const { return valueAndIsReference.getInt(); }
443 assert(isReference());
444 cgf.cgm.errorNYI(refExpr->getSourceRange(),
445 "ConstantEmission::getReferenceLValue");
446 return {};
447 }
448
449 mlir::TypedAttr getValue() const {
450 assert(!isReference());
451 return mlir::cast<mlir::TypedAttr>(valueAndIsReference.getPointer());
452 }
453 };
454
455 ConstantEmission tryEmitAsConstant(const DeclRefExpr *refExpr);
456 ConstantEmission tryEmitAsConstant(const MemberExpr *me);
457
460 /// The address of the alloca for languages with explicit address space
461 /// (e.g. OpenCL) or alloca casted to generic pointer for address space
462 /// agnostic languages (e.g. C++). Invalid if the variable was emitted
463 /// as a global constant.
465
466 /// True if the variable is of aggregate type and has a constant
467 /// initializer.
469
470 /// True if the variable is a __block variable that is captured by an
471 /// escaping block.
472 bool IsEscapingByRef = false;
473
474 /// True if the variable was emitted as an offload recipe, and thus doesn't
475 /// have the same sort of alloca initialization.
476 bool EmittedAsOffload = false;
477
478 mlir::Value NRVOFlag{};
479
480 struct Invalid {};
482
484 : Variable(&variable), Addr(Address::invalid()) {}
485
487
488 bool wasEmittedAsGlobal() const { return !Addr.isValid(); }
489
491
492 /// Returns the raw, allocated address, which is not necessarily
493 /// the address of the object itself. It is casted to default
494 /// address space for address space agnostic languages.
495 Address getAllocatedAddress() const { return Addr; }
496
497 // Changes the stored address for the emission. This function should only
498 // be used in extreme cases, and isn't required to model normal AST
499 // initialization/variables.
501
502 /// Returns the address of the object within this declaration.
503 /// Note that this does not chase the forwarding pointer for
504 /// __block decls.
506 if (!IsEscapingByRef)
507 return Addr;
508
510 return Address::invalid();
511 }
512 };
513
514 /// Perform the usual unary conversions on the specified expression and
515 /// compare the result against zero, returning an Int1Ty value.
516 mlir::Value evaluateExprAsBool(const clang::Expr *e);
517
518 cir::GlobalOp addInitializerToStaticVarDecl(const VarDecl &d,
519 cir::GlobalOp gv,
520 cir::GetGlobalOp gvAddr);
521
522 /// Set the address of a local variable.
524 assert(!localDeclMap.count(vd) && "Decl already exists in LocalDeclMap!");
525 localDeclMap.insert({vd, addr});
526
527 // Add to the symbol table if not there already.
528 if (symbolTable.count(vd))
529 return;
530 symbolTable.insert(vd, addr.getPointer());
531 }
532
533 // A class to allow reverting changes to a var-decl's registration to the
534 // localDeclMap. This is used in cases where things are being inserted into
535 // the variable list but don't follow normal lookup/search rules, like in
536 // OpenACC recipe generation.
538 CIRGenFunction &cgf;
539 const VarDecl *vd;
540 bool shouldDelete = false;
541 Address oldAddr = Address::invalid();
542
543 public:
545 : cgf(cgf), vd(vd) {
546 auto mapItr = cgf.localDeclMap.find(vd);
547
548 if (mapItr != cgf.localDeclMap.end())
549 oldAddr = mapItr->second;
550 else
551 shouldDelete = true;
552 }
553
555 if (shouldDelete)
556 cgf.localDeclMap.erase(vd);
557 else
558 cgf.localDeclMap.insert_or_assign(vd, oldAddr);
559 }
560 };
561
563
566
567 static bool
569
570 struct VPtr {
575 };
576
579
583 const clang::CXXRecordDecl *nearestVBase,
584 clang::CharUnits offsetFromNearestVBase,
585 bool baseIsNonVirtualPrimaryBase,
586 const clang::CXXRecordDecl *vtableClass,
587 VisitedVirtualBasesSetTy &vbases, VPtrsVector &vptrs);
588 /// Return the Value of the vtable pointer member pointed to by thisAddr.
589 mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr,
590 const clang::CXXRecordDecl *vtableClass);
591
592 /// Returns whether we should perform a type checked load when loading a
593 /// virtual function for virtual calls to members of RD. This is generally
594 /// true when both vcall CFI and whole-program-vtables are enabled.
596
597 /// A scope within which we are constructing the fields of an object which
598 /// might use a CXXDefaultInitExpr. This stashes away a 'this' value to use if
599 /// we need to evaluate the CXXDefaultInitExpr within the evaluation.
601 public:
603 : cgf(cgf), oldCXXDefaultInitExprThis(cgf.cxxDefaultInitExprThis) {
604 cgf.cxxDefaultInitExprThis = thisAddr;
605 }
607 cgf.cxxDefaultInitExprThis = oldCXXDefaultInitExprThis;
608 }
609
610 private:
611 CIRGenFunction &cgf;
612 Address oldCXXDefaultInitExprThis;
613 };
614
616 LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty);
617
618 /// Construct an address with the natural alignment of T. If a pointer to T
619 /// is expected to be signed, the pointer passed to this function must have
620 /// been signed, and the returned Address will have the pointer authentication
621 /// information needed to authenticate the signed pointer.
623 CharUnits alignment,
624 bool forPointeeType = false,
625 LValueBaseInfo *baseInfo = nullptr) {
626 if (alignment.isZero())
627 alignment = cgm.getNaturalTypeAlignment(t, baseInfo);
628 return Address(ptr, convertTypeForMem(t), alignment);
629 }
630
632 Address value, const CXXRecordDecl *derived,
633 llvm::iterator_range<CastExpr::path_const_iterator> path,
634 bool nullCheckValue, SourceLocation loc);
635
638 return makeAddrLValue(addr, ty, LValueBaseInfo(source));
639 }
640
642 return LValue::makeAddr(addr, ty, baseInfo);
643 }
644
645 void initializeVTablePointers(mlir::Location loc,
646 const clang::CXXRecordDecl *rd);
647 void initializeVTablePointer(mlir::Location loc, const VPtr &vptr);
648
649 /// Return the address of a local variable.
651 auto it = localDeclMap.find(vd);
652 assert(it != localDeclMap.end() &&
653 "Invalid argument to getAddrOfLocalVar(), no decl!");
654 return it->second;
655 }
656
658 mlir::Type fieldType, unsigned index);
659
660 /// Load the value for 'this'. This function is only valid while generating
661 /// code for an C++ member function.
662 /// FIXME(cir): this should return a mlir::Value!
663 mlir::Value loadCXXThis() {
664 assert(cxxThisValue && "no 'this' value for this function");
665 return cxxThisValue;
666 }
668
669 /// Convert the given pointer to a complete class to the given direct base.
671 Address value,
672 const CXXRecordDecl *derived,
673 const CXXRecordDecl *base,
674 bool baseIsVirtual);
675
676 /// Determine whether a base class initialization may overlap some other
677 /// object.
679 const CXXRecordDecl *baseRD,
680 bool isVirtual);
681
682 /// Get an appropriate 'undef' rvalue for the given type.
683 /// TODO: What's the equivalent for MLIR? Currently we're only using this for
684 /// void types so it just returns RValue::get(nullptr) but it'll need
685 /// addressed later.
687
688 cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
689 cir::FuncType funcType);
690
692 FunctionArgList &args);
693
694 /// Emit code for the start of a function.
695 /// \param loc The location to be associated with the function.
696 /// \param startLoc The location of the function body.
698 cir::FuncOp fn, cir::FuncType funcType,
700 clang::SourceLocation startLoc);
701
702 /// The cleanup depth enclosing all the cleanups associated with the
703 /// parameters.
705
706 /// Takes the old cleanup stack size and emits the cleanup blocks
707 /// that have been added.
708 void popCleanupBlocks(EHScopeStack::stable_iterator oldCleanupStackDepth);
709 void popCleanupBlock();
710
711 /// Push a cleanup to be run at the end of the current full-expression. Safe
712 /// against the possibility that we're currently inside a
713 /// conditionally-evaluated expression.
714 template <class T, class... As>
715 void pushFullExprCleanup(CleanupKind kind, As... a) {
716 // If we're not in a conditional branch, or if none of the
717 // arguments requires saving, then use the unconditional cleanup.
719 return ehStack.pushCleanup<T>(kind, a...);
720
721 cgm.errorNYI("pushFullExprCleanup in conditional branch");
722 }
723
724 /// Enters a new scope for capturing cleanups, all of which
725 /// will be executed once the scope is exited.
727 EHScopeStack::stable_iterator cleanupStackDepth, oldCleanupStackDepth;
728
729 protected:
731
732 private:
733 RunCleanupsScope(const RunCleanupsScope &) = delete;
734 void operator=(const RunCleanupsScope &) = delete;
735
736 protected:
738
739 public:
740 /// Enter a new cleanup scope.
743 cleanupStackDepth = cgf.ehStack.stable_begin();
744 oldCleanupStackDepth = cgf.currentCleanupStackDepth;
745 cgf.currentCleanupStackDepth = cleanupStackDepth;
746 }
747
748 /// Exit this cleanup scope, emitting any accumulated cleanups.
750 if (performCleanup)
751 forceCleanup();
752 }
753
754 /// Force the emission of cleanups now, instead of waiting
755 /// until this object is destroyed.
757 assert(performCleanup && "Already forced cleanup");
758 {
759 mlir::OpBuilder::InsertionGuard guard(cgf.getBuilder());
760 cgf.popCleanupBlocks(cleanupStackDepth);
761 performCleanup = false;
762 cgf.currentCleanupStackDepth = oldCleanupStackDepth;
763 }
764 }
765 };
766
767 // Cleanup stack depth of the RunCleanupsScope that was pushed most recently.
769
770public:
771 /// Represents a scope, including function bodies, compound statements, and
772 /// the substatements of if/while/do/for/switch/try statements. This class
773 /// handles any automatic cleanup, along with the return value.
775 private:
776 // Block containing cleanup code for things initialized in this
777 // lexical context (scope).
778 mlir::Block *cleanupBlock = nullptr;
779
780 // Points to the scope entry block. This is useful, for instance, for
781 // helping to insert allocas before finalizing any recursive CodeGen from
782 // switches.
783 mlir::Block *entryBlock;
784
785 LexicalScope *parentScope = nullptr;
786
787 // Only Regular is used at the moment. Support for other kinds will be
788 // added as the relevant statements/expressions are upstreamed.
789 enum Kind {
790 Regular, // cir.if, cir.scope, if_regions
791 Ternary, // cir.ternary
792 Switch, // cir.switch
793 Try, // cir.try
794 GlobalInit // cir.global initialization code
795 };
796 Kind scopeKind = Kind::Regular;
797
798 // The scope return value.
799 mlir::Value retVal = nullptr;
800
801 mlir::Location beginLoc;
802 mlir::Location endLoc;
803
804 public:
805 unsigned depth = 0;
806
807 LexicalScope(CIRGenFunction &cgf, mlir::Location loc, mlir::Block *eb)
808 : RunCleanupsScope(cgf), entryBlock(eb), parentScope(cgf.curLexScope),
809 beginLoc(loc), endLoc(loc) {
810
811 assert(entryBlock && "LexicalScope requires an entry block");
812 cgf.curLexScope = this;
813 if (parentScope)
814 ++depth;
815
816 if (const auto fusedLoc = mlir::dyn_cast<mlir::FusedLoc>(loc)) {
817 assert(fusedLoc.getLocations().size() == 2 && "too many locations");
818 beginLoc = fusedLoc.getLocations()[0];
819 endLoc = fusedLoc.getLocations()[1];
820 }
821 }
822
823 void setRetVal(mlir::Value v) { retVal = v; }
824
825 void cleanup();
826 void restore() { cgf.curLexScope = parentScope; }
827
830 cleanup();
831 restore();
832 }
833
834 // ---
835 // Kind
836 // ---
837 bool isGlobalInit() { return scopeKind == Kind::GlobalInit; }
838 bool isRegular() { return scopeKind == Kind::Regular; }
839 bool isSwitch() { return scopeKind == Kind::Switch; }
840 bool isTernary() { return scopeKind == Kind::Ternary; }
841 bool isTry() { return scopeKind == Kind::Try; }
842
843 void setAsGlobalInit() { scopeKind = Kind::GlobalInit; }
844 void setAsSwitch() { scopeKind = Kind::Switch; }
845 void setAsTernary() { scopeKind = Kind::Ternary; }
846
847 // Lazy create cleanup block or return what's available.
848 mlir::Block *getOrCreateCleanupBlock(mlir::OpBuilder &builder) {
849 if (cleanupBlock)
850 return cleanupBlock;
851 cleanupBlock = createCleanupBlock(builder);
852 return cleanupBlock;
853 }
854
855 mlir::Block *getCleanupBlock(mlir::OpBuilder &builder) {
856 return cleanupBlock;
857 }
858
859 mlir::Block *createCleanupBlock(mlir::OpBuilder &builder) {
860 // Create the cleanup block but dont hook it up around just yet.
861 mlir::OpBuilder::InsertionGuard guard(builder);
862 mlir::Region *r = builder.getBlock() ? builder.getBlock()->getParent()
863 : &cgf.curFn->getRegion(0);
864 cleanupBlock = builder.createBlock(r);
865 return cleanupBlock;
866 }
867
868 // ---
869 // Return handling.
870 // ---
871
872 private:
873 // `returnBlock`, `returnLoc`, and all the functions that deal with them
874 // will change and become more complicated when `switch` statements are
875 // upstreamed. `case` statements within the `switch` are in the same scope
876 // but have their own regions. Therefore the LexicalScope will need to
877 // keep track of multiple return blocks.
878 mlir::Block *returnBlock = nullptr;
879 std::optional<mlir::Location> returnLoc;
880
881 // See the comment on `getOrCreateRetBlock`.
882 mlir::Block *createRetBlock(CIRGenFunction &cgf, mlir::Location loc) {
883 assert(returnBlock == nullptr && "only one return block per scope");
884 // Create the cleanup block but don't hook it up just yet.
885 mlir::OpBuilder::InsertionGuard guard(cgf.builder);
886 returnBlock =
887 cgf.builder.createBlock(cgf.builder.getBlock()->getParent());
888 updateRetLoc(returnBlock, loc);
889 return returnBlock;
890 }
891
892 cir::ReturnOp emitReturn(mlir::Location loc);
893 void emitImplicitReturn();
894
895 public:
896 mlir::Block *getRetBlock() { return returnBlock; }
897 mlir::Location getRetLoc(mlir::Block *b) { return *returnLoc; }
898 void updateRetLoc(mlir::Block *b, mlir::Location loc) { returnLoc = loc; }
899
900 // Create the return block for this scope, or return the existing one.
901 // This get-or-create logic is necessary to handle multiple return
902 // statements within the same scope, which can happen if some of them are
903 // dead code or if there is a `goto` into the middle of the scope.
904 mlir::Block *getOrCreateRetBlock(CIRGenFunction &cgf, mlir::Location loc) {
905 if (returnBlock == nullptr) {
906 returnBlock = createRetBlock(cgf, loc);
907 return returnBlock;
908 }
909 updateRetLoc(returnBlock, loc);
910 return returnBlock;
911 }
912
913 mlir::Block *getEntryBlock() { return entryBlock; }
914 };
915
917
918 typedef void Destroyer(CIRGenFunction &cgf, Address addr, QualType ty);
919
921
923 Destroyer *destroyer);
924
926
927 /// ----------------------
928 /// CIR emit functions
929 /// ----------------------
930public:
931 mlir::Value emitAlignmentAssumption(mlir::Value ptrValue, QualType ty,
932 SourceLocation loc,
933 SourceLocation assumptionLoc,
934 int64_t alignment,
935 mlir::Value offsetValue = nullptr);
936
937 mlir::Value emitAlignmentAssumption(mlir::Value ptrValue, const Expr *expr,
938 SourceLocation assumptionLoc,
939 int64_t alignment,
940 mlir::Value offsetValue = nullptr);
941
942private:
943 void emitAndUpdateRetAlloca(clang::QualType type, mlir::Location loc,
944 clang::CharUnits alignment);
945
946 CIRGenCallee emitDirectCallee(const GlobalDecl &gd);
947
948public:
950 llvm::StringRef fieldName,
951 unsigned fieldIndex);
952
953 mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty,
954 mlir::Location loc, clang::CharUnits alignment,
955 bool insertIntoFnEntryBlock,
956 mlir::Value arraySize = nullptr);
957 mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty,
958 mlir::Location loc, clang::CharUnits alignment,
959 mlir::OpBuilder::InsertPoint ip,
960 mlir::Value arraySize = nullptr);
961
962 void emitAggregateStore(mlir::Value value, Address dest);
963
964 void emitAggExpr(const clang::Expr *e, AggValueSlot slot);
965
967
968 /// Emit code to compute the specified expression which can have any type. The
969 /// result is returned as an RValue struct. If this is an aggregate
970 /// expression, the aggloc/agglocvolatile arguments indicate where the result
971 /// should be returned.
974
975 /// Emits the code necessary to evaluate an arbitrary expression into the
976 /// given memory location.
977 void emitAnyExprToMem(const Expr *e, Address location, Qualifiers quals,
978 bool isInitializer);
979
980 /// Similarly to emitAnyExpr(), however, the result will always be accessible
981 /// even if no aggregate location is provided.
983
984 void emitArrayDestroy(mlir::Value begin, mlir::Value end,
985 QualType elementType, CharUnits elementAlign,
986 Destroyer *destroyer);
987
988 mlir::Value emitArrayLength(const clang::ArrayType *arrayType,
989 QualType &baseType, Address &addr);
991
993 LValueBaseInfo *baseInfo = nullptr);
994
995 mlir::LogicalResult emitAsmStmt(const clang::AsmStmt &s);
996
998 void emitAtomicInit(Expr *init, LValue dest);
999
1001 mlir::OpBuilder::InsertPoint ip = {});
1002
1003 /// Emit code and set up symbol table for a variable declaration with auto,
1004 /// register, or no storage class specifier. These turn into simple stack
1005 /// objects, globals depending on target.
1006 void emitAutoVarDecl(const clang::VarDecl &d);
1007
1008 void emitAutoVarCleanups(const AutoVarEmission &emission);
1009 /// Emit the initializer for an allocated variable. If this call is not
1010 /// associated with the call to emitAutoVarAlloca (as the address of the
1011 /// emission is not directly an alloca), the allocatedSeparately parameter can
1012 /// be used to suppress the assertions. However, this should only be used in
1013 /// extreme cases, as it doesn't properly reflect the language/AST.
1014 void emitAutoVarInit(const AutoVarEmission &emission);
1015 void emitAutoVarTypeCleanup(const AutoVarEmission &emission,
1017
1018 void maybeEmitDeferredVarDeclInit(const VarDecl *vd);
1019
1020 void emitBaseInitializer(mlir::Location loc, const CXXRecordDecl *classDecl,
1021 CXXCtorInitializer *baseInit);
1022
1024
1025 mlir::LogicalResult emitBreakStmt(const clang::BreakStmt &s);
1026
1027 RValue emitBuiltinExpr(const clang::GlobalDecl &gd, unsigned builtinID,
1028 const clang::CallExpr *e, ReturnValueSlot returnValue);
1029
1030 RValue emitCall(const CIRGenFunctionInfo &funcInfo,
1031 const CIRGenCallee &callee, ReturnValueSlot returnValue,
1032 const CallArgList &args, cir::CIRCallOpInterface *callOp,
1033 mlir::Location loc);
1035 const CIRGenCallee &callee, ReturnValueSlot returnValue,
1036 const CallArgList &args,
1037 cir::CIRCallOpInterface *callOrTryCall = nullptr) {
1038 assert(currSrcLoc && "source location must have been set");
1039 return emitCall(funcInfo, callee, returnValue, args, callOrTryCall,
1040 *currSrcLoc);
1041 }
1042
1043 RValue emitCall(clang::QualType calleeTy, const CIRGenCallee &callee,
1044 const clang::CallExpr *e, ReturnValueSlot returnValue);
1045 void emitCallArg(CallArgList &args, const clang::Expr *e,
1046 clang::QualType argType);
1047 void emitCallArgs(
1048 CallArgList &args, PrototypeWrapper prototype,
1049 llvm::iterator_range<clang::CallExpr::const_arg_iterator> argRange,
1050 AbstractCallee callee = AbstractCallee(), unsigned paramsToSkip = 0);
1052 ReturnValueSlot returnValue = ReturnValueSlot());
1055
1056 template <typename T>
1057 mlir::LogicalResult emitCaseDefaultCascade(const T *stmt, mlir::Type condType,
1058 mlir::ArrayAttr value,
1059 cir::CaseOpKind kind,
1060 bool buildingTopLevelCase);
1061
1062 mlir::LogicalResult emitCaseStmt(const clang::CaseStmt &s,
1063 mlir::Type condType,
1064 bool buildingTopLevelCase);
1065
1066 LValue emitCastLValue(const CastExpr *e);
1067
1068 /// Emits an argument for a call to a `__builtin_assume`. If the builtin
1069 /// sanitizer is enabled, a runtime check is also emitted.
1070 mlir::Value emitCheckedArgForAssume(const Expr *e);
1071
1072 /// Emit a conversion from the specified complex type to the specified
1073 /// destination type, where the destination type is an LLVM scalar type.
1074 mlir::Value emitComplexToScalarConversion(mlir::Value src, QualType srcTy,
1075 QualType dstTy, SourceLocation loc);
1076
1079
1081
1082 void emitDestroy(Address addr, QualType type, Destroyer *destroyer);
1083
1085
1086 mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s);
1087
1089 AggValueSlot dest);
1090
1093 Address arrayBegin, const CXXConstructExpr *e,
1094 bool newPointerIsChecked,
1095 bool zeroInitialize = false);
1097 mlir::Value numElements, Address arrayBase,
1098 const CXXConstructExpr *e,
1099 bool newPointerIsChecked,
1100 bool zeroInitialize);
1102 clang::CXXCtorType type, bool forVirtualBase,
1103 bool delegating, AggValueSlot thisAVS,
1104 const clang::CXXConstructExpr *e);
1105
1107 clang::CXXCtorType type, bool forVirtualBase,
1108 bool delegating, Address thisAddr,
1110
1112 bool forVirtualBase, bool delegating,
1113 Address thisAddr, QualType thisTy);
1114
1116 mlir::Value thisVal, QualType thisTy,
1117 mlir::Value implicitParam,
1118 QualType implicitParamTy, const CallExpr *e);
1119
1120 mlir::LogicalResult emitCXXForRangeStmt(const CXXForRangeStmt &s,
1122
1124 ReturnValueSlot returnValue);
1125
1127 const clang::CXXMethodDecl *md, const CIRGenCallee &callee,
1128 ReturnValueSlot returnValue, mlir::Value thisPtr,
1129 mlir::Value implicitParam, clang::QualType implicitParamTy,
1130 const clang::CallExpr *ce, CallArgList *rtlArgs);
1131
1133 const clang::CallExpr *ce, const clang::CXXMethodDecl *md,
1134 ReturnValueSlot returnValue, bool hasQualifier,
1135 clang::NestedNameSpecifier qualifier, bool isArrow,
1136 const clang::Expr *base);
1137
1138 mlir::Value emitCXXNewExpr(const CXXNewExpr *e);
1139
1141 const CXXMethodDecl *md,
1142 ReturnValueSlot returnValue);
1143
1145
1146 void emitCXXThrowExpr(const CXXThrowExpr *e);
1147
1149 clang::CXXCtorType ctorType, FunctionArgList &args);
1150
1151 // It's important not to confuse this and emitDelegateCXXConstructorCall.
1152 // Delegating constructors are the C++11 feature. The constructor delegate
1153 // optimization is used to reduce duplication in the base and complete
1154 // constructors where they are substantially the same.
1156 const FunctionArgList &args);
1157
1158 mlir::LogicalResult emitDoStmt(const clang::DoStmt &s);
1159
1160 /// Emit an expression as an initializer for an object (variable, field, etc.)
1161 /// at the given location. The expression is not necessarily the normal
1162 /// initializer for the object, and the address is not necessarily
1163 /// its normal location.
1164 ///
1165 /// \param init the initializing expression
1166 /// \param d the object to act as if we're initializing
1167 /// \param lvalue the lvalue to initialize
1168 /// \param capturedByInit true if \p d is a __block variable whose address is
1169 /// potentially changed by the initializer
1170 void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d,
1171 LValue lvalue, bool capturedByInit = false);
1172
1173 mlir::LogicalResult emitFunctionBody(const clang::Stmt *body);
1174
1175 mlir::LogicalResult emitGotoStmt(const clang::GotoStmt &s);
1176
1178
1180 clang::Expr *init);
1181
1182 mlir::Value emitPromotedComplexExpr(const Expr *e, QualType promotionType);
1183
1184 mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType);
1185
1186 mlir::Value emitPromotedValue(mlir::Value result, QualType promotionType);
1187
1188 /// Emit the computation of the specified expression of scalar type.
1189 mlir::Value emitScalarExpr(const clang::Expr *e);
1190
1191 mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,
1192 cir::UnaryOpKind kind, bool isPre);
1193
1194 /// Build a debug stoppoint if we are emitting debug info.
1195 void emitStopPoint(const Stmt *s);
1196
1197 // Build CIR for a statement. useCurrentScope should be true if no
1198 // new scopes need be created when finding a compound statement.
1199 mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope,
1200 llvm::ArrayRef<const Attr *> attrs = {});
1201
1202 mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s,
1203 bool useCurrentScope);
1204
1205 mlir::LogicalResult emitForStmt(const clang::ForStmt &s);
1206
1207 /// Emit the computation of the specified expression of complex type,
1208 /// returning the result.
1209 mlir::Value emitComplexExpr(const Expr *e);
1210
1211 void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit);
1212
1213 mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv,
1214 cir::UnaryOpKind op, bool isPre);
1215
1219 mlir::Value &result);
1220
1221 mlir::LogicalResult
1222 emitCompoundStmt(const clang::CompoundStmt &s, Address *lastValue = nullptr,
1224
1225 mlir::LogicalResult
1227 Address *lastValue = nullptr,
1229
1230 void emitDecl(const clang::Decl &d, bool evaluateConditionDecl = false);
1231 mlir::LogicalResult emitDeclStmt(const clang::DeclStmt &s);
1233
1234 mlir::LogicalResult emitDefaultStmt(const clang::DefaultStmt &s,
1235 mlir::Type condType,
1236 bool buildingTopLevelCase);
1237
1239 clang::CXXCtorType ctorType,
1240 const FunctionArgList &args,
1242
1243 /// We are performing a delegate call; that is, the current function is
1244 /// delegating to another one. Produce a r-value suitable for passing the
1245 /// given parameter.
1246 void emitDelegateCallArg(CallArgList &args, const clang::VarDecl *param,
1248
1249 /// Emit an `if` on a boolean condition to the specified blocks.
1250 /// FIXME: Based on the condition, this might try to simplify the codegen of
1251 /// the conditional based on the branch.
1252 /// In the future, we may apply code generation simplifications here,
1253 /// similar to those used in classic LLVM codegen
1254 /// See `EmitBranchOnBoolExpr` for inspiration.
1255 mlir::LogicalResult emitIfOnBoolExpr(const clang::Expr *cond,
1256 const clang::Stmt *thenS,
1257 const clang::Stmt *elseS);
1258 cir::IfOp emitIfOnBoolExpr(const clang::Expr *cond,
1259 BuilderCallbackRef thenBuilder,
1260 mlir::Location thenLoc,
1261 BuilderCallbackRef elseBuilder,
1262 std::optional<mlir::Location> elseLoc = {});
1263
1264 mlir::Value emitOpOnBoolExpr(mlir::Location loc, const clang::Expr *cond);
1265
1266 mlir::LogicalResult emitLabel(const clang::LabelDecl &d);
1267 mlir::LogicalResult emitLabelStmt(const clang::LabelStmt &s);
1268
1269 mlir::LogicalResult emitIfStmt(const clang::IfStmt &s);
1270
1271 /// Emit code to compute the specified expression,
1272 /// ignoring the result.
1273 void emitIgnoredExpr(const clang::Expr *e);
1274
1275 RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc);
1276
1277 /// Load a complex number from the specified l-value.
1278 mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc);
1279
1280 /// Given an expression that represents a value lvalue, this method emits
1281 /// the address of the lvalue, then loads the result as an rvalue,
1282 /// returning the rvalue.
1283 RValue emitLoadOfLValue(LValue lv, SourceLocation loc);
1284
1285 Address emitLoadOfReference(LValue refLVal, mlir::Location loc,
1286 LValueBaseInfo *pointeeBaseInfo);
1287 LValue emitLoadOfReferenceLValue(Address refAddr, mlir::Location loc,
1288 QualType refTy, AlignmentSource source);
1289
1290 /// EmitLoadOfScalar - Load a scalar value from an address, taking
1291 /// care to appropriately convert from the memory representation to
1292 /// the LLVM value representation. The l-value must be a simple
1293 /// l-value.
1294 mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc);
1295
1296 /// Emit code to compute a designator that specifies the location
1297 /// of the expression.
1298 /// FIXME: document this function better.
1299 LValue emitLValue(const clang::Expr *e);
1300 LValue emitLValueForBitField(LValue base, const FieldDecl *field);
1301 LValue emitLValueForField(LValue base, const clang::FieldDecl *field);
1302
1303 /// Like emitLValueForField, excpet that if the Field is a reference, this
1304 /// will return the address of the reference and not the address of the value
1305 /// stored in the reference.
1306 LValue emitLValueForFieldInitialization(LValue base,
1307 const clang::FieldDecl *field,
1308 llvm::StringRef fieldName);
1309
1311
1312 LValue emitMemberExpr(const MemberExpr *e);
1313
1314 /// Given an expression with a pointer type, emit the value and compute our
1315 /// best estimate of the alignment of the pointee.
1316 ///
1317 /// One reasonable way to use this information is when there's a language
1318 /// guarantee that the pointer must be aligned to some stricter value, and
1319 /// we're simply trying to ensure that sufficiently obvious uses of under-
1320 /// aligned objects don't get miscompiled; for example, a placement new
1321 /// into the address of a local variable. In such a case, it's quite
1322 /// reasonable to just ignore the returned alignment when it isn't from an
1323 /// explicit source.
1325 LValueBaseInfo *baseInfo = nullptr);
1326
1327 /// Emits a reference binding to the passed in expression.
1328 RValue emitReferenceBindingToExpr(const Expr *e);
1329
1330 mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s);
1331
1332 RValue emitRotate(const CallExpr *e, bool isRotateLeft);
1333
1334 mlir::Value emitScalarConstant(const ConstantEmission &constant, Expr *e);
1335
1336 /// Emit a conversion from the specified type to the specified destination
1337 /// type, both of which are CIR scalar types.
1338 mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType,
1339 clang::QualType dstType,
1341
1342 void emitScalarInit(const clang::Expr *init, mlir::Location loc,
1343 LValue lvalue, bool capturedByInit = false);
1344
1345 void emitStaticVarDecl(const VarDecl &d, cir::GlobalLinkageKind linkage);
1346
1347 void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest,
1348 bool isInit);
1349
1350 void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile,
1351 clang::QualType ty, bool isInit = false,
1352 bool isNontemporal = false);
1353 void emitStoreOfScalar(mlir::Value value, LValue lvalue, bool isInit);
1354
1355 /// Store the specified rvalue into the specified
1356 /// lvalue, where both are guaranteed to the have the same type, and that type
1357 /// is 'Ty'.
1358 void emitStoreThroughLValue(RValue src, LValue dst, bool isInit = false);
1359
1360 mlir::Value emitStoreThroughBitfieldLValue(RValue src, LValue dstresult);
1361
1362 LValue emitStringLiteralLValue(const StringLiteral *e);
1363
1364 mlir::LogicalResult emitSwitchBody(const clang::Stmt *s);
1365 mlir::LogicalResult emitSwitchCase(const clang::SwitchCase &s,
1366 bool buildingTopLevelCase);
1367 mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s);
1368
1369 /// Given a value and its clang type, returns the value casted to its memory
1370 /// representation.
1371 /// Note: CIR defers most of the special casting to the final lowering passes
1372 /// to conserve the high level information.
1373 mlir::Value emitToMemory(mlir::Value value, clang::QualType ty);
1374
1375 /// Emit a trap instruction, which is used to abort the program in an abnormal
1376 /// way, usually for debugging purposes.
1377 /// \p createNewBlock indicates whether to create a new block for the IR
1378 /// builder. Since the `cir.trap` operation is a terminator, operations that
1379 /// follow a trap cannot be emitted after `cir.trap` in the same block. To
1380 /// ensure these operations get emitted successfully, you need to create a new
1381 /// dummy block and set the insertion point there before continuing from the
1382 /// trap operation.
1383 void emitTrap(mlir::Location loc, bool createNewBlock);
1384
1385 LValue emitUnaryOpLValue(const clang::UnaryOperator *e);
1386
1387 mlir::Value emitUnPromotedValue(mlir::Value result, QualType unPromotionType);
1388
1389 /// Emit a reached-unreachable diagnostic if \p loc is valid and runtime
1390 /// checking is enabled. Otherwise, just emit an unreachable instruction.
1391 /// \p createNewBlock indicates whether to create a new block for the IR
1392 /// builder. Since the `cir.unreachable` operation is a terminator, operations
1393 /// that follow an unreachable point cannot be emitted after `cir.unreachable`
1394 /// in the same block. To ensure these operations get emitted successfully,
1395 /// you need to create a dummy block and set the insertion point there before
1396 /// continuing from the unreachable point.
1397 void emitUnreachable(clang::SourceLocation loc, bool createNewBlock);
1398
1399 /// This method handles emission of any variable declaration
1400 /// inside a function, including static vars etc.
1401 void emitVarDecl(const clang::VarDecl &d);
1402
1404
1405 mlir::LogicalResult emitWhileStmt(const clang::WhileStmt &s);
1406
1407 /// Given an assignment `*lhs = rhs`, emit a test that checks if \p rhs is
1408 /// nonnull, if 1\p LHS is marked _Nonnull.
1409 void emitNullabilityCheck(LValue lhs, mlir::Value rhs,
1411
1412 /// An object to manage conditionally-evaluated expressions.
1414 CIRGenFunction &cgf;
1415 mlir::OpBuilder::InsertPoint insertPt;
1416
1417 public:
1419 : cgf(cgf), insertPt(cgf.builder.saveInsertionPoint()) {}
1420 ConditionalEvaluation(CIRGenFunction &cgf, mlir::OpBuilder::InsertPoint ip)
1421 : cgf(cgf), insertPt(ip) {}
1422
1424 assert(cgf.outermostConditional != this);
1425 if (!cgf.outermostConditional)
1426 cgf.outermostConditional = this;
1427 }
1428
1430 assert(cgf.outermostConditional != nullptr);
1431 if (cgf.outermostConditional == this)
1432 cgf.outermostConditional = nullptr;
1433 }
1434
1435 /// Returns the insertion point which will be executed prior to each
1436 /// evaluation of the conditional code. In LLVM OG, this method
1437 /// is called getStartingBlock.
1438 mlir::OpBuilder::InsertPoint getInsertPoint() const { return insertPt; }
1439 };
1440
1442 std::optional<LValue> lhs{}, rhs{};
1443 mlir::Value result{};
1444 };
1445
1446 // Return true if we're currently emitting one branch or the other of a
1447 // conditional expression.
1448 bool isInConditionalBranch() const { return outermostConditional != nullptr; }
1449
1450 void setBeforeOutermostConditional(mlir::Value value, Address addr) {
1451 assert(isInConditionalBranch());
1452 {
1453 mlir::OpBuilder::InsertionGuard guard(builder);
1454 builder.restoreInsertionPoint(outermostConditional->getInsertPoint());
1455 builder.createStore(
1456 value.getLoc(), value, addr, /*isVolatile=*/false,
1457 mlir::IntegerAttr::get(
1458 mlir::IntegerType::get(value.getContext(), 64),
1459 (uint64_t)addr.getAlignment().getAsAlign().value()));
1460 }
1461 }
1462
1463 // Points to the outermost active conditional control. This is used so that
1464 // we know if a temporary should be destroyed conditionally.
1466
1467 /// An RAII object to record that we're evaluating a statement
1468 /// expression.
1470 CIRGenFunction &cgf;
1471
1472 /// We have to save the outermost conditional: cleanups in a
1473 /// statement expression aren't conditional just because the
1474 /// StmtExpr is.
1475 ConditionalEvaluation *savedOutermostConditional;
1476
1477 public:
1479 : cgf(cgf), savedOutermostConditional(cgf.outermostConditional) {
1480 cgf.outermostConditional = nullptr;
1481 }
1482
1484 cgf.outermostConditional = savedOutermostConditional;
1485 }
1486 };
1487
1488 template <typename FuncTy>
1490 const FuncTy &branchGenFunc);
1491
1492 mlir::Value emitTernaryOnBoolExpr(const clang::Expr *cond, mlir::Location loc,
1493 const clang::Stmt *thenS,
1494 const clang::Stmt *elseS);
1495
1496 /// Build a "reference" to a va_list; this is either the address or the value
1497 /// of the expression, depending on how va_list is defined.
1498 Address emitVAListRef(const Expr *e);
1499
1500 /// Emits the start of a CIR variable-argument operation (`cir.va_start`)
1501 ///
1502 /// \param vaList A reference to the \c va_list as emitted by either
1503 /// \c emitVAListRef or \c emitMSVAListRef.
1504 ///
1505 /// \param count The number of arguments in \c vaList
1506 void emitVAStart(mlir::Value vaList, mlir::Value count);
1507
1508 /// Emits the end of a CIR variable-argument operation (`cir.va_start`)
1509 ///
1510 /// \param vaList A reference to the \c va_list as emitted by either
1511 /// \c emitVAListRef or \c emitMSVAListRef.
1512 void emitVAEnd(mlir::Value vaList);
1513
1514 /// Generate code to get an argument from the passed in pointer
1515 /// and update it accordingly.
1516 ///
1517 /// \param ve The \c VAArgExpr for which to generate code.
1518 ///
1519 /// \param vaListAddr Receives a reference to the \c va_list as emitted by
1520 /// either \c emitVAListRef or \c emitMSVAListRef.
1521 ///
1522 /// \returns SSA value with the argument.
1523 mlir::Value emitVAArg(VAArgExpr *ve);
1524
1525 /// ----------------------
1526 /// CIR build helpers
1527 /// -----------------
1528public:
1529 cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc,
1530 const Twine &name = "tmp",
1531 mlir::Value arraySize = nullptr,
1532 bool insertIntoFnEntryBlock = false);
1533 cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc,
1534 const Twine &name = "tmp",
1535 mlir::OpBuilder::InsertPoint ip = {},
1536 mlir::Value arraySize = nullptr);
1537 Address createTempAlloca(mlir::Type ty, CharUnits align, mlir::Location loc,
1538 const Twine &name = "tmp",
1539 mlir::Value arraySize = nullptr,
1540 Address *alloca = nullptr,
1541 mlir::OpBuilder::InsertPoint ip = {});
1542 Address createTempAllocaWithoutCast(mlir::Type ty, CharUnits align,
1543 mlir::Location loc,
1544 const Twine &name = "tmp",
1545 mlir::Value arraySize = nullptr,
1546 mlir::OpBuilder::InsertPoint ip = {});
1547
1548 /// Create a temporary memory object of the given type, with
1549 /// appropriate alignmen and cast it to the default address space. Returns
1550 /// the original alloca instruction by \p Alloca if it is not nullptr.
1551 Address createMemTemp(QualType t, mlir::Location loc,
1552 const Twine &name = "tmp", Address *alloca = nullptr,
1553 mlir::OpBuilder::InsertPoint ip = {});
1554 Address createMemTemp(QualType t, CharUnits align, mlir::Location loc,
1555 const Twine &name = "tmp", Address *alloca = nullptr,
1556 mlir::OpBuilder::InsertPoint ip = {});
1557
1558 //===--------------------------------------------------------------------===//
1559 // OpenACC Emission
1560 //===--------------------------------------------------------------------===//
1561private:
1562 template <typename Op>
1563 Op emitOpenACCOp(mlir::Location start, OpenACCDirectiveKind dirKind,
1564 SourceLocation dirLoc,
1566 // Function to do the basic implementation of an operation with an Associated
1567 // Statement. Models AssociatedStmtConstruct.
1568 template <typename Op, typename TermOp>
1569 mlir::LogicalResult emitOpenACCOpAssociatedStmt(
1570 mlir::Location start, mlir::Location end, OpenACCDirectiveKind dirKind,
1571 SourceLocation dirLoc, llvm::ArrayRef<const OpenACCClause *> clauses,
1572 const Stmt *associatedStmt);
1573
1574 template <typename Op, typename TermOp>
1575 mlir::LogicalResult emitOpenACCOpCombinedConstruct(
1576 mlir::Location start, mlir::Location end, OpenACCDirectiveKind dirKind,
1577 SourceLocation dirLoc, llvm::ArrayRef<const OpenACCClause *> clauses,
1578 const Stmt *loopStmt);
1579
1580 template <typename Op>
1581 void emitOpenACCClauses(Op &op, OpenACCDirectiveKind dirKind,
1582 SourceLocation dirLoc,
1583 ArrayRef<const OpenACCClause *> clauses);
1584 // The second template argument doesn't need to be a template, since it should
1585 // always be an mlir::acc::LoopOp, but as this is a template anyway, we make
1586 // it a template argument as this way we can avoid including the OpenACC MLIR
1587 // headers here. We will count on linker failures/explicit instantiation to
1588 // ensure we don't mess this up, but it is only called from 1 place, and
1589 // instantiated 3x.
1590 template <typename ComputeOp, typename LoopOp>
1591 void emitOpenACCClauses(ComputeOp &op, LoopOp &loopOp,
1592 OpenACCDirectiveKind dirKind, SourceLocation dirLoc,
1593 ArrayRef<const OpenACCClause *> clauses);
1594
1595 // The OpenACC LoopOp requires that we have auto, seq, or independent on all
1596 // LoopOp operations for the 'none' device type case. This function checks if
1597 // the LoopOp has one, else it updates it to have one.
1598 void updateLoopOpParallelism(mlir::acc::LoopOp &op, bool isOrphan,
1600
1601 // The OpenACC 'cache' construct actually applies to the 'loop' if present. So
1602 // keep track of the 'loop' so that we can add the cache vars to it correctly.
1603 mlir::acc::LoopOp *activeLoopOp = nullptr;
1604
1605 struct ActiveOpenACCLoopRAII {
1606 CIRGenFunction &cgf;
1607 mlir::acc::LoopOp *oldLoopOp;
1608
1609 ActiveOpenACCLoopRAII(CIRGenFunction &cgf, mlir::acc::LoopOp *newOp)
1610 : cgf(cgf), oldLoopOp(cgf.activeLoopOp) {
1611 cgf.activeLoopOp = newOp;
1612 }
1613 ~ActiveOpenACCLoopRAII() { cgf.activeLoopOp = oldLoopOp; }
1614 };
1615
1616public:
1617 // Helper type used to store the list of important information for a 'data'
1618 // clause variable, or a 'cache' variable reference.
1620 mlir::Location beginLoc;
1621 mlir::Value varValue;
1622 std::string name;
1625 };
1626 // Gets the collection of info required to lower and OpenACC clause or cache
1627 // construct variable reference.
1629 // Helper function to emit the integer expressions as required by an OpenACC
1630 // clause/construct.
1631 mlir::Value emitOpenACCIntExpr(const Expr *intExpr);
1632 // Helper function to emit an integer constant as an mlir int type, used for
1633 // constants in OpenACC constructs/clauses.
1634 mlir::Value createOpenACCConstantInt(mlir::Location loc, unsigned width,
1635 int64_t value);
1636
1637 mlir::LogicalResult
1639 mlir::LogicalResult emitOpenACCLoopConstruct(const OpenACCLoopConstruct &s);
1640 mlir::LogicalResult
1642 mlir::LogicalResult emitOpenACCDataConstruct(const OpenACCDataConstruct &s);
1643 mlir::LogicalResult
1645 mlir::LogicalResult
1647 mlir::LogicalResult
1649 mlir::LogicalResult emitOpenACCWaitConstruct(const OpenACCWaitConstruct &s);
1650 mlir::LogicalResult emitOpenACCInitConstruct(const OpenACCInitConstruct &s);
1651 mlir::LogicalResult
1653 mlir::LogicalResult emitOpenACCSetConstruct(const OpenACCSetConstruct &s);
1654 mlir::LogicalResult
1656 mlir::LogicalResult
1658 mlir::LogicalResult emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s);
1659
1662
1663 /// Create a temporary memory object for the given aggregate type.
1664 AggValueSlot createAggTemp(QualType ty, mlir::Location loc,
1665 const Twine &name = "tmp",
1666 Address *alloca = nullptr) {
1668 return AggValueSlot::forAddr(
1669 createMemTemp(ty, loc, name, alloca), ty.getQualifiers(),
1672 }
1673
1674private:
1675 QualType getVarArgType(const Expr *arg);
1676};
1677
1678} // namespace clang::CIRGen
1679
1680#endif
Defines the clang::ASTContext interface.
llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> BuilderCallbackRef
Definition: CIRDialect.h:38
C Language Family Type Representation.
__device__ __2f16 b
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition: Expr.h:4289
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2723
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: TypeBase.h:3738
AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
Definition: Stmt.h:3205
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6816
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition: Expr.h:4389
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Definition: Expr.h:4427
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
Definition: Expr.h:4424
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3974
BreakStmt - This represents a break.
Definition: Stmt.h:3090
mlir::Value getPointer() const
Definition: Address.h:81
static Address invalid()
Definition: Address.h:66
clang::CharUnits getAlignment() const
Definition: Address.h:109
bool isValid() const
Definition: Address.h:67
An aggregate value slot.
Definition: CIRGenValue.h:302
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Definition: CIRGenValue.h:359
static AggValueSlot ignored()
Returns an aggregate value slot indicating that the aggregate value is being ignored.
Definition: CIRGenValue.h:348
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::MemOrderAttr order={})
An abstract representation of regular/ObjC call/message targets.
AbstractCallee(const clang::FunctionDecl *fd)
const clang::ParmVarDecl * getParamDecl(unsigned I) const
An object to manage conditionally-evaluated expressions.
ConditionalEvaluation(CIRGenFunction &cgf, mlir::OpBuilder::InsertPoint ip)
mlir::OpBuilder::InsertPoint getInsertPoint() const
Returns the insertion point which will be executed prior to each evaluation of the conditional code.
static ConstantEmission forReference(mlir::TypedAttr c)
static ConstantEmission forValue(mlir::TypedAttr c)
LValue getReferenceLValue(CIRGenFunction &cgf, Expr *refExpr) const
DeclMapRevertingRAII(CIRGenFunction &cgf, const VarDecl *vd)
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
FieldConstructionScope(CIRGenFunction &cgf, Address thisAddr)
A non-RAII class containing all the information about a bound opaque value.
static OpaqueValueMappingData bind(CIRGenFunction &cgf, const OpaqueValueExpr *ov, const LValue &lv)
static OpaqueValueMappingData bind(CIRGenFunction &cgf, const OpaqueValueExpr *ov, const RValue &rv)
static OpaqueValueMappingData bind(CIRGenFunction &cgf, const OpaqueValueExpr *ov, const Expr *e)
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
OpaqueValueMapping(CIRGenFunction &cgf, const OpaqueValueExpr *opaqueValue, RValue rvalue)
OpaqueValueMapping(CIRGenFunction &cgf, const OpaqueValueExpr *opaqueValue, LValue lvalue)
OpaqueValueMapping(CIRGenFunction &cgf, const AbstractConditionalOperator *op)
Build the opaque value mapping for the given conditional operator if it's the GNU ?...
OpaqueValueMapping(CIRGenFunction &cgf, const OpaqueValueExpr *ov)
Build the opaque value mapping for an OpaqueValueExpr whose source expression is set to the expressio...
static bool shouldBindAsLValue(const Expr *expr)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
RunCleanupsScope(CIRGenFunction &cgf)
Enter a new cleanup scope.
void forceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
~RunCleanupsScope()
Exit this cleanup scope, emitting any accumulated cleanups.
void restore()
Can be used to restore the state early, before the dtor is run.
SourceLocRAIIObject(CIRGenFunction &cgf, mlir::Location value)
An RAII object to record that we're evaluating a statement expression.
static bool isConstructorDelegationValid(const clang::CXXConstructorDecl *ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
Definition: CIRGenClass.cpp:29
static bool hasScalarEvaluationKind(clang::QualType type)
void emitOpenACCRoutine(const OpenACCRoutineDecl &d)
mlir::Value emitComplexToScalarConversion(mlir::Value src, QualType srcTy, QualType dstTy, SourceLocation loc)
Emit a conversion from the specified complex type to the specified destination type,...
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0)
Definition: CIRGenCall.cpp:731
mlir::Type convertType(clang::QualType t)
cir::GlobalOp addInitializerToStaticVarDecl(const VarDecl &d, cir::GlobalOp gv, cir::GetGlobalOp gvAddr)
Add the initializer for 'd' to the global variable that has already been created for it.
Definition: CIRGenDecl.cpp:358
mlir::Value emitCheckedArgForAssume(const Expr *e)
Emits an argument for a call to a __builtin_assume.
mlir::LogicalResult emitDoStmt(const clang::DoStmt &s)
Definition: CIRGenStmt.cpp:834
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
RValue convertTempToRValue(Address addr, clang::QualType type, clang::SourceLocation loc)
Given the address of a temporary variable, produce an r-value of its type.
mlir::LogicalResult emitOpenACCDataConstruct(const OpenACCDataConstruct &s)
AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d, mlir::OpBuilder::InsertPoint ip={})
Definition: CIRGenDecl.cpp:27
mlir::Value emitPromotedValue(mlir::Value result, QualType promotionType)
void emitAutoVarTypeCleanup(const AutoVarEmission &emission, clang::QualType::DestructionKind dtorKind)
Enter a destroy cleanup for the given local variable.
Definition: CIRGenDecl.cpp:776
ImplicitParamDecl * cxxabiThisDecl
CXXThisDecl - When generating code for a C++ member function, this will hold the implicit 'this' decl...
EHScopeStack::stable_iterator prologueCleanupDepth
The cleanup depth enclosing all the cleanups associated with the parameters.
mlir::LogicalResult emitOpenACCCombinedConstruct(const OpenACCCombinedConstruct &s)
mlir::LogicalResult emitOpenACCWaitConstruct(const OpenACCWaitConstruct &s)
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
CIRGenTypes & getTypes() const
Address emitPointerWithAlignment(const clang::Expr *expr, LValueBaseInfo *baseInfo=nullptr)
Given an expression with a pointer type, emit the value and compute our best estimate of the alignmen...
Definition: CIRGenExpr.cpp:67
llvm::ScopedHashTable< const clang::Decl *, mlir::Value > SymTableTy
The symbol table maps a variable name to a value in the current scope.
void emitVariablyModifiedType(QualType ty)
RValue emitLoadOfLValue(LValue lv, SourceLocation loc)
Given an expression that represents a value lvalue, this method emits the address of the lvalue,...
Definition: CIRGenExpr.cpp:566
const clang::LangOptions & getLangOpts() const
cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, bool insertIntoFnEntryBlock=false)
This creates an alloca and inserts it into the entry block if ArraySize is nullptr,...
void emitTrap(mlir::Location loc, bool createNewBlock)
Emit a trap instruction, which is used to abort the program in an abnormal way, usually for debugging...
mlir::Block * getCurFunctionEntryBlock()
RValue emitCXXMemberCallExpr(const clang::CXXMemberCallExpr *e, ReturnValueSlot returnValue)
mlir::LogicalResult emitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &s)
LValue emitLValueForBitField(LValue base, const FieldDecl *field)
Definition: CIRGenExpr.cpp:414
mlir::LogicalResult emitIfOnBoolExpr(const clang::Expr *cond, const clang::Stmt *thenS, const clang::Stmt *elseS)
Emit an if on a boolean condition to the specified blocks.
LValue emitScalarCompoundAssignWithComplex(const CompoundAssignOperator *e, mlir::Value &result)
Address cxxDefaultInitExprThis
The value of 'this' to sue when evaluating CXXDefaultInitExprs within this expression.
void emitStaticVarDecl(const VarDecl &d, cir::GlobalLinkageKind linkage)
Definition: CIRGenDecl.cpp:410
mlir::Value emitComplexExpr(const Expr *e)
Emit the computation of the specified expression of complex type, returning the result.
void setBeforeOutermostConditional(mlir::Value value, Address addr)
mlir::LogicalResult emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s)
mlir::Value loadCXXThis()
Load the value for 'this'.
LValue makeNaturalAlignPointeeAddrLValue(mlir::Value v, clang::QualType t)
Given a value of type T* that may not be to a complete object, construct an l-vlaue withi the natural...
RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())
LValue emitMemberExpr(const MemberExpr *e)
clang::CharUnits cxxThisAlignment
const TargetInfo & getTarget() const
llvm::DenseMap< const clang::Decl *, Address > DeclMapTy
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
Address makeNaturalAddressForPointer(mlir::Value ptr, QualType t, CharUnits alignment, bool forPointeeType=false, LValueBaseInfo *baseInfo=nullptr)
Construct an address with the natural alignment of T.
const clang::Decl * curFuncDecl
mlir::LogicalResult emitCXXForRangeStmt(const CXXForRangeStmt &s, llvm::ArrayRef< const Attr * > attrs)
Definition: CIRGenStmt.cpp:686
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOrTryCall=nullptr)
mlir::Value evaluateExprAsBool(const clang::Expr *e)
Perform the usual unary conversions on the specified expression and compare the result against zero,...
Definition: CIRGenExpr.cpp:688
bool isTrivialInitializer(const Expr *init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
Definition: CIRGenDecl.cpp:66
void emitOpenACCDeclare(const OpenACCDeclareDecl &d)
Address getAddrOfLocalVar(const clang::VarDecl *vd)
Return the address of a local variable.
LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)
bool constantFoldsToSimpleInteger(const clang::Expr *cond, llvm::APSInt &resultInt, bool allowLabels=false)
If the specified expression does not fold to a constant, or if it does fold but contains a label,...
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, bool isInit=false, bool isNontemporal=false)
Definition: CIRGenExpr.cpp:312
LValue emitComplexCompoundAssignmentLValue(const CompoundAssignOperator *e)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
void initializeVTablePointers(mlir::Location loc, const clang::CXXRecordDecl *rd)
mlir::Type convertType(const TypeDecl *t)
void emitArrayDestroy(mlir::Value begin, mlir::Value end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer)
Destroys all the elements of the given array, beginning from last to first.
Definition: CIRGenDecl.cpp:695
bool constantFoldsToBool(const clang::Expr *cond, bool &resultBool, bool allowLabels=false)
If the specified expression does not fold to a constant, or if it does but contains a label,...
mlir::Value emitOpOnBoolExpr(mlir::Location loc, const clang::Expr *cond)
TODO(cir): see EmitBranchOnBoolExpr for extra ideas).
void initializeVTablePointer(mlir::Location loc, const VPtr &vptr)
Address getAddressOfBaseClass(Address value, const CXXRecordDecl *derived, llvm::iterator_range< CastExpr::path_const_iterator > path, bool nullCheckValue, SourceLocation loc)
LValue emitStringLiteralLValue(const StringLiteral *e)
Definition: CIRGenExpr.cpp:964
void emitAggregateStore(mlir::Value value, Address dest)
Definition: CIRGenCall.cpp:83
mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s)
Definition: CIRGenStmt.cpp:442
LValue emitLoadOfReferenceLValue(Address refAddr, mlir::Location loc, QualType refTy, AlignmentSource source)
void emitDelegateCXXConstructorCall(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, const FunctionArgList &args, clang::SourceLocation loc)
mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv, cir::UnaryOpKind kind, bool isPre)
ConditionalEvaluation * outermostConditional
mlir::LogicalResult emitOpenACCInitConstruct(const OpenACCInitConstruct &s)
void emitAnyExprToMem(const Expr *e, Address location, Qualifiers quals, bool isInitializer)
Emits the code necessary to evaluate an arbitrary expression into the given memory location.
RValue emitCXXMemberOrOperatorCall(const clang::CXXMethodDecl *md, const CIRGenCallee &callee, ReturnValueSlot returnValue, mlir::Value thisPtr, mlir::Value implicitParam, clang::QualType implicitParamTy, const clang::CallExpr *ce, CallArgList *rtlArgs)
void emitBaseInitializer(mlir::Location loc, const CXXRecordDecl *classDecl, CXXCtorInitializer *baseInit)
RValue emitAtomicExpr(AtomicExpr *e)
void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d, LValue lvalue, bool capturedByInit=false)
Emit an expression as an initializer for an object (variable, field, etc.) at the given location.
Definition: CIRGenDecl.cpp:487
llvm::ScopedHashTableScope< const clang::Decl *, mlir::Value > SymTableScopeTy
mlir::Value emitArrayLength(const clang::ArrayType *arrayType, QualType &baseType, Address &addr)
Computes the length of an array in elements, as well as the base element type and a properly-typed fi...
void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)
mlir::LogicalResult emitOpenACCSetConstruct(const OpenACCSetConstruct &s)
RValue emitReferenceBindingToExpr(const Expr *e)
Emits a reference binding to the passed in expression.
void emitVAStart(mlir::Value vaList, mlir::Value count)
Emits the start of a CIR variable-argument operation (cir.va_start)
VPtrsVector getVTablePointers(const clang::CXXRecordDecl *vtableClass)
RValue emitAnyExpr(const clang::Expr *e, AggValueSlot aggSlot=AggValueSlot::ignored())
Emit code to compute the specified expression which can have any type.
mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s)
Definition: CIRGenStmt.cpp:978
mlir::LogicalResult emitCaseStmt(const clang::CaseStmt &s, mlir::Type condType, bool buildingTopLevelCase)
Definition: CIRGenStmt.cpp:638
LValue emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e)
Definition: CIRGenExpr.cpp:876
OpenACCDataOperandInfo getOpenACCDataOperandInfo(const Expr *e)
mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s, bool useCurrentScope)
Definition: CIRGenStmt.cpp:295
mlir::LogicalResult emitAsmStmt(const clang::AsmStmt &s)
Definition: CIRGenAsm.cpp:86
mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType, clang::QualType dstType, clang::SourceLocation loc)
Emit a conversion from the specified type to the specified destination type, both of which are CIR sc...
mlir::Value emitPromotedComplexExpr(const Expr *e, QualType promotionType)
mlir::LogicalResult emitOpenACCComputeConstruct(const OpenACCComputeConstruct &s)
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
mlir::Value emitUnPromotedValue(mlir::Value result, QualType unPromotionType)
mlir::LogicalResult emitSwitchBody(const clang::Stmt *s)
Definition: CIRGenStmt.cpp:941
mlir::LogicalResult emitForStmt(const clang::ForStmt &s)
Definition: CIRGenStmt.cpp:762
AggValueSlot createAggTemp(QualType ty, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr)
Create a temporary memory object for the given aggregate type.
std::optional< mlir::Value > fnRetAlloca
The compiler-generated variable that holds the return value.
void emitImplicitAssignmentOperatorBody(FunctionArgList &args)
clang::SanitizerSet sanOpts
Sanitizers enabled for this function.
mlir::Type convertTypeForMem(QualType t)
clang::QualType buildFunctionArgList(clang::GlobalDecl gd, FunctionArgList &args)
ConditionalInfo emitConditionalBlocks(const AbstractConditionalOperator *e, const FuncTy &branchGenFunc)
void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args)
This routine generates necessary code to initialize base classes and non-static data members belongin...
mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, mlir::Location loc, clang::CharUnits alignment, bool insertIntoFnEntryBlock, mlir::Value arraySize=nullptr)
void emitUnreachable(clang::SourceLocation loc, bool createNewBlock)
Emit a reached-unreachable diagnostic if loc is valid and runtime checking is enabled.
mlir::Value createDummyValue(mlir::Location loc, clang::QualType qt)
void emitCXXConstructExpr(const clang::CXXConstructExpr *e, AggValueSlot dest)
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc)
Load a complex number from the specified l-value.
LValue emitAggExprToLValue(const Expr *e)
void emitVarDecl(const clang::VarDecl &d)
This method handles emission of any variable declaration inside a function, including static vars etc...
Definition: CIRGenDecl.cpp:211
static Destroyer destroyCXXObject
LValue emitCompoundAssignmentLValue(const clang::CompoundAssignOperator *e)
mlir::Value emitCXXNewExpr(const CXXNewExpr *e)
RValue getUndefRValue(clang::QualType ty)
Get an appropriate 'undef' rvalue for the given type.
LValue makeAddrLValue(Address addr, QualType ty, LValueBaseInfo baseInfo)
mlir::LogicalResult emitLabel(const clang::LabelDecl &d)
Definition: CIRGenStmt.cpp:519
void emitCXXConstructorCall(const clang::CXXConstructorDecl *d, clang::CXXCtorType type, bool forVirtualBase, bool delegating, AggValueSlot thisAVS, const clang::CXXConstructExpr *e)
static bool hasAggregateEvaluationKind(clang::QualType type)
mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass)
Return the Value of the vtable pointer member pointed to by thisAddr.
RValue emitAnyExprToTemp(const clang::Expr *e)
Similarly to emitAnyExpr(), however, the result will always be accessible even if no aggregate locati...
Definition: CIRGenCall.cpp:721
void finishFunction(SourceLocation endLoc)
mlir::LogicalResult emitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &s)
mlir::LogicalResult emitFunctionBody(const clang::Stmt *body)
mlir::LogicalResult emitBreakStmt(const clang::BreakStmt &s)
Definition: CIRGenStmt.cpp:545
mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv, cir::UnaryOpKind op, bool isPre)
mlir::Value emitTernaryOnBoolExpr(const clang::Expr *cond, mlir::Location loc, const clang::Stmt *thenS, const clang::Stmt *elseS)
void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest, bool isInit)
void emitScalarInit(const clang::Expr *init, mlir::Location loc, LValue lvalue, bool capturedByInit=false)
Definition: CIRGenDecl.cpp:473
LValue emitUnaryOpLValue(const clang::UnaryOperator *e)
Definition: CIRGenExpr.cpp:707
bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc)
Definition: CIRGenExpr.cpp:382
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
Definition: CIRGenCall.cpp:500
LValue emitComplexAssignmentLValue(const BinaryOperator *e)
void emitCallArg(CallArgList &args, const clang::Expr *e, clang::QualType argType)
Definition: CIRGenCall.cpp:675
mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s)
Definition: CIRGenStmt.cpp:510
void emitConstructorBody(FunctionArgList &args)
LValue emitLValueForFieldInitialization(LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName)
Like emitLValueForField, excpet that if the Field is a reference, this will return the address of the...
Definition: CIRGenExpr.cpp:500
LValue emitCallExprLValue(const clang::CallExpr *e)
bool haveInsertPoint() const
True if an insertion point is defined.
llvm::SmallVector< mlir::Type, 2 > condTypeStack
The type of the condition for the emitting switch statement.
mlir::Value emitScalarExpr(const clang::Expr *e)
Emit the computation of the specified expression of scalar type.
void emitAutoVarInit(const AutoVarEmission &emission)
Emit the initializer for an allocated variable.
Definition: CIRGenDecl.cpp:79
void emitInitializerForField(clang::FieldDecl *field, LValue lhs, clang::Expr *init)
void emitStopPoint(const Stmt *s)
Build a debug stoppoint if we are emitting debug info.
Definition: CIRGenStmt.cpp:104
void maybeEmitDeferredVarDeclInit(const VarDecl *vd)
Definition: CIRGenDecl.cpp:821
void emitVAEnd(mlir::Value vaList)
Emits the end of a CIR variable-argument operation (cir.va_start)
mlir::Value emitToMemory(mlir::Value value, clang::QualType ty)
Given a value and its clang type, returns the value casted to its memory representation.
Definition: CIRGenExpr.cpp:528
mlir::LogicalResult emitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &s)
LValue emitLValueForField(LValue base, const clang::FieldDecl *field)
Definition: CIRGenExpr.cpp:438
mlir::LogicalResult emitIfStmt(const clang::IfStmt &s)
Definition: CIRGenStmt.cpp:371
void emitAutoVarDecl(const clang::VarDecl &d)
Emit code and set up symbol table for a variable declaration with auto, register, or no storage class...
Definition: CIRGenDecl.cpp:205
cir::FuncOp curFn
The function for which code is currently being generated.
void pushDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer)
Definition: CIRGenDecl.cpp:683
mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType)
mlir::LogicalResult emitSwitchCase(const clang::SwitchCase &s, bool buildingTopLevelCase)
Definition: CIRGenStmt.cpp:669
Address emitLoadOfReference(LValue refLVal, mlir::Location loc, LValueBaseInfo *pointeeBaseInfo)
Address getAddressOfDirectBaseInCompleteClass(mlir::Location loc, Address value, const CXXRecordDecl *derived, const CXXRecordDecl *base, bool baseIsVirtual)
Convert the given pointer to a complete class to the given direct base.
bool shouldNullCheckClassCastValue(const CastExpr *ce)
CIRGenBuilderTy & getBuilder()
void emitDecl(const clang::Decl &d, bool evaluateConditionDecl=false)
Definition: CIRGenDecl.cpp:530
LValue emitBinaryOperatorLValue(const BinaryOperator *e)
mlir::Value emitOpenACCIntExpr(const Expr *intExpr)
Address getAddrOfBitFieldStorage(LValue base, const clang::FieldDecl *field, mlir::Type fieldType, unsigned index)
Definition: CIRGenExpr.cpp:399
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *rd, const CXXRecordDecl *baseRD, bool isVirtual)
Determine whether a base class initialization may overlap some other object.
void emitDestroy(Address addr, QualType type, Destroyer *destroyer)
Immediately perform the destruction of the given object.
Definition: CIRGenDecl.cpp:727
const CIRGenModule & getCIRGenModule() const
void startFunction(clang::GlobalDecl gd, clang::QualType returnType, cir::FuncOp fn, cir::FuncType funcType, FunctionArgList args, clang::SourceLocation loc, clang::SourceLocation startLoc)
Emit code for the start of a function.
CIRGenModule & getCIRGenModule()
unsigned counterRefTmp
Hold counters for incrementally naming temporaries.
mlir::MLIRContext & getMLIRContext()
mlir::LogicalResult emitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &s)
Destroyer * getDestroyer(clang::QualType::DestructionKind kind)
Definition: CIRGenDecl.cpp:760
void Destroyer(CIRGenFunction &cgf, Address addr, QualType ty)
void emitDestructorBody(FunctionArgList &args)
Emits the body of the current destructor.
void emitAtomicInit(Expr *init, LValue dest)
LValue emitCastLValue(const CastExpr *e)
Casts are never lvalues unless that cast is to a reference type.
Definition: CIRGenExpr.cpp:981
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
Definition: CIRGenExpr.cpp:546
bool containsLabel(const clang::Stmt *s, bool ignoreCaseStmts=false)
Return true if the statement contains a label in it.
DeclMapTy localDeclMap
This keeps track of the CIR allocas or globals for local C declarations.
mlir::Value createOpenACCConstantInt(mlir::Location loc, unsigned width, int64_t value)
LValue emitDeclRefLValue(const clang::DeclRefExpr *e)
Definition: CIRGenExpr.cpp:618
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
ConstantEmission tryEmitAsConstant(const DeclRefExpr *refExpr)
Try to emit a reference to the given value without producing it as an l-value.
mlir::Value emitAlignmentAssumption(mlir::Value ptrValue, QualType ty, SourceLocation loc, SourceLocation assumptionLoc, int64_t alignment, mlir::Value offsetValue=nullptr)
mlir::LogicalResult emitCaseDefaultCascade(const T *stmt, mlir::Type condType, mlir::ArrayAttr value, cir::CaseOpKind kind, bool buildingTopLevelCase)
void emitCXXThrowExpr(const CXXThrowExpr *e)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
bool sawAsmBlock
Whether or not a Microsoft-style asm block has been processed within this fuction.
mlir::LogicalResult emitDeclStmt(const clang::DeclStmt &s)
Definition: CIRGenStmt.cpp:433
llvm::DenseMap< const OpaqueValueExpr *, RValue > opaqueRValues
mlir::LogicalResult emitDefaultStmt(const clang::DefaultStmt &s, mlir::Type condType, bool buildingTopLevelCase)
Definition: CIRGenStmt.cpp:662
mlir::LogicalResult emitWhileStmt(const clang::WhileStmt &s)
Definition: CIRGenStmt.cpp:885
mlir::LogicalResult emitLabelStmt(const clang::LabelStmt &s)
Definition: CIRGenStmt.cpp:333
Address emitArrayToPointerDecay(const Expr *e, LValueBaseInfo *baseInfo=nullptr)
EHScopeStack::stable_iterator currentCleanupStackDepth
void emitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, const clang::ArrayType *arrayType, Address arrayBegin, const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize=false)
Emit a loop to call a particular constructor for each of several members of an array.
void pushFullExprCleanup(CleanupKind kind, As... a)
Push a cleanup to be run at the end of the current full-expression.
void emitDelegateCallArg(CallArgList &args, const clang::VarDecl *param, clang::SourceLocation loc)
We are performing a delegate call; that is, the current function is delegating to another one.
Definition: CIRGenCall.cpp:257
mlir::Value emitStoreThroughBitfieldLValue(RValue src, LValue dstresult)
Definition: CIRGenExpr.cpp:364
llvm::DenseMap< const OpaqueValueExpr *, LValue > opaqueLValues
Keeps track of the current set of opaque value expressions.
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
LValue emitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e)
clang::ASTContext & getContext() const
RValue emitCXXMemberOrOperatorMemberCallExpr(const clang::CallExpr *ce, const clang::CXXMethodDecl *md, ReturnValueSlot returnValue, bool hasQualifier, clang::NestedNameSpecifier qualifier, bool isArrow, const clang::Expr *base)
void setAddrOfLocalVar(const clang::VarDecl *vd, Address addr)
Set the address of a local variable.
mlir::Value emitScalarConstant(const ConstantEmission &constant, Expr *e)
RValue emitBuiltinExpr(const clang::GlobalDecl &gd, unsigned builtinID, const clang::CallExpr *e, ReturnValueSlot returnValue)
RValue emitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *e, const CXXMethodDecl *md, ReturnValueSlot returnValue)
mlir::LogicalResult emitCompoundStmt(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
Definition: CIRGenStmt.cpp:87
void emitNullabilityCheck(LValue lhs, mlir::Value rhs, clang::SourceLocation loc)
Given an assignment *lhs = rhs, emit a test that checks if rhs is nonnull, if 1LHS is marked _Nonnull...
Definition: CIRGenDecl.cpp:653
mlir::LogicalResult emitGotoStmt(const clang::GotoStmt &s)
Definition: CIRGenStmt.cpp:491
void emitStoreThroughLValue(RValue src, LValue dst, bool isInit=false)
Store the specified rvalue into the specified lvalue, where both are guaranteed to the have the same ...
Definition: CIRGenExpr.cpp:246
bool isLValueSuitableForInlineAtomic(LValue lv)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
Definition: CIRGenStmt.cpp:110
void popCleanupBlocks(EHScopeStack::stable_iterator oldCleanupStackDepth)
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
Address createTempAllocaWithoutCast(mlir::Type ty, CharUnits align, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, mlir::OpBuilder::InsertPoint ip={})
This creates a alloca and inserts it into the entry block of the current region.
Address emitVAListRef(const Expr *e)
Build a "reference" to a va_list; this is either the address or the value of the expression,...
mlir::LogicalResult emitCompoundStmtWithoutScope(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
Definition: CIRGenStmt.cpp:66
mlir::LogicalResult emitOpenACCExitDataConstruct(const OpenACCExitDataConstruct &s)
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
void emitDelegatingCXXConstructorCall(const CXXConstructorDecl *ctor, const FunctionArgList &args)
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, mlir::Location loc, clang::CharUnits alignment, mlir::OpBuilder::InsertPoint ip, mlir::Value arraySize=nullptr)
mlir::LogicalResult emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s)
void popCleanupBlock()
Pops a cleanup block.
mlir::Value emitVAArg(VAArgExpr *ve)
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr)
LValue emitCompoundLiteralLValue(const CompoundLiteralExpr *e)
void emitAutoVarCleanups(const AutoVarEmission &emission)
Definition: CIRGenDecl.cpp:187
RValue emitRotate(const CallExpr *e, bool isRotateLeft)
mlir::LogicalResult emitOpenACCLoopConstruct(const OpenACCLoopConstruct &s)
CIRGenCallee emitCallee(const clang::Expr *e)
Address emitAddrOfFieldStorage(Address base, const FieldDecl *field, llvm::StringRef fieldName, unsigned fieldIndex)
Get the address of a zero-sized field within a record.
Definition: CIRGenExpr.cpp:35
This class organizes the cross-function state that is used while generating CIR code.
Definition: CIRGenModule.h:56
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
Definition: CIRGenModule.h:102
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo)
FIXME: this could likely be a common helper and not necessarily related with codegen.
const clang::TargetInfo & getTarget() const
Definition: CIRGenModule.h:103
const clang::LangOptions & getLangOpts() const
Definition: CIRGenModule.h:107
mlir::MLIRContext & getMLIRContext()
Definition: CIRGenModule.h:110
This class organizes the cross-module state that is used while lowering AST types to CIR types.
Definition: CIRGenTypes.h:48
A saved depth on the scope stack.
Definition: EHScopeStack.h:53
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
Definition: EHScopeStack.h:44
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
Definition: EHScopeStack.h:174
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
Definition: EHScopeStack.h:179
Type for representing both the decl and type of parameters to a function.
Definition: CIRGenCall.h:191
static LValue makeAddr(Address address, clang::QualType t, LValueBaseInfo baseInfo)
Definition: CIRGenValue.h:229
This trivial value class is used to represent the result of an expression that is evaluated.
Definition: CIRGenValue.h:33
Contains the address where the return value of a function can be stored, and whether the address is v...
Definition: CIRGenCall.h:252
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1549
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2604
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2369
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2869
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition: StmtCXX.h:135
Represents a call to a member function that may be written either with member call syntax (e....
Definition: ExprCXX.h:179
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2129
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2349
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:84
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition: ExprCXX.h:2739
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1209
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
CaseStmt - Represent a case statement.
Definition: Stmt.h:1931
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3612
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:122
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
Definition: CharUnits.h:189
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4236
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3541
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1731
ContinueStmt - This represents a continue.
Definition: Stmt.h:3060
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1272
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1622
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2835
This represents one expression.
Definition: Expr.h:112
Represents a member of a struct/union/class.
Definition: Decl.h:3153
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2891
Represents a function declaration or definition.
Definition: Decl.h:1999
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:57
GotoStmt - This represents a direct goto.
Definition: Stmt.h:2972
IfStmt - This represents an if/then/else.
Definition: Stmt.h:2262
Represents the declaration of a label.
Definition: Decl.h:523
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:2157
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:434
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4914
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3300
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1180
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1230
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Definition: StmtOpenACC.h:132
This class represents a 'loop' construct.
Definition: StmtOpenACC.h:190
Represents a parameter to a function.
Definition: Decl.h:1789
A (possibly-)qualified type.
Definition: TypeBase.h:937
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: TypeBase.h:8383
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3129
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition: Stmt.h:85
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1801
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2512
Exposes information about the current target.
Definition: TargetInfo.h:226
Represents a declaration of a type.
Definition: Decl.h:3506
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2246
Represents a call to the builtin function __builtin_va_arg.
Definition: Expr.h:4893
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:711
Represents a variable declaration or definition.
Definition: Decl.h:925
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:2700
#define bool
Definition: gpuintrin.h:32
AlignmentSource
The source of the alignment of an l-value; an expression of confidence in the alignment actually matc...
Definition: CIRGenValue.h:115
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
CXXCtorType
C++ constructor types.
Definition: ABI.h:24
OpenACCDirectiveKind
Definition: OpenACCKinds.h:28
CXXDtorType
C++ destructor types.
Definition: ABI.h:33
const FunctionProtoType * T
#define true
Definition: stdbool.h:25
static bool aggValueSlot()
static bool peepholeProtection()
static bool opAllocaEscapeByReference()
static bool generateDebugInfo()
AutoVarEmission(const clang::VarDecl &variable)
bool IsEscapingByRef
True if the variable is a __block variable that is captured by an escaping block.
Address getAllocatedAddress() const
Returns the raw, allocated address, which is not necessarily the address of the object itself.
Address getObjectAddress(CIRGenFunction &cgf) const
Returns the address of the object within this declaration.
bool EmittedAsOffload
True if the variable was emitted as an offload recipe, and thus doesn't have the same sort of alloca ...
Address Addr
The address of the alloca for languages with explicit address space (e.g.
bool IsConstantAggregate
True if the variable is of aggregate type and has a constant initializer.
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
mlir::Block * createCleanupBlock(mlir::OpBuilder &builder)
mlir::Block * getOrCreateRetBlock(CIRGenFunction &cgf, mlir::Location loc)
LexicalScope(CIRGenFunction &cgf, mlir::Location loc, mlir::Block *eb)
void updateRetLoc(mlir::Block *b, mlir::Location loc)
mlir::Block * getCleanupBlock(mlir::OpBuilder &builder)
mlir::Block * getOrCreateCleanupBlock(mlir::OpBuilder &builder)
mlir::Location getRetLoc(mlir::Block *b)
llvm::PointerUnion< const clang::FunctionProtoType *, const clang::ObjCMethodDecl * > p
PrototypeWrapper(const clang::ObjCMethodDecl *md)
PrototypeWrapper(const clang::FunctionProtoType *ft)
const clang::CXXRecordDecl * vtableClass
const clang::CXXRecordDecl * nearestVBase
This structure provides a set of types that are commonly used during IR emission.